From 918a68f222be33742e44d5614387430f8a579e94 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 2 Oct 2024 09:23:24 +0400 Subject: [PATCH] parse block hash as a free param (#12539) --- chain/types/ethtypes/eth_types.go | 10 +++ chain/types/ethtypes/eth_types_test.go | 98 ++++++++++++++++++++++++++ itests/fevm_test.go | 10 +++ 3 files changed, 118 insertions(+) diff --git a/chain/types/ethtypes/eth_types.go b/chain/types/ethtypes/eth_types.go index 026fe77cd8..9c0e3f9979 100644 --- a/chain/types/ethtypes/eth_types.go +++ b/chain/types/ethtypes/eth_types.go @@ -1045,6 +1045,16 @@ func (e *EthBlockNumberOrHash) UnmarshalJSON(b []byte) error { return nil } + // check if input is a block hash (66 characters long) + if len(str) == 66 && strings.HasPrefix(str, "0x") { + hash, err := ParseEthHash(str) + if err != nil { + return err + } + e.BlockHash = &hash + return nil + } + // check if block param is a number (decimal or hex) var num EthUint64 if err := num.UnmarshalJSON(b); err == nil { diff --git a/chain/types/ethtypes/eth_types_test.go b/chain/types/ethtypes/eth_types_test.go index f68d390e1a..5bd9e72d49 100644 --- a/chain/types/ethtypes/eth_types_test.go +++ b/chain/types/ethtypes/eth_types_test.go @@ -2,6 +2,7 @@ package ethtypes import ( "encoding/json" + "fmt" "strings" "testing" @@ -534,6 +535,103 @@ func TestFilecoinAddressToEthAddressParams(t *testing.T) { } } +func TestEthBlockNumberOrHashUnmarshalJSON(t *testing.T) { + testCases := []struct { + name string + input string + expected func() EthBlockNumberOrHash + wantErr bool + }{ + { + name: "Valid block number", + input: `{"blockNumber": "0x1234"}`, + expected: func() EthBlockNumberOrHash { + v := uint64(0x1234) + return EthBlockNumberOrHash{BlockNumber: (*EthUint64)(&v)} + }, + }, + { + name: "Valid block hash", + input: `{"blockHash": "0x1234567890123456789012345678901234567890123456789012345678901234"}`, + expected: func() EthBlockNumberOrHash { + h, _ := ParseEthHash("0x1234567890123456789012345678901234567890123456789012345678901234") + return EthBlockNumberOrHash{BlockHash: &h} + }, + }, + { + name: "Valid block number as string", + input: `"0x1234"`, + expected: func() EthBlockNumberOrHash { + v := uint64(0x1234) + return EthBlockNumberOrHash{BlockNumber: (*EthUint64)(&v)} + }, + }, + { + name: "Valid block hash as string", + input: `"0x1234567890123456789012345678901234567890123456789012345678901234"`, + expected: func() EthBlockNumberOrHash { + h, _ := ParseEthHash("0x1234567890123456789012345678901234567890123456789012345678901234") + return EthBlockNumberOrHash{BlockHash: &h} + }, + }, + { + name: "Valid 'latest' string", + input: `"latest"`, + expected: func() EthBlockNumberOrHash { + return EthBlockNumberOrHash{PredefinedBlock: stringPtr("latest")} + }, + }, + { + name: "Valid 'earliest' string", + input: `"earliest"`, + expected: func() EthBlockNumberOrHash { + return EthBlockNumberOrHash{PredefinedBlock: stringPtr("earliest")} + }, + }, + { + name: "Valid 'pending' string", + input: `"pending"`, + expected: func() EthBlockNumberOrHash { + return EthBlockNumberOrHash{PredefinedBlock: stringPtr("pending")} + }, + }, + { + name: "Invalid: both block number and hash", + input: `{"blockNumber": "0x1234", "blockHash": "0x1234567890123456789012345678901234567890123456789012345678901234"}`, + wantErr: true, + }, + { + name: "Invalid block number", + input: `{"blockNumber": "invalid"}`, + wantErr: true, + }, + { + name: "Invalid block hash", + input: `{"blockHash": "invalid"}`, + wantErr: true, + }, + { + name: "Invalid string", + input: `"invalid"`, + wantErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var got EthBlockNumberOrHash + err := got.UnmarshalJSON([]byte(tc.input)) + + if tc.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err, fmt.Sprintf("did not expect error but got %s", err)) + require.Equal(t, tc.expected(), got) + } + }) + } +} + func stringPtr(s string) *string { return &s } diff --git a/itests/fevm_test.go b/itests/fevm_test.go index 9728a130f6..5418df6237 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -1162,6 +1162,16 @@ func TestEthGetBlockReceipts(t *testing.T) { require.NoError(t, err) require.Equal(t, txReceipt, receipt) } + + // try with the geth request format for `EthBlockNumberOrHash` + var req ethtypes.EthBlockNumberOrHash + reqStr := fmt.Sprintf(`"%s"`, lastReceipt.BlockHash.String()) + err = req.UnmarshalJSON([]byte(reqStr)) + require.NoError(t, err) + + gethBlockReceipts, err := client.EthGetBlockReceipts(ctx, req) + require.NoError(t, err) + require.Len(t, gethBlockReceipts, 3) } func deployContractWithEth(ctx context.Context, t *testing.T, client *kit.TestFullNode, ethAddr ethtypes.EthAddress,