ponder 0.17.6 → 0.17.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/esm/client/index.js +3 -1
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/runtime/filter.js +121 -1
- package/dist/esm/runtime/filter.js.map +1 -1
- package/dist/esm/sync-historical/index.js +30 -131
- package/dist/esm/sync-historical/index.js.map +1 -1
- package/dist/esm/sync-store/index.js +7 -3
- package/dist/esm/sync-store/index.js.map +1 -1
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/indexing/index.d.ts +1 -1
- package/dist/types/runtime/filter.d.ts +33 -1
- package/dist/types/runtime/filter.d.ts.map +1 -1
- package/dist/types/sync-historical/index.d.ts +2 -1
- package/dist/types/sync-historical/index.d.ts.map +1 -1
- package/dist/types/sync-store/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/client/index.ts +4 -1
- package/src/runtime/filter.ts +177 -1
- package/src/sync-historical/index.ts +33 -152
- package/src/sync-store/index.ts +6 -2
package/src/runtime/filter.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Address, hexToNumber } from "viem";
|
|
1
|
+
import { type Address, type Hex, hexToNumber, numberToHex } from "viem";
|
|
2
2
|
import type {
|
|
3
3
|
BlockFilter,
|
|
4
4
|
Factory,
|
|
@@ -23,6 +23,8 @@ import type {
|
|
|
23
23
|
TransactionFilter,
|
|
24
24
|
TransferFilter,
|
|
25
25
|
} from "@/internal/types.js";
|
|
26
|
+
import { type RequestParameters, sanitizeLogTopics } from "@/rpc/index.js";
|
|
27
|
+
import type { ChildAddresses, IntervalWithFilter } from "@/runtime/index.js";
|
|
26
28
|
import type {
|
|
27
29
|
Block,
|
|
28
30
|
Log,
|
|
@@ -30,6 +32,7 @@ import type {
|
|
|
30
32
|
Transaction,
|
|
31
33
|
TransactionReceipt,
|
|
32
34
|
} from "@/types/eth.js";
|
|
35
|
+
import type { Interval } from "@/utils/interval.js";
|
|
33
36
|
import { toLowerCase } from "@/utils/lowercase.js";
|
|
34
37
|
|
|
35
38
|
/** Returns true if `address` is an address filter. */
|
|
@@ -46,6 +49,179 @@ export const isAddressFactory = (
|
|
|
46
49
|
return Array.isArray(address) ? isAddressFactory(address[0]) : true;
|
|
47
50
|
};
|
|
48
51
|
|
|
52
|
+
type EthGetLogsRequest = Extract<
|
|
53
|
+
RequestParameters,
|
|
54
|
+
{ method: "eth_getLogs" }
|
|
55
|
+
> & {
|
|
56
|
+
params: [
|
|
57
|
+
Extract<
|
|
58
|
+
Extract<RequestParameters, { method: "eth_getLogs" }>["params"][0],
|
|
59
|
+
{ blockHash?: undefined }
|
|
60
|
+
> & { fromBlock: Hex; toBlock: Hex },
|
|
61
|
+
];
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const logRequestKeys = [
|
|
65
|
+
"address",
|
|
66
|
+
"topic0",
|
|
67
|
+
"topic1",
|
|
68
|
+
"topic2",
|
|
69
|
+
"topic3",
|
|
70
|
+
] as const;
|
|
71
|
+
|
|
72
|
+
const getLogRequestValue = (
|
|
73
|
+
request: EthGetLogsRequest,
|
|
74
|
+
key: (typeof logRequestKeys)[number],
|
|
75
|
+
): Hex | Hex[] | undefined => {
|
|
76
|
+
if (key === "address") return request.params[0].address;
|
|
77
|
+
|
|
78
|
+
const topic = request.params[0].topics?.[Number(key.slice(-1))];
|
|
79
|
+
return topic === null ? undefined : topic;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/** Returns `true` if `left` and `right` overlap by at least 80% of the smaller interval's length. */
|
|
83
|
+
const hasSufficientLogIntervalOverlap = (
|
|
84
|
+
left: Interval,
|
|
85
|
+
right: Interval,
|
|
86
|
+
): boolean => {
|
|
87
|
+
const overlapStart = Math.max(left[0], right[0]);
|
|
88
|
+
const overlapEnd = Math.min(left[1], right[1]);
|
|
89
|
+
if (overlapStart > overlapEnd) return false;
|
|
90
|
+
|
|
91
|
+
const overlapLength = overlapEnd - overlapStart + 1;
|
|
92
|
+
const smallerIntervalLength = Math.min(
|
|
93
|
+
left[1] - left[0] + 1,
|
|
94
|
+
right[1] - right[0] + 1,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
return overlapLength / smallerIntervalLength >= 0.8;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const mergeLogFilterValue = <value extends Hex>(
|
|
101
|
+
left: value | value[] | undefined,
|
|
102
|
+
right: value | value[] | undefined,
|
|
103
|
+
): value[] | undefined =>
|
|
104
|
+
left === undefined || right === undefined
|
|
105
|
+
? undefined
|
|
106
|
+
: [
|
|
107
|
+
...new Set([
|
|
108
|
+
...(Array.isArray(left) ? left : [left]),
|
|
109
|
+
...(Array.isArray(right) ? right : [right]),
|
|
110
|
+
]),
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Merge `LogFilter`s into the smallest possible set of "eth_getLogs" requests.
|
|
115
|
+
*
|
|
116
|
+
* @dev Two filters are merged into a single request when:
|
|
117
|
+
* 1. their required intervals overlap by at least 80% (of the smaller
|
|
118
|
+
* interval's length), and
|
|
119
|
+
* 2. at most one of `address`, `topic0`, `topic1`, `topic2`, or `topic3`
|
|
120
|
+
* differs between them.
|
|
121
|
+
* The one differing dimension (if any) is unioned into an array.
|
|
122
|
+
*
|
|
123
|
+
* @dev Factory addresses are resolved into concrete child addresses (or
|
|
124
|
+
* `undefined`, above `factoryAddressCountThreshold`) before merging, so
|
|
125
|
+
* requests originating from different factories can still be merged.
|
|
126
|
+
*/
|
|
127
|
+
export const mergeLogFiltersToRequests = (
|
|
128
|
+
filters: IntervalWithFilter[],
|
|
129
|
+
childAddresses: ChildAddresses,
|
|
130
|
+
factoryAddressCountThreshold: number,
|
|
131
|
+
): EthGetLogsRequest[] => {
|
|
132
|
+
const requests: EthGetLogsRequest[] = [];
|
|
133
|
+
|
|
134
|
+
for (const { filter, interval } of filters) {
|
|
135
|
+
if (filter.type !== "log") continue;
|
|
136
|
+
|
|
137
|
+
let address: Hex | Hex[] | undefined;
|
|
138
|
+
if (isAddressFactory(filter.address)) {
|
|
139
|
+
const addresses = childAddresses.get(filter.address.id)!;
|
|
140
|
+
if (addresses.size === 0) continue;
|
|
141
|
+
|
|
142
|
+
address =
|
|
143
|
+
addresses.size >= factoryAddressCountThreshold
|
|
144
|
+
? undefined
|
|
145
|
+
: Array.from(addresses.keys());
|
|
146
|
+
} else {
|
|
147
|
+
address = filter.address;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const candidate: EthGetLogsRequest = {
|
|
151
|
+
method: "eth_getLogs",
|
|
152
|
+
params: [
|
|
153
|
+
{
|
|
154
|
+
address,
|
|
155
|
+
topics: sanitizeLogTopics([
|
|
156
|
+
filter.topic0,
|
|
157
|
+
filter.topic1 ?? null,
|
|
158
|
+
filter.topic2 ?? null,
|
|
159
|
+
filter.topic3 ?? null,
|
|
160
|
+
]),
|
|
161
|
+
fromBlock: numberToHex(interval[0]),
|
|
162
|
+
toBlock: numberToHex(interval[1]),
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
let isMerged = false;
|
|
168
|
+
|
|
169
|
+
for (const request of requests) {
|
|
170
|
+
if (
|
|
171
|
+
hasSufficientLogIntervalOverlap(
|
|
172
|
+
[
|
|
173
|
+
hexToNumber(request.params[0].fromBlock),
|
|
174
|
+
hexToNumber(request.params[0].toBlock),
|
|
175
|
+
],
|
|
176
|
+
interval,
|
|
177
|
+
) === false
|
|
178
|
+
) {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const numberOfDifferences = logRequestKeys.filter(
|
|
183
|
+
(key) =>
|
|
184
|
+
JSON.stringify(getLogRequestValue(request, key)) !==
|
|
185
|
+
JSON.stringify(getLogRequestValue(candidate, key)),
|
|
186
|
+
).length;
|
|
187
|
+
if (numberOfDifferences > 1) continue;
|
|
188
|
+
|
|
189
|
+
const requestParams = request.params[0];
|
|
190
|
+
for (const key of logRequestKeys) {
|
|
191
|
+
const requestValue = getLogRequestValue(request, key);
|
|
192
|
+
const candidateValue = getLogRequestValue(candidate, key);
|
|
193
|
+
if (JSON.stringify(requestValue) === JSON.stringify(candidateValue)) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const mergedValue = mergeLogFilterValue(requestValue, candidateValue);
|
|
198
|
+
if (key === "address") {
|
|
199
|
+
requestParams.address = mergedValue;
|
|
200
|
+
} else {
|
|
201
|
+
const topics = [...(requestParams.topics ?? [])];
|
|
202
|
+
topics[Number(key.slice(-1))] = mergedValue ?? null;
|
|
203
|
+
requestParams.topics = sanitizeLogTopics(topics);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
requestParams.fromBlock = numberToHex(
|
|
208
|
+
Math.min(hexToNumber(requestParams.fromBlock), interval[0]),
|
|
209
|
+
);
|
|
210
|
+
requestParams.toBlock = numberToHex(
|
|
211
|
+
Math.max(hexToNumber(requestParams.toBlock), interval[1]),
|
|
212
|
+
);
|
|
213
|
+
isMerged = true;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (isMerged === false) {
|
|
218
|
+
requests.push(candidate);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return requests;
|
|
223
|
+
};
|
|
224
|
+
|
|
49
225
|
export const getChildAddress = ({
|
|
50
226
|
log,
|
|
51
227
|
factory,
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
type Hash,
|
|
5
5
|
type Hex,
|
|
6
6
|
hexToNumber,
|
|
7
|
-
type LogTopic,
|
|
8
7
|
numberToHex,
|
|
9
8
|
type RpcError,
|
|
10
9
|
toHex,
|
|
@@ -37,7 +36,7 @@ import {
|
|
|
37
36
|
validateTracesAndBlock,
|
|
38
37
|
validateTransactionsAndBlock,
|
|
39
38
|
} from "@/rpc/actions.js";
|
|
40
|
-
import {
|
|
39
|
+
import type { RequestParameters, Rpc } from "@/rpc/index.js";
|
|
41
40
|
import {
|
|
42
41
|
getChildAddress,
|
|
43
42
|
isAddressFactory,
|
|
@@ -49,6 +48,7 @@ import {
|
|
|
49
48
|
isTraceFilterMatched,
|
|
50
49
|
isTransactionFilterMatched,
|
|
51
50
|
isTransferFilterMatched,
|
|
51
|
+
mergeLogFiltersToRequests,
|
|
52
52
|
} from "@/runtime/filter.js";
|
|
53
53
|
import type {
|
|
54
54
|
ChildAddresses,
|
|
@@ -79,6 +79,7 @@ export type HistoricalSync = {
|
|
|
79
79
|
}): Promise<SyncLog[]>;
|
|
80
80
|
/**
|
|
81
81
|
* Sync block data that must be queried for a single block (block, transactions, receipts, traces).
|
|
82
|
+
* @returns Closest-to-tip synced block.
|
|
82
83
|
*/
|
|
83
84
|
syncBlockData(params: {
|
|
84
85
|
interval: Interval;
|
|
@@ -120,48 +121,37 @@ export const createHistoricalSync = (
|
|
|
120
121
|
// Helper functions for sync tasks
|
|
121
122
|
////////
|
|
122
123
|
|
|
123
|
-
type EthGetLogsParams = {
|
|
124
|
-
address: Address | Address[] | undefined;
|
|
125
|
-
topic0?: LogTopic;
|
|
126
|
-
topic1?: LogTopic;
|
|
127
|
-
topic2?: LogTopic;
|
|
128
|
-
topic3?: LogTopic;
|
|
129
|
-
interval: Interval;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
124
|
/**
|
|
133
125
|
* Split "eth_getLogs" requests into ranges inferred from errors
|
|
134
126
|
* and batch requests.
|
|
135
127
|
*/
|
|
136
128
|
const syncLogsDynamic = async (
|
|
137
|
-
|
|
129
|
+
params: Extract<RequestParameters, { method: "eth_getLogs" }>["params"][0],
|
|
138
130
|
context?: Parameters<Rpc["request"]>[1],
|
|
139
131
|
): Promise<SyncLog[]> => {
|
|
132
|
+
const { address, topics } = params;
|
|
133
|
+
|
|
140
134
|
const intervals = getChunks({
|
|
141
|
-
interval
|
|
135
|
+
interval: [
|
|
136
|
+
hexToNumber(params.fromBlock as Hex),
|
|
137
|
+
hexToNumber(params.toBlock as Hex),
|
|
138
|
+
],
|
|
142
139
|
maxChunkSize:
|
|
143
140
|
args.chain.ethGetLogsBlockRange ??
|
|
144
141
|
logsRequestMetadata.confirmedRange ??
|
|
145
142
|
logsRequestMetadata.estimatedRange,
|
|
146
143
|
});
|
|
147
144
|
|
|
148
|
-
const topics = sanitizeLogTopics([
|
|
149
|
-
topic0 ?? null,
|
|
150
|
-
topic1 ?? null,
|
|
151
|
-
topic2 ?? null,
|
|
152
|
-
topic3 ?? null,
|
|
153
|
-
])!;
|
|
154
|
-
|
|
155
145
|
const logs = await Promise.all(
|
|
156
|
-
intervals.map((
|
|
146
|
+
intervals.map(([fromBlock, toBlock]) =>
|
|
157
147
|
eth_getLogs(
|
|
158
148
|
args.rpc,
|
|
159
149
|
[
|
|
160
150
|
{
|
|
161
151
|
address,
|
|
162
152
|
topics,
|
|
163
|
-
fromBlock: numberToHex(
|
|
164
|
-
toBlock: numberToHex(
|
|
153
|
+
fromBlock: numberToHex(fromBlock),
|
|
154
|
+
toBlock: numberToHex(toBlock),
|
|
165
155
|
},
|
|
166
156
|
],
|
|
167
157
|
context,
|
|
@@ -177,8 +167,8 @@ export const createHistoricalSync = (
|
|
|
177
167
|
{
|
|
178
168
|
address,
|
|
179
169
|
topics,
|
|
180
|
-
fromBlock: toHex(
|
|
181
|
-
toBlock: toHex(
|
|
170
|
+
fromBlock: toHex(fromBlock),
|
|
171
|
+
toBlock: toHex(toBlock),
|
|
182
172
|
},
|
|
183
173
|
],
|
|
184
174
|
error: error as RpcError,
|
|
@@ -205,7 +195,12 @@ export const createHistoricalSync = (
|
|
|
205
195
|
};
|
|
206
196
|
|
|
207
197
|
return syncLogsDynamic(
|
|
208
|
-
{
|
|
198
|
+
{
|
|
199
|
+
address,
|
|
200
|
+
topics,
|
|
201
|
+
fromBlock: numberToHex(fromBlock),
|
|
202
|
+
toBlock: numberToHex(toBlock),
|
|
203
|
+
},
|
|
209
204
|
context,
|
|
210
205
|
);
|
|
211
206
|
}),
|
|
@@ -318,14 +313,15 @@ export const createHistoricalSync = (
|
|
|
318
313
|
const logs = await syncLogsDynamic(
|
|
319
314
|
{
|
|
320
315
|
address: factory.address,
|
|
321
|
-
|
|
322
|
-
interval,
|
|
316
|
+
topics: [factory.eventSelector],
|
|
317
|
+
fromBlock: numberToHex(interval[0]),
|
|
318
|
+
toBlock: numberToHex(interval[1]),
|
|
323
319
|
},
|
|
324
320
|
context,
|
|
325
321
|
);
|
|
326
322
|
|
|
327
323
|
const childAddresses = new Map<Address, number>();
|
|
328
|
-
const
|
|
324
|
+
const factoryChildAddresses = args.childAddresses.get(factory.id)!;
|
|
329
325
|
|
|
330
326
|
const childAddressDecodeFailureIds = new Set<string>();
|
|
331
327
|
let childAddressDecodeFailureCount = 0;
|
|
@@ -358,7 +354,7 @@ export const createHistoricalSync = (
|
|
|
358
354
|
throw error;
|
|
359
355
|
}
|
|
360
356
|
}
|
|
361
|
-
const existingBlockNumber =
|
|
357
|
+
const existingBlockNumber = factoryChildAddresses.get(address);
|
|
362
358
|
const newBlockNumber = hexToNumber(log.blockNumber);
|
|
363
359
|
|
|
364
360
|
if (
|
|
@@ -366,7 +362,7 @@ export const createHistoricalSync = (
|
|
|
366
362
|
existingBlockNumber > newBlockNumber
|
|
367
363
|
) {
|
|
368
364
|
childAddresses.set(address, newBlockNumber);
|
|
369
|
-
|
|
365
|
+
factoryChildAddresses.set(address, newBlockNumber);
|
|
370
366
|
}
|
|
371
367
|
}
|
|
372
368
|
}
|
|
@@ -428,132 +424,17 @@ export const createHistoricalSync = (
|
|
|
428
424
|
}),
|
|
429
425
|
);
|
|
430
426
|
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
if (filter.type !== "log") continue;
|
|
436
|
-
|
|
437
|
-
const hasAddress = filter.address !== undefined;
|
|
438
|
-
const hasTopic1 = filter.topic1 !== undefined && filter.topic1 !== null;
|
|
439
|
-
const hasTopic2 = filter.topic2 !== undefined && filter.topic2 !== null;
|
|
440
|
-
const hasTopic3 = filter.topic3 !== undefined && filter.topic3 !== null;
|
|
441
|
-
|
|
442
|
-
if (hasAddress === false || hasTopic1 || hasTopic2 || hasTopic3) {
|
|
443
|
-
if (isAddressFactory(filter.address)) {
|
|
444
|
-
const childAddresses = args.childAddresses.get(filter.address.id)!;
|
|
445
|
-
|
|
446
|
-
if (childAddresses.size === 0) {
|
|
447
|
-
continue;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
singleEthGetLogsParams.push({
|
|
451
|
-
address:
|
|
452
|
-
childAddresses.size >=
|
|
453
|
-
args.common.options.factoryAddressCountThreshold
|
|
454
|
-
? undefined
|
|
455
|
-
: Array.from(childAddresses.keys()),
|
|
456
|
-
topic0: filter.topic0,
|
|
457
|
-
topic1: filter.topic1,
|
|
458
|
-
topic2: filter.topic2,
|
|
459
|
-
topic3: filter.topic3,
|
|
460
|
-
interval,
|
|
461
|
-
});
|
|
462
|
-
} else {
|
|
463
|
-
singleEthGetLogsParams.push({
|
|
464
|
-
address: filter.address,
|
|
465
|
-
topic0: filter.topic0,
|
|
466
|
-
topic1: filter.topic1,
|
|
467
|
-
topic2: filter.topic2,
|
|
468
|
-
topic3: filter.topic3,
|
|
469
|
-
interval,
|
|
470
|
-
});
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
continue;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
let addressKey: string;
|
|
477
|
-
if (isAddressFactory(filter.address)) {
|
|
478
|
-
addressKey = filter.address.id;
|
|
479
|
-
} else if (Array.isArray(filter.address)) {
|
|
480
|
-
addressKey = filter.address.join("_");
|
|
481
|
-
} else {
|
|
482
|
-
addressKey = filter.address as Address;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
if (mergedEthGetLogsParams.has(addressKey) === false) {
|
|
486
|
-
if (isAddressFactory(filter.address)) {
|
|
487
|
-
const childAddresses = args.childAddresses.get(filter.address.id)!;
|
|
488
|
-
|
|
489
|
-
if (childAddresses.size === 0) {
|
|
490
|
-
continue;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
mergedEthGetLogsParams.set(addressKey, {
|
|
494
|
-
address:
|
|
495
|
-
childAddresses.size >=
|
|
496
|
-
args.common.options.factoryAddressCountThreshold
|
|
497
|
-
? undefined
|
|
498
|
-
: Array.from(childAddresses.keys()),
|
|
499
|
-
topic0: filter.topic0,
|
|
500
|
-
topic1: filter.topic1,
|
|
501
|
-
topic2: filter.topic2,
|
|
502
|
-
topic3: filter.topic3,
|
|
503
|
-
interval,
|
|
504
|
-
});
|
|
505
|
-
} else {
|
|
506
|
-
mergedEthGetLogsParams.set(addressKey, {
|
|
507
|
-
address: filter.address,
|
|
508
|
-
topic0: filter.topic0,
|
|
509
|
-
topic1: filter.topic1,
|
|
510
|
-
topic2: filter.topic2,
|
|
511
|
-
topic3: filter.topic3,
|
|
512
|
-
interval,
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
} else {
|
|
516
|
-
const existingInterval =
|
|
517
|
-
mergedEthGetLogsParams.get(addressKey)!.interval;
|
|
518
|
-
const existingTopic0 = mergedEthGetLogsParams.get(addressKey)!
|
|
519
|
-
.topic0 as Hex | Hex[];
|
|
520
|
-
|
|
521
|
-
if (Array.isArray(existingTopic0)) {
|
|
522
|
-
if (existingTopic0.includes(filter.topic0) === false) {
|
|
523
|
-
mergedEthGetLogsParams.get(addressKey)!.topic0 = [
|
|
524
|
-
...existingTopic0,
|
|
525
|
-
filter.topic0,
|
|
526
|
-
];
|
|
527
|
-
}
|
|
528
|
-
} else {
|
|
529
|
-
if (existingTopic0 !== filter.topic0) {
|
|
530
|
-
mergedEthGetLogsParams.get(addressKey)!.topic0 = [
|
|
531
|
-
existingTopic0,
|
|
532
|
-
filter.topic0,
|
|
533
|
-
];
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
mergedEthGetLogsParams.get(addressKey)!.interval = intervalBounds([
|
|
538
|
-
existingInterval,
|
|
539
|
-
interval,
|
|
540
|
-
]);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
const ethGetLogsParams = dedupe(
|
|
545
|
-
[
|
|
546
|
-
...singleEthGetLogsParams,
|
|
547
|
-
...Array.from(mergedEthGetLogsParams.values()),
|
|
548
|
-
],
|
|
549
|
-
(params) => JSON.stringify(params),
|
|
427
|
+
const ethGetLogsRequests = mergeLogFiltersToRequests(
|
|
428
|
+
requiredIntervals,
|
|
429
|
+
args.childAddresses,
|
|
430
|
+
args.common.options.factoryAddressCountThreshold,
|
|
550
431
|
);
|
|
551
432
|
|
|
552
433
|
let logs: SyncLog[] = [];
|
|
553
434
|
|
|
554
435
|
await Promise.all(
|
|
555
|
-
|
|
556
|
-
const _logs = await syncLogsDynamic(params, context);
|
|
436
|
+
ethGetLogsRequests.map(async (request) => {
|
|
437
|
+
const _logs = await syncLogsDynamic(request.params[0], context);
|
|
557
438
|
for (const log of _logs) {
|
|
558
439
|
logs.push(log);
|
|
559
440
|
}
|
package/src/sync-store/index.ts
CHANGED
|
@@ -351,11 +351,15 @@ export const createSyncStore = ({
|
|
|
351
351
|
const batchSize = 200;
|
|
352
352
|
|
|
353
353
|
for (let i = 0; i < queries.length; i += batchSize) {
|
|
354
|
+
const batch = queries.slice(i, i + batchSize);
|
|
354
355
|
const _rows = await qb.wrap(
|
|
355
356
|
{ label: "select_intervals" },
|
|
356
|
-
() =>
|
|
357
|
+
() => {
|
|
358
|
+
if (batch.length === 1) return batch[0]!.execute();
|
|
359
|
+
|
|
357
360
|
// @ts-expect-error
|
|
358
|
-
unionAll(...
|
|
361
|
+
return unionAll(...batch);
|
|
362
|
+
},
|
|
359
363
|
context,
|
|
360
364
|
);
|
|
361
365
|
|