Skip to content

Commit

Permalink
Unified fees txs (#106)
Browse files Browse the repository at this point in the history
* Unified fees txs

* update tests

* change name

* comment test

* Update v1 parser

* tests
  • Loading branch information
lucaslopezf authored and emmanuelm41 committed Apr 7, 2024
1 parent 66b7747 commit 574eb9d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 117 deletions.
6 changes: 6 additions & 0 deletions parser/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/lotus/api"
"github.com/ipfs/go-cid"
"math/big"
)

type ControlAddress struct {
Expand Down Expand Up @@ -78,6 +79,11 @@ type BurnFee struct {
Amount string
}

type FeeData struct {
FeesMetadata
Amount *big.Int `json:"amount"`
}

type FeesMetadata struct {
TxType string
MinerFee MinerFee
Expand Down
101 changes: 41 additions & 60 deletions parser/v1/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package v1
import (
"encoding/json"
"errors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"math/big"
"strings"

Expand Down Expand Up @@ -119,7 +121,7 @@ func (p *Parser) ParseTransactions(traces []byte, tipset *types.ExtendedTipSet,
}

// Main transaction
transaction, err := p.parseTrace(trace.ExecutionTrace, trace.MsgCid, tipset, ethLogs, uuid.Nil.String())
transaction, err := p.parseTrace(trace.ExecutionTrace, trace.MsgCid, tipset, ethLogs, trace.GasCost, uuid.Nil.String())
if err != nil {
continue
}
Expand All @@ -134,12 +136,6 @@ func (p *Parser) ParseTransactions(traces []byte, tipset *types.ExtendedTipSet,
transactions = append(transactions, subTxs...)
}
}

// Fees
if trace.GasCost.TotalCost.Uint64() > 0 {
feeTx := p.feesTransactions(trace, tipset, transaction.TxType, transaction.Id)
transactions = append(transactions, feeTx)
}
}

transactions = tools.SetNodeMetadataOnTxs(transactions, metadata, Version)
Expand Down Expand Up @@ -182,8 +178,10 @@ func (p *Parser) GetBaseFee(traces []byte, tipset *types.ExtendedTipSet) (uint64
func (p *Parser) parseSubTxs(subTxs []typesV1.ExecutionTraceV1, mainMsgCid cid.Cid, tipSet *types.ExtendedTipSet, ethLogs []types.EthLog, txHash string,
parentId string, level uint16) (txs []*types.Transaction) {
level++
gasCost := api.MsgGasCost{TotalCost: abi.NewTokenAmount(0)} // It is necessary to avoid adding fees to transactions with level != 0

for _, subTx := range subTxs {
subTransaction, err := p.parseTrace(subTx, mainMsgCid, tipSet, ethLogs, parentId)
subTransaction, err := p.parseTrace(subTx, mainMsgCid, tipSet, ethLogs, gasCost, parentId)
if err != nil {
continue
}
Expand All @@ -195,7 +193,7 @@ func (p *Parser) parseSubTxs(subTxs []typesV1.ExecutionTraceV1, mainMsgCid cid.C
return
}

func (p *Parser) parseTrace(trace typesV1.ExecutionTraceV1, mainMsgCid cid.Cid, tipset *types.ExtendedTipSet, ethLogs []types.EthLog, parentId string) (*types.Transaction, error) {
func (p *Parser) parseTrace(trace typesV1.ExecutionTraceV1, mainMsgCid cid.Cid, tipset *types.ExtendedTipSet, ethLogs []types.EthLog, gasCost api.MsgGasCost, parentId string) (*types.Transaction, error) {
txType, err := p.helper.GetMethodName(&parser.LotusMessage{
To: trace.Msg.To,
From: trace.Msg.From,
Expand Down Expand Up @@ -244,7 +242,7 @@ func (p *Parser) parseTrace(trace typesV1.ExecutionTraceV1, mainMsgCid cid.Cid,

messageUuid := tools.BuildMessageId(tipsetCid, blockCid, mainMsgCid.String(), trace.Msg.Cid().String(), parentId)

return &types.Transaction{
tx := &types.Transaction{
TxBasicBlockData: types.TxBasicBlockData{
BasicBlockData: types.BasicBlockData{
Height: uint64(tipset.Height()),
Expand All @@ -262,59 +260,13 @@ func (p *Parser) parseTrace(trace typesV1.ExecutionTraceV1, mainMsgCid cid.Cid,
Status: parser.GetExitCodeStatus(trace.MsgRct.ExitCode),
TxType: txType,
TxMetadata: string(jsonMetadata),
}, nil
}

func (p *Parser) feesTransactions(msg *typesV1.InvocResultV1, tipset *types.ExtendedTipSet, txType, parentTxId string) *types.Transaction {
timestamp := parser.GetTimestamp(tipset.MinTimestamp())
appTools := tools.Tools{Logger: p.logger}
blockCid, err := appTools.GetBlockCidFromMsgCid(msg.MsgCid.String(), txType, nil, tipset)
if err != nil {
p.logger.Sugar().Errorf("Error when trying to get block cid from message, txType '%s': %v", txType, err)
}

minerAddress, err := tipset.GetBlockMiner(blockCid)
if err != nil {
p.logger.Sugar().Errorf("Error when trying to get miner address from block cid '%s': %v", blockCid, err)
}

feesMetadata := parser.FeesMetadata{
TxType: txType,
MinerFee: parser.MinerFee{
MinerAddress: minerAddress,
Amount: msg.GasCost.MinerTip.String(),
},
OverEstimationBurnFee: parser.OverEstimationBurnFee{
BurnAddress: parser.BurnAddress,
Amount: msg.GasCost.OverEstimationBurn.String(),
},
BurnFee: parser.BurnFee{
BurnAddress: parser.BurnAddress,
Amount: msg.GasCost.BaseFeeBurn.String(),
},
}

metadata, _ := json.Marshal(feesMetadata)
feeID := tools.BuildFeeId(tipset.GetCidString(), blockCid, msg.MsgCid.String())

return &types.Transaction{
TxBasicBlockData: types.TxBasicBlockData{
BasicBlockData: types.BasicBlockData{
Height: uint64(tipset.Height()),
TipsetCid: tipset.GetCidString(),
},
BlockCid: blockCid,
},
Id: feeID,
ParentId: parentTxId,
TxTimestamp: timestamp,
TxCid: msg.MsgCid.String(),
TxFrom: msg.Msg.From.String(),
Amount: msg.GasCost.TotalCost.Int,
Status: "Ok",
TxType: parser.TotalFeeOp,
TxMetadata: string(metadata),
if gasCost.TotalCost.Uint64() > 0 {
transactionFeesJson := p.calculateTransactionFees(gasCost, tipset, blockCid)
tx.FeeData = string(transactionFeesJson)
}
return tx, nil
}

func hasMessage(trace *typesV1.InvocResultV1) bool {
Expand All @@ -338,3 +290,32 @@ func (p *Parser) appendAddressInfo(msg *filTypes.Message, key filTypes.TipSetKey
toAdd := p.helper.GetActorAddressInfo(msg.To, key)
parser.AppendToAddressesMap(p.addresses, fromAdd, toAdd)
}

func (p *Parser) calculateTransactionFees(gasCost api.MsgGasCost, tipset *types.ExtendedTipSet, blockCid string) []byte {
minerAddress, err := tipset.GetBlockMiner(blockCid)
if err != nil {
p.logger.Sugar().Errorf("Error when trying to get miner address from block cid '%s': %v", blockCid, err)
}

feeData := parser.FeeData{
FeesMetadata: parser.FeesMetadata{
MinerFee: parser.MinerFee{
MinerAddress: minerAddress,
Amount: gasCost.MinerTip.String(),
},
OverEstimationBurnFee: parser.OverEstimationBurnFee{
BurnAddress: parser.BurnAddress,
Amount: gasCost.OverEstimationBurn.String(),
},
BurnFee: parser.BurnFee{
BurnAddress: parser.BurnAddress,
Amount: gasCost.BaseFeeBurn.String(),
},
},
Amount: gasCost.TotalCost.Int,
}

data, _ := json.Marshal(feeData)

return data
}
83 changes: 32 additions & 51 deletions parser/v2/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package v2
import (
"encoding/json"
"errors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"math/big"
"strings"

Expand Down Expand Up @@ -80,7 +82,7 @@ func (p *Parser) ParseTransactions(traces []byte, tipset *types.ExtendedTipSet,
}

// Main transaction
transaction, err := p.parseTrace(trace.ExecutionTrace, trace.MsgCid, tipset, ethLogs, uuid.Nil.String())
transaction, err := p.parseTrace(trace.ExecutionTrace, trace.MsgCid, tipset, ethLogs, trace.GasCost, uuid.Nil.String())
if err != nil {
continue
}
Expand All @@ -99,12 +101,6 @@ func (p *Parser) ParseTransactions(traces []byte, tipset *types.ExtendedTipSet,
transactions = append(transactions, subTxs...)
}
}

// Fees
if trace.GasCost.TotalCost.Uint64() > 0 {
feeTx := p.feesTransactions(trace, tipset, transaction.TxType, transaction.Id)
transactions = append(transactions, feeTx)
}
}

transactions = tools.SetNodeMetadataOnTxs(transactions, metadata, Version)
Expand Down Expand Up @@ -147,8 +143,10 @@ func (p *Parser) GetBaseFee(traces []byte, tipset *types.ExtendedTipSet) (uint64
func (p *Parser) parseSubTxs(subTxs []typesV2.ExecutionTraceV2, mainMsgCid cid.Cid, tipSet *types.ExtendedTipSet, ethLogs []types.EthLog, txHash string,
parentId string, level uint16) (txs []*types.Transaction) {
level++
gasCost := api.MsgGasCost{TotalCost: abi.NewTokenAmount(0)} // It is necessary to avoid adding fees to transactions with level != 0

for _, subTx := range subTxs {
subTransaction, err := p.parseTrace(subTx, mainMsgCid, tipSet, ethLogs, parentId)
subTransaction, err := p.parseTrace(subTx, mainMsgCid, tipSet, ethLogs, gasCost, parentId)
if err != nil {
continue
}
Expand All @@ -160,7 +158,7 @@ func (p *Parser) parseSubTxs(subTxs []typesV2.ExecutionTraceV2, mainMsgCid cid.C
return
}

func (p *Parser) parseTrace(trace typesV2.ExecutionTraceV2, mainMsgCid cid.Cid, tipset *types.ExtendedTipSet, ethLogs []types.EthLog, parentId string) (*types.Transaction, error) {
func (p *Parser) parseTrace(trace typesV2.ExecutionTraceV2, mainMsgCid cid.Cid, tipset *types.ExtendedTipSet, ethLogs []types.EthLog, gasCost api.MsgGasCost, parentId string) (*types.Transaction, error) {
txType, err := p.helper.GetMethodName(&parser.LotusMessage{
To: trace.Msg.To,
From: trace.Msg.From,
Expand Down Expand Up @@ -220,7 +218,7 @@ func (p *Parser) parseTrace(trace typesV2.ExecutionTraceV2, mainMsgCid cid.Cid,
tipsetCid := tipset.GetCidString()
messageUuid := tools.BuildMessageId(tipsetCid, blockCid, mainMsgCid.String(), msgCid, parentId)

return &types.Transaction{
tx := &types.Transaction{
TxBasicBlockData: types.TxBasicBlockData{
BasicBlockData: types.BasicBlockData{
Height: uint64(tipset.Height()),
Expand All @@ -238,59 +236,42 @@ func (p *Parser) parseTrace(trace typesV2.ExecutionTraceV2, mainMsgCid cid.Cid,
Status: parser.GetExitCodeStatus(trace.MsgRct.ExitCode),
TxType: txType,
TxMetadata: string(jsonMetadata),
}, nil
}
}

func (p *Parser) feesTransactions(msg *typesV2.InvocResultV2, tipset *types.ExtendedTipSet, txType, parentTxId string) *types.Transaction {
timestamp := parser.GetTimestamp(tipset.MinTimestamp())
appTools := tools.Tools{Logger: p.logger}
blockCid, err := appTools.GetBlockCidFromMsgCid(msg.MsgCid.String(), txType, nil, tipset)
if err != nil {
p.logger.Sugar().Errorf("Error when trying to get block cid from message, txType '%s': %v", txType, err)
if gasCost.TotalCost.Uint64() > 0 {
transactionFeesJson := p.calculateTransactionFees(gasCost, tipset, blockCid)
tx.FeeData = string(transactionFeesJson)
}
return tx, nil
}

func (p *Parser) calculateTransactionFees(gasCost api.MsgGasCost, tipset *types.ExtendedTipSet, blockCid string) []byte {
minerAddress, err := tipset.GetBlockMiner(blockCid)
if err != nil {
p.logger.Sugar().Errorf("Error when trying to get miner address from block cid '%s': %v", blockCid, err)
}

feesMetadata := parser.FeesMetadata{
TxType: txType,
MinerFee: parser.MinerFee{
MinerAddress: minerAddress,
Amount: msg.GasCost.MinerTip.String(),
},
OverEstimationBurnFee: parser.OverEstimationBurnFee{
BurnAddress: parser.BurnAddress,
Amount: msg.GasCost.OverEstimationBurn.String(),
},
BurnFee: parser.BurnFee{
BurnAddress: parser.BurnAddress,
Amount: msg.GasCost.BaseFeeBurn.String(),
feeData := parser.FeeData{
FeesMetadata: parser.FeesMetadata{
MinerFee: parser.MinerFee{
MinerAddress: minerAddress,
Amount: gasCost.MinerTip.String(),
},
OverEstimationBurnFee: parser.OverEstimationBurnFee{
BurnAddress: parser.BurnAddress,
Amount: gasCost.OverEstimationBurn.String(),
},
BurnFee: parser.BurnFee{
BurnAddress: parser.BurnAddress,
Amount: gasCost.BaseFeeBurn.String(),
},
},
Amount: gasCost.TotalCost.Int,
}

metadata, _ := json.Marshal(feesMetadata)
feeID := tools.BuildFeeId(tipset.GetCidString(), blockCid, msg.MsgCid.String())
data, _ := json.Marshal(feeData)

return &types.Transaction{
TxBasicBlockData: types.TxBasicBlockData{
BasicBlockData: types.BasicBlockData{
Height: uint64(tipset.Height()),
TipsetCid: tipset.GetCidString(),
},
BlockCid: blockCid,
},
Id: feeID,
ParentId: parentTxId,
TxTimestamp: timestamp,
TxCid: msg.MsgCid.String(),
TxFrom: msg.Msg.From.String(),
Amount: msg.GasCost.TotalCost.Int,
Status: "Ok",
TxType: parser.TotalFeeOp,
TxMetadata: string(metadata),
}
return data
}

func (p *Parser) appendAddressInfo(msg *parser.LotusMessage, key filTypes.TipSetKey) {
Expand Down
12 changes: 6 additions & 6 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "2907480",
results: expectedResults{
totalTraces: 650,
totalTraces: 551,
totalAddress: 98,
},
},
Expand All @@ -150,7 +150,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "845259",
results: expectedResults{
totalTraces: 31,
totalTraces: 26,
totalAddress: 3,
},
},
Expand All @@ -160,7 +160,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "2907520",
results: expectedResults{
totalTraces: 907,
totalTraces: 760,
totalAddress: 88,
},
},
Expand All @@ -170,7 +170,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "3573062",
results: expectedResults{
totalTraces: 773,
totalTraces: 655,
totalAddress: 70,
},
},
Expand All @@ -180,7 +180,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "3573064",
results: expectedResults{
totalTraces: 734,
totalTraces: 637,
totalAddress: 75,
},
},
Expand All @@ -190,7 +190,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "3573066",
results: expectedResults{
totalTraces: 1118,
totalTraces: 941,
totalAddress: 102,
},
},
Expand Down
2 changes: 2 additions & 0 deletions types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type Transaction struct {
TxMetadata string `json:"tx_metadata"`
// ParserVersion is the parser version used to parse this tx
ParserVersion string `json:"parser_version"`
// FeeData is the fee data
FeeData string `json:"fee_data"`
NodeInfo
}

Expand Down

0 comments on commit 574eb9d

Please sign in to comment.