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 May 10, 2024
1 parent 4deef22 commit 47d48e3
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 118 deletions.
6 changes: 6 additions & 0 deletions parser/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,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 @@ -79,6 +80,11 @@ type BurnFee struct {
Amount string
}

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

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

Expand Down Expand Up @@ -123,7 +125,7 @@ func (p *Parser) ParseTransactions(ctx context.Context, txsData types.TxsData) (
}

// Main transaction
transaction, err := p.parseTrace(trace.ExecutionTrace, trace.MsgCid, txsData.Tipset, txsData.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 @@ -138,13 +140,6 @@ func (p *Parser) ParseTransactions(ctx context.Context, txsData types.TxsData) (
transactions = append(transactions, subTxs...)
}
}

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

// TxCid <-> TxHash
txHash, err := parser.TranslateTxCidToTxHash(p.helper.GetFilecoinNodeClient(), trace.MsgCid)
if err == nil && txHash != "" {
Expand Down Expand Up @@ -205,8 +200,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 @@ -218,7 +215,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 @@ -267,7 +264,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 @@ -285,59 +282,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 @@ -361,3 +312,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 @@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"errors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"math/big"
"strings"

Expand Down Expand Up @@ -84,7 +86,7 @@ func (p *Parser) ParseTransactions(_ context.Context, txsData types.TxsData) (*t
}

// Main transaction
transaction, err := p.parseTrace(trace.ExecutionTrace, trace.MsgCid, txsData.Tipset, txsData.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 @@ -104,12 +106,6 @@ func (p *Parser) ParseTransactions(_ context.Context, txsData types.TxsData) (*t
}
}

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

// TxCid <-> TxHash
txHash, err := parser.TranslateTxCidToTxHash(p.helper.GetFilecoinNodeClient(), trace.MsgCid)
if err == nil && txHash != "" {
Expand Down Expand Up @@ -196,8 +192,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 @@ -209,7 +207,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 @@ -269,7 +267,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 @@ -287,59 +285,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 @@ -175,7 +175,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "2907480",
results: expectedResults{
totalTraces: 650,
totalTraces: 551,
totalAddress: 98,
totalTxCids: 99,
},
Expand All @@ -186,7 +186,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "845259",
results: expectedResults{
totalTraces: 31,
totalTraces: 26,
totalAddress: 3,
totalTxCids: 0,
},
Expand All @@ -197,7 +197,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "2907520",
results: expectedResults{
totalTraces: 907,
totalTraces: 760,
totalAddress: 88,
totalTxCids: 147,
},
Expand All @@ -208,7 +208,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "3573062",
results: expectedResults{
totalTraces: 773,
totalTraces: 655,
totalAddress: 70,
totalTxCids: 118,
},
Expand All @@ -219,7 +219,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "3573064",
results: expectedResults{
totalTraces: 734,
totalTraces: 637,
totalAddress: 75,
totalTxCids: 97,
},
Expand All @@ -230,7 +230,7 @@ func TestParser_ParseTransactions(t *testing.T) {
url: nodeUrl,
height: "3573066",
results: expectedResults{
totalTraces: 1118,
totalTraces: 941,
totalAddress: 102,
totalTxCids: 177,
},
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 47d48e3

Please sign in to comment.