1- import { BlockLogs , FilterArgs } from "@ganache/ethereum-utils" ;
1+ import { BlockLogs , FilterArgs , RangeFilterArgs , Tag } from "@ganache/ethereum-utils" ;
22import { LevelUp } from "levelup" ;
33import Manager from "./manager" ;
44import { Quantity } from "@ganache/utils" ;
55import Blockchain from "../blockchain" ;
6- import { parseFilter , parseFilterDetails } from "../helpers/filter-parsing" ;
6+ import { parseFilter , parseFilterDetails , parseFilterRange } from "../helpers/filter-parsing" ;
77import { Ethereum } from "../api-types" ;
88
99export default class BlockLogManager extends Manager < BlockLogs > {
1010 #blockchain: Blockchain ;
11+
1112 constructor ( base : LevelUp , blockchain : Blockchain ) {
1213 super ( base , BlockLogs ) ;
1314 this . #blockchain = blockchain ;
@@ -31,38 +32,51 @@ export default class BlockLogManager extends Manager<BlockLogs> {
3132 async getLogs ( filter : FilterArgs ) : Promise < Ethereum . Logs > {
3233 const blockchain = this . #blockchain;
3334 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 ( ) ) ;
3440 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 ) ;
4141 return logs ? [ ...logs . filter ( addresses , topics ) ] : [ ] ;
4242 }
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 ) ;
4846 const fork = this . #blockchain. fallback ;
4947 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 ( ) ;
5152 }
53+ if ( rangeFilter . toBlock == Tag . earliest ) {
54+ toBlock = await this . forkEarliest ( ) ;
55+ }
56+ fromBlock = Quantity . min ( fromBlock , toBlock ) ;
57+
5258 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 ) ) ;
5561 }
5662 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 ) ) ;
5865 }
5966 return ret ;
6067 }
6168
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 > {
6377 const { addresses, topics } = parseFilter ( filter , this . #blockchain) ;
6478 const pendingLogsPromises : Promise < BlockLogs > [ ] = [ ] ;
65- for ( let i = from ; i <= toBlockNumber ; i ++ ) {
79+ for ( let i = from . toNumber ( ) ; i <= to . toNumber ( ) ; i ++ ) {
6680 pendingLogsPromises . push ( this . get ( Quantity . toBuffer ( i ) ) ) ;
6781 }
6882 return Promise . all ( pendingLogsPromises ) . then ( blockLogsRange => {
0 commit comments