Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit bd1f941

Browse files
committed
fix: make fetching logs from fork efficient
1 parent 57f0423 commit bd1f941

File tree

1 file changed

+37
-8
lines changed

1 file changed

+37
-8
lines changed

src/chains/ethereum/ethereum/src/data-managers/blocklog-manager.ts

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Blockchain from "../blockchain";
55
import { parseFilter, parseFilterDetails } from "../helpers/filter-parsing";
66
import { Ethereum } from "../api-types";
77
import { GanacheLevelUp } from "../database";
8+
type Topic = string | string[];
89

910
export default class BlockLogManager extends Manager<BlockLogs> {
1011
#blockchain: Blockchain;
@@ -28,6 +29,19 @@ export default class BlockLogManager extends Manager<BlockLogs> {
2829
return log;
2930
}
3031

32+
async getRange(fromBlockNumber: string | Buffer, toBlockNumber: string | Buffer, topics: Topic[], address: String | String[]) {
33+
const blockchain = this.#blockchain;
34+
if (!blockchain.fallback){
35+
throw new Error("Not a forked instance");
36+
}
37+
const res = await this.#blockchain.fallback.request<any[] | null>(
38+
"eth_getLogs",
39+
[{ address, topics, fromBlock: Quantity.from(fromBlockNumber), toBlock: Quantity.from(toBlockNumber) }]
40+
);
41+
return BlockLogs.fromJSON(res);
42+
43+
}
44+
3145
async getLogs(filter: FilterArgs): Promise<Ethereum.Logs> {
3246
const blockchain = this.#blockchain;
3347
if ("blockHash" in filter) {
@@ -44,19 +58,34 @@ export default class BlockLogManager extends Manager<BlockLogs> {
4458
filter,
4559
blockchain
4660
);
47-
48-
const pendingLogsPromises: Promise<BlockLogs>[] = [
49-
this.get(fromBlock.toBuffer())
50-
];
61+
const pendingLogsPromises: Promise<BlockLogs>[] = [];
5162

5263
const fromBlockNumber = fromBlock.toNumber();
5364
// if we have a range of blocks to search, do that here:
5465
if (fromBlockNumber !== toBlockNumber) {
55-
// fetch all the blockLogs in-between `fromBlock` and `toBlock` (excluding
56-
// from, because we already started fetching that one)
57-
for (let i = fromBlockNumber + 1, l = toBlockNumber + 1; i < l; i++) {
58-
pendingLogsPromises.push(this.get(Quantity.toBuffer(i)));
66+
if (
67+
!blockchain.fallback || // We're not a forked chain
68+
blockchain.fallback.blockNumber < fromBlock // Or we are, but only querying post-fork
69+
) {
70+
// fetch all the blockLogs in-between `fromBlock` and `toBlock`
71+
for (let i = fromBlockNumber, l = toBlockNumber + 1; i < l; i++) {
72+
pendingLogsPromises.push(this.get(Quantity.toBuffer(i)));
73+
}
74+
} else {
75+
// Fetch all the logs from fromBlockNumber to forkBlock in one request
76+
let addressesAsStrings: String[]|String;
77+
if (Array.isArray(addresses)){
78+
addressesAsStrings = addresses.map(x => `0x${x.toString('hex')}`)
79+
}
80+
pendingLogsPromises.push(this.getRange(Quantity.from(fromBlockNumber).toString(), Quantity.from(toBlockNumber).toString(), topics, addressesAsStrings ));
81+
// fetch all the blockLogs in-between `forkBlock` + 1 and `toBlock` locally in the
82+
// way that we normally do
83+
for (let i = blockchain.fallback.blockNumber.toNumber() + 1, l = toBlockNumber + 1; i < l; i++) {
84+
pendingLogsPromises.push(this.get(Quantity.toBuffer(i)));
85+
}
5986
}
87+
} else {
88+
pendingLogsPromises.push(this.get(Quantity.toBuffer(fromBlockNumber)));
6089
}
6190

6291
// now filter and compute all the blocks' blockLogs (in block order)

0 commit comments

Comments
 (0)