internal/ethapi: implement eth_getBlockReceipts (#27702)
This commit is contained in:
+36
-3
@@ -897,6 +897,34 @@ 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) {
|
||||
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
|
||||
// of a message call.
|
||||
// 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.
|
||||
|
||||
// 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 +1782,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.
|
||||
|
||||
Reference in New Issue
Block a user