envio 3.3.0-alpha.9 → 3.3.0-rc.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/index.d.ts +19 -0
- package/licenses/CLA.md +35 -0
- package/licenses/EULA.md +67 -0
- package/licenses/LICENSE.md +45 -0
- package/licenses/README.md +35 -0
- package/package.json +9 -8
- package/src/Batch.res.mjs +1 -1
- package/src/BatchProcessing.res +0 -7
- package/src/BatchProcessing.res.mjs +1 -8
- package/src/ChainFetching.res +30 -18
- package/src/ChainFetching.res.mjs +23 -13
- package/src/ChainState.res +134 -55
- package/src/ChainState.res.mjs +78 -36
- package/src/ChainState.resi +14 -2
- package/src/Config.res +9 -5
- package/src/Config.res.mjs +2 -2
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +12 -0
- package/src/CrossChainState.res +115 -34
- package/src/CrossChainState.res.mjs +37 -14
- package/src/EffectState.res +100 -0
- package/src/EffectState.res.mjs +74 -0
- package/src/EffectState.resi +32 -0
- package/src/Envio.res +25 -7
- package/src/Envio.res.mjs +15 -19
- package/src/EventConfigBuilder.res +21 -46
- package/src/EventConfigBuilder.res.mjs +18 -25
- package/src/EventProcessing.res +8 -5
- package/src/EventProcessing.res.mjs +2 -1
- package/src/FetchState.res +814 -467
- package/src/FetchState.res.mjs +541 -369
- package/src/HandlerRegister.res +3 -1
- package/src/HandlerRegister.res.mjs +3 -2
- package/src/InMemoryStore.res +14 -26
- package/src/InMemoryStore.res.mjs +6 -19
- package/src/IndexerState.res +15 -39
- package/src/IndexerState.res.mjs +18 -29
- package/src/IndexerState.resi +2 -10
- package/src/Internal.res +98 -14
- package/src/Internal.res.mjs +96 -2
- package/src/LoadLayer.res +44 -24
- package/src/LoadLayer.res.mjs +43 -20
- package/src/LoadLayer.resi +1 -0
- package/src/LogSelection.res +0 -62
- package/src/LogSelection.res.mjs +0 -74
- package/src/Metrics.res +1 -1
- package/src/Metrics.res.mjs +1 -1
- package/src/Persistence.res +12 -3
- package/src/PgStorage.res +155 -82
- package/src/PgStorage.res.mjs +130 -77
- package/src/Prometheus.res +20 -10
- package/src/Prometheus.res.mjs +22 -10
- package/src/PruneStaleHistory.res +146 -35
- package/src/PruneStaleHistory.res.mjs +114 -20
- package/src/RawEvent.res +2 -2
- package/src/Rollback.res +32 -13
- package/src/Rollback.res.mjs +24 -11
- package/src/SimulateDeadInputTracker.res +1 -1
- package/src/SimulateItems.res +38 -6
- package/src/SimulateItems.res.mjs +28 -9
- package/src/TestIndexer.res +2 -2
- package/src/TestIndexer.res.mjs +2 -2
- package/src/TopicFilter.res +1 -25
- package/src/TopicFilter.res.mjs +0 -74
- package/src/UserContext.res +62 -23
- package/src/UserContext.res.mjs +26 -6
- package/src/Writing.res +60 -21
- package/src/Writing.res.mjs +27 -9
- package/src/bindings/NodeJs.res +5 -0
- package/src/bindings/Viem.res +0 -5
- package/src/sources/EventRouter.res +0 -21
- package/src/sources/EventRouter.res.mjs +0 -12
- package/src/sources/EvmChain.res +2 -27
- package/src/sources/EvmChain.res.mjs +2 -23
- package/src/sources/EvmRpcClient.res +58 -23
- package/src/sources/EvmRpcClient.res.mjs +11 -5
- package/src/sources/HyperSync.res +9 -38
- package/src/sources/HyperSync.res.mjs +16 -28
- package/src/sources/HyperSync.resi +2 -2
- package/src/sources/HyperSyncClient.res +88 -11
- package/src/sources/HyperSyncClient.res.mjs +39 -6
- package/src/sources/HyperSyncSource.res +18 -199
- package/src/sources/HyperSyncSource.res.mjs +9 -128
- package/src/sources/Rpc.res +0 -32
- package/src/sources/Rpc.res.mjs +1 -46
- package/src/sources/RpcSource.res +129 -522
- package/src/sources/RpcSource.res.mjs +161 -366
- package/src/sources/SimulateSource.res +37 -19
- package/src/sources/SimulateSource.res.mjs +27 -10
- package/src/sources/SourceManager.res +3 -7
- package/src/sources/SourceManager.res.mjs +2 -7
- package/src/sources/SourceManager.resi +0 -2
- package/src/sources/SvmHyperSyncSource.res +13 -3
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
package/src/Writing.res.mjs
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Env from "./Env.res.mjs";
|
|
4
4
|
import * as Utils from "./Utils.res.mjs";
|
|
5
|
+
import * as Internal from "./Internal.res.mjs";
|
|
5
6
|
import * as Throttler from "./Throttler.res.mjs";
|
|
6
7
|
import * as Prometheus from "./Prometheus.res.mjs";
|
|
8
|
+
import * as EffectState from "./EffectState.res.mjs";
|
|
7
9
|
import * as IndexerState from "./IndexerState.res.mjs";
|
|
8
10
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
9
11
|
import * as InMemoryStore from "./InMemoryStore.res.mjs";
|
|
@@ -11,6 +13,7 @@ import * as InMemoryTable from "./InMemoryTable.res.mjs";
|
|
|
11
13
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
12
14
|
import * as RollbackCommit from "./RollbackCommit.res.mjs";
|
|
13
15
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
16
|
+
import * as PruneStaleHistory from "./PruneStaleHistory.res.mjs";
|
|
14
17
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
15
18
|
|
|
16
19
|
function getChangesCount(state) {
|
|
@@ -20,7 +23,7 @@ function getChangesCount(state) {
|
|
|
20
23
|
IndexerState.allEntities(state).forEach(entityConfig => {
|
|
21
24
|
total.contents = total.contents + InMemoryStore.getInMemTable(state, entityConfig).changesCount;
|
|
22
25
|
});
|
|
23
|
-
|
|
26
|
+
EffectState.forEach(IndexerState.effectState(state), inMemTable => {
|
|
24
27
|
total.contents = total.contents + inMemTable.changesCount;
|
|
25
28
|
});
|
|
26
29
|
IndexerState.processedBatches(state).forEach(batch => {
|
|
@@ -35,10 +38,12 @@ function waitForCommit(state) {
|
|
|
35
38
|
|
|
36
39
|
function snapshotEffects(state, cache) {
|
|
37
40
|
let acc = [];
|
|
38
|
-
|
|
41
|
+
EffectState.forEach(IndexerState.effectState(state), inMemTable => {
|
|
39
42
|
let idsToStore = inMemTable.idsToStore;
|
|
40
43
|
let invalidationsCount = inMemTable.invalidationsCount;
|
|
41
44
|
let dict = inMemTable.dict;
|
|
45
|
+
let table = inMemTable.table;
|
|
46
|
+
let scope = inMemTable.scope;
|
|
42
47
|
let effect = inMemTable.effect;
|
|
43
48
|
if (idsToStore.length !== 0) {
|
|
44
49
|
let items = Stdlib_Array.filterMap(idsToStore, id => {
|
|
@@ -51,23 +56,27 @@ function snapshotEffects(state, cache) {
|
|
|
51
56
|
}
|
|
52
57
|
});
|
|
53
58
|
let effectName = effect.name;
|
|
54
|
-
let
|
|
59
|
+
let tableName = table.tableName;
|
|
60
|
+
let c = cache[tableName];
|
|
55
61
|
let effectCacheRecord;
|
|
56
62
|
if (c !== undefined) {
|
|
57
63
|
effectCacheRecord = c;
|
|
58
64
|
} else {
|
|
59
65
|
let c$1 = {
|
|
60
66
|
effectName: effectName,
|
|
67
|
+
scope: scope,
|
|
68
|
+
tableName: tableName,
|
|
61
69
|
count: 0
|
|
62
70
|
};
|
|
63
|
-
cache[
|
|
71
|
+
cache[tableName] = c$1;
|
|
64
72
|
effectCacheRecord = c$1;
|
|
65
73
|
}
|
|
66
74
|
let shouldInitialize = effectCacheRecord.count === 0;
|
|
67
75
|
effectCacheRecord.count = (effectCacheRecord.count + items.length | 0) - invalidationsCount | 0;
|
|
68
|
-
Prometheus.EffectCacheCount.set(effectCacheRecord.count, effectName);
|
|
76
|
+
Prometheus.EffectCacheCount.set(effectCacheRecord.count, effectName, Internal.EffectCache.scopeToString(scope));
|
|
69
77
|
acc.push({
|
|
70
|
-
|
|
78
|
+
table: table,
|
|
79
|
+
itemSchema: effect.storageMeta.itemSchema,
|
|
71
80
|
items: items,
|
|
72
81
|
shouldInitialize: shouldInitialize
|
|
73
82
|
});
|
|
@@ -111,11 +120,20 @@ async function runOneWrite(state) {
|
|
|
111
120
|
}
|
|
112
121
|
});
|
|
113
122
|
let updatedEffectsCache = snapshotEffects(state, cache);
|
|
114
|
-
|
|
123
|
+
let writtenEntityNames = new Set();
|
|
124
|
+
updatedEntities.forEach(param => {
|
|
125
|
+
writtenEntityNames.add(param.entityConfig.name);
|
|
126
|
+
});
|
|
127
|
+
let pruneTargets = PruneStaleHistory.select(state, writtenEntityNames, Stdlib_Option.isSome(rollback));
|
|
128
|
+
await Promise.all([
|
|
129
|
+
persistence.storage.writeBatch(batch, rollback, batch.isInReorgThreshold, config, persistence.allEntities, updatedEffectsCache, updatedEntities, chainMetaData),
|
|
130
|
+
PruneStaleHistory.runConcurrent(state, pruneTargets)
|
|
131
|
+
]);
|
|
115
132
|
IndexerState.markCommitted(state, upToCheckpointId);
|
|
116
133
|
if (rollback !== undefined && Utils.$$Array.notEmpty(RollbackCommit.callbacks)) {
|
|
117
|
-
|
|
134
|
+
await RollbackCommit.fire(rollback.progressBlockNumberByChainId);
|
|
118
135
|
}
|
|
136
|
+
return await PruneStaleHistory.runForced(state, pruneTargets);
|
|
119
137
|
}
|
|
120
138
|
|
|
121
139
|
function hasPendingWrite(state) {
|
|
@@ -164,7 +182,7 @@ function commitBatch(state, batch) {
|
|
|
164
182
|
function dropCommitted(state, keepLoadedFromDb) {
|
|
165
183
|
let committedCheckpointId = IndexerState.committedCheckpointId(state);
|
|
166
184
|
IndexerState.allEntities(state).forEach(entityConfig => InMemoryTable.Entity.dropCommittedChanges(InMemoryStore.getInMemTable(state, entityConfig), committedCheckpointId, keepLoadedFromDb));
|
|
167
|
-
|
|
185
|
+
EffectState.forEach(IndexerState.effectState(state), inMemTable => InMemoryStore.dropCommittedEffects(inMemTable, committedCheckpointId, keepLoadedFromDb));
|
|
168
186
|
}
|
|
169
187
|
|
|
170
188
|
async function awaitCapacity(state) {
|
package/src/bindings/NodeJs.res
CHANGED
|
@@ -173,5 +173,10 @@ module Fs = {
|
|
|
173
173
|
|
|
174
174
|
@module("fs") @scope("promises")
|
|
175
175
|
external readdir: Path.t => promise<array<string>> = "readdir"
|
|
176
|
+
|
|
177
|
+
type stats
|
|
178
|
+
@module("fs") @scope("promises")
|
|
179
|
+
external stat: Path.t => promise<stats> = "stat"
|
|
180
|
+
@send external statsIsDirectory: stats => bool = "isDirectory"
|
|
176
181
|
}
|
|
177
182
|
}
|
package/src/bindings/Viem.res
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
type hex = EvmTypes.Hex.t
|
|
2
2
|
@module("viem") external toHex: 'a => hex = "toHex"
|
|
3
|
-
@module("viem") external keccak256: hex => hex = "keccak256"
|
|
4
3
|
@module("viem") external pad: hex => hex = "pad"
|
|
5
4
|
|
|
6
5
|
type sizeOptions = {size: int}
|
|
7
6
|
@module("viem") external bigintToHex: (bigint, ~options: sizeOptions=?) => hex = "numberToHex"
|
|
8
|
-
@module("viem") external stringToHex: (string, ~options: sizeOptions=?) => hex = "stringToHex"
|
|
9
|
-
@module("viem") external boolToHex: (bool, ~options: sizeOptions=?) => hex = "boolToHex"
|
|
10
|
-
@module("viem") external bytesToHex: (Uint8Array.t, ~options: sizeOptions=?) => hex = "bytesToHex"
|
|
11
|
-
@module("viem") external concat: array<hex> => hex = "concat"
|
|
@@ -92,27 +92,6 @@ let get = (router: t<'a>, ~tag, ~contractAddress, ~contractNameByAddress) => {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
let getEvmEventId = (~sighash, ~topicCount) => {
|
|
96
|
-
sighash ++ "_" ++ topicCount->Int.toString
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
let fromEvmEventModsOrThrow = (events: array<Internal.evmOnEventRegistration>, ~chain): t<
|
|
100
|
-
Internal.evmOnEventRegistration,
|
|
101
|
-
> => {
|
|
102
|
-
let router = empty()
|
|
103
|
-
events->Array.forEach(config => {
|
|
104
|
-
router->addOrThrow(
|
|
105
|
-
config.eventConfig.id,
|
|
106
|
-
config,
|
|
107
|
-
~contractName=config.eventConfig.contractName,
|
|
108
|
-
~eventName=config.eventConfig.name,
|
|
109
|
-
~chain,
|
|
110
|
-
~isWildcard=config.isWildcard,
|
|
111
|
-
)
|
|
112
|
-
})
|
|
113
|
-
router
|
|
114
|
-
}
|
|
115
|
-
|
|
116
95
|
/** Dispatch key for SVM instructions. `None` matches any instruction in the
|
|
117
96
|
program (lowest priority). */
|
|
118
97
|
let getSvmEventId = (~programId: SvmTypes.Pubkey.t, ~discriminator: option<string>) =>
|
|
@@ -97,16 +97,6 @@ function get$1(router, tag, contractAddress, contractNameByAddress) {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
function getEvmEventId(sighash, topicCount) {
|
|
101
|
-
return sighash + "_" + topicCount.toString();
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function fromEvmEventModsOrThrow(events, chain) {
|
|
105
|
-
let router = {};
|
|
106
|
-
events.forEach(config => addOrThrow$1(router, config.eventConfig.id, config, config.eventConfig.contractName, config.isWildcard, config.eventConfig.name, chain));
|
|
107
|
-
return router;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
100
|
function getSvmEventId(programId, discriminator) {
|
|
111
101
|
if (discriminator !== undefined) {
|
|
112
102
|
return programId + "_" + discriminator;
|
|
@@ -157,8 +147,6 @@ export {
|
|
|
157
147
|
empty$1 as empty,
|
|
158
148
|
addOrThrow$1 as addOrThrow,
|
|
159
149
|
get$1 as get,
|
|
160
|
-
getEvmEventId,
|
|
161
|
-
fromEvmEventModsOrThrow,
|
|
162
150
|
getSvmEventId,
|
|
163
151
|
fromSvmEventConfigsOrThrow,
|
|
164
152
|
}
|
package/src/sources/EvmChain.res
CHANGED
|
@@ -39,25 +39,6 @@ let getSyncConfig = (
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
let collectEventParams = (onEventRegistrations: array<Internal.evmOnEventRegistration>): array<
|
|
43
|
-
HyperSyncClient.Decoder.eventParamsInput,
|
|
44
|
-
> => {
|
|
45
|
-
let result = []
|
|
46
|
-
onEventRegistrations->Array.forEach(reg => {
|
|
47
|
-
let event = reg.eventConfig->(Utils.magic: Internal.eventConfig => Internal.evmEventConfig)
|
|
48
|
-
result
|
|
49
|
-
->Array.push({
|
|
50
|
-
HyperSyncClient.Decoder.sighash: event.sighash,
|
|
51
|
-
topicCount: event.topicCount,
|
|
52
|
-
eventName: event.name,
|
|
53
|
-
contractName: event.contractName,
|
|
54
|
-
params: event.paramsMetadata,
|
|
55
|
-
})
|
|
56
|
-
->ignore
|
|
57
|
-
})
|
|
58
|
-
result
|
|
59
|
-
}
|
|
60
|
-
|
|
61
42
|
let makeSources = (
|
|
62
43
|
~chain,
|
|
63
44
|
~onEventRegistrations: array<Internal.evmOnEventRegistration>,
|
|
@@ -65,17 +46,12 @@ let makeSources = (
|
|
|
65
46
|
~rpcs: array<rpc>,
|
|
66
47
|
~lowercaseAddresses,
|
|
67
48
|
) => {
|
|
68
|
-
let eventRouter = onEventRegistrations->EventRouter.fromEvmEventModsOrThrow(~chain)
|
|
69
|
-
|
|
70
|
-
let allEventParams = collectEventParams(onEventRegistrations)
|
|
71
|
-
|
|
72
49
|
let sources = switch hyperSync {
|
|
73
50
|
| Some(endpointUrl) => [
|
|
74
51
|
HyperSyncSource.make({
|
|
75
52
|
chain,
|
|
76
53
|
endpointUrl,
|
|
77
|
-
|
|
78
|
-
eventRouter,
|
|
54
|
+
onEventRegistrations,
|
|
79
55
|
apiToken: Env.envioApiToken,
|
|
80
56
|
clientTimeoutMillis: Env.hyperSyncClientTimeoutMillis,
|
|
81
57
|
lowercaseAddresses,
|
|
@@ -92,8 +68,7 @@ let makeSources = (
|
|
|
92
68
|
sourceFor,
|
|
93
69
|
syncConfig: getSyncConfig(syncConfig->Option.getOr({})),
|
|
94
70
|
url,
|
|
95
|
-
|
|
96
|
-
allEventParams,
|
|
71
|
+
onEventRegistrations,
|
|
97
72
|
lowercaseAddresses,
|
|
98
73
|
?ws,
|
|
99
74
|
?headers,
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Env from "../Env.res.mjs";
|
|
4
4
|
import * as RpcSource from "./RpcSource.res.mjs";
|
|
5
|
-
import * as EventRouter from "./EventRouter.res.mjs";
|
|
6
5
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
6
|
import * as HyperSyncSource from "./HyperSyncSource.res.mjs";
|
|
8
7
|
|
|
@@ -20,29 +19,11 @@ function getSyncConfig(param) {
|
|
|
20
19
|
};
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
function collectEventParams(onEventRegistrations) {
|
|
24
|
-
let result = [];
|
|
25
|
-
onEventRegistrations.forEach(reg => {
|
|
26
|
-
let event = reg.eventConfig;
|
|
27
|
-
result.push({
|
|
28
|
-
sighash: event.sighash,
|
|
29
|
-
topicCount: event.topicCount,
|
|
30
|
-
eventName: event.name,
|
|
31
|
-
contractName: event.contractName,
|
|
32
|
-
params: event.paramsMetadata
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
return result;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
22
|
function makeSources(chain, onEventRegistrations, hyperSync, rpcs, lowercaseAddresses) {
|
|
39
|
-
let eventRouter = EventRouter.fromEvmEventModsOrThrow(onEventRegistrations, chain);
|
|
40
|
-
let allEventParams = collectEventParams(onEventRegistrations);
|
|
41
23
|
let sources = hyperSync !== undefined ? [HyperSyncSource.make({
|
|
42
24
|
chain: chain,
|
|
43
25
|
endpointUrl: hyperSync,
|
|
44
|
-
|
|
45
|
-
eventRouter: eventRouter,
|
|
26
|
+
onEventRegistrations: onEventRegistrations,
|
|
46
27
|
apiToken: Env.envioApiToken,
|
|
47
28
|
clientTimeoutMillis: Env.hyperSyncClientTimeoutMillis,
|
|
48
29
|
lowercaseAddresses: lowercaseAddresses,
|
|
@@ -56,8 +37,7 @@ function makeSources(chain, onEventRegistrations, hyperSync, rpcs, lowercaseAddr
|
|
|
56
37
|
syncConfig: getSyncConfig(Stdlib_Option.getOr(param.syncConfig, {})),
|
|
57
38
|
url: param.url,
|
|
58
39
|
chain: chain,
|
|
59
|
-
|
|
60
|
-
allEventParams: allEventParams,
|
|
40
|
+
onEventRegistrations: onEventRegistrations,
|
|
61
41
|
lowercaseAddresses: lowercaseAddresses,
|
|
62
42
|
ws: param.ws,
|
|
63
43
|
headers: param.headers
|
|
@@ -69,7 +49,6 @@ function makeSources(chain, onEventRegistrations, hyperSync, rpcs, lowercaseAddr
|
|
|
69
49
|
|
|
70
50
|
export {
|
|
71
51
|
getSyncConfig,
|
|
72
|
-
collectEventParams,
|
|
73
52
|
makeSources,
|
|
74
53
|
}
|
|
75
54
|
/* Env Not a pure module */
|
|
@@ -1,32 +1,51 @@
|
|
|
1
|
-
type cfg = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
type cfg = {
|
|
2
|
+
url: string,
|
|
3
|
+
httpReqTimeoutMillis?: int,
|
|
4
|
+
headers?: dict<string>,
|
|
5
|
+
initialBlockInterval: int,
|
|
6
|
+
backoffMultiplicative: float,
|
|
7
|
+
accelerationAdditive: int,
|
|
8
|
+
intervalCeiling: int,
|
|
9
|
+
backoffMillis: int,
|
|
10
|
+
queryTimeoutMillis: int,
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
//
|
|
14
|
-
//
|
|
13
|
+
// Only logs that resolved to a registration cross the boundary, each carrying
|
|
14
|
+
// its registration's chain-scoped index.
|
|
15
15
|
type rpcEventItem = {
|
|
16
16
|
log: Rpc.GetLogs.log,
|
|
17
|
-
|
|
17
|
+
onEventRegistrationIndex: int,
|
|
18
|
+
params: Internal.eventParams,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type nextPageParams = {
|
|
22
|
+
fromBlock: int,
|
|
23
|
+
toBlockCeiling: int,
|
|
24
|
+
partitionId: string,
|
|
25
|
+
// The partition's registration selection, by chain-scoped index. Log
|
|
26
|
+
// selections and the routing index are derived on the Rust side from the
|
|
27
|
+
// registrations passed at construction.
|
|
28
|
+
registrationIndexes: array<int>,
|
|
29
|
+
addressesByContractName: dict<array<Address.t>>,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type nextPageResponse = {
|
|
33
|
+
items: array<rpcEventItem>,
|
|
34
|
+
toBlock: int,
|
|
35
|
+
requestStats: array<Source.requestStat>,
|
|
18
36
|
}
|
|
19
37
|
|
|
38
|
+
// The caller provides a range; Rust decides the actual `toBlock` and returns it.
|
|
20
39
|
type t = {
|
|
21
40
|
getHeight: unit => promise<int>,
|
|
22
|
-
|
|
41
|
+
getNextPage: nextPageParams => promise<nextPageResponse>,
|
|
23
42
|
}
|
|
24
43
|
|
|
25
44
|
@send
|
|
26
45
|
external classNew: (
|
|
27
46
|
Core.evmRpcClientCtor,
|
|
28
47
|
cfg,
|
|
29
|
-
array<HyperSyncClient.
|
|
48
|
+
array<HyperSyncClient.Registration.input>,
|
|
30
49
|
~checksumAddresses: bool,
|
|
31
50
|
) => t = "new"
|
|
32
51
|
|
|
@@ -59,15 +78,31 @@ let coerceErrorOrThrow = exn =>
|
|
|
59
78
|
| None => exn->throw
|
|
60
79
|
}
|
|
61
80
|
|
|
62
|
-
let make = (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
let make = (
|
|
82
|
+
~url,
|
|
83
|
+
~checksumAddresses,
|
|
84
|
+
~syncConfig: Config.sourceSync,
|
|
85
|
+
~httpReqTimeoutMillis=?,
|
|
86
|
+
~headers=?,
|
|
87
|
+
~eventRegistrations=[],
|
|
88
|
+
) => {
|
|
89
|
+
let client = Core.getAddon().evmRpcClient->classNew(
|
|
90
|
+
{
|
|
91
|
+
url,
|
|
92
|
+
?httpReqTimeoutMillis,
|
|
93
|
+
?headers,
|
|
94
|
+
initialBlockInterval: syncConfig.initialBlockInterval,
|
|
95
|
+
backoffMultiplicative: syncConfig.backoffMultiplicative,
|
|
96
|
+
accelerationAdditive: syncConfig.accelerationAdditive,
|
|
97
|
+
intervalCeiling: syncConfig.intervalCeiling,
|
|
98
|
+
backoffMillis: syncConfig.backoffMillis,
|
|
99
|
+
queryTimeoutMillis: syncConfig.queryTimeoutMillis,
|
|
100
|
+
},
|
|
101
|
+
eventRegistrations,
|
|
102
|
+
~checksumAddresses,
|
|
103
|
+
)
|
|
69
104
|
{
|
|
70
105
|
getHeight: () => client.getHeight()->Promise.catch(coerceErrorOrThrow),
|
|
71
|
-
|
|
106
|
+
getNextPage: params => client.getNextPage(params)->Promise.catch(coerceErrorOrThrow),
|
|
72
107
|
}
|
|
73
108
|
}
|
|
@@ -46,16 +46,22 @@ function coerceErrorOrThrow(exn) {
|
|
|
46
46
|
throw exn;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function make(url, checksumAddresses, httpReqTimeoutMillis, headers,
|
|
50
|
-
let
|
|
49
|
+
function make(url, checksumAddresses, syncConfig, httpReqTimeoutMillis, headers, eventRegistrationsOpt) {
|
|
50
|
+
let eventRegistrations = eventRegistrationsOpt !== undefined ? eventRegistrationsOpt : [];
|
|
51
51
|
let client = Core.getAddon().EvmRpcClient.new({
|
|
52
52
|
url: url,
|
|
53
53
|
httpReqTimeoutMillis: httpReqTimeoutMillis,
|
|
54
|
-
headers: headers
|
|
55
|
-
|
|
54
|
+
headers: headers,
|
|
55
|
+
initialBlockInterval: syncConfig.initialBlockInterval,
|
|
56
|
+
backoffMultiplicative: syncConfig.backoffMultiplicative,
|
|
57
|
+
accelerationAdditive: syncConfig.accelerationAdditive,
|
|
58
|
+
intervalCeiling: syncConfig.intervalCeiling,
|
|
59
|
+
backoffMillis: syncConfig.backoffMillis,
|
|
60
|
+
queryTimeoutMillis: syncConfig.queryTimeoutMillis
|
|
61
|
+
}, eventRegistrations, checksumAddresses);
|
|
56
62
|
return {
|
|
57
63
|
getHeight: () => Stdlib_Promise.$$catch(client.getHeight(), coerceErrorOrThrow),
|
|
58
|
-
|
|
64
|
+
getNextPage: params => Stdlib_Promise.$$catch(client.getNextPage(params), coerceErrorOrThrow)
|
|
59
65
|
};
|
|
60
66
|
}
|
|
61
67
|
|
|
@@ -61,23 +61,6 @@ module GetLogs = {
|
|
|
61
61
|
|
|
62
62
|
exception Error(error)
|
|
63
63
|
|
|
64
|
-
let makeRequestBody = (
|
|
65
|
-
~fromBlock,
|
|
66
|
-
~toBlockInclusive,
|
|
67
|
-
~addressesWithTopics,
|
|
68
|
-
~fieldSelection,
|
|
69
|
-
~maxNumLogs,
|
|
70
|
-
): HyperSyncClient.QueryTypes.query => {
|
|
71
|
-
fromBlock,
|
|
72
|
-
toBlockExclusive: ?switch toBlockInclusive {
|
|
73
|
-
| Some(toBlockInclusive) => Some(toBlockInclusive + 1)
|
|
74
|
-
| None => None
|
|
75
|
-
},
|
|
76
|
-
logs: addressesWithTopics,
|
|
77
|
-
fieldSelection,
|
|
78
|
-
maxNumLogs,
|
|
79
|
-
}
|
|
80
|
-
|
|
81
64
|
// Rust encodes structured failures as a JSON payload in the napi error's
|
|
82
65
|
// message: `{"kind":"MissingFields","fields":["block.timestamp", ...]}`.
|
|
83
66
|
// JSON.parse + shape check is the recovery protocol — no string-grepping
|
|
@@ -107,29 +90,17 @@ module GetLogs = {
|
|
|
107
90
|
~client: HyperSyncClient.t,
|
|
108
91
|
~fromBlock,
|
|
109
92
|
~toBlock,
|
|
110
|
-
~logSelections: array<LogSelection.t>,
|
|
111
|
-
~fieldSelection,
|
|
112
93
|
~maxNumLogs,
|
|
94
|
+
~registrationIndexes,
|
|
95
|
+
~addressesByContractName,
|
|
113
96
|
): logsQueryPage => {
|
|
114
|
-
let
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
)
|
|
122
|
-
HyperSyncClient.QueryTypes.makeLogSelection(~address=addresses, ~topics)
|
|
123
|
-
})
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
let query = makeRequestBody(
|
|
127
|
-
~fromBlock,
|
|
128
|
-
~toBlockInclusive=toBlock,
|
|
129
|
-
~addressesWithTopics,
|
|
130
|
-
~fieldSelection,
|
|
131
|
-
~maxNumLogs,
|
|
132
|
-
)
|
|
97
|
+
let query: HyperSyncClient.EventItems.query = {
|
|
98
|
+
fromBlock,
|
|
99
|
+
toBlock,
|
|
100
|
+
maxNumLogs,
|
|
101
|
+
registrationIndexes,
|
|
102
|
+
addressesByContractName,
|
|
103
|
+
}
|
|
133
104
|
|
|
134
105
|
let (res, transactionStore, blockStore) = switch await client.getEventItems(~query) {
|
|
135
106
|
| res => res
|
|
@@ -12,7 +12,6 @@ import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
|
12
12
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
13
13
|
import * as Stdlib_Result from "@rescript/runtime/lib/es6/Stdlib_Result.js";
|
|
14
14
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
15
|
-
import * as HyperSyncClient from "./HyperSyncClient.res.mjs";
|
|
16
15
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
17
16
|
|
|
18
17
|
function reraisIfRateLimited(exn) {
|
|
@@ -62,16 +61,6 @@ function mapExn(queryResponse) {
|
|
|
62
61
|
|
|
63
62
|
let $$Error = /* @__PURE__ */Primitive_exceptions.create("HyperSync.GetLogs.Error");
|
|
64
63
|
|
|
65
|
-
function makeRequestBody(fromBlock, toBlockInclusive, addressesWithTopics, fieldSelection, maxNumLogs) {
|
|
66
|
-
return {
|
|
67
|
-
fromBlock: fromBlock,
|
|
68
|
-
toBlock: toBlockInclusive !== undefined ? toBlockInclusive + 1 | 0 : undefined,
|
|
69
|
-
logs: addressesWithTopics,
|
|
70
|
-
fieldSelection: fieldSelection,
|
|
71
|
-
maxNumLogs: maxNumLogs
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
64
|
function extractMissingParams(exn) {
|
|
76
65
|
let message = exn.RE_EXN_ID === "JsExn" ? Stdlib_JsExn.message(exn._1) : undefined;
|
|
77
66
|
if (message === undefined) {
|
|
@@ -93,15 +82,14 @@ function extractMissingParams(exn) {
|
|
|
93
82
|
}
|
|
94
83
|
}
|
|
95
84
|
|
|
96
|
-
async function query(client, fromBlock, toBlock,
|
|
97
|
-
let
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
let query$1 = makeRequestBody(fromBlock, toBlock, addressesWithTopics, fieldSelection, maxNumLogs);
|
|
85
|
+
async function query(client, fromBlock, toBlock, maxNumLogs, registrationIndexes, addressesByContractName) {
|
|
86
|
+
let query$1 = {
|
|
87
|
+
fromBlock: fromBlock,
|
|
88
|
+
toBlock: toBlock,
|
|
89
|
+
maxNumLogs: maxNumLogs,
|
|
90
|
+
registrationIndexes: registrationIndexes,
|
|
91
|
+
addressesByContractName: addressesByContractName
|
|
92
|
+
};
|
|
105
93
|
let match;
|
|
106
94
|
try {
|
|
107
95
|
match = await client.getEventItems(query$1);
|
|
@@ -140,7 +128,13 @@ async function query(client, fromBlock, toBlock, logSelections, fieldSelection,
|
|
|
140
128
|
};
|
|
141
129
|
}
|
|
142
130
|
|
|
143
|
-
|
|
131
|
+
let GetLogs = {
|
|
132
|
+
$$Error: $$Error,
|
|
133
|
+
extractMissingParams: extractMissingParams,
|
|
134
|
+
query: query
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
function makeRequestBody(fromBlock, toBlock) {
|
|
144
138
|
return {
|
|
145
139
|
fromBlock: fromBlock,
|
|
146
140
|
toBlock: toBlock + 1 | 0,
|
|
@@ -193,7 +187,7 @@ function convertResponse(res) {
|
|
|
193
187
|
}
|
|
194
188
|
|
|
195
189
|
async function queryBlockData(client, fromBlock, toBlock, sourceName, chainId, logger, requestStats) {
|
|
196
|
-
let body = makeRequestBody
|
|
190
|
+
let body = makeRequestBody(fromBlock, toBlock);
|
|
197
191
|
let logger$1 = Logging.createChildFrom(logger, {
|
|
198
192
|
logType: "HyperSync get block hash query",
|
|
199
193
|
fromBlock: fromBlock,
|
|
@@ -282,12 +276,6 @@ function queryBlockData$1(client, blockNumber, sourceName, chainId, logger) {
|
|
|
282
276
|
]);
|
|
283
277
|
}
|
|
284
278
|
|
|
285
|
-
let GetLogs = {
|
|
286
|
-
$$Error: $$Error,
|
|
287
|
-
extractMissingParams: extractMissingParams,
|
|
288
|
-
query: query
|
|
289
|
-
};
|
|
290
|
-
|
|
291
279
|
export {
|
|
292
280
|
queryErrorToMsq,
|
|
293
281
|
GetLogs,
|
|
@@ -32,9 +32,9 @@ module GetLogs: {
|
|
|
32
32
|
~client: HyperSyncClient.t,
|
|
33
33
|
~fromBlock: int,
|
|
34
34
|
~toBlock: option<int>,
|
|
35
|
-
~logSelections: array<LogSelection.t>,
|
|
36
|
-
~fieldSelection: HyperSyncClient.QueryTypes.fieldSelection,
|
|
37
35
|
~maxNumLogs: int,
|
|
36
|
+
~registrationIndexes: array<int>,
|
|
37
|
+
~addressesByContractName: dict<array<Address.t>>,
|
|
38
38
|
) => promise<logsQueryPage>
|
|
39
39
|
}
|
|
40
40
|
|