diff options
author | gary rong <garyrong0905@gmail.com> | 2019-07-23 21:52:24 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2019-07-23 21:52:24 +0800 |
commit | 530f78e22de9580c3779d33fd0e3b3c8e677c8d0 (patch) | |
tree | b58ab931e139c69a1e2b9dbc005efda23bca02e7 /internal | |
parent | 57d9c93dcdf8341088abdf322d0f7a2787768ec6 (diff) | |
download | go-tangerine-530f78e22de9580c3779d33fd0e3b3c8e677c8d0.tar go-tangerine-530f78e22de9580c3779d33fd0e3b3c8e677c8d0.tar.gz go-tangerine-530f78e22de9580c3779d33fd0e3b3c8e677c8d0.tar.bz2 go-tangerine-530f78e22de9580c3779d33fd0e3b3c8e677c8d0.tar.lz go-tangerine-530f78e22de9580c3779d33fd0e3b3c8e677c8d0.tar.xz go-tangerine-530f78e22de9580c3779d33fd0e3b3c8e677c8d0.tar.zst go-tangerine-530f78e22de9580c3779d33fd0e3b3c8e677c8d0.zip |
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
Diffstat (limited to 'internal')
-rw-r--r-- | internal/ethapi/api.go | 94 | ||||
-rw-r--r-- | internal/ethapi/backend.go | 15 | ||||
-rw-r--r-- | internal/web3ext/web3ext.go | 24 |
3 files changed, 98 insertions, 35 deletions
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 04df794ec..8b0489e7a 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -616,13 +616,43 @@ func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Addre }, state.Error() } -// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all -// transactions in the block are returned in full detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { - block, err := s.b.BlockByNumber(ctx, blockNr) - if block != nil { - response, err := s.rpcOutputBlock(block, true, fullTx) - if err == nil && blockNr == rpc.PendingBlockNumber { +// GetHeaderByNumber returns the requested canonical block header. +// * When blockNr is -1 the chain head is returned. +// * When blockNr is -2 the pending chain head is returned. +func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { + header, err := s.b.HeaderByNumber(ctx, number) + if header != nil && err == nil { + response := s.rpcMarshalHeader(header) + if number == rpc.PendingBlockNumber { + // Pending header need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + return response, err + } + return nil, err +} + +// GetHeaderByHash returns the requested header by hash. +func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { + header := s.b.GetHeader(ctx, hash) + if header != nil { + return s.rpcMarshalHeader(header) + } + return nil +} + +// GetBlockByNumber returns the requested canonical block. +// * When blockNr is -1 the chain head is returned. +// * When blockNr is -2 the pending chain head is returned. +// * When fullTx is true all transactions in the block are returned, otherwise +// only the transaction hash is returned. +func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { + block, err := s.b.BlockByNumber(ctx, number) + if block != nil && err == nil { + response, err := s.rpcMarshalBlock(block, true, fullTx) + if err == nil && number == rpc.PendingBlockNumber { // Pending blocks need to nil out a few fields for _, field := range []string{"hash", "nonce", "miner"} { response[field] = nil @@ -635,10 +665,10 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc. // GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full // detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) { - block, err := s.b.GetBlock(ctx, blockHash) +func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { + block, err := s.b.GetBlock(ctx, hash) if block != nil { - return s.rpcOutputBlock(block, true, fullTx) + return s.rpcMarshalBlock(block, true, fullTx) } return nil, err } @@ -654,7 +684,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, return nil, nil } block = types.NewBlockWithHeader(uncles[index]) - return s.rpcOutputBlock(block, false, false) + return s.rpcMarshalBlock(block, false, false) } return nil, err } @@ -670,7 +700,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, b return nil, nil } block = types.NewBlockWithHeader(uncles[index]) - return s.rpcOutputBlock(block, false, false) + return s.rpcMarshalBlock(block, false, false) } return nil, err } @@ -933,14 +963,11 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes { return formatted } -// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are -// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain -// transaction hashes. -func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { - head := b.Header() // copies the header once - fields := map[string]interface{}{ +// RPCMarshalHeader converts the given header to the RPC output . +func RPCMarshalHeader(head *types.Header) map[string]interface{} { + return map[string]interface{}{ "number": (*hexutil.Big)(head.Number), - "hash": b.Hash(), + "hash": head.Hash(), "parentHash": head.ParentHash, "nonce": head.Nonce, "mixHash": head.MixDigest, @@ -950,13 +977,21 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter "miner": head.Coinbase, "difficulty": (*hexutil.Big)(head.Difficulty), "extraData": hexutil.Bytes(head.Extra), - "size": hexutil.Uint64(b.Size()), + "size": hexutil.Uint64(head.Size()), "gasLimit": hexutil.Uint64(head.GasLimit), "gasUsed": hexutil.Uint64(head.GasUsed), "timestamp": hexutil.Uint64(head.Time), "transactionsRoot": head.TxHash, "receiptsRoot": head.ReceiptHash, } +} + +// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are +// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain +// transaction hashes. +func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { + fields := RPCMarshalHeader(block.Header()) + fields["size"] = block.Size() if inclTx { formatTx := func(tx *types.Transaction) (interface{}, error) { @@ -964,10 +999,10 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter } if fullTx { formatTx = func(tx *types.Transaction) (interface{}, error) { - return newRPCTransactionFromBlockHash(b, tx.Hash()), nil + return newRPCTransactionFromBlockHash(block, tx.Hash()), nil } } - txs := b.Transactions() + txs := block.Transactions() transactions := make([]interface{}, len(txs)) var err error for i, tx := range txs { @@ -977,8 +1012,7 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter } fields["transactions"] = transactions } - - uncles := b.Uncles() + uncles := block.Uncles() uncleHashes := make([]common.Hash, len(uncles)) for i, uncle := range uncles { uncleHashes[i] = uncle.Hash() @@ -988,9 +1022,17 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter return fields, nil } -// rpcOutputBlock uses the generalized output filler, then adds the total difficulty field, which requires +// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires +// a `PublicBlockchainAPI`. +func (s *PublicBlockChainAPI) rpcMarshalHeader(header *types.Header) map[string]interface{} { + fields := RPCMarshalHeader(header) + fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(header.Hash())) + return fields +} + +// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires // a `PublicBlockchainAPI`. -func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { +func (s *PublicBlockChainAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { fields, err := RPCMarshalBlock(b, inclTx, fullTx) if err != nil { return nil, err diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 28ec69897..0869d986c 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -50,13 +50,14 @@ type Backend interface { // Blockchain API SetHead(number uint64) - HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) - HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error) - BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) - StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) - GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) - GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) - GetTd(blockHash common.Hash) *big.Int + HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) + HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) + BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) + StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) + GetHeader(ctx context.Context, hash common.Hash) *types.Header + GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error) + GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) + GetTd(hash common.Hash) *big.Int GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 0abcd5a8a..4a5d4b4dd 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -484,6 +484,26 @@ web3._extend({ inputFormatter: [web3._extend.formatters.inputTransactionFormatter] }), new web3._extend.Method({ + name: 'getHeaderByNumber', + call: 'eth_getHeaderByNumber', + params: 1 + }), + new web3._extend.Method({ + name: 'getHeaderByHash', + call: 'eth_getHeaderByHash', + params: 1 + }), + new web3._extend.Method({ + name: 'getBlockByNumber', + call: 'eth_getBlockByNumber', + params: 2 + }), + new web3._extend.Method({ + name: 'getBlockByHash', + call: 'eth_getBlockByHash', + params: 2 + }), + new web3._extend.Method({ name: 'getRawTransaction', call: 'eth_getRawTransactionByHash', params: 1 @@ -765,7 +785,7 @@ web3._extend({ const LESJs = ` web3._extend({ property: 'les', - methods: + methods: [ new web3._extend.Method({ name: 'getCheckpoint', @@ -773,7 +793,7 @@ web3._extend({ params: 1 }), ], - properties: + properties: [ new web3._extend.Property({ name: 'latestCheckpoint', |