From a84c14215511117f65bfd97d4d22c5346d09f769 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Tue, 11 Jul 2023 23:59:45 +0800 Subject: [PATCH 01/15] internal/ethapi: marshalReceipt Signed-off-by: jsvisa --- internal/ethapi/api.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 52dbaf164cd7..16dda7d24c13 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1717,13 +1717,18 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common. // Derive the sender. signer := types.MakeSigner(s.b.ChainConfig(), header.Number, header.Time) + return marshalReceipt(receipt, blockHash, blockNumber, signer, tx, int(index)), nil +} + +// marshalReceipt marshals a transaction receipt into a JSON object. +func marshalReceipt(receipt *types.Receipt, blockHash common.Hash, blockNumber uint64, signer types.Signer, tx *types.Transaction, txIndex int) map[string]interface{} { from, _ := types.Sender(signer, tx) fields := map[string]interface{}{ "blockHash": blockHash, "blockNumber": hexutil.Uint64(blockNumber), - "transactionHash": hash, - "transactionIndex": hexutil.Uint64(index), + "transactionHash": tx.Hash(), + "transactionIndex": hexutil.Uint64(txIndex), "from": from, "to": tx.To(), "gasUsed": hexutil.Uint64(receipt.GasUsed), @@ -1749,7 +1754,7 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common. if receipt.ContractAddress != (common.Address{}) { fields["contractAddress"] = receipt.ContractAddress } - return fields, nil + return fields } // sign is a helper function that signs a transaction with the private key of the given address. From 28d73472efb420b62e1b347ea947f3ca0e080b45 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Wed, 12 Jul 2023 00:00:02 +0800 Subject: [PATCH 02/15] internal/ethapi: add GetBlockReceipts RPC Signed-off-by: jsvisa --- internal/ethapi/api.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 16dda7d24c13..73b6b935b906 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -897,6 +897,43 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address return res[:], state.Error() } +// GetBlockReceipts returns the block receipts for the given block hash or number or tag. +func (s *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { + var hash common.Hash + if h, ok := blockNrOrHash.Hash(); ok { + hash = h + } else { + block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash) + if err != nil { + return nil, err + } + hash = block.Hash() + } + + block, err := s.b.BlockByHash(ctx, hash) + if err != nil { + return nil, err + } + receipts, err := s.b.GetReceipts(ctx, hash) + if err != nil { + return nil, err + } + txs := block.Transactions() + if len(txs) != len(receipts) { + return nil, fmt.Errorf("receipts length mismatch: %d vs %d", len(txs), len(receipts)) + } + + // Derive the sender. + signer := types.MakeSigner(s.b.ChainConfig(), block.Number(), block.Time()) + + result := make([]map[string]interface{}, len(receipts)) + for i, receipt := range receipts { + result[i] = marshalReceipt(receipt, block.Hash(), block.NumberU64(), signer, txs[i], i) + } + + return result, nil +} + // OverrideAccount indicates the overriding fields of account during the execution // of a message call. // Note, state and stateDiff can't be specified at the same time. If state is From c658bb5cfd2acae4a1bfa6f1df772c6405828592 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Wed, 12 Jul 2023 00:18:13 +0800 Subject: [PATCH 03/15] ethclient: add BlockReceipts client Signed-off-by: jsvisa --- ethclient/ethclient.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 4508027fa47b..82b9ae3dfc80 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -108,6 +108,16 @@ func (ec *Client) PeerCount(ctx context.Context) (uint64, error) { return uint64(result), err } +// BlockReceipts returns the receipts of a given block number or hash +func (ec *Client) BlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]*types.Receipt, error) { + var r []*types.Receipt + err := ec.c.CallContext(ctx, &r, "eth_getBlockReceipts", blockNrOrHash) + if err == nil && r == nil { + return nil, ethereum.NotFound + } + return r, err +} + type rpcBlock struct { Hash common.Hash `json:"hash"` Transactions []rpcTransaction `json:"transactions"` From cb91e0e88f93d6788a8355d6430d0250bd0ac570 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Wed, 12 Jul 2023 23:49:21 +0800 Subject: [PATCH 04/15] internal/ethapi: dry Signed-off-by: jsvisa --- internal/ethapi/api.go | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 73b6b935b906..3ce5af470424 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -899,22 +899,11 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address // GetBlockReceipts returns the block receipts for the given block hash or number or tag. func (s *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { - var hash common.Hash - if h, ok := blockNrOrHash.Hash(); ok { - hash = h - } else { - block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash) - if err != nil { - return nil, err - } - hash = block.Hash() - } - - block, err := s.b.BlockByHash(ctx, hash) + block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash) if err != nil { return nil, err } - receipts, err := s.b.GetReceipts(ctx, hash) + receipts, err := s.b.GetReceipts(ctx, block.Hash()) if err != nil { return nil, err } From 7d6c8e150e3818cb1943becf9fe3f72e59b98860 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Wed, 12 Jul 2023 23:58:53 +0800 Subject: [PATCH 05/15] internal/web3ext: add js method Signed-off-by: jsvisa --- internal/web3ext/web3ext.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 55f19f3104ee..b86b5909d2cb 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -617,6 +617,11 @@ web3._extend({ params: 4, inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputDefaultBlockNumberFormatter, null, null], }), + new web3._extend.Method({ + name: 'getBlockReceipts', + call: 'eth_getBlockReceipts', + params: 1, + }), ], properties: [ new web3._extend.Property({ From 2bb8cfdb6c3a64f0aeb86804c25d080a412705d2 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Thu, 13 Jul 2023 00:14:49 +0800 Subject: [PATCH 06/15] internal/jsre: add inputBlockNumberOrHashFormatter Signed-off-by: jsvisa --- internal/jsre/deps/web3.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index 7a09fddab033..6a72e268529f 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -3706,6 +3706,13 @@ var inputDefaultBlockNumberFormatter = function (blockNumber) { return inputBlockNumberFormatter(blockNumber); }; +var inputBlockNumberOrHashFormatter = function (numberOrHash) { + if (utils.isString(numberOrHash) && numberOrHash.indexOf('0x') === 0) { + return numberOrHash; + } + return inputBlockNumberFormatter(numberOrHash); +}; + var inputBlockNumberFormatter = function (blockNumber) { if (blockNumber === undefined) { return undefined; From f9b59ddee82e1d2da0ac9721801c87a67e5619a3 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Thu, 13 Jul 2023 00:16:01 +0800 Subject: [PATCH 07/15] internal/web3ext: format input blockNrOrHash Signed-off-by: jsvisa --- internal/web3ext/web3ext.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index b86b5909d2cb..768c9d8a5831 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -621,6 +621,7 @@ web3._extend({ name: 'getBlockReceipts', call: 'eth_getBlockReceipts', params: 1, + inputFormatter: [web3._extend.formatters.inputBlockNumberOrHashFormatter], }), ], properties: [ From cf7ea1e507280c65b2e13ff84226444ba0c34e5a Mon Sep 17 00:00:00 2001 From: jsvisa Date: Thu, 13 Jul 2023 00:21:04 +0800 Subject: [PATCH 08/15] internal/jsre: export inputBlockNumberOrHashFormatter Signed-off-by: jsvisa --- internal/jsre/deps/web3.js | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index 6a72e268529f..5d669d496f23 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -3974,6 +3974,7 @@ var outputSyncingFormatter = function(result) { module.exports = { inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter, + inputBlockNumberOrHashFormatter: inputBlockNumberOrHashFormatter, inputBlockNumberFormatter: inputBlockNumberFormatter, inputCallFormatter: inputCallFormatter, inputTransactionFormatter: inputTransactionFormatter, From ae56e11580765ea379628cfedb2b2c0045356dfc Mon Sep 17 00:00:00 2001 From: jsvisa Date: Thu, 13 Jul 2023 22:54:41 +0800 Subject: [PATCH 09/15] internal/ethapi: add a helper to setup receipt backend Signed-off-by: jsvisa --- internal/ethapi/api_test.go | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 671b9b2e4972..e379f18e46fa 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -1766,9 +1766,7 @@ func TestRPCGetBlockOrHeader(t *testing.T) { } } -func TestRPCGetTransactionReceipt(t *testing.T) { - t.Parallel() - +func setupReceiptBackend(t *testing.T, genBlocks int) (*testBackend, []common.Hash) { // Initialize test accounts var ( acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") @@ -1794,9 +1792,8 @@ func TestRPCGetTransactionReceipt(t *testing.T) { contract: {Balance: big.NewInt(params.Ether), Code: common.FromHex("0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a9059cbb14610030575b600080fd5b61004a6004803603810190610045919061016a565b610060565b60405161005791906101c5565b60405180910390f35b60008273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516100bf91906101ef565b60405180910390a36001905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610101826100d6565b9050919050565b610111816100f6565b811461011c57600080fd5b50565b60008135905061012e81610108565b92915050565b6000819050919050565b61014781610134565b811461015257600080fd5b50565b6000813590506101648161013e565b92915050565b60008060408385031215610181576101806100d1565b5b600061018f8582860161011f565b92505060206101a085828601610155565b9150509250929050565b60008115159050919050565b6101bf816101aa565b82525050565b60006020820190506101da60008301846101b6565b92915050565b6101e981610134565b82525050565b600060208201905061020460008301846101e0565b9291505056fea2646970667358221220b469033f4b77b9565ee84e0a2f04d496b18160d26034d54f9487e57788fd36d564736f6c63430008120033")}, }, } - genBlocks = 5 - signer = types.LatestSignerForChainID(params.TestChainConfig.ChainID) - txHashes = make([]common.Hash, genBlocks) + signer = types.LatestSignerForChainID(params.TestChainConfig.ChainID) + txHashes = make([]common.Hash, genBlocks) ) backend := newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) { var ( @@ -1838,16 +1835,16 @@ func TestRPCGetTransactionReceipt(t *testing.T) { txHashes[i] = tx.Hash() } }) - api := NewTransactionAPI(backend, new(AddrLocker)) - blockHashes := make([]common.Hash, genBlocks+1) - ctx := context.Background() - for i := 0; i <= genBlocks; i++ { - header, err := backend.HeaderByNumber(ctx, rpc.BlockNumber(i)) - if err != nil { - t.Errorf("failed to get block: %d err: %v", i, err) - } - blockHashes[i] = header.Hash() - } + return backend, txHashes +} + +func TestRPCGetTransactionReceipt(t *testing.T) { + t.Parallel() + + var ( + backend, txHashes = setupReceiptBackend(t, 5) + api = NewTransactionAPI(backend, new(AddrLocker)) + ) var testSuite = []struct { txHash common.Hash From ec72fb3030ad74dce693b0506a5505ef5938f002 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Thu, 13 Jul 2023 23:32:55 +0800 Subject: [PATCH 10/15] internal/ethapi: early quit if block is nil Signed-off-by: jsvisa --- internal/ethapi/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 3ce5af470424..a876673db1b3 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -900,7 +900,7 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address // GetBlockReceipts returns the block receipts for the given block hash or number or tag. func (s *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash) - if err != nil { + if block == nil || err != nil { return nil, err } receipts, err := s.b.GetReceipts(ctx, block.Hash()) From 54dfe9591df12d9520009ed5185a9166f2ce162c Mon Sep 17 00:00:00 2001 From: jsvisa Date: Fri, 14 Jul 2023 00:03:01 +0800 Subject: [PATCH 11/15] internal/ethapi: add getBlockReceipts testcase Signed-off-by: jsvisa --- internal/ethapi/api_test.go | 99 +++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index e379f18e46fa..4cb104c40530 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -1997,3 +1997,102 @@ func TestRPCGetTransactionReceipt(t *testing.T) { require.JSONEqf(t, want, have, "test %d: json not match, want: %s, have: %s", i, want, have) } } + +func TestRPCGetBlockReceipts(t *testing.T) { + t.Parallel() + + var ( + genBlocks = 5 + backend, _ = setupReceiptBackend(t, genBlocks) + api = NewBlockChainAPI(backend) + ) + blockHashes := make([]common.Hash, genBlocks+1) + ctx := context.Background() + for i := 0; i <= genBlocks; i++ { + header, err := backend.HeaderByNumber(ctx, rpc.BlockNumber(i)) + if err != nil { + t.Errorf("failed to get block: %d err: %v", i, err) + } + blockHashes[i] = header.Hash() + } + + var testSuite = []struct { + test rpc.BlockNumberOrHash + want string + }{ + // 0. block without any txs(hash) + { + test: rpc.BlockNumberOrHashWithHash(blockHashes[0], false), + want: `[]`, + }, + // 1. block without any txs(number) + { + test: rpc.BlockNumberOrHashWithNumber(0), + want: `[]`, + }, + // 2. earliest tag + { + test: rpc.BlockNumberOrHashWithNumber(rpc.EarliestBlockNumber), + want: `[]`, + }, + // 3. latest tag + { + test: rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber), + want: `[{"blockHash":"0x08e23d8e3711a21fbb8becd7de22fda8fb0a49fba14e1be763d00f99063627e1","blockNumber":"0x5","contractAddress":"0xfdaa97661a584d977b4d3abb5370766ff5b86a18","cumulativeGasUsed":"0xe01a","effectiveGasPrice":"0x1ecb3f75","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0xe01a","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":null,"transactionHash":"0x8f3c4e2663af0312d508ebd8587f0c88dccbbc8a9bcc322421ff4bc28c456a92","transactionIndex":"0x0","type":"0x1"}]`, + }, + // 4. block with legacy transfer tx(hash) + { + test: rpc.BlockNumberOrHashWithHash(blockHashes[1], false), + want: `[{"blockHash":"0x1356e49a24d4504e450b303aa770f4ae13c29b9ffacaea1d7dd4043396229dd9","blockNumber":"0x1","contractAddress":null,"cumulativeGasUsed":"0x5208","effectiveGasPrice":"0x342770c0","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0x5208","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":"0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e","transactionHash":"0x644a31c354391520d00e95b9affbbb010fc79ac268144ab8e28207f4cf51097e","transactionIndex":"0x0","type":"0x0"}]`, + }, + // 5. block with contract create tx(number) + { + test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(2)), + want: `[{"blockHash":"0x4fc27a4efa7fb8faa04b12b53ec8c8424ab4c21aab1323846365f000e8b4a594","blockNumber":"0x2","contractAddress":"0xae9bea628c4ce503dcfd7e305cab4e29e7476592","cumulativeGasUsed":"0xcf4e","effectiveGasPrice":"0x2db16291","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0xcf4e","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":null,"transactionHash":"0x340e58cda5086495010b571fe25067fecc9954dc4ee3cedece00691fa3f5904a","transactionIndex":"0x0","type":"0x0"}]`, + }, + // 6. block with legacy contract call tx(hash) + { + test: rpc.BlockNumberOrHashWithHash(blockHashes[3], false), + want: `[{"blockHash":"0x73385c190219326907524b0020ef453ebc450eaa971ebce16f79e2d23e7e8d4d","blockNumber":"0x3","contractAddress":null,"cumulativeGasUsed":"0x5e28","effectiveGasPrice":"0x281c2534","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0x5e28","logs":[{"address":"0x0000000000000000000000000000000000031ec7","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x000000000000000000000000703c4b2bd70c169f5717101caee543299fc946c7","0x0000000000000000000000000000000000000000000000000000000000000003"],"data":"0x000000000000000000000000000000000000000000000000000000000000000d","blockNumber":"0x3","transactionHash":"0x9dbf43ec9afc8d711932618616471088f66ba4f25fd5c672d97473d02dae967f","transactionIndex":"0x0","blockHash":"0x73385c190219326907524b0020ef453ebc450eaa971ebce16f79e2d23e7e8d4d","logIndex":"0x0","removed":false}],"logsBloom":"0x00000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000800000000000000008000000000000000000000000000000000020000000080000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000400000000002000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000","status":"0x1","to":"0x0000000000000000000000000000000000031ec7","transactionHash":"0x9dbf43ec9afc8d711932618616471088f66ba4f25fd5c672d97473d02dae967f","transactionIndex":"0x0","type":"0x0"}]`, + }, + // 7. block with dynamic fee tx(number) + { + test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(4)), + want: `[{"blockHash":"0x77c3f8919590e0e68db4ce74a3da3140ac3e96dd3d078a48db1da4c08b07503d","blockNumber":"0x4","contractAddress":null,"cumulativeGasUsed":"0x538d","effectiveGasPrice":"0x2325c3e8","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0x538d","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x0","to":"0x0000000000000000000000000000000000031ec7","transactionHash":"0x672e3e39adf23b5656989b7a36e54d54004b1866f53871113bc52e137edb9faf","transactionIndex":"0x0","type":"0x2"}]`, + }, + // 8. block is empty + { + test: rpc.BlockNumberOrHashWithHash(common.Hash{}, false), + want: `null`, + }, + // 9. block is not found + { + test: rpc.BlockNumberOrHashWithHash(common.HexToHash("deadbeef"), false), + want: `null`, + }, + // 10. block is not found + { + test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(genBlocks + 1)), + want: `null`, + }, + } + + for i, tt := range testSuite { + var ( + result interface{} + err error + ) + result, err = api.GetBlockReceipts(context.Background(), tt.test) + if err != nil { + t.Errorf("test %d: want no error, have %v", i, err) + continue + } + data, err := json.Marshal(result) + if err != nil { + t.Errorf("test %d: json marshal error", i) + continue + } + want, have := tt.want, string(data) + require.JSONEqf(t, want, have, "test %d: json not match, want: %s, have: %s", i, want, have) + } +} From c0d32b8bf63e8cc9e479cc5421ef8bc845636bcb Mon Sep 17 00:00:00 2001 From: jsvisa Date: Fri, 14 Jul 2023 17:54:44 +0800 Subject: [PATCH 12/15] internal: return null if block not found Signed-off-by: jsvisa --- internal/ethapi/api.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index a876673db1b3..09f41a836157 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -901,7 +901,9 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address func (s *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash) if block == nil || err != nil { - return nil, err + // When the block doesn't exist, the RPC method should return JSON null + // as per specification. + return nil, nil } receipts, err := s.b.GetReceipts(ctx, block.Hash()) if err != nil { From 0f4753e7585ba1ae1faa7e63ae281ae9cb7cab0a Mon Sep 17 00:00:00 2001 From: jsvisa Date: Mon, 7 Aug 2023 22:53:40 +0800 Subject: [PATCH 13/15] Revert "internal/jsre: export inputBlockNumberOrHashFormatter" This reverts commit cf7ea1e507280c65b2e13ff84226444ba0c34e5a. Signed-off-by: jsvisa --- internal/jsre/deps/web3.js | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index 5d669d496f23..6a72e268529f 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -3974,7 +3974,6 @@ var outputSyncingFormatter = function(result) { module.exports = { inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter, - inputBlockNumberOrHashFormatter: inputBlockNumberOrHashFormatter, inputBlockNumberFormatter: inputBlockNumberFormatter, inputCallFormatter: inputCallFormatter, inputTransactionFormatter: inputTransactionFormatter, From db4c6d8168025917bd0b96b9500f07f6039e2179 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Mon, 7 Aug 2023 22:53:51 +0800 Subject: [PATCH 14/15] Revert "internal/jsre: add inputBlockNumberOrHashFormatter" This reverts commit 2bb8cfdb6c3a64f0aeb86804c25d080a412705d2. Signed-off-by: jsvisa --- internal/jsre/deps/web3.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index 6a72e268529f..7a09fddab033 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -3706,13 +3706,6 @@ var inputDefaultBlockNumberFormatter = function (blockNumber) { return inputBlockNumberFormatter(blockNumber); }; -var inputBlockNumberOrHashFormatter = function (numberOrHash) { - if (utils.isString(numberOrHash) && numberOrHash.indexOf('0x') === 0) { - return numberOrHash; - } - return inputBlockNumberFormatter(numberOrHash); -}; - var inputBlockNumberFormatter = function (blockNumber) { if (blockNumber === undefined) { return undefined; From 7c090aa388f58cf6fc692784da872ea5674007c1 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Mon, 7 Aug 2023 23:04:17 +0800 Subject: [PATCH 15/15] Revert "internal/web3ext: format input blockNrOrHash" This reverts commit f9b59ddee82e1d2da0ac9721801c87a67e5619a3. Signed-off-by: jsvisa --- internal/web3ext/web3ext.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 768c9d8a5831..b86b5909d2cb 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -621,7 +621,6 @@ web3._extend({ name: 'getBlockReceipts', call: 'eth_getBlockReceipts', params: 1, - inputFormatter: [web3._extend.formatters.inputBlockNumberOrHashFormatter], }), ], properties: [