aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Buchwald <aaron.buchwald56@gmail.com>2020-10-16 15:22:23 -0400
committerAaron Buchwald <aaron.buchwald56@gmail.com>2020-10-16 15:22:23 -0400
commit77a2d0f97f142261a351f0cdcc1d001d0cead4cf (patch)
tree31b5eb91d754c6c46f8d749d7a08c17d3cc9ec13
parent3b3cf1aeaa1eb41f64383e2a18c00240ffde7d2b (diff)
Clean up use of pending/latest meta block numbers
-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
-rw-r--r--internal/ethapi/api.go36
6 files changed, 60 insertions, 98 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
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 825f8fc..5190410 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -546,8 +546,8 @@ func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 {
}
// GetBalance returns the amount of wei for the given address in the state of the
-// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta
-// block numbers are also allowed.
+// given block number. The rpc.LatestBlockNumber, rpc.PendingBlockNumber, and
+// rpc.AcceptedBlockNumber meta block numbers are also allowed.
func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) {
state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if state == nil || err != nil {
@@ -556,9 +556,9 @@ func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Add
return (*hexutil.Big)(state.GetBalance(address)), state.Error()
}
-// GetBalanceMultiCoin returns the amount of wei for the given address in the state of the
-// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta
-// block numbers are also allowed.
+// GetAssetBalance returns the amount of wei for the given address in the state of the
+// given block number. The rpc.LatestBlockNumber, rpc.PendingBlockNumber, and
+// rpc.AcceptedBlockNumber meta block numbers are also allowed.
func (s *PublicBlockChainAPI) GetAssetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash, assetID ids.ID) (*hexutil.Big, error) {
state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if state == nil || err != nil {
@@ -640,12 +640,13 @@ func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.
header, err := s.b.HeaderByNumber(ctx, number)
if header != nil && err == nil {
response := s.rpcMarshalHeader(ctx, header)
- if number == rpc.PendingBlockNumber {
- // Pending header need to nil out a few fields
- for _, field := range []string{"hash", "nonce", "miner"} {
- response[field] = nil
- }
- }
+ // coreth has no notion of a pending block
+ // 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
@@ -669,12 +670,13 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.B
block, err := s.b.BlockByNumber(ctx, number)
if block != nil && err == nil {
response, err := s.rpcMarshalBlock(ctx, 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
- }
- }
+ // coreth has no notion of a pending block
+ // 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
+ // }
+ // }
return response, err
}
return nil, err