mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
eth: API error code for pruned blocks
This commit is contained in:
parent
f0cdc40ceb
commit
1dcc65d429
4 changed files with 70 additions and 29 deletions
|
|
@ -86,6 +86,11 @@ func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
|||
return bc.hc.GetHeaderByNumber(number)
|
||||
}
|
||||
|
||||
// GetBlockNumber retrieves the block number associated with a block hash.
|
||||
func (bc *BlockChain) GetBlockNumber(hash common.Hash) *uint64 {
|
||||
return bc.hc.GetBlockNumber(hash)
|
||||
}
|
||||
|
||||
// GetHeadersFrom returns a contiguous segment of headers, in rlp-form, going
|
||||
// backwards from the given number.
|
||||
func (bc *BlockChain) GetHeadersFrom(number, count uint64) []rlp.RawValue {
|
||||
|
|
@ -437,3 +442,10 @@ func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript
|
|||
func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription {
|
||||
return bc.scope.Track(bc.blockProcFeed.Subscribe(ch))
|
||||
}
|
||||
|
||||
// HistoryCutoff returns the tail of the block history.
|
||||
func (bc *BlockChain) HistoryCutoff() uint64 {
|
||||
// Only nofreezedb returns an error.
|
||||
tail, _ := bc.db.Tail()
|
||||
return tail
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,3 +187,5 @@ func WriteTransitionStatus(db ethdb.KeyValueWriter, data []byte) {
|
|||
log.Crit("Failed to store the eth2 transition status", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// ReadHistoryTail retrieves the first
|
||||
|
|
|
|||
|
|
@ -143,11 +143,25 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe
|
|||
}
|
||||
return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
|
||||
}
|
||||
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
|
||||
bn := uint64(number)
|
||||
if number == rpc.EarliestBlockNumber {
|
||||
bn = b.eth.blockchain.HistoryCutoff()
|
||||
}
|
||||
if bn < b.eth.blockchain.HistoryCutoff() {
|
||||
return nil, &prunedHistoryError{}
|
||||
}
|
||||
return b.eth.blockchain.GetBlockByNumber(bn), nil
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
|
||||
return b.eth.blockchain.GetBlockByHash(hash), nil
|
||||
number := b.eth.blockchain.GetBlockNumber(hash)
|
||||
if number == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if *number < b.eth.blockchain.HistoryCutoff() {
|
||||
return nil, &prunedHistoryError{}
|
||||
}
|
||||
return b.eth.blockchain.GetBlock(hash, *number), nil
|
||||
}
|
||||
|
||||
// GetBody returns body of a block. It does not resolve special block numbers.
|
||||
|
|
@ -173,6 +187,9 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r
|
|||
if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash {
|
||||
return nil, errors.New("hash is not currently canonical")
|
||||
}
|
||||
if header.Number.Uint64() < b.eth.blockchain.HistoryCutoff() {
|
||||
return nil, &prunedHistoryError{}
|
||||
}
|
||||
block := b.eth.blockchain.GetBlock(hash, header.Number.Uint64())
|
||||
if block == nil {
|
||||
return nil, errors.New("header found, but block body is missing")
|
||||
|
|
@ -421,3 +438,8 @@ func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, re
|
|||
func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*types.Transaction, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
|
||||
}
|
||||
|
||||
type prunedHistoryError struct{}
|
||||
|
||||
func (e *prunedHistoryError) Error() string { return "Pruned history unavailable" }
|
||||
func (e *prunedHistoryError) ErrorCode() int { return 4444 }
|
||||
|
|
|
|||
|
|
@ -549,21 +549,23 @@ func (api *BlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, block
|
|||
}
|
||||
|
||||
// GetUncleCountByBlockNumber returns number of uncles in the block for the given block number
|
||||
func (api *BlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
|
||||
if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil {
|
||||
func (api *BlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) (*hexutil.Uint, error) {
|
||||
block, err := api.b.BlockByNumber(ctx, blockNr)
|
||||
if block != nil {
|
||||
n := hexutil.Uint(len(block.Uncles()))
|
||||
return &n
|
||||
return &n, nil
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// GetUncleCountByBlockHash returns number of uncles in the block for the given block hash
|
||||
func (api *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint {
|
||||
if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil {
|
||||
func (api *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) (*hexutil.Uint, error) {
|
||||
block, err := api.b.BlockByHash(ctx, blockHash)
|
||||
if block != nil {
|
||||
n := hexutil.Uint(len(block.Uncles()))
|
||||
return &n
|
||||
return &n, nil
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// GetCode returns the code stored at the given address in the state for the given block number.
|
||||
|
|
@ -596,9 +598,7 @@ func (api *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Addre
|
|||
func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) {
|
||||
block, err := api.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
|
||||
return nil, err
|
||||
}
|
||||
receipts, err := api.b.GetReceipts(ctx, block.Hash())
|
||||
if err != nil {
|
||||
|
|
@ -1258,37 +1258,41 @@ func NewTransactionAPI(b Backend, nonceLock *AddrLocker) *TransactionAPI {
|
|||
}
|
||||
|
||||
// GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number.
|
||||
func (api *TransactionAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
|
||||
if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil {
|
||||
func (api *TransactionAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*hexutil.Uint, error) {
|
||||
block, err := api.b.BlockByNumber(ctx, blockNr)
|
||||
if block != nil {
|
||||
n := hexutil.Uint(len(block.Transactions()))
|
||||
return &n
|
||||
return &n, nil
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash.
|
||||
func (api *TransactionAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint {
|
||||
if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil {
|
||||
func (api *TransactionAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) (*hexutil.Uint, error) {
|
||||
block, err := api.b.BlockByHash(ctx, blockHash)
|
||||
if block != nil {
|
||||
n := hexutil.Uint(len(block.Transactions()))
|
||||
return &n
|
||||
return &n, nil
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index.
|
||||
func (api *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction {
|
||||
if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil {
|
||||
return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig())
|
||||
func (api *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (*RPCTransaction, error) {
|
||||
block, err := api.b.BlockByNumber(ctx, blockNr)
|
||||
if block != nil {
|
||||
return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig()), nil
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
|
||||
func (api *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction {
|
||||
if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil {
|
||||
return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig())
|
||||
func (api *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (*RPCTransaction, error) {
|
||||
block, err := api.b.BlockByHash(ctx, blockHash)
|
||||
if block != nil {
|
||||
return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig()), nil
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index.
|
||||
|
|
@ -1365,6 +1369,7 @@ func (api *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash com
|
|||
|
||||
// GetTransactionReceipt returns the transaction receipt for the given transaction hash.
|
||||
func (api *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
|
||||
// TODO(s1na): transaction lookup should be pruned as well.
|
||||
found, tx, blockHash, blockNumber, index, err := api.b.GetTransaction(ctx, hash)
|
||||
if err != nil {
|
||||
return nil, NewTxIndexingError() // transaction is not fully indexed
|
||||
|
|
|
|||
Loading…
Reference in a new issue