Skip to content

Commit

Permalink
feat: implement eth_getBlockReceipts (#127)
Browse files Browse the repository at this point in the history
feat: implement eth_getBlockReceipts (#796)

---------

Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
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>
  • Loading branch information
7 people committed Aug 9, 2024
1 parent 28c4a33 commit 7d4df46
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 4 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 @@ -898,6 +898,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 @@ -1702,13 +1736,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 @@ -1720,10 +1759,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

0 comments on commit 7d4df46

Please sign in to comment.