mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +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)
|
||||
}
|
||||
|
||||
// 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"`
|
||||
|
|
|
|||
|
|
@ -652,6 +652,34 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
|
|||
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
|
||||
// of a message call.
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
||||
// Look up the wallet containing the requested signer
|
||||
|
|
|
|||
|
|
@ -522,6 +522,11 @@ web3._extend({
|
|||
params: 2,
|
||||
inputFormatter: [null, web3._extend.formatters.inputBlockNumberFormatter],
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'getBlockReceipts',
|
||||
call: 'eth_getBlockReceipts',
|
||||
params: 1,
|
||||
}),
|
||||
],
|
||||
properties: [
|
||||
new web3._extend.Property({
|
||||
|
|
|
|||
Loading…
Reference in a new issue