ponder 0.14.13 → 0.15.0
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 +16 -0
- package/dist/esm/bin/commands/createViews.js +28 -11
- package/dist/esm/bin/commands/createViews.js.map +1 -1
- package/dist/esm/bin/commands/dev.js +42 -22
- package/dist/esm/bin/commands/dev.js.map +1 -1
- package/dist/esm/bin/commands/prune.js +3 -0
- package/dist/esm/bin/commands/prune.js.map +1 -1
- package/dist/esm/bin/commands/serve.js +4 -1
- package/dist/esm/bin/commands/serve.js.map +1 -1
- package/dist/esm/bin/commands/start.js +18 -6
- package/dist/esm/bin/commands/start.js.map +1 -1
- package/dist/esm/bin/isolatedController.js +200 -0
- package/dist/esm/bin/isolatedController.js.map +1 -0
- package/dist/esm/bin/isolatedWorker.js +146 -0
- package/dist/esm/bin/isolatedWorker.js.map +1 -0
- package/dist/esm/build/config.js +322 -402
- package/dist/esm/build/config.js.map +1 -1
- package/dist/esm/build/index.js +8 -11
- package/dist/esm/build/index.js.map +1 -1
- package/dist/esm/build/pre.js +1 -4
- package/dist/esm/build/pre.js.map +1 -1
- package/dist/esm/build/schema.js +25 -3
- package/dist/esm/build/schema.js.map +1 -1
- package/dist/esm/client/index.js +306 -42
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/database/actions.js +264 -104
- package/dist/esm/database/actions.js.map +1 -1
- package/dist/esm/database/index.js +39 -33
- package/dist/esm/database/index.js.map +1 -1
- package/dist/esm/database/queryBuilder.js +1 -0
- package/dist/esm/database/queryBuilder.js.map +1 -1
- package/dist/esm/drizzle/index.js +11 -7
- package/dist/esm/drizzle/index.js.map +1 -1
- package/dist/esm/drizzle/onchain.js +18 -0
- package/dist/esm/drizzle/onchain.js.map +1 -1
- package/dist/esm/indexing/client.js +32 -25
- package/dist/esm/indexing/client.js.map +1 -1
- package/dist/esm/indexing/index.js +110 -178
- package/dist/esm/indexing/index.js.map +1 -1
- package/dist/esm/indexing/profile.js +1 -1
- package/dist/esm/indexing/profile.js.map +1 -1
- package/dist/esm/indexing-store/cache.js +196 -274
- package/dist/esm/indexing-store/cache.js.map +1 -1
- package/dist/esm/indexing-store/historical.js +17 -13
- package/dist/esm/indexing-store/historical.js.map +1 -1
- package/dist/esm/indexing-store/index.js +10 -1
- package/dist/esm/indexing-store/index.js.map +1 -1
- package/dist/esm/indexing-store/profile.js +3 -3
- package/dist/esm/indexing-store/profile.js.map +1 -1
- package/dist/esm/indexing-store/realtime.js +27 -2
- package/dist/esm/indexing-store/realtime.js.map +1 -1
- package/dist/esm/internal/errors.js +28 -0
- package/dist/esm/internal/errors.js.map +1 -1
- package/dist/esm/internal/metrics.js +279 -82
- package/dist/esm/internal/metrics.js.map +1 -1
- package/dist/esm/internal/options.js +1 -0
- package/dist/esm/internal/options.js.map +1 -1
- package/dist/esm/internal/telemetry.js +1 -1
- package/dist/esm/internal/telemetry.js.map +1 -1
- package/dist/esm/rpc/http.js +130 -0
- package/dist/esm/rpc/http.js.map +1 -0
- package/dist/esm/rpc/index.js +38 -7
- package/dist/esm/rpc/index.js.map +1 -1
- package/dist/esm/runtime/events.js +179 -212
- package/dist/esm/runtime/events.js.map +1 -1
- package/dist/esm/runtime/filter.js +71 -0
- package/dist/esm/runtime/filter.js.map +1 -1
- package/dist/esm/runtime/fragments.js +78 -73
- package/dist/esm/runtime/fragments.js.map +1 -1
- package/dist/esm/runtime/historical.js +306 -130
- package/dist/esm/runtime/historical.js.map +1 -1
- package/dist/esm/runtime/index.js +183 -58
- package/dist/esm/runtime/index.js.map +1 -1
- package/dist/esm/runtime/isolated.js +462 -0
- package/dist/esm/runtime/isolated.js.map +1 -0
- package/dist/esm/runtime/multichain.js +80 -73
- package/dist/esm/runtime/multichain.js.map +1 -1
- package/dist/esm/runtime/omnichain.js +82 -75
- package/dist/esm/runtime/omnichain.js.map +1 -1
- package/dist/esm/runtime/realtime.js +198 -66
- package/dist/esm/runtime/realtime.js.map +1 -1
- package/dist/esm/sync-historical/index.js +416 -457
- package/dist/esm/sync-historical/index.js.map +1 -1
- package/dist/esm/sync-realtime/bloom.js +3 -3
- package/dist/esm/sync-realtime/bloom.js.map +1 -1
- package/dist/esm/sync-realtime/index.js +27 -46
- package/dist/esm/sync-realtime/index.js.map +1 -1
- package/dist/esm/sync-store/index.js +112 -63
- package/dist/esm/sync-store/index.js.map +1 -1
- package/dist/esm/utils/abi.js +20 -32
- package/dist/esm/utils/abi.js.map +1 -1
- package/dist/esm/utils/chunk.js +8 -0
- package/dist/esm/utils/chunk.js.map +1 -0
- package/dist/esm/utils/promiseAllSettledWithThrow.js +19 -0
- package/dist/esm/utils/promiseAllSettledWithThrow.js.map +1 -0
- package/dist/esm/{client/parse.js → utils/sql-parse.js} +94 -80
- package/dist/esm/utils/sql-parse.js.map +1 -0
- package/dist/types/bin/commands/createViews.d.ts.map +1 -1
- package/dist/types/bin/commands/dev.d.ts.map +1 -1
- package/dist/types/bin/commands/prune.d.ts.map +1 -1
- package/dist/types/bin/commands/serve.d.ts.map +1 -1
- package/dist/types/bin/commands/start.d.ts.map +1 -1
- package/dist/types/bin/isolatedController.d.ts +13 -0
- package/dist/types/bin/isolatedController.d.ts.map +1 -0
- package/dist/types/bin/isolatedWorker.d.ts +9 -0
- package/dist/types/bin/isolatedWorker.d.ts.map +1 -0
- package/dist/types/build/config.d.ts +29 -11
- package/dist/types/build/config.d.ts.map +1 -1
- package/dist/types/build/index.d.ts +3 -2
- package/dist/types/build/index.d.ts.map +1 -1
- package/dist/types/build/pre.d.ts +1 -1
- package/dist/types/build/pre.d.ts.map +1 -1
- package/dist/types/build/schema.d.ts +5 -3
- package/dist/types/build/schema.d.ts.map +1 -1
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/config/index.d.ts +3 -3
- package/dist/types/config/index.d.ts.map +1 -1
- package/dist/types/database/actions.d.ts +53 -7
- package/dist/types/database/actions.d.ts.map +1 -1
- package/dist/types/database/index.d.ts +21 -21
- package/dist/types/database/index.d.ts.map +1 -1
- package/dist/types/database/queryBuilder.d.ts.map +1 -1
- package/dist/types/drizzle/index.d.ts +4 -5
- package/dist/types/drizzle/index.d.ts.map +1 -1
- package/dist/types/drizzle/onchain.d.ts +6 -0
- package/dist/types/drizzle/onchain.d.ts.map +1 -1
- package/dist/types/indexing/client.d.ts.map +1 -1
- package/dist/types/indexing/index.d.ts +2 -5
- package/dist/types/indexing/index.d.ts.map +1 -1
- package/dist/types/indexing-store/cache.d.ts +3 -2
- package/dist/types/indexing-store/cache.d.ts.map +1 -1
- package/dist/types/indexing-store/historical.d.ts +2 -1
- package/dist/types/indexing-store/historical.d.ts.map +1 -1
- package/dist/types/indexing-store/index.d.ts +1 -0
- package/dist/types/indexing-store/index.d.ts.map +1 -1
- package/dist/types/indexing-store/realtime.d.ts +2 -1
- package/dist/types/indexing-store/realtime.d.ts.map +1 -1
- package/dist/types/internal/errors.d.ts +5 -0
- package/dist/types/internal/errors.d.ts.map +1 -1
- package/dist/types/internal/metrics.d.ts +21 -0
- package/dist/types/internal/metrics.d.ts.map +1 -1
- package/dist/types/internal/options.d.ts +2 -0
- package/dist/types/internal/options.d.ts.map +1 -1
- package/dist/types/internal/types.d.ts +66 -58
- package/dist/types/internal/types.d.ts.map +1 -1
- package/dist/types/rpc/http.d.ts +17 -0
- package/dist/types/rpc/http.d.ts.map +1 -0
- package/dist/types/rpc/index.d.ts.map +1 -1
- package/dist/types/runtime/events.d.ts +4 -4
- package/dist/types/runtime/events.d.ts.map +1 -1
- package/dist/types/runtime/filter.d.ts +5 -1
- package/dist/types/runtime/filter.d.ts.map +1 -1
- package/dist/types/runtime/fragments.d.ts +4 -3
- package/dist/types/runtime/fragments.d.ts.map +1 -1
- package/dist/types/runtime/historical.d.ts +29 -13
- package/dist/types/runtime/historical.d.ts.map +1 -1
- package/dist/types/runtime/index.d.ts +49 -6
- package/dist/types/runtime/index.d.ts.map +1 -1
- package/dist/types/runtime/init.d.ts +5 -5
- package/dist/types/runtime/init.d.ts.map +1 -1
- package/dist/types/runtime/isolated.d.ts +14 -0
- package/dist/types/runtime/isolated.d.ts.map +1 -0
- package/dist/types/runtime/multichain.d.ts.map +1 -1
- package/dist/types/runtime/omnichain.d.ts.map +1 -1
- package/dist/types/runtime/realtime.d.ts +21 -10
- package/dist/types/runtime/realtime.d.ts.map +1 -1
- package/dist/types/sync-historical/index.d.ts +18 -8
- package/dist/types/sync-historical/index.d.ts.map +1 -1
- package/dist/types/sync-realtime/bloom.d.ts.map +1 -1
- package/dist/types/sync-realtime/index.d.ts +2 -2
- package/dist/types/sync-realtime/index.d.ts.map +1 -1
- package/dist/types/sync-store/index.d.ts +9 -9
- package/dist/types/sync-store/index.d.ts.map +1 -1
- package/dist/types/utils/abi.d.ts +3 -34
- package/dist/types/utils/abi.d.ts.map +1 -1
- package/dist/types/utils/chunk.d.ts +2 -0
- package/dist/types/utils/chunk.d.ts.map +1 -0
- package/dist/types/utils/promiseAllSettledWithThrow.d.ts +8 -0
- package/dist/types/utils/promiseAllSettledWithThrow.d.ts.map +1 -0
- package/dist/types/utils/sql-parse.d.ts +21 -0
- package/dist/types/utils/sql-parse.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/bin/commands/createViews.ts +35 -15
- package/src/bin/commands/dev.ts +43 -21
- package/src/bin/commands/prune.ts +6 -0
- package/src/bin/commands/serve.ts +4 -1
- package/src/bin/commands/start.ts +20 -5
- package/src/bin/isolatedController.ts +300 -0
- package/src/bin/isolatedWorker.ts +192 -0
- package/src/build/config.ts +570 -632
- package/src/build/index.ts +14 -14
- package/src/build/pre.ts +1 -4
- package/src/build/schema.ts +49 -4
- package/src/client/index.ts +386 -48
- package/src/config/index.ts +3 -3
- package/src/database/actions.ts +469 -120
- package/src/database/index.ts +85 -58
- package/src/database/queryBuilder.ts +1 -0
- package/src/drizzle/index.ts +15 -7
- package/src/drizzle/onchain.ts +19 -0
- package/src/indexing/client.ts +38 -25
- package/src/indexing/index.ts +137 -230
- package/src/indexing/profile.ts +1 -1
- package/src/indexing-store/cache.ts +285 -414
- package/src/indexing-store/historical.ts +20 -10
- package/src/indexing-store/index.ts +16 -0
- package/src/indexing-store/profile.ts +3 -3
- package/src/indexing-store/realtime.ts +28 -0
- package/src/internal/errors.ts +26 -0
- package/src/internal/metrics.ts +341 -111
- package/src/internal/options.ts +4 -0
- package/src/internal/telemetry.ts +1 -1
- package/src/internal/types.ts +70 -87
- package/src/rpc/http.ts +164 -0
- package/src/rpc/index.ts +39 -7
- package/src/runtime/events.ts +195 -240
- package/src/runtime/filter.ts +85 -1
- package/src/runtime/fragments.ts +109 -113
- package/src/runtime/historical.ts +467 -189
- package/src/runtime/index.ts +337 -69
- package/src/runtime/init.ts +5 -5
- package/src/runtime/isolated.ts +768 -0
- package/src/runtime/multichain.ts +137 -102
- package/src/runtime/omnichain.ts +138 -106
- package/src/runtime/realtime.ts +322 -123
- package/src/sync-historical/index.ts +556 -692
- package/src/sync-realtime/bloom.ts +7 -3
- package/src/sync-realtime/index.ts +31 -46
- package/src/sync-store/index.ts +189 -95
- package/src/utils/abi.ts +33 -90
- package/src/utils/chunk.ts +7 -0
- package/src/utils/promiseAllSettledWithThrow.ts +27 -0
- package/src/{client/parse.ts → utils/sql-parse.ts} +100 -90
- package/dist/esm/client/parse.js.map +0 -1
- package/dist/types/client/parse.d.ts +0 -14
- package/dist/types/client/parse.d.ts.map +0 -1
package/src/runtime/index.ts
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import type { Common } from "@/internal/common.js";
|
|
2
2
|
import type {
|
|
3
3
|
Chain,
|
|
4
|
+
Factory,
|
|
4
5
|
FactoryId,
|
|
5
6
|
Filter,
|
|
6
7
|
Fragment,
|
|
7
8
|
LightBlock,
|
|
8
|
-
Source,
|
|
9
9
|
} from "@/internal/types.js";
|
|
10
10
|
import type { SyncBlock } from "@/internal/types.js";
|
|
11
11
|
import { _eth_getBlockByNumber } from "@/rpc/actions.js";
|
|
12
12
|
import type { Rpc } from "@/rpc/index.js";
|
|
13
|
-
import {
|
|
14
|
-
|
|
13
|
+
import {
|
|
14
|
+
getFilterFactories,
|
|
15
|
+
getFilterFromBlock,
|
|
16
|
+
getFilterToBlock,
|
|
17
|
+
isAddressFactory,
|
|
18
|
+
} from "@/runtime/filter.js";
|
|
19
|
+
import { getFragments, recoverFilter } from "@/runtime/fragments.js";
|
|
15
20
|
import type { SyncStore } from "@/sync-store/index.js";
|
|
16
21
|
import {
|
|
17
22
|
MAX_CHECKPOINT,
|
|
@@ -20,8 +25,11 @@ import {
|
|
|
20
25
|
} from "@/utils/checkpoint.js";
|
|
21
26
|
import {
|
|
22
27
|
type Interval,
|
|
28
|
+
intervalBounds,
|
|
29
|
+
intervalDifference,
|
|
23
30
|
intervalIntersection,
|
|
24
31
|
intervalIntersectionMany,
|
|
32
|
+
intervalUnion,
|
|
25
33
|
sortIntervals,
|
|
26
34
|
} from "@/utils/interval.js";
|
|
27
35
|
import { type Address, hexToNumber, toHex } from "viem";
|
|
@@ -41,15 +49,25 @@ export type SyncProgress = {
|
|
|
41
49
|
export type ChildAddresses = Map<FactoryId, Map<Address, number>>;
|
|
42
50
|
|
|
43
51
|
export type CachedIntervals = Map<
|
|
44
|
-
Filter,
|
|
52
|
+
Filter | Factory,
|
|
45
53
|
{ fragment: Fragment; intervals: Interval[] }[]
|
|
46
54
|
>;
|
|
47
55
|
|
|
56
|
+
export type IntervalWithFilter = {
|
|
57
|
+
interval: Interval;
|
|
58
|
+
filter: Filter;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export type IntervalWithFactory = {
|
|
62
|
+
interval: Interval;
|
|
63
|
+
factory: Factory;
|
|
64
|
+
};
|
|
65
|
+
|
|
48
66
|
export async function getLocalSyncProgress(params: {
|
|
49
67
|
common: Common;
|
|
50
|
-
sources: Source[];
|
|
51
68
|
chain: Chain;
|
|
52
69
|
rpc: Rpc;
|
|
70
|
+
filters: Filter[];
|
|
53
71
|
finalizedBlock: LightBlock;
|
|
54
72
|
cachedIntervals: CachedIntervals;
|
|
55
73
|
}): Promise<SyncProgress> {
|
|
@@ -96,36 +114,12 @@ export async function getLocalSyncProgress(params: {
|
|
|
96
114
|
);
|
|
97
115
|
},
|
|
98
116
|
} as SyncProgress;
|
|
99
|
-
const filters = params.sources.map(({ filter }) => filter);
|
|
100
117
|
|
|
101
118
|
// Earliest `fromBlock` among all `filters`
|
|
102
|
-
const start = Math.min(
|
|
103
|
-
...filters.flatMap((filter) => {
|
|
104
|
-
const fromBlocks: number[] = [filter.fromBlock ?? 0];
|
|
105
|
-
switch (filter.type) {
|
|
106
|
-
case "log":
|
|
107
|
-
if (isAddressFactory(filter.address)) {
|
|
108
|
-
fromBlocks.push(filter.address.fromBlock ?? 0);
|
|
109
|
-
}
|
|
110
|
-
break;
|
|
111
|
-
case "transaction":
|
|
112
|
-
case "trace":
|
|
113
|
-
case "transfer":
|
|
114
|
-
if (isAddressFactory(filter.fromAddress)) {
|
|
115
|
-
fromBlocks.push(filter.fromAddress.fromBlock ?? 0);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (isAddressFactory(filter.toAddress)) {
|
|
119
|
-
fromBlocks.push(filter.toAddress.fromBlock ?? 0);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return fromBlocks;
|
|
124
|
-
}),
|
|
125
|
-
);
|
|
119
|
+
const start = Math.min(...params.filters.map(getFilterFromBlock));
|
|
126
120
|
|
|
127
121
|
const cached = getCachedBlock({
|
|
128
|
-
filters,
|
|
122
|
+
filters: params.filters,
|
|
129
123
|
cachedIntervals: params.cachedIntervals,
|
|
130
124
|
});
|
|
131
125
|
|
|
@@ -158,12 +152,12 @@ export async function getLocalSyncProgress(params: {
|
|
|
158
152
|
syncProgress.current = diagnostics[1];
|
|
159
153
|
}
|
|
160
154
|
|
|
161
|
-
if (filters.some((filter) => filter.toBlock === undefined)) {
|
|
155
|
+
if (params.filters.some((filter) => filter.toBlock === undefined)) {
|
|
162
156
|
return syncProgress;
|
|
163
157
|
}
|
|
164
158
|
|
|
165
159
|
// Latest `toBlock` among all `filters`
|
|
166
|
-
const end = Math.max(...filters.map((filter) => filter.toBlock!));
|
|
160
|
+
const end = Math.max(...params.filters.map((filter) => filter.toBlock!));
|
|
167
161
|
|
|
168
162
|
if (end > hexToNumber(params.finalizedBlock.number)) {
|
|
169
163
|
syncProgress.end = {
|
|
@@ -184,35 +178,35 @@ export async function getLocalSyncProgress(params: {
|
|
|
184
178
|
}
|
|
185
179
|
|
|
186
180
|
export async function getChildAddresses(params: {
|
|
187
|
-
|
|
181
|
+
filters: Filter[];
|
|
188
182
|
syncStore: SyncStore;
|
|
189
183
|
}): Promise<ChildAddresses> {
|
|
190
184
|
const childAddresses: ChildAddresses = new Map();
|
|
191
|
-
for (const
|
|
192
|
-
switch (
|
|
185
|
+
for (const filter of params.filters) {
|
|
186
|
+
switch (filter.type) {
|
|
193
187
|
case "log":
|
|
194
|
-
if (isAddressFactory(
|
|
188
|
+
if (isAddressFactory(filter.address)) {
|
|
195
189
|
const _childAddresses = await params.syncStore.getChildAddresses({
|
|
196
|
-
factory:
|
|
190
|
+
factory: filter.address,
|
|
197
191
|
});
|
|
198
|
-
childAddresses.set(
|
|
192
|
+
childAddresses.set(filter.address.id, _childAddresses);
|
|
199
193
|
}
|
|
200
194
|
break;
|
|
201
195
|
case "transaction":
|
|
202
196
|
case "transfer":
|
|
203
197
|
case "trace":
|
|
204
|
-
if (isAddressFactory(
|
|
198
|
+
if (isAddressFactory(filter.fromAddress)) {
|
|
205
199
|
const _childAddresses = await params.syncStore.getChildAddresses({
|
|
206
|
-
factory:
|
|
200
|
+
factory: filter.fromAddress,
|
|
207
201
|
});
|
|
208
|
-
childAddresses.set(
|
|
202
|
+
childAddresses.set(filter.fromAddress.id, _childAddresses);
|
|
209
203
|
}
|
|
210
204
|
|
|
211
|
-
if (isAddressFactory(
|
|
205
|
+
if (isAddressFactory(filter.toAddress)) {
|
|
212
206
|
const _childAddresses = await params.syncStore.getChildAddresses({
|
|
213
|
-
factory:
|
|
207
|
+
factory: filter.toAddress,
|
|
214
208
|
});
|
|
215
|
-
childAddresses.set(
|
|
209
|
+
childAddresses.set(filter.toAddress.id, _childAddresses);
|
|
216
210
|
}
|
|
217
211
|
|
|
218
212
|
break;
|
|
@@ -223,18 +217,18 @@ export async function getChildAddresses(params: {
|
|
|
223
217
|
|
|
224
218
|
export async function getCachedIntervals(params: {
|
|
225
219
|
chain: Chain;
|
|
220
|
+
filters: Filter[];
|
|
226
221
|
syncStore: SyncStore;
|
|
227
|
-
sources: Source[];
|
|
228
222
|
}): Promise<CachedIntervals> {
|
|
229
223
|
/**
|
|
230
|
-
* Intervals that have been completed for all filters in `args.
|
|
224
|
+
* Intervals that have been completed for all filters in `args.filters`.
|
|
231
225
|
*
|
|
232
226
|
* Note: `intervalsCache` is not updated after a new interval is synced.
|
|
233
227
|
*/
|
|
234
228
|
let cachedIntervals: CachedIntervals;
|
|
235
229
|
if (params.chain.disableCache) {
|
|
236
230
|
cachedIntervals = new Map();
|
|
237
|
-
for (const
|
|
231
|
+
for (const filter of params.filters) {
|
|
238
232
|
cachedIntervals.set(filter, []);
|
|
239
233
|
for (const { fragment } of getFragments(filter)) {
|
|
240
234
|
cachedIntervals.get(filter)!.push({ fragment, intervals: [] });
|
|
@@ -242,14 +236,253 @@ export async function getCachedIntervals(params: {
|
|
|
242
236
|
}
|
|
243
237
|
} else {
|
|
244
238
|
cachedIntervals = await params.syncStore.getIntervals({
|
|
245
|
-
filters: params.
|
|
239
|
+
filters: params.filters,
|
|
246
240
|
});
|
|
247
241
|
}
|
|
248
242
|
|
|
249
243
|
return cachedIntervals;
|
|
250
244
|
}
|
|
251
245
|
|
|
252
|
-
/**
|
|
246
|
+
/**
|
|
247
|
+
* Returns the intervals that need to be synced to complete the `interval`
|
|
248
|
+
* for all `filters`.
|
|
249
|
+
*
|
|
250
|
+
* @param params.filters - The filters to sync.
|
|
251
|
+
* @param params.interval - The interval to sync.
|
|
252
|
+
* @param params.cachedIntervals - The cached intervals for the filters.
|
|
253
|
+
* @returns The intervals that need to be synced.
|
|
254
|
+
*/
|
|
255
|
+
export const getRequiredIntervals = (params: {
|
|
256
|
+
filters: Filter[];
|
|
257
|
+
interval: Interval;
|
|
258
|
+
cachedIntervals: CachedIntervals;
|
|
259
|
+
}): Interval[] => {
|
|
260
|
+
const requiredIntervals: Interval[] = [];
|
|
261
|
+
for (const filter of params.filters) {
|
|
262
|
+
const filterTotalIntervals = intervalIntersection(
|
|
263
|
+
[params.interval],
|
|
264
|
+
[[filter.fromBlock ?? 0, filter.toBlock ?? Number.POSITIVE_INFINITY]],
|
|
265
|
+
);
|
|
266
|
+
let filterCachedIntervals = params.cachedIntervals.get(filter)!;
|
|
267
|
+
|
|
268
|
+
const factories = getFilterFactories(filter);
|
|
269
|
+
|
|
270
|
+
const missingFactoryIntervals: Interval[] = [];
|
|
271
|
+
for (const factory of factories) {
|
|
272
|
+
const factoryTotalIntervals = intervalIntersection(
|
|
273
|
+
[params.interval],
|
|
274
|
+
[[factory.fromBlock ?? 0, factory.toBlock ?? Number.POSITIVE_INFINITY]],
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
missingFactoryIntervals.push(
|
|
278
|
+
...intervalDifference(
|
|
279
|
+
factoryTotalIntervals,
|
|
280
|
+
intervalIntersectionMany(
|
|
281
|
+
params.cachedIntervals
|
|
282
|
+
.get(factory)!
|
|
283
|
+
.map(({ intervals }) => intervals),
|
|
284
|
+
),
|
|
285
|
+
),
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (missingFactoryIntervals.length > 0) {
|
|
290
|
+
const firstMissingFactoryBlock = sortIntervals(
|
|
291
|
+
missingFactoryIntervals,
|
|
292
|
+
)[0]![0];
|
|
293
|
+
|
|
294
|
+
// Note: When a filter with a factory is missing blocks,
|
|
295
|
+
// all blocks after the first missing block are also missing.
|
|
296
|
+
|
|
297
|
+
filterCachedIntervals = filterCachedIntervals.map(
|
|
298
|
+
({ fragment, intervals }) => {
|
|
299
|
+
return {
|
|
300
|
+
fragment,
|
|
301
|
+
intervals: intervalDifference(intervals, [
|
|
302
|
+
[firstMissingFactoryBlock, params.interval[1]],
|
|
303
|
+
]),
|
|
304
|
+
};
|
|
305
|
+
},
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const missingIntervals = intervalDifference(
|
|
310
|
+
filterTotalIntervals,
|
|
311
|
+
intervalIntersectionMany(
|
|
312
|
+
filterCachedIntervals.map(({ intervals }) => intervals),
|
|
313
|
+
),
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
requiredIntervals.push(...missingIntervals, ...missingFactoryIntervals);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return intervalUnion(requiredIntervals);
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Returns the intervals that need to be synced to complete the `interval`
|
|
324
|
+
* for all `filters`.
|
|
325
|
+
*
|
|
326
|
+
* Note: This function dynamically builds filters using `recoverFilter`.
|
|
327
|
+
* Fragments are used to create a minimal filter, to avoid refetching data
|
|
328
|
+
* even if a filter is only partially synced.
|
|
329
|
+
*
|
|
330
|
+
* @param params.filters - The filters to sync.
|
|
331
|
+
* @param params.interval - The interval to sync.
|
|
332
|
+
* @param params.cachedIntervals - The cached intervals for the filters.
|
|
333
|
+
* @returns The intervals that need to be synced.
|
|
334
|
+
*/
|
|
335
|
+
export const getRequiredIntervalsWithFilters = (params: {
|
|
336
|
+
filters: Filter[];
|
|
337
|
+
interval: Interval;
|
|
338
|
+
cachedIntervals: CachedIntervals;
|
|
339
|
+
}): {
|
|
340
|
+
intervals: IntervalWithFilter[];
|
|
341
|
+
factoryIntervals: IntervalWithFactory[];
|
|
342
|
+
} => {
|
|
343
|
+
const requiredIntervals: IntervalWithFilter[] = [];
|
|
344
|
+
const requiredFactoryIntervals: IntervalWithFactory[] = [];
|
|
345
|
+
|
|
346
|
+
// Determine the requests that need to be made, and which intervals need to be inserted.
|
|
347
|
+
// Fragments are used to create a minimal filter, to avoid refetching data even if a filter
|
|
348
|
+
// is only partially synced.
|
|
349
|
+
|
|
350
|
+
for (const filter of params.filters) {
|
|
351
|
+
const filterTotalIntervals = intervalIntersection(
|
|
352
|
+
[params.interval],
|
|
353
|
+
[[filter.fromBlock ?? 0, filter.toBlock ?? Number.POSITIVE_INFINITY]],
|
|
354
|
+
);
|
|
355
|
+
let filterCachedIntervals = params.cachedIntervals.get(filter)!;
|
|
356
|
+
|
|
357
|
+
const factories = getFilterFactories(filter);
|
|
358
|
+
|
|
359
|
+
const missingFactoryIntervals: Interval[] = [];
|
|
360
|
+
for (const factory of factories) {
|
|
361
|
+
const factoryTotalIntervals = intervalIntersection(
|
|
362
|
+
[params.interval],
|
|
363
|
+
[[factory.fromBlock ?? 0, factory.toBlock ?? Number.POSITIVE_INFINITY]],
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
missingFactoryIntervals.push(
|
|
367
|
+
...intervalDifference(
|
|
368
|
+
factoryTotalIntervals,
|
|
369
|
+
intervalIntersectionMany(
|
|
370
|
+
params.cachedIntervals
|
|
371
|
+
.get(factory)!
|
|
372
|
+
.map(({ intervals }) => intervals),
|
|
373
|
+
),
|
|
374
|
+
),
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (missingFactoryIntervals.length > 0) {
|
|
379
|
+
const firstMissingFactoryBlock = sortIntervals(
|
|
380
|
+
missingFactoryIntervals,
|
|
381
|
+
)[0]![0];
|
|
382
|
+
|
|
383
|
+
// Note: When a filter with a factory is missing blocks,
|
|
384
|
+
// all blocks after the first missing block are also missing.
|
|
385
|
+
|
|
386
|
+
filterCachedIntervals = filterCachedIntervals.map(
|
|
387
|
+
({ fragment, intervals }) => {
|
|
388
|
+
return {
|
|
389
|
+
fragment,
|
|
390
|
+
intervals: intervalDifference(intervals, [
|
|
391
|
+
[firstMissingFactoryBlock, params.interval[1]],
|
|
392
|
+
]),
|
|
393
|
+
};
|
|
394
|
+
},
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const requiredFragmentIntervals: {
|
|
399
|
+
fragment: Fragment;
|
|
400
|
+
intervals: Interval[];
|
|
401
|
+
}[] = [];
|
|
402
|
+
|
|
403
|
+
for (const {
|
|
404
|
+
fragment,
|
|
405
|
+
intervals: fragmentIntervals,
|
|
406
|
+
} of filterCachedIntervals) {
|
|
407
|
+
const missingFragmentIntervals = intervalDifference(
|
|
408
|
+
filterTotalIntervals,
|
|
409
|
+
fragmentIntervals,
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
if (missingFragmentIntervals.length > 0) {
|
|
413
|
+
requiredFragmentIntervals.push({
|
|
414
|
+
fragment,
|
|
415
|
+
intervals: missingFragmentIntervals,
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (requiredFragmentIntervals.length > 0) {
|
|
421
|
+
const requiredInterval = intervalBounds(
|
|
422
|
+
requiredFragmentIntervals.flatMap(({ intervals }) => intervals),
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
const requiredFilter = recoverFilter(
|
|
426
|
+
filter,
|
|
427
|
+
requiredFragmentIntervals.map(({ fragment }) => fragment),
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
requiredIntervals.push({
|
|
431
|
+
filter: requiredFilter,
|
|
432
|
+
interval: requiredInterval,
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
for (const factory of factories) {
|
|
437
|
+
const factoryTotalIntervals = intervalIntersection(
|
|
438
|
+
[params.interval],
|
|
439
|
+
[[factory.fromBlock ?? 0, factory.toBlock ?? Number.POSITIVE_INFINITY]],
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
const requiredFactoryFragmentIntervals: {
|
|
443
|
+
fragment: Fragment;
|
|
444
|
+
intervals: Interval[];
|
|
445
|
+
}[] = [];
|
|
446
|
+
|
|
447
|
+
for (const {
|
|
448
|
+
fragment,
|
|
449
|
+
intervals: fragmentIntervals,
|
|
450
|
+
} of params.cachedIntervals.get(factory)!) {
|
|
451
|
+
const missingFragmentIntervals = intervalDifference(
|
|
452
|
+
factoryTotalIntervals,
|
|
453
|
+
fragmentIntervals,
|
|
454
|
+
);
|
|
455
|
+
|
|
456
|
+
if (missingFragmentIntervals.length > 0) {
|
|
457
|
+
requiredFactoryFragmentIntervals.push({
|
|
458
|
+
fragment,
|
|
459
|
+
intervals: missingFragmentIntervals,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if (requiredFactoryFragmentIntervals.length > 0) {
|
|
465
|
+
const requiredInterval = intervalBounds(
|
|
466
|
+
requiredFactoryFragmentIntervals.flatMap(
|
|
467
|
+
({ intervals }) => intervals,
|
|
468
|
+
),
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
requiredFactoryIntervals.push({
|
|
472
|
+
factory,
|
|
473
|
+
interval: requiredInterval,
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
return {
|
|
480
|
+
intervals: requiredIntervals,
|
|
481
|
+
factoryIntervals: requiredFactoryIntervals,
|
|
482
|
+
};
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
/** Returns the closest-to-tip block that has been synced for all `filters`. */
|
|
253
486
|
export const getCachedBlock = ({
|
|
254
487
|
filters,
|
|
255
488
|
cachedIntervals,
|
|
@@ -258,35 +491,70 @@ export const getCachedBlock = ({
|
|
|
258
491
|
cachedIntervals: CachedIntervals;
|
|
259
492
|
}): number | undefined => {
|
|
260
493
|
const latestCompletedBlocks = filters.map((filter) => {
|
|
261
|
-
const
|
|
494
|
+
const filterTotalInterval = [
|
|
262
495
|
filter.fromBlock ?? 0,
|
|
263
496
|
filter.toBlock ?? Number.POSITIVE_INFINITY,
|
|
264
497
|
] satisfies Interval;
|
|
265
|
-
|
|
498
|
+
let filterCachedIntervals = cachedIntervals.get(filter)!;
|
|
499
|
+
|
|
500
|
+
const factories = getFilterFactories(filter);
|
|
266
501
|
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
502
|
+
const missingFactoryIntervals: Interval[] = [];
|
|
503
|
+
for (const factory of factories) {
|
|
504
|
+
const factoryTotalInterval = [
|
|
505
|
+
factory.fromBlock ?? 0,
|
|
506
|
+
factory.toBlock ?? Number.POSITIVE_INFINITY,
|
|
507
|
+
] satisfies Interval;
|
|
508
|
+
|
|
509
|
+
missingFactoryIntervals.push(
|
|
510
|
+
...intervalDifference(
|
|
511
|
+
[factoryTotalInterval],
|
|
512
|
+
intervalIntersectionMany(
|
|
513
|
+
cachedIntervals.get(factory)!.map(({ intervals }) => intervals),
|
|
514
|
+
),
|
|
272
515
|
),
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
if (missingFactoryIntervals.length > 0) {
|
|
520
|
+
const firstMissingFactoryBlock = sortIntervals(
|
|
521
|
+
missingFactoryIntervals,
|
|
522
|
+
)[0]![0];
|
|
523
|
+
|
|
524
|
+
// Note: When a filter with a factory is missing blocks,
|
|
525
|
+
// all blocks after the first missing block are also missing.
|
|
526
|
+
|
|
527
|
+
filterCachedIntervals = filterCachedIntervals.map(
|
|
528
|
+
({ fragment, intervals }) => {
|
|
529
|
+
return {
|
|
530
|
+
fragment,
|
|
531
|
+
intervals: intervalDifference(intervals, [
|
|
532
|
+
[firstMissingFactoryBlock, filterTotalInterval[1]],
|
|
533
|
+
]),
|
|
534
|
+
};
|
|
535
|
+
},
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
let missingIntervals = intervalDifference(
|
|
540
|
+
[filterTotalInterval],
|
|
541
|
+
intervalIntersectionMany(
|
|
542
|
+
filterCachedIntervals.map(({ intervals }) => intervals),
|
|
273
543
|
),
|
|
274
544
|
);
|
|
275
545
|
|
|
276
|
-
if (
|
|
277
|
-
|
|
278
|
-
if ((filter.fromBlock ?? 0) === 0) return undefined;
|
|
279
|
-
return filter.fromBlock! - 1;
|
|
546
|
+
if (missingIntervals.length === 0 && missingFactoryIntervals.length === 0) {
|
|
547
|
+
return getFilterToBlock(filter);
|
|
280
548
|
}
|
|
281
549
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return
|
|
550
|
+
missingIntervals = sortIntervals([
|
|
551
|
+
...missingIntervals,
|
|
552
|
+
...missingFactoryIntervals,
|
|
553
|
+
]);
|
|
554
|
+
|
|
555
|
+
if (missingIntervals[0]![0] === 0) return undefined;
|
|
556
|
+
// First missing block - 1 is the last completed block
|
|
557
|
+
return missingIntervals[0]![0] - 1;
|
|
290
558
|
});
|
|
291
559
|
|
|
292
560
|
if (latestCompletedBlocks.every((block) => block !== undefined)) {
|
package/src/runtime/init.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import type { Database } from "@/database/index.js";
|
|
1
2
|
import type { Common } from "@/internal/common.js";
|
|
2
3
|
import type {
|
|
3
4
|
Chain,
|
|
5
|
+
EventCallback,
|
|
4
6
|
IndexingBuild,
|
|
5
7
|
RawEvent,
|
|
6
|
-
Source,
|
|
7
8
|
} from "@/internal/types.js";
|
|
8
9
|
import type { Rpc } from "@/rpc/index.js";
|
|
9
|
-
import type { SyncStore } from "@/sync-store/index.js";
|
|
10
10
|
import { getLocalEventGenerator, refetchLocalEvents } from "./historical.js";
|
|
11
11
|
import {
|
|
12
12
|
type CachedIntervals,
|
|
@@ -19,18 +19,18 @@ export async function initEventGenerator(params: {
|
|
|
19
19
|
common: Common;
|
|
20
20
|
indexingBuild: Pick<
|
|
21
21
|
IndexingBuild,
|
|
22
|
-
"
|
|
22
|
+
"eventCallbacks" | "chains" | "rpcs" | "finalizedBlocks"
|
|
23
23
|
>;
|
|
24
24
|
chain: Chain;
|
|
25
25
|
rpc: Rpc;
|
|
26
|
-
|
|
26
|
+
eventCallbacks: EventCallback[];
|
|
27
27
|
childAddresses: ChildAddresses;
|
|
28
28
|
syncProgress: SyncProgress;
|
|
29
29
|
cachedIntervals: CachedIntervals;
|
|
30
30
|
from: string;
|
|
31
31
|
to: string;
|
|
32
32
|
limit: number;
|
|
33
|
-
|
|
33
|
+
database: Database;
|
|
34
34
|
isCatchup: boolean;
|
|
35
35
|
}) {
|
|
36
36
|
return getLocalEventGenerator(params);
|