aboutsummaryrefslogtreecommitdiff
path: root/eth
diff options
context:
space:
mode:
authorAaron Buchwald <[email protected]>2020-10-16 15:22:23 -0400
committerAaron Buchwald <[email protected]>2020-10-16 15:22:23 -0400
commit77a2d0f97f142261a351f0cdcc1d001d0cead4cf (patch)
tree31b5eb91d754c6c46f8d749d7a08c17d3cc9ec13 /eth
parent3b3cf1aeaa1eb41f64383e2a18c00240ffde7d2b (diff)
Clean up use of pending/latest meta block numbers
Diffstat (limited to 'eth')
-rw-r--r--eth/api.go46
-rw-r--r--eth/api_backend.go37
-rw-r--r--eth/api_tracer.go32
-rw-r--r--eth/filters/api.go5
-rw-r--r--eth/filters/filter.go2
5 files changed, 41 insertions, 81 deletions
diff --git a/eth/api.go b/eth/api.go
index ada2a97..bad357d 100644
--- a/eth/api.go
+++ b/eth/api.go
@@ -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