mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 05:36:46 +00:00
feat: implement eth_getBlockReceipts (#796)
* internal/ethapi: implement eth_getBlockReceipts (#27702) * chore: auto version bump [bot] * chore: auto version bump [bot] --------- Co-authored-by: Delweng <delweng@gmail.com> Co-authored-by: Thegaram <Thegaram@users.noreply.github.com> Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Co-authored-by: Ömer Faruk Irmak <omerfirmak@gmail.com> Co-authored-by: omerfirmak <omerfirmak@users.noreply.github.com>
This commit is contained in:
parent
60bbfc1c2c
commit
81074f58d8
4 changed files with 77 additions and 5 deletions
|
|
@ -101,6 +101,23 @@ func (ec *Client) BlockNumber(ctx context.Context) (uint64, error) {
|
||||||
return uint64(result), err
|
return uint64(result), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PeerCount returns the number of p2p peers as reported by the net_peerCount method.
|
||||||
|
func (ec *Client) PeerCount(ctx context.Context) (uint64, error) {
|
||||||
|
var result hexutil.Uint64
|
||||||
|
err := ec.c.CallContext(ctx, &result, "net_peerCount")
|
||||||
|
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"`
|
||||||
|
|
|
||||||
|
|
@ -859,6 +859,40 @@ 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.
|
||||||
|
|
||||||
|
result := make([]map[string]interface{}, len(receipts))
|
||||||
|
for i, receipt := range receipts {
|
||||||
|
blockNumber := block.NumberU64()
|
||||||
|
bigblock := new(big.Int).SetUint64(blockNumber)
|
||||||
|
signer := types.MakeSigner(s.b.ChainConfig(), bigblock)
|
||||||
|
res, err := marshalReceipt(ctx, s.b, receipt, bigblock, block.Hash(), blockNumber, signer, txs[i], i)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to marshal receipt %d: %w", i, err)
|
||||||
|
}
|
||||||
|
result[i] = res
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -1663,13 +1697,18 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
|
||||||
// Derive the sender.
|
// Derive the sender.
|
||||||
bigblock := new(big.Int).SetUint64(blockNumber)
|
bigblock := new(big.Int).SetUint64(blockNumber)
|
||||||
signer := types.MakeSigner(s.b.ChainConfig(), bigblock)
|
signer := types.MakeSigner(s.b.ChainConfig(), bigblock)
|
||||||
|
return marshalReceipt(ctx, s.b, receipt, bigblock, blockHash, blockNumber, signer, tx, int(index))
|
||||||
|
}
|
||||||
|
|
||||||
|
// marshalReceipt marshals a transaction receipt into a JSON object.
|
||||||
|
func marshalReceipt(ctx context.Context, b Backend, receipt *types.Receipt, bigblock *big.Int, blockHash common.Hash, blockNumber uint64, signer types.Signer, tx *types.Transaction, txIndex int) (map[string]interface{}, error) {
|
||||||
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),
|
||||||
|
|
@ -1681,10 +1720,10 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
|
||||||
"l1Fee": (*hexutil.Big)(receipt.L1Fee),
|
"l1Fee": (*hexutil.Big)(receipt.L1Fee),
|
||||||
}
|
}
|
||||||
// Assign the effective gas price paid
|
// Assign the effective gas price paid
|
||||||
if !s.b.ChainConfig().IsCurie(bigblock) {
|
if !b.ChainConfig().IsCurie(bigblock) {
|
||||||
fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64())
|
fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64())
|
||||||
} else {
|
} else {
|
||||||
header, err := s.b.HeaderByHash(ctx, blockHash)
|
header, err := b.HeaderByHash(ctx, blockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -577,6 +577,22 @@ web3._extend({
|
||||||
params: 3,
|
params: 3,
|
||||||
inputFormatter: [null, web3._extend.formatters.inputBlockNumberFormatter, null]
|
inputFormatter: [null, web3._extend.formatters.inputBlockNumberFormatter, null]
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'getLogs',
|
||||||
|
call: 'eth_getLogs',
|
||||||
|
params: 1,
|
||||||
|
}),
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'call',
|
||||||
|
call: 'eth_call',
|
||||||
|
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: [
|
properties: [
|
||||||
new web3._extend.Property({
|
new web3._extend.Property({
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 5 // Major version component of the current release
|
VersionMajor = 5 // Major version component of the current release
|
||||||
VersionMinor = 3 // Minor version component of the current release
|
VersionMinor = 3 // Minor version component of the current release
|
||||||
VersionPatch = 36 // Patch version component of the current release
|
VersionPatch = 37 // Patch version component of the current release
|
||||||
VersionMeta = "mainnet" // Version metadata to append to the version string
|
VersionMeta = "mainnet" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue