Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: EthAPI: Make newEthBlockFromFilecoinTipSet faster and correct #10380

Merged
merged 1 commit into from
Mar 4, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 47 additions & 22 deletions node/impl/full/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,8 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
return ethtypes.EthBlock{}, err
}

bn := ethtypes.EthUint64(ts.Height())

blkCid, err := ts.Key().Cid()
if err != nil {
return ethtypes.EthBlock{}, err
Expand All @@ -1792,19 +1794,34 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx

block := ethtypes.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 := sa.StateSearchMsg(ctx, types.EmptyTSK, msg.Cid(), api.LookbackNoLimit, false)
if err != nil || msgLookup == nil {
return ethtypes.EthBlock{}, nil
compOutput, err := sa.StateCompute(ctx, ts.Height(), nil, ts.Key())
if err != nil {
return ethtypes.EthBlock{}, xerrors.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 {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arajasek, there is still an issue. The transactionIndex returns different results in the eth_getBlockByNumber and eth_getTransactionReceipt interfaces. The reason is that txIdx did not ignore system messages, and this is not as expected.

Example in hyperspace:

 curl -s --location 'http://localhost:8839/rpc/v1' \
--header 'Content-Type: application/json' \
--data '{
    "jsonrpc":"2.0",
    "method":"eth_getTransactionReceipt",
    "params":["0xcc502ba55e9d312349c647783964c7edb00c3890b96842bd53e718475dc8c71e"],
    "id":1
}' |gojq
{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "blockHash": "0x52206698ebadc31c0e3e211a9cd3f02dc81603f74e8a604dc460fa3cab1f597b",
    "blockNumber": "0x1f302",
    "contractAddress": null,
    "cumulativeGasUsed": "0x0",
    "effectiveGasPrice": "0x48724a74",
    "from": "0xff000000000000000000000000000000000005e4",
    "gasUsed": "0x135482a",
    "logs": [],
    "logsBloom": "0x09000c0000085003840012000100102008204100010000002105018000100000040000400024000100800000003000000010001002001110500000020016a0048880004040800081488100088e80400208048011010410000120000180002086200000280a022004000000812068490000002004000400000a01001000420800010000440400000002410100000004045800200500b000a0800140024001000060081000008109000000001800020800000420008083800060888044000040000200840a00002010600000000010d0800400000000080048081408000800600028400800048000400000400000a1000108000020001003440504088000026000",
    "root": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "status": "0x1",
    "to": "0xff0000000000000000000000000000000000088a",
    "transactionHash": "0xcc502ba55e9d312349c647783964c7edb00c3890b96842bd53e718475dc8c71e",
    "transactionIndex": "0x0",
    "type": "0x2"
  }
}
curl -s --location 'http://localhost:8839/rpc/v1' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "eth_getBlockByNumber",
"id": 1,
"params": ["0x1f302", true]
}
' |gojq
{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "baseFeePerGas": "0x64",
    "difficulty": "0x0",
    "extraData": "0x",
    "gasLimit": "0x2540be400",
    "gasUsed": "0x135482a",
    "hash": "0x52206698ebadc31c0e3e211a9cd3f02dc81603f74e8a604dc460fa3cab1f597b",
    "logsBloom": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
    "miner": "0x0000000000000000000000000000000000000000",
    "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "nonce": "0x0000000000000000",
    "number": "0x1f302",
    "parentHash": "0xef02f6d94ef93a9755fcfa001708a45f058569e5a871b9b0ed574a2ee79501c6",
    "receiptsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
    "size": "0x0",
    "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp": "0x63ff621c",
    "totalDifficulty": "0x0",
    "transactions": [
      {
        "accessList": [],
        "blockHash": "0x52206698ebadc31c0e3e211a9cd3f02dc81603f74e8a604dc460fa3cab1f597b",
        "blockNumber": "0x1f302",
        "chainId": "0xc45",
        "from": "0xff000000000000000000000000000000000005e4",
        "gas": "0x18149c7",
        "hash": "0xcc502ba55e9d312349c647783964c7edb00c3890b96842bd53e718475dc8c71e",
        "input": "0x",
        "maxFeePerGas": "0x3a27a7a0",
        "maxPriorityFeePerGas": "0x3a27a382",
        "nonce": "0x113f",
        "r": "0x0",
        "s": "0x0",
        "to": "0xff0000000000000000000000000000000000088a",
        "transactionIndex": "0x1",
        "type": "0x2",
        "v": "0x0",
        "value": "0x0"
      }
    ],
    "transactionsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "uncles": []
  }
}

continue
}
gasUsed += msgLookup.Receipt.GasUsed

tx, err := newEthTxFromMessageLookup(ctx, msgLookup, txIdx, cs, sa)
gasUsed += msg.MsgRct.GasUsed
smsgCid, err := getSignedMessage(ctx, cs, msg.MsgCid)
if err != nil {
return ethtypes.EthBlock{}, nil
return ethtypes.EthBlock{}, xerrors.Errorf("failed to get signed msg %s: %w", msg.MsgCid, err)
}
tx, err := newEthTxFromSignedMessage(ctx, smsgCid, sa)
if err != nil {
return ethtypes.EthBlock{}, xerrors.Errorf("failed to convert msg to ethTx: %w", err)
}

ti := ethtypes.EthUint64(txIdx)

tx.ChainID = ethtypes.EthUint64(build.Eip155ChainId)
tx.BlockHash = &blkHash
tx.BlockNumber = &bn
tx.TransactionIndex = &ti

if fullTxInfo {
block.Transactions = append(block.Transactions, tx)
Expand All @@ -1814,7 +1831,7 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
}

block.Hash = blkHash
block.Number = ethtypes.EthUint64(ts.Height())
block.Number = bn
block.ParentHash = parentBlkHash
block.Timestamp = ethtypes.EthUint64(ts.Blocks()[0].Timestamp)
block.BaseFeePerGas = ethtypes.EthBigInt{Int: ts.Blocks()[0].ParentBaseFee.Int}
Expand Down Expand Up @@ -1995,20 +2012,9 @@ func newEthTxFromMessageLookup(ctx context.Context, msgLookup *api.MsgLookup, tx
return ethtypes.EthTx{}, err
}

smsg, err := cs.GetSignedMessage(ctx, msgLookup.Message)
smsg, err := getSignedMessage(ctx, cs, 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 := cs.GetMessage(ctx, msgLookup.Message)
if err != nil {
return ethtypes.EthTx{}, err
}
smsg = &types.SignedMessage{
Message: *msg,
Signature: crypto.Signature{
Type: crypto.SigTypeBLS,
Data: nil,
},
}
return ethtypes.EthTx{}, xerrors.Errorf("failed to get signed msg: %w", err)
}

tx, err := newEthTxFromSignedMessage(ctx, smsg, sa)
Expand Down Expand Up @@ -2364,6 +2370,25 @@ func calculateRewardsAndGasUsed(rewardPercentiles []float64, txGasRewards gasRew
return rewards, totalGasUsed
}

func getSignedMessage(ctx context.Context, cs *store.ChainStore, msgCid cid.Cid) (*types.SignedMessage, error) {
smsg, err := cs.GetSignedMessage(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 := cs.GetMessage(ctx, msgCid)
if err != nil {
return nil, xerrors.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 ethtypes.EthBigInt
Expand Down