diff options
author | Aaron Buchwald <[email protected]> | 2020-10-16 15:22:23 -0400 |
---|---|---|
committer | Aaron Buchwald <[email protected]> | 2020-10-16 15:22:23 -0400 |
commit | 77a2d0f97f142261a351f0cdcc1d001d0cead4cf (patch) | |
tree | 31b5eb91d754c6c46f8d749d7a08c17d3cc9ec13 /eth | |
parent | 3b3cf1aeaa1eb41f64383e2a18c00240ffde7d2b (diff) |
Clean up use of pending/latest meta block numbers
Diffstat (limited to 'eth')
-rw-r--r-- | eth/api.go | 46 | ||||
-rw-r--r-- | eth/api_backend.go | 37 | ||||
-rw-r--r-- | eth/api_tracer.go | 32 | ||||
-rw-r--r-- | eth/filters/api.go | 5 | ||||
-rw-r--r-- | eth/filters/filter.go | 2 |
5 files changed, 41 insertions, 81 deletions
@@ -278,21 +278,13 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { // DumpBlock retrieves the entire state of the database at a given block. func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) { - if blockNr == rpc.PendingBlockNumber { - // If we're dumping the pending state, we need to request - // both the pending block as well as the pending state from - // the miner and operate on those - _, stateDb := api.eth.miner.Pending() - return stateDb.RawDump(false, false, true), nil - } var block *types.Block - if blockNr == rpc.LatestBlockNumber { - block = api.eth.blockchain.CurrentBlock() - } else if blockNr == rpc.AcceptedBlockNumber { + if blockNr.IsAccepted() { block = api.eth.AcceptedBlock() } else { block = api.eth.blockchain.GetBlockByNumber(uint64(blockNr)) } + if block == nil { return state.Dump{}, fmt.Errorf("block #%d not found", blockNr) } @@ -362,27 +354,19 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta var err error if number, ok := blockNrOrHash.Number(); ok { - if number == rpc.PendingBlockNumber { - // If we're dumping the pending state, we need to request - // both the pending block as well as the pending state from - // the miner and operate on those - _, stateDb = api.eth.miner.Pending() + var block *types.Block + if number.IsAccepted() { + block = api.eth.AcceptedBlock() } else { - var block *types.Block - if number == rpc.LatestBlockNumber { - block = api.eth.blockchain.CurrentBlock() - } else if number == rpc.AcceptedBlockNumber { - block = api.eth.AcceptedBlock() - } else { - block = api.eth.blockchain.GetBlockByNumber(uint64(number)) - } - if block == nil { - return state.IteratorDump{}, fmt.Errorf("block #%d not found", number) - } - stateDb, err = api.eth.BlockChain().StateAt(block.Root()) - if err != nil { - return state.IteratorDump{}, err - } + block = api.eth.blockchain.GetBlockByNumber(uint64(number)) + } + + if block == nil { + return state.IteratorDump{}, fmt.Errorf("block #%d not found", number) + } + stateDb, err = api.eth.BlockChain().StateAt(block.Root()) + if err != nil { + return state.IteratorDump{}, err } } else if hash, ok := blockNrOrHash.Hash(); ok { block := api.eth.blockchain.GetBlockByHash(hash) @@ -393,6 +377,8 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta if err != nil { return state.IteratorDump{}, err } + } else { + return state.IteratorDump{}, errors.New("either block number or block hash must be specified") } if maxResults > AccountRangeMaxResults || maxResults <= 0 { diff --git a/eth/api_backend.go b/eth/api_backend.go index 6c5ebd8..f1b5f74 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -65,20 +65,12 @@ func (b *EthAPIBackend) SetHead(number uint64) { } func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { - // Pending block is only known by the miner in - // Ethereum, but Coreth does not have the same notion. - // So we treat requests for the pending block identically - // to the latest accepted block instead - if number == rpc.PendingBlockNumber { - return b.eth.AcceptedBlock().Header(), nil - } - // Otherwise resolve and return the block - if number == rpc.LatestBlockNumber { - return b.eth.blockchain.CurrentBlock().Header(), nil - } - if number == rpc.AcceptedBlockNumber { + // Treat requests for the pending, latest, or accepted block + // identically. + if number.IsAccepted() { return b.eth.AcceptedBlock().Header(), nil } + return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil } @@ -104,20 +96,12 @@ func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*ty } func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { - // Pending block is only known by the miner in - // Ethereum, but Coreth does not have the same notion. - // So we treat requests for the pending block identically - // to the latest accepted block instead - if number == rpc.PendingBlockNumber { - return b.eth.AcceptedBlock(), nil - } - // Otherwise resolve and return the block - if number == rpc.LatestBlockNumber { - return b.eth.blockchain.CurrentBlock(), nil - } - if number == rpc.AcceptedBlockNumber { + // Treat requests for the pending, latest, or accepted block + // identically. + if number.IsAccepted() { return b.eth.AcceptedBlock(), nil } + return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil } @@ -147,11 +131,6 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r } func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { - // Note: Ethereum typically first checks if the request is for - // the pending block (by rpc.PendingBlockNumber), but Coreth - // does not have the same notion of the miner having a pending - // block, so this is skipped here - // Request the block by its number and retrieve its state header, err := b.HeaderByNumber(ctx, number) if err != nil { diff --git a/eth/api_tracer.go b/eth/api_tracer.go index c044dcc..23209de 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -105,26 +105,18 @@ func (api *PrivateDebugAPI) TraceChain(ctx context.Context, start, end rpc.Block // Fetch the block interval that we want to trace var from, to *types.Block - switch start { - case rpc.PendingBlockNumber: - from = api.eth.miner.PendingBlock() - case rpc.LatestBlockNumber: - from = api.eth.blockchain.CurrentBlock() - case rpc.AcceptedBlockNumber: + if start.IsAccepted() { from = api.eth.AcceptedBlock() - default: + } else { from = api.eth.blockchain.GetBlockByNumber(uint64(start)) } - switch end { - case rpc.PendingBlockNumber: - to = api.eth.miner.PendingBlock() - case rpc.LatestBlockNumber: - to = api.eth.blockchain.CurrentBlock() - case rpc.AcceptedBlockNumber: - from = api.eth.AcceptedBlock() - default: + + if end.IsAccepted() { + to = api.eth.AcceptedBlock() + } else { to = api.eth.blockchain.GetBlockByNumber(uint64(end)) } + // Trace the chain if we've found all our blocks if from == nil { return nil, fmt.Errorf("starting block #%d not found", start) @@ -360,16 +352,12 @@ func (api *PrivateDebugAPI) TraceBlockByNumber(ctx context.Context, number rpc.B // Fetch the block that we want to trace var block *types.Block - switch number { - case rpc.PendingBlockNumber: - block = api.eth.miner.PendingBlock() - case rpc.LatestBlockNumber: - block = api.eth.blockchain.CurrentBlock() - case rpc.AcceptedBlockNumber: + if number.IsAccepted() { block = api.eth.AcceptedBlock() - default: + } else { block = api.eth.blockchain.GetBlockByNumber(uint64(number)) } + // Trace the block if it was found if block == nil { return nil, fmt.Errorf("block #%d not found", number) diff --git a/eth/filters/api.go b/eth/filters/api.go index 71e6454..9ee96af 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -330,6 +330,8 @@ func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([ filter = NewBlockFilter(api.backend, *crit.BlockHash, crit.Addresses, crit.Topics) } else { // Convert the RPC block numbers into internal representations + // LatestBlockNumber is left in place here to be handled + // correctly within NewRangeFilter begin := rpc.LatestBlockNumber.Int64() if crit.FromBlock != nil { begin = crit.FromBlock.Int64() @@ -385,6 +387,9 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty filter = NewBlockFilter(api.backend, *f.crit.BlockHash, f.crit.Addresses, f.crit.Topics) } else { // Convert the RPC block numbers into internal representations + // Leave LatestBlockNumber in place here as the defaults + // Should be handled correctly as request for the last + // accepted block instead throughout all APIs. begin := rpc.LatestBlockNumber.Int64() if f.crit.FromBlock != nil { begin = f.crit.FromBlock.Int64() diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 48a76c7..3c18e6e 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -129,6 +129,8 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return f.blockLogs(ctx, header) } // Figure out the limits of the filter range + // LatestBlockNumber is handled appropriately in HeaderByNumber + // so it is left in place here. header, _ := f.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber) if header == nil { return nil, nil |