1
- import { BlockLogs , FilterArgs } from "@ganache/ethereum-utils" ;
1
+ import { BlockLogs , FilterArgs , RangeFilterArgs , Tag } from "@ganache/ethereum-utils" ;
2
2
import { LevelUp } from "levelup" ;
3
3
import Manager from "./manager" ;
4
4
import { Quantity } from "@ganache/utils" ;
5
5
import Blockchain from "../blockchain" ;
6
- import { parseFilter , parseFilterDetails } from "../helpers/filter-parsing" ;
6
+ import { parseFilter , parseFilterDetails , parseFilterRange } from "../helpers/filter-parsing" ;
7
7
import { Ethereum } from "../api-types" ;
8
8
9
9
export default class BlockLogManager extends Manager < BlockLogs > {
10
10
#blockchain: Blockchain ;
11
+
11
12
constructor ( base : LevelUp , blockchain : Blockchain ) {
12
13
super ( base , BlockLogs ) ;
13
14
this . #blockchain = blockchain ;
@@ -31,38 +32,51 @@ export default class BlockLogManager extends Manager<BlockLogs> {
31
32
async getLogs ( filter : FilterArgs ) : Promise < Ethereum . Logs > {
32
33
const blockchain = this . #blockchain;
33
34
if ( "blockHash" in filter ) {
35
+ // TODO: revert back to getNumberFromHash (when they add support for fallback/forks)
36
+ const block = await blockchain . blocks . getByHash ( filter . blockHash ) ;
37
+ if ( ! block ) return [ ] ;
38
+ const blockNumber = block . header . number ;
39
+ const logs = await this . get ( blockNumber . toBuffer ( ) ) ;
34
40
const { addresses, topics } = parseFilterDetails ( filter ) ;
35
- const blockNumber = await blockchain . blocks . getNumberFromHash (
36
- filter . blockHash
37
- ) ;
38
- if ( ! blockNumber ) return [ ] ;
39
-
40
- const logs = await this . get ( blockNumber ) ;
41
41
return logs ? [ ...logs . filter ( addresses , topics ) ] : [ ] ;
42
42
}
43
- const { addresses, topics, fromBlock, toBlock } = parseFilter (
44
- filter ,
45
- blockchain
46
- ) ;
47
- const from = Quantity . min ( fromBlock , toBlock ) ;
43
+ const rangeFilter = filter as RangeFilterArgs ;
44
+
45
+ let { fromBlock, toBlock } = parseFilterRange ( rangeFilter , blockchain ) ;
48
46
const fork = this . #blockchain. fallback ;
49
47
if ( ! fork ) {
50
- return await this . getLocal ( from . toNumber ( ) , toBlock . toNumber ( ) , filter ) ;
48
+ return await this . getLocal ( fromBlock , toBlock , filter ) ;
49
+ }
50
+ if ( rangeFilter . fromBlock == Tag . earliest ) {
51
+ fromBlock = await this . forkEarliest ( ) ;
51
52
}
53
+ if ( rangeFilter . toBlock == Tag . earliest ) {
54
+ toBlock = await this . forkEarliest ( ) ;
55
+ }
56
+ fromBlock = Quantity . min ( fromBlock , toBlock ) ;
57
+
52
58
const ret : Ethereum . Logs = [ ] ;
53
- if ( fork . isValidForkBlockNumber ( from ) ) {
54
- ret . push ( ...await this . getFromFork ( from , Quantity . min ( toBlock , fork . blockNumber ) , filter ) ) ;
59
+ if ( fork . isValidForkBlockNumber ( fromBlock ) ) {
60
+ ret . push ( ...await this . getFromFork ( fromBlock , Quantity . min ( toBlock , fork . blockNumber ) , filter ) ) ;
55
61
}
56
62
if ( ! fork . isValidForkBlockNumber ( toBlock ) ) {
57
- ret . push ( ...await this . getLocal ( fork . blockNumber . toNumber ( ) + 1 , toBlock . toNumber ( ) , filter ) ) ;
63
+ const blockNumberPlusOne = Quantity . from ( fork . blockNumber . toNumber ( ) + 1 ) ;
64
+ ret . push ( ...await this . getLocal ( Quantity . max ( fromBlock , blockNumberPlusOne ) , toBlock , filter ) ) ;
58
65
}
59
66
return ret ;
60
67
}
61
68
62
- getLocal ( from : number , toBlockNumber : number , filter : FilterArgs ) : Promise < Ethereum . Logs > {
69
+ // TODO: Use block-manager earliest when fixed (currently it doesn't support fallback/fork correctly)
70
+ async forkEarliest ( ) {
71
+ const fork = this . #blockchain. fallback ;
72
+ const block = await fork . request < any > ( "eth_getBlockByNumber" , [ Tag . earliest , false ] , { disableCache : true } ) ;
73
+ return Quantity . from ( block . number ) ;
74
+ }
75
+
76
+ getLocal ( from : Quantity , to : Quantity , filter : FilterArgs ) : Promise < Ethereum . Logs > {
63
77
const { addresses, topics } = parseFilter ( filter , this . #blockchain) ;
64
78
const pendingLogsPromises : Promise < BlockLogs > [ ] = [ ] ;
65
- for ( let i = from ; i <= toBlockNumber ; i ++ ) {
79
+ for ( let i = from . toNumber ( ) ; i <= to . toNumber ( ) ; i ++ ) {
66
80
pendingLogsPromises . push ( this . get ( Quantity . toBuffer ( i ) ) ) ;
67
81
}
68
82
return Promise . all ( pendingLogsPromises ) . then ( blockLogsRange => {
0 commit comments