Skip to content

Commit 4650e3d

Browse files
committed
eth, internal: add getHeaderBy* APIs ethereum#19669
1 parent f46920b commit 4650e3d

File tree

4 files changed

+97
-43
lines changed

4 files changed

+97
-43
lines changed

eth/api_backend.go

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,16 @@ func (b *EthAPIBackend) SetHead(number uint64) {
7676
b.eth.blockchain.SetHead(number)
7777
}
7878

79-
func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
79+
func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
8080
// Pending block is only known by the miner
81-
if blockNr == rpc.PendingBlockNumber {
82-
blockNr = rpc.LatestBlockNumber
81+
if number == rpc.PendingBlockNumber {
82+
number = rpc.LatestBlockNumber
8383
}
8484
// Otherwise resolve and return the block
85-
if blockNr == rpc.LatestBlockNumber {
85+
if number == rpc.LatestBlockNumber {
8686
return b.eth.blockchain.CurrentBlock().Header(), nil
8787
}
88-
if blockNr == rpc.CommittedBlockNumber {
88+
if number == rpc.CommittedBlockNumber {
8989
if b.eth.chainConfig.XDPoS == nil {
9090
return nil, errors.New("PoW does not support confirmed block lookup")
9191
}
@@ -102,7 +102,7 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNum
102102
return nil, errors.New("PoS V1 does not support confirmed block lookup")
103103
}
104104
}
105-
header := b.eth.blockchain.GetHeaderByNumber(uint64(blockNr))
105+
header := b.eth.blockchain.GetHeaderByNumber(uint64(number))
106106
if header == nil {
107107
return nil, errors.New("header for number not found")
108108
}
@@ -130,16 +130,16 @@ func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*ty
130130
return b.eth.blockchain.GetHeaderByHash(hash), nil
131131
}
132132

133-
func (b *EthAPIBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) {
133+
func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
134134
// Pending block is only known by the miner
135-
if blockNr == rpc.PendingBlockNumber {
136-
blockNr = rpc.LatestBlockNumber
135+
if number == rpc.PendingBlockNumber {
136+
number = rpc.LatestBlockNumber
137137
}
138138
// Otherwise resolve and return the block
139-
if blockNr == rpc.LatestBlockNumber {
139+
if number == rpc.LatestBlockNumber {
140140
return b.eth.blockchain.CurrentBlock(), nil
141141
}
142-
if blockNr == rpc.CommittedBlockNumber {
142+
if number == rpc.CommittedBlockNumber {
143143
if b.eth.chainConfig.XDPoS == nil {
144144
return nil, errors.New("PoW does not support confirmed block lookup")
145145
}
@@ -156,7 +156,7 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb
156156
return nil, errors.New("PoS V1 does not support confirmed block lookup")
157157
}
158158
}
159-
return b.eth.blockchain.GetBlockByNumber(uint64(blockNr)), nil
159+
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
160160
}
161161

162162
func (b *EthAPIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
@@ -199,13 +199,13 @@ func (b *EthAPIBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts)
199199
return b.eth.miner.PendingBlockAndReceipts()
200200
}
201201

202-
func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
202+
func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
203203
// Pending state is only known by the miner
204-
if blockNr == rpc.PendingBlockNumber {
205-
blockNr = rpc.LatestBlockNumber
204+
if number == rpc.PendingBlockNumber {
205+
number = rpc.LatestBlockNumber
206206
}
207207
// Otherwise resolve the block number and return its state
208-
header, err := b.HeaderByNumber(ctx, blockNr)
208+
header, err := b.HeaderByNumber(ctx, number)
209209
if err != nil {
210210
return nil, nil, err
211211
}
@@ -243,8 +243,12 @@ func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockN
243243
return nil, nil, errors.New("invalid arguments; neither block nor hash specified")
244244
}
245245

246-
func (b *EthAPIBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) {
247-
return b.eth.blockchain.GetBlockByHash(blockHash), nil
246+
func (b *EthAPIBackend) GetHeader(ctx context.Context, hash common.Hash) *types.Header {
247+
return b.eth.blockchain.GetHeaderByHash(hash)
248+
}
249+
250+
func (b *EthAPIBackend) GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error) {
251+
return b.eth.blockchain.GetBlockByHash(hash), nil
248252
}
249253

250254
func (b *EthAPIBackend) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) {

internal/ethapi/api.go

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -377,13 +377,42 @@ func (s *BlockChainAPI) GetTransactionAndReceiptProof(ctx context.Context, hash
377377
return fields, nil
378378
}
379379

380+
// GetHeaderByNumber returns the requested canonical block header.
381+
// - When blockNr is -1 the chain pending header is returned.
382+
// - When blockNr is -2 the chain latest header is returned.
383+
// - When blockNr is -3 the chain finalized header is returned.
384+
// - When blockNr is -4 the chain safe header is returned.
385+
func (api *BlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) {
386+
header, err := api.b.HeaderByNumber(ctx, number)
387+
if header != nil && err == nil {
388+
response := RPCMarshalHeader(header)
389+
if number == rpc.PendingBlockNumber {
390+
// Pending header need to nil out a few fields
391+
for _, field := range []string{"hash", "nonce", "miner"} {
392+
response[field] = nil
393+
}
394+
}
395+
return response, err
396+
}
397+
return nil, err
398+
}
399+
400+
// GetHeaderByHash returns the requested header by hash.
401+
func (api *BlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} {
402+
header, _ := api.b.HeaderByHash(ctx, hash)
403+
if header != nil {
404+
return RPCMarshalHeader(header)
405+
}
406+
return nil
407+
}
408+
380409
// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all
381410
// transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
382-
func (s *BlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
383-
block, err := s.b.BlockByNumber(ctx, blockNr)
411+
func (s *BlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
412+
block, err := s.b.BlockByNumber(ctx, number)
384413
if block != nil {
385-
response, err := s.rpcOutputBlock(block, true, fullTx)
386-
if err == nil && blockNr == rpc.PendingBlockNumber {
414+
response, err := s.rpcMarshalBlock(block, true, fullTx)
415+
if err == nil && number == rpc.PendingBlockNumber {
387416
// Pending blocks need to nil out a few fields
388417
for _, field := range []string{"hash", "nonce", "miner"} {
389418
response[field] = nil
@@ -396,10 +425,10 @@ func (s *BlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockN
396425

397426
// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full
398427
// detail, otherwise only the transaction hash is returned.
399-
func (s *BlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) {
400-
block, err := s.b.GetBlock(ctx, blockHash)
428+
func (s *BlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) {
429+
block, err := s.b.GetBlock(ctx, hash)
401430
if block != nil {
402-
return s.rpcOutputBlock(block, true, fullTx)
431+
return s.rpcMarshalBlock(block, true, fullTx)
403432
}
404433
return nil, err
405434
}
@@ -415,7 +444,7 @@ func (s *BlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, block
415444
return nil, nil
416445
}
417446
block = types.NewBlockWithHeader(uncles[index])
418-
return s.rpcOutputBlock(block, false, false)
447+
return s.rpcMarshalBlock(block, false, false)
419448
}
420449
return nil, err
421450
}
@@ -432,7 +461,7 @@ func (s *BlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHa
432461
return nil, nil
433462
}
434463
block = types.NewBlockWithHeader(uncles[index])
435-
return s.rpcOutputBlock(block, false, false)
464+
return s.rpcMarshalBlock(block, false, false)
436465
}
437466
return nil, err
438467
}
@@ -1414,20 +1443,20 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
14141443
// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
14151444
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
14161445
// transaction hashes.
1417-
func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
1418-
fields := RPCMarshalHeader(b.Header())
1419-
fields["size"] = hexutil.Uint64(b.Size())
1446+
func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
1447+
fields := RPCMarshalHeader(block.Header())
1448+
fields["size"] = hexutil.Uint64(block.Size())
14201449

14211450
if inclTx {
14221451
formatTx := func(tx *types.Transaction) (interface{}, error) {
14231452
return tx.Hash(), nil
14241453
}
14251454
if fullTx {
14261455
formatTx = func(tx *types.Transaction) (interface{}, error) {
1427-
return newRPCTransactionFromBlockHash(b, tx.Hash()), nil
1456+
return newRPCTransactionFromBlockHash(block, tx.Hash()), nil
14281457
}
14291458
}
1430-
txs := b.Transactions()
1459+
txs := block.Transactions()
14311460
transactions := make([]interface{}, len(txs))
14321461
var err error
14331462
for i, tx := range txs {
@@ -1437,20 +1466,18 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
14371466
}
14381467
fields["transactions"] = transactions
14391468
}
1440-
1441-
uncles := b.Uncles()
1469+
uncles := block.Uncles()
14421470
uncleHashes := make([]common.Hash, len(uncles))
14431471
for i, uncle := range uncles {
14441472
uncleHashes[i] = uncle.Hash()
14451473
}
14461474
fields["uncles"] = uncleHashes
1447-
14481475
return fields, nil
14491476
}
14501477

1451-
// rpcOutputBlock uses the generalized output filler, then adds the total difficulty field, which requires
1478+
// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires
14521479
// a `BlockChainAPI`.
1453-
func (s *BlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
1480+
func (s *BlockChainAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
14541481
fields, err := RPCMarshalBlock(b, inclTx, fullTx)
14551482
if err != nil {
14561483
return nil, err

internal/ethapi/backend.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,19 @@ type Backend interface {
6262

6363
// BlockChain API
6464
SetHead(number uint64)
65-
HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error)
65+
HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
6666
HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error)
6767
HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error)
6868
CurrentHeader() *types.Header
69-
BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error)
69+
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
7070
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
7171
BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error)
72-
StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error)
72+
StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error)
7373
StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error)
74-
GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
74+
GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error)
7575
PendingBlockAndReceipts() (*types.Block, types.Receipts)
76-
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
77-
GetTd(ctx context.Context, blockHash common.Hash) *big.Int
76+
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
77+
GetTd(ctx context.Context, hash common.Hash) *big.Int
7878
GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error, error)
7979
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
8080
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription

internal/web3ext/web3ext.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,29 @@ web3._extend({
521521
params: 1,
522522
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
523523
}),
524+
new web3._extend.Method({
525+
name: 'getHeaderByNumber',
526+
call: 'eth_getHeaderByNumber',
527+
params: 1,
528+
inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter]
529+
}),
530+
new web3._extend.Method({
531+
name: 'getHeaderByHash',
532+
call: 'eth_getHeaderByHash',
533+
params: 1
534+
}),
535+
new web3._extend.Method({
536+
name: 'getBlockByNumber',
537+
call: 'eth_getBlockByNumber',
538+
params: 2,
539+
inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter, function (val) { return !!val; }]
540+
}),
541+
new web3._extend.Method({
542+
name: 'getBlockByHash',
543+
call: 'eth_getBlockByHash',
544+
params: 2,
545+
inputFormatter: [null, function (val) { return !!val; }]
546+
}),
524547
new web3._extend.Method({
525548
name: 'getRawTransaction',
526549
call: 'eth_getRawTransactionByHash',

0 commit comments

Comments
 (0)