mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-05 12:41:14 +00:00
ethapi: implement eth_getBlockReceipts (#27702)
This commit is contained in:
parent
d6a5095fa1
commit
c928c79d95
3 changed files with 81 additions and 0 deletions
|
|
@ -70,6 +70,16 @@ func (ec *Client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Bl
|
||||||
return ec.getBlock(ctx, "eth_getBlockByNumber", toBlockNumArg(number), true)
|
return ec.getBlock(ctx, "eth_getBlockByNumber", toBlockNumArg(number), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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"`
|
||||||
|
|
|
||||||
|
|
@ -652,6 +652,34 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
|
||||||
return res[:], state.Error()
|
return res[:], state.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlockReceipts returns the block receipts for the given block hash or number or tag.
|
||||||
|
func (s *PublicBlockChainAPI) 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())
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -2123,6 +2151,44 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
|
||||||
return fields, nil
|
return fields, 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": tx.Hash(),
|
||||||
|
"transactionIndex": hexutil.Uint64(txIndex),
|
||||||
|
"from": from,
|
||||||
|
"to": tx.To(),
|
||||||
|
"gasUsed": hexutil.Uint64(receipt.GasUsed),
|
||||||
|
"cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed),
|
||||||
|
"contractAddress": nil,
|
||||||
|
"logs": receipt.Logs,
|
||||||
|
"logsBloom": receipt.Bloom,
|
||||||
|
"type": hexutil.Uint(tx.Type()),
|
||||||
|
// uncomment below line after EIP-1559
|
||||||
|
// TODO: "effectiveGasPrice": (*hexutil.Big)(receipt.EffectiveGasPrice),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign receipt status or post state.
|
||||||
|
if len(receipt.PostState) > 0 {
|
||||||
|
fields["root"] = hexutil.Bytes(receipt.PostState)
|
||||||
|
} else {
|
||||||
|
fields["status"] = hexutil.Uint(receipt.Status)
|
||||||
|
}
|
||||||
|
if receipt.Logs == nil {
|
||||||
|
fields["logs"] = []*types.Log{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
|
||||||
|
if receipt.ContractAddress != (common.Address{}) {
|
||||||
|
fields["contractAddress"] = receipt.ContractAddress
|
||||||
|
}
|
||||||
|
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.
|
||||||
func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
||||||
// Look up the wallet containing the requested signer
|
// Look up the wallet containing the requested signer
|
||||||
|
|
|
||||||
|
|
@ -522,6 +522,11 @@ web3._extend({
|
||||||
params: 2,
|
params: 2,
|
||||||
inputFormatter: [null, web3._extend.formatters.inputBlockNumberFormatter],
|
inputFormatter: [null, web3._extend.formatters.inputBlockNumberFormatter],
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'getBlockReceipts',
|
||||||
|
call: 'eth_getBlockReceipts',
|
||||||
|
params: 1,
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
properties: [
|
properties: [
|
||||||
new web3._extend.Property({
|
new web3._extend.Property({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue