From f869f32183e4d7a4bd73abec0ecbe9e1edcda489 Mon Sep 17 00:00:00 2001 From: simlecode <69969590+simlecode@users.noreply.github.com> Date: Tue, 7 Mar 2023 16:38:04 +0800 Subject: [PATCH] fix: EthAPI: Make newEthBlockFromFilecoinTipSet faster and correct --- app/submodule/eth/eth_api.go | 75 +++++++++++++++++++++------------ pkg/statemanger/state_manger.go | 1 - 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/app/submodule/eth/eth_api.go b/app/submodule/eth/eth_api.go index 1f829c0e41..c742f48f92 100644 --- a/app/submodule/eth/eth_api.go +++ b/app/submodule/eth/eth_api.go @@ -1058,11 +1058,7 @@ func (a *ethAPI) Web3ClientVersion(ctx context.Context) (string, error) { } func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTxInfo bool, ms *chain.MessageStore, ca v1.IChain) (types.EthBlock, error) { - parent, err := ca.ChainGetTipSet(ctx, ts.Parents()) - if err != nil { - return types.EthBlock{}, err - } - parentKeyCid, err := parent.Key().Cid() + parentKeyCid, err := ts.Parents().Cid() if err != nil { return types.EthBlock{}, err } @@ -1071,6 +1067,8 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx return types.EthBlock{}, err } + bn := types.EthUint64(ts.Height()) + blkCid, err := ts.Key().Cid() if err != nil { return types.EthBlock{}, err @@ -1087,19 +1085,34 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx block := types.NewEthBlock(len(msgs) > 0) - // this seems to be a very expensive way to get gasUsed of the block. may need to find an efficient way to do it gasUsed := int64(0) - for txIdx, msg := range msgs { - msgLookup, err := ca.StateSearchMsg(ctx, types.EmptyTSK, msg.Cid(), constants.LookbackNoLimit, false) - if err != nil || msgLookup == nil { - return types.EthBlock{}, nil + compOutput, err := ca.StateCompute(ctx, ts.Height(), nil, ts.Key()) + if err != nil { + return types.EthBlock{}, fmt.Errorf("failed to compute state: %w", err) + } + + for txIdx, msg := range compOutput.Trace { + // skip system messages like reward application and cron + if msg.Msg.From == builtintypes.SystemActorAddr { + continue } - gasUsed += msgLookup.Receipt.GasUsed - tx, err := newEthTxFromMessageLookup(ctx, msgLookup, txIdx, ms, ca) + gasUsed += msg.MsgRct.GasUsed + smsgCid, err := getSignedMessage(ctx, ms, msg.MsgCid) if err != nil { - return types.EthBlock{}, nil + return types.EthBlock{}, fmt.Errorf("failed to get signed msg %s: %w", msg.MsgCid, err) } + tx, err := newEthTxFromSignedMessage(ctx, smsgCid, ca) + if err != nil { + return types.EthBlock{}, fmt.Errorf("failed to convert msg to ethTx: %w", err) + } + + ti := types.EthUint64(txIdx) + + tx.ChainID = types.EthUint64(types2.Eip155ChainID) + tx.BlockHash = &blkHash + tx.BlockNumber = &bn + tx.TransactionIndex = &ti if fullTxInfo { block.Transactions = append(block.Transactions, tx) @@ -1109,7 +1122,7 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx } block.Hash = blkHash - block.Number = types.EthUint64(ts.Height()) + block.Number = bn block.ParentHash = parentBlkHash block.Timestamp = types.EthUint64(ts.Blocks()[0].Timestamp) block.BaseFeePerGas = types.EthBigInt{Int: ts.Blocks()[0].ParentBaseFee.Int} @@ -1290,20 +1303,9 @@ func newEthTxFromMessageLookup(ctx context.Context, msgLookup *types.MsgLookup, return types.EthTx{}, err } - smsg, err := ms.LoadSignedMessage(ctx, msgLookup.Message) + smsg, err := getSignedMessage(ctx, ms, msgLookup.Message) if err != nil { - // We couldn't find the signed message, it might be a BLS message, so search for a regular message. - msg, err := ms.LoadUnsignedMessage(ctx, msgLookup.Message) - if err != nil { - return types.EthTx{}, err - } - smsg = &types.SignedMessage{ - Message: *msg, - Signature: crypto.Signature{ - Type: crypto.SigTypeUnknown, - Data: nil, - }, - } + return types.EthTx{}, fmt.Errorf("failed to get signed msg: %w", err) } tx, err := newEthTxFromSignedMessage(ctx, smsg, ca) @@ -1664,6 +1666,25 @@ func calculateRewardsAndGasUsed(rewardPercentiles []float64, txGasRewards gasRew return rewards, totalGasUsed } +func getSignedMessage(ctx context.Context, ms *chain.MessageStore, msgCid cid.Cid) (*types.SignedMessage, error) { + smsg, err := ms.LoadSignedMessage(ctx, msgCid) + if err != nil { + // We couldn't find the signed message, it might be a BLS message, so search for a regular message. + msg, err := ms.LoadUnsignedMessage(ctx, msgCid) + if err != nil { + return nil, fmt.Errorf("failed to find msg %s: %w", msgCid, err) + } + smsg = &types.SignedMessage{ + Message: *msg, + Signature: crypto.Signature{ + Type: crypto.SigTypeBLS, + }, + } + } + + return smsg, nil +} + type gasRewardTuple struct { gas uint64 reward types.EthBigInt diff --git a/pkg/statemanger/state_manger.go b/pkg/statemanger/state_manger.go index 7e246681ad..28fcaef613 100644 --- a/pkg/statemanger/state_manger.go +++ b/pkg/statemanger/state_manger.go @@ -478,7 +478,6 @@ func (s *Stmgr) ExecutionTrace(ctx context.Context, ts *types.TipSet) (cid.Cid, } func MakeMsgGasCost(msg *types.Message, ret *vm.Ret) types.MsgGasCost { - fmt.Println(msg.RequiredFunds(), ret.OutPuts.Refund) return types.MsgGasCost{ Message: msg.Cid(), GasUsed: big.NewInt(ret.Receipt.GasUsed),