Skip to content

Commit

Permalink
feat: implement eth_getBlockReceipts (#796)
Browse files Browse the repository at this point in the history
* internal/ethapi: implement eth_getBlockReceipts (ethereum#27702)

* chore: auto version bump [bot]

* chore: auto version bump [bot]

---------

Co-authored-by: Delweng <[email protected]>
Co-authored-by: Thegaram <[email protected]>
Co-authored-by: HAOYUatHZ <[email protected]>
Co-authored-by: Ömer Faruk Irmak <[email protected]>
Co-authored-by: omerfirmak <[email protected]>
  • Loading branch information
6 people authored Jun 5, 2024
1 parent 60bbfc1 commit 81074f5
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 5 deletions.
17 changes: 17 additions & 0 deletions ethclient/ethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,23 @@ func (ec *Client) BlockNumber(ctx context.Context) (uint64, error) {
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 {
Hash common.Hash `json:"hash"`
Transactions []rpcTransaction `json:"transactions"`
Expand Down
47 changes: 43 additions & 4 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,40 @@ 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.

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
// of a message call.
// Note, state and stateDiff can't be specified at the same time. If state is
Expand Down Expand Up @@ -1663,13 +1697,18 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
// Derive the sender.
bigblock := new(big.Int).SetUint64(blockNumber)
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)

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),
Expand All @@ -1681,10 +1720,10 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
"l1Fee": (*hexutil.Big)(receipt.L1Fee),
}
// Assign the effective gas price paid
if !s.b.ChainConfig().IsCurie(bigblock) {
if !b.ChainConfig().IsCurie(bigblock) {
fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64())
} else {
header, err := s.b.HeaderByHash(ctx, blockHash)
header, err := b.HeaderByHash(ctx, blockHash)
if err != nil {
return nil, err
}
Expand Down
16 changes: 16 additions & 0 deletions internal/web3ext/web3ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,22 @@ web3._extend({
params: 3,
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: [
new web3._extend.Property({
Expand Down
2 changes: 1 addition & 1 deletion params/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
const (
VersionMajor = 5 // Major 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
)

Expand Down

0 comments on commit 81074f5

Please sign in to comment.