Skip to content

Commit 530f78e

Browse files
rjl493456442karalabe
authored andcommitted
eth, internal, les: add getHeaderBy* APIs (#19669)
* eth, interal, les: add getHeaderBy* APIs * internal: address the comment * eth, internal, les: getHeader nits, missing TD, console callable
1 parent 57d9c93 commit 530f78e

File tree

5 files changed

+126
-55
lines changed

5 files changed

+126
-55
lines changed

eth/api_backend.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,44 +59,44 @@ func (b *EthAPIBackend) SetHead(number uint64) {
5959
b.eth.blockchain.SetHead(number)
6060
}
6161

62-
func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
62+
func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
6363
// Pending block is only known by the miner
64-
if blockNr == rpc.PendingBlockNumber {
64+
if number == rpc.PendingBlockNumber {
6565
block := b.eth.miner.PendingBlock()
6666
return block.Header(), nil
6767
}
6868
// Otherwise resolve and return the block
69-
if blockNr == rpc.LatestBlockNumber {
69+
if number == rpc.LatestBlockNumber {
7070
return b.eth.blockchain.CurrentBlock().Header(), nil
7171
}
72-
return b.eth.blockchain.GetHeaderByNumber(uint64(blockNr)), nil
72+
return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil
7373
}
7474

7575
func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
7676
return b.eth.blockchain.GetHeaderByHash(hash), nil
7777
}
7878

79-
func (b *EthAPIBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) {
79+
func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
8080
// Pending block is only known by the miner
81-
if blockNr == rpc.PendingBlockNumber {
81+
if number == rpc.PendingBlockNumber {
8282
block := b.eth.miner.PendingBlock()
8383
return block, nil
8484
}
8585
// Otherwise resolve and return the block
86-
if blockNr == rpc.LatestBlockNumber {
86+
if number == rpc.LatestBlockNumber {
8787
return b.eth.blockchain.CurrentBlock(), nil
8888
}
89-
return b.eth.blockchain.GetBlockByNumber(uint64(blockNr)), nil
89+
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
9090
}
9191

92-
func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
92+
func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
9393
// Pending state is only known by the miner
94-
if blockNr == rpc.PendingBlockNumber {
94+
if number == rpc.PendingBlockNumber {
9595
block, state := b.eth.miner.Pending()
9696
return state, block.Header(), nil
9797
}
9898
// Otherwise resolve the block number and return its state
99-
header, err := b.HeaderByNumber(ctx, blockNr)
99+
header, err := b.HeaderByNumber(ctx, number)
100100
if err != nil {
101101
return nil, nil, err
102102
}
@@ -107,6 +107,10 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.
107107
return stateDb, header, err
108108
}
109109

110+
func (b *EthAPIBackend) GetHeader(ctx context.Context, hash common.Hash) *types.Header {
111+
return b.eth.blockchain.GetHeaderByHash(hash)
112+
}
113+
110114
func (b *EthAPIBackend) GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error) {
111115
return b.eth.blockchain.GetBlockByHash(hash), nil
112116
}

internal/ethapi/api.go

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -616,13 +616,43 @@ func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Addre
616616
}, state.Error()
617617
}
618618

619-
// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all
620-
// transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
621-
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
622-
block, err := s.b.BlockByNumber(ctx, blockNr)
623-
if block != nil {
624-
response, err := s.rpcOutputBlock(block, true, fullTx)
625-
if err == nil && blockNr == rpc.PendingBlockNumber {
619+
// GetHeaderByNumber returns the requested canonical block header.
620+
// * When blockNr is -1 the chain head is returned.
621+
// * When blockNr is -2 the pending chain head is returned.
622+
func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) {
623+
header, err := s.b.HeaderByNumber(ctx, number)
624+
if header != nil && err == nil {
625+
response := s.rpcMarshalHeader(header)
626+
if number == rpc.PendingBlockNumber {
627+
// Pending header need to nil out a few fields
628+
for _, field := range []string{"hash", "nonce", "miner"} {
629+
response[field] = nil
630+
}
631+
}
632+
return response, err
633+
}
634+
return nil, err
635+
}
636+
637+
// GetHeaderByHash returns the requested header by hash.
638+
func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} {
639+
header := s.b.GetHeader(ctx, hash)
640+
if header != nil {
641+
return s.rpcMarshalHeader(header)
642+
}
643+
return nil
644+
}
645+
646+
// GetBlockByNumber returns the requested canonical block.
647+
// * When blockNr is -1 the chain head is returned.
648+
// * When blockNr is -2 the pending chain head is returned.
649+
// * When fullTx is true all transactions in the block are returned, otherwise
650+
// only the transaction hash is returned.
651+
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
652+
block, err := s.b.BlockByNumber(ctx, number)
653+
if block != nil && err == nil {
654+
response, err := s.rpcMarshalBlock(block, true, fullTx)
655+
if err == nil && number == rpc.PendingBlockNumber {
626656
// Pending blocks need to nil out a few fields
627657
for _, field := range []string{"hash", "nonce", "miner"} {
628658
response[field] = nil
@@ -635,10 +665,10 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.
635665

636666
// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full
637667
// detail, otherwise only the transaction hash is returned.
638-
func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) {
639-
block, err := s.b.GetBlock(ctx, blockHash)
668+
func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) {
669+
block, err := s.b.GetBlock(ctx, hash)
640670
if block != nil {
641-
return s.rpcOutputBlock(block, true, fullTx)
671+
return s.rpcMarshalBlock(block, true, fullTx)
642672
}
643673
return nil, err
644674
}
@@ -654,7 +684,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context,
654684
return nil, nil
655685
}
656686
block = types.NewBlockWithHeader(uncles[index])
657-
return s.rpcOutputBlock(block, false, false)
687+
return s.rpcMarshalBlock(block, false, false)
658688
}
659689
return nil, err
660690
}
@@ -670,7 +700,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, b
670700
return nil, nil
671701
}
672702
block = types.NewBlockWithHeader(uncles[index])
673-
return s.rpcOutputBlock(block, false, false)
703+
return s.rpcMarshalBlock(block, false, false)
674704
}
675705
return nil, err
676706
}
@@ -933,14 +963,11 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes {
933963
return formatted
934964
}
935965

936-
// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
937-
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
938-
// transaction hashes.
939-
func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
940-
head := b.Header() // copies the header once
941-
fields := map[string]interface{}{
966+
// RPCMarshalHeader converts the given header to the RPC output .
967+
func RPCMarshalHeader(head *types.Header) map[string]interface{} {
968+
return map[string]interface{}{
942969
"number": (*hexutil.Big)(head.Number),
943-
"hash": b.Hash(),
970+
"hash": head.Hash(),
944971
"parentHash": head.ParentHash,
945972
"nonce": head.Nonce,
946973
"mixHash": head.MixDigest,
@@ -950,24 +977,32 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
950977
"miner": head.Coinbase,
951978
"difficulty": (*hexutil.Big)(head.Difficulty),
952979
"extraData": hexutil.Bytes(head.Extra),
953-
"size": hexutil.Uint64(b.Size()),
980+
"size": hexutil.Uint64(head.Size()),
954981
"gasLimit": hexutil.Uint64(head.GasLimit),
955982
"gasUsed": hexutil.Uint64(head.GasUsed),
956983
"timestamp": hexutil.Uint64(head.Time),
957984
"transactionsRoot": head.TxHash,
958985
"receiptsRoot": head.ReceiptHash,
959986
}
987+
}
988+
989+
// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
990+
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
991+
// transaction hashes.
992+
func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
993+
fields := RPCMarshalHeader(block.Header())
994+
fields["size"] = block.Size()
960995

961996
if inclTx {
962997
formatTx := func(tx *types.Transaction) (interface{}, error) {
963998
return tx.Hash(), nil
964999
}
9651000
if fullTx {
9661001
formatTx = func(tx *types.Transaction) (interface{}, error) {
967-
return newRPCTransactionFromBlockHash(b, tx.Hash()), nil
1002+
return newRPCTransactionFromBlockHash(block, tx.Hash()), nil
9681003
}
9691004
}
970-
txs := b.Transactions()
1005+
txs := block.Transactions()
9711006
transactions := make([]interface{}, len(txs))
9721007
var err error
9731008
for i, tx := range txs {
@@ -977,8 +1012,7 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
9771012
}
9781013
fields["transactions"] = transactions
9791014
}
980-
981-
uncles := b.Uncles()
1015+
uncles := block.Uncles()
9821016
uncleHashes := make([]common.Hash, len(uncles))
9831017
for i, uncle := range uncles {
9841018
uncleHashes[i] = uncle.Hash()
@@ -988,9 +1022,17 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
9881022
return fields, nil
9891023
}
9901024

991-
// rpcOutputBlock uses the generalized output filler, then adds the total difficulty field, which requires
1025+
// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires
1026+
// a `PublicBlockchainAPI`.
1027+
func (s *PublicBlockChainAPI) rpcMarshalHeader(header *types.Header) map[string]interface{} {
1028+
fields := RPCMarshalHeader(header)
1029+
fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(header.Hash()))
1030+
return fields
1031+
}
1032+
1033+
// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires
9921034
// a `PublicBlockchainAPI`.
993-
func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
1035+
func (s *PublicBlockChainAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
9941036
fields, err := RPCMarshalBlock(b, inclTx, fullTx)
9951037
if err != nil {
9961038
return nil, err

internal/ethapi/backend.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@ type Backend interface {
5050

5151
// Blockchain API
5252
SetHead(number uint64)
53-
HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error)
54-
HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error)
55-
BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error)
56-
StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error)
57-
GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
58-
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
59-
GetTd(blockHash common.Hash) *big.Int
53+
HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
54+
HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error)
55+
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
56+
StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error)
57+
GetHeader(ctx context.Context, hash common.Hash) *types.Header
58+
GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error)
59+
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
60+
GetTd(hash common.Hash) *big.Int
6061
GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error)
6162
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
6263
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription

internal/web3ext/web3ext.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,26 @@ web3._extend({
483483
params: 1,
484484
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
485485
}),
486+
new web3._extend.Method({
487+
name: 'getHeaderByNumber',
488+
call: 'eth_getHeaderByNumber',
489+
params: 1
490+
}),
491+
new web3._extend.Method({
492+
name: 'getHeaderByHash',
493+
call: 'eth_getHeaderByHash',
494+
params: 1
495+
}),
496+
new web3._extend.Method({
497+
name: 'getBlockByNumber',
498+
call: 'eth_getBlockByNumber',
499+
params: 2
500+
}),
501+
new web3._extend.Method({
502+
name: 'getBlockByHash',
503+
call: 'eth_getBlockByHash',
504+
params: 2
505+
}),
486506
new web3._extend.Method({
487507
name: 'getRawTransaction',
488508
call: 'eth_getRawTransactionByHash',
@@ -765,15 +785,15 @@ web3._extend({
765785
const LESJs = `
766786
web3._extend({
767787
property: 'les',
768-
methods:
788+
methods:
769789
[
770790
new web3._extend.Method({
771791
name: 'getCheckpoint',
772792
call: 'les_getCheckpoint',
773793
params: 1
774794
}),
775795
],
776-
properties:
796+
properties:
777797
[
778798
new web3._extend.Property({
779799
name: 'latestCheckpoint',

les/api_backend.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,27 +58,27 @@ func (b *LesApiBackend) SetHead(number uint64) {
5858
b.eth.blockchain.SetHead(number)
5959
}
6060

61-
func (b *LesApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
62-
if blockNr == rpc.LatestBlockNumber || blockNr == rpc.PendingBlockNumber {
61+
func (b *LesApiBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
62+
if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber {
6363
return b.eth.blockchain.CurrentHeader(), nil
6464
}
65-
return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(blockNr))
65+
return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(number))
6666
}
6767

6868
func (b *LesApiBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
6969
return b.eth.blockchain.GetHeaderByHash(hash), nil
7070
}
7171

72-
func (b *LesApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) {
73-
header, err := b.HeaderByNumber(ctx, blockNr)
72+
func (b *LesApiBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
73+
header, err := b.HeaderByNumber(ctx, number)
7474
if header == nil || err != nil {
7575
return nil, err
7676
}
7777
return b.GetBlock(ctx, header.Hash())
7878
}
7979

80-
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
81-
header, err := b.HeaderByNumber(ctx, blockNr)
80+
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
81+
header, err := b.HeaderByNumber(ctx, number)
8282
if err != nil {
8383
return nil, nil, err
8484
}
@@ -88,8 +88,12 @@ func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.
8888
return light.NewState(ctx, header, b.eth.odr), header, nil
8989
}
9090

91-
func (b *LesApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) {
92-
return b.eth.blockchain.GetBlockByHash(ctx, blockHash)
91+
func (b *LesApiBackend) GetHeader(ctx context.Context, hash common.Hash) *types.Header {
92+
return b.eth.blockchain.GetHeaderByHash(hash)
93+
}
94+
95+
func (b *LesApiBackend) GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error) {
96+
return b.eth.blockchain.GetBlockByHash(ctx, hash)
9397
}
9498

9599
func (b *LesApiBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {

0 commit comments

Comments
 (0)