Unverified Commit f1801a9f authored by Delweng's avatar Delweng Committed by GitHub

internal/ethapi: implement eth_getBlockReceipts (#27702)

parent 509cd428
...@@ -108,6 +108,16 @@ func (ec *Client) PeerCount(ctx context.Context) (uint64, error) { ...@@ -108,6 +108,16 @@ func (ec *Client) PeerCount(ctx context.Context) (uint64, error) {
return uint64(result), err 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 { type rpcBlock struct {
Hash common.Hash `json:"hash"` Hash common.Hash `json:"hash"`
Transactions []rpcTransaction `json:"transactions"` Transactions []rpcTransaction `json:"transactions"`
......
...@@ -897,6 +897,34 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address ...@@ -897,6 +897,34 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address
return res[:], state.Error() 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) {
block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash)
if block == nil || err != nil {
// 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 {
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 // OverrideAccount indicates the overriding fields of account during the execution
// of a message call. // of a message call.
// Note, state and stateDiff can't be specified at the same time. If state is // Note, state and stateDiff can't be specified at the same time. If state is
...@@ -1717,13 +1745,18 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common. ...@@ -1717,13 +1745,18 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.
// Derive the sender. // Derive the sender.
signer := types.MakeSigner(s.b.ChainConfig(), header.Number, header.Time) 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) from, _ := types.Sender(signer, tx)
fields := map[string]interface{}{ fields := map[string]interface{}{
"blockHash": blockHash, "blockHash": blockHash,
"blockNumber": hexutil.Uint64(blockNumber), "blockNumber": hexutil.Uint64(blockNumber),
"transactionHash": hash, "transactionHash": tx.Hash(),
"transactionIndex": hexutil.Uint64(index), "transactionIndex": hexutil.Uint64(txIndex),
"from": from, "from": from,
"to": tx.To(), "to": tx.To(),
"gasUsed": hexutil.Uint64(receipt.GasUsed), "gasUsed": hexutil.Uint64(receipt.GasUsed),
...@@ -1749,7 +1782,7 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common. ...@@ -1749,7 +1782,7 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.
if receipt.ContractAddress != (common.Address{}) { if receipt.ContractAddress != (common.Address{}) {
fields["contractAddress"] = receipt.ContractAddress 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. // sign is a helper function that signs a transaction with the private key of the given address.
......
This diff is collapsed.
...@@ -617,6 +617,11 @@ web3._extend({ ...@@ -617,6 +617,11 @@ web3._extend({
params: 4, params: 4,
inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputDefaultBlockNumberFormatter, null, null], inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputDefaultBlockNumberFormatter, null, null],
}), }),
new web3._extend.Method({
name: 'getBlockReceipts',
call: 'eth_getBlockReceipts',
params: 1,
}),
], ],
properties: [ properties: [
new web3._extend.Property({ new web3._extend.Property({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment