diff options
author | Domino Valdano <dominoplural@gmail.com> | 2018-05-12 17:20:46 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2018-07-12 23:16:32 +0800 |
commit | 96339daf40989072ff2a9e8b476da6698da45dc7 (patch) | |
tree | dd1d0dba7a4ac7071378cf06983dc68ce5b40f9d /eth | |
parent | e8824f6e7409a2064b1165c5b6cc6b2d390573ce (diff) | |
download | dexon-96339daf40989072ff2a9e8b476da6698da45dc7.tar dexon-96339daf40989072ff2a9e8b476da6698da45dc7.tar.gz dexon-96339daf40989072ff2a9e8b476da6698da45dc7.tar.bz2 dexon-96339daf40989072ff2a9e8b476da6698da45dc7.tar.lz dexon-96339daf40989072ff2a9e8b476da6698da45dc7.tar.xz dexon-96339daf40989072ff2a9e8b476da6698da45dc7.tar.zst dexon-96339daf40989072ff2a9e8b476da6698da45dc7.zip |
eth/filters, ethereum: EIP-234 add blockHash param for eth_getLogs
Diffstat (limited to 'eth')
-rw-r--r-- | eth/filters/api.go | 56 | ||||
-rw-r--r-- | eth/filters/filter_system_test.go | 27 |
2 files changed, 70 insertions, 13 deletions
diff --git a/eth/filters/api.go b/eth/filters/api.go index 592ad3b82..f964d9232 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -28,6 +28,7 @@ import ( ethereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" @@ -324,15 +325,35 @@ func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) { // // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) { - // Convert the RPC block numbers into internal representations - if crit.FromBlock == nil { - crit.FromBlock = big.NewInt(rpc.LatestBlockNumber.Int64()) - } - if crit.ToBlock == nil { - crit.ToBlock = big.NewInt(rpc.LatestBlockNumber.Int64()) + var ( + fromBlock int64 + toBlock int64 + ) + + if crit.BlockHash != nil { + // look up block number from block hash + if block := rawdb.ReadHeaderNumber(api.chainDb, *crit.BlockHash); block != nil { + // verify block is part of canonical chain + if canonical := rawdb.ReadCanonicalHash(api.chainDb, *block); canonical != *crit.BlockHash { + return nil, fmt.Errorf("Block with hash %s was removed from canonical chain", crit.BlockHash.Hex()) + } + fromBlock = int64(*block) + toBlock = fromBlock + } else { + return nil, fmt.Errorf("Block with hash %s was not found", crit.BlockHash.Hex()) + } + } else { + // Convert the RPC block numbers into internal representations + if crit.FromBlock == nil { + fromBlock = int64(rpc.LatestBlockNumber) + } + if crit.ToBlock == nil { + toBlock = int64(rpc.LatestBlockNumber) + } } + // Create and run the filter to get all the logs - filter := New(api.backend, crit.FromBlock.Int64(), crit.ToBlock.Int64(), crit.Addresses, crit.Topics) + filter := New(api.backend, fromBlock, toBlock, crit.Addresses, crit.Topics) logs, err := filter.Logs(ctx) if err != nil { @@ -444,7 +465,8 @@ func returnLogs(logs []*types.Log) []*types.Log { // UnmarshalJSON sets *args fields with given data. func (args *FilterCriteria) UnmarshalJSON(data []byte) error { type input struct { - From *rpc.BlockNumber `json:"fromBlock"` + BlockHash *common.Hash `json:"blockHash"` + FromBlock *rpc.BlockNumber `json:"fromBlock"` ToBlock *rpc.BlockNumber `json:"toBlock"` Addresses interface{} `json:"address"` Topics []interface{} `json:"topics"` @@ -455,12 +477,20 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error { return err } - if raw.From != nil { - args.FromBlock = big.NewInt(raw.From.Int64()) - } + if raw.BlockHash != nil { + if raw.FromBlock != nil || raw.ToBlock != nil { + // BlockHash is mutually exclusive with FromBlock/ToBlock criteria + return fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock, choose one or the other") + } + args.BlockHash = raw.BlockHash + } else { + if raw.FromBlock != nil { + args.FromBlock = big.NewInt(raw.FromBlock.Int64()) + } - if raw.ToBlock != nil { - args.ToBlock = big.NewInt(raw.ToBlock.Int64()) + if raw.ToBlock != nil { + args.ToBlock = big.NewInt(raw.ToBlock.Int64()) + } } args.Addresses = []common.Address{} diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index ff1af85a8..2c1e8a2eb 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -343,6 +343,33 @@ func TestInvalidLogFilterCreation(t *testing.T) { } } +func TestInvalidGetLogsRequest(t *testing.T) { + var ( + mux = new(event.TypeMux) + db = ethdb.NewMemDatabase() + txFeed = new(event.Feed) + rmLogsFeed = new(event.Feed) + logsFeed = new(event.Feed) + chainFeed = new(event.Feed) + backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed} + api = NewPublicFilterAPI(backend, false) + blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") + ) + + // Reason: Cannot specify both BlockHash and FromBlock/ToBlock) + testCases := []FilterCriteria{ + 0: {BlockHash: &blockHash, FromBlock: big.NewInt(100)}, + 1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)}, + 2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, + } + + for i, test := range testCases { + if _, err := api.GetLogs(context.Background(), test); err == nil { + t.Errorf("Expected Logs for case #%d to fail", i) + } + } +} + // TestLogFilter tests whether log filters match the correct logs that are posted to the event feed. func TestLogFilter(t *testing.T) { t.Parallel() |