envio 3.3.0-alpha.2 → 3.3.0-alpha.4
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 +23 -21
- package/package.json +6 -6
- package/src/Bin.res +3 -0
- package/src/Bin.res.mjs +4 -0
- package/src/ChainFetching.res +26 -3
- package/src/ChainFetching.res.mjs +22 -3
- package/src/ChainState.res +3 -12
- package/src/ChainState.res.mjs +6 -8
- package/src/ChainState.resi +0 -2
- package/src/CrossChainState.res +15 -0
- package/src/CrossChainState.res.mjs +12 -0
- package/src/Ecosystem.res +0 -6
- package/src/EventConfigBuilder.res +45 -18
- package/src/EventConfigBuilder.res.mjs +28 -10
- package/src/EventProcessing.res +53 -37
- package/src/EventProcessing.res.mjs +41 -36
- package/src/FetchState.res +35 -42
- package/src/FetchState.res.mjs +37 -63
- package/src/HandlerLoader.res +10 -1
- package/src/HandlerLoader.res.mjs +15 -8
- package/src/Internal.res +8 -3
- package/src/Internal.res.mjs +1 -1
- package/src/LoadLayer.res +5 -5
- package/src/LoadLayer.res.mjs +6 -6
- package/src/Main.res +17 -9
- package/src/Main.res.mjs +15 -6
- package/src/PgStorage.res +4 -4
- package/src/PgStorage.res.mjs +5 -5
- package/src/Prometheus.res +10 -10
- package/src/Prometheus.res.mjs +9 -9
- package/src/PruneStaleHistory.res +2 -2
- package/src/PruneStaleHistory.res.mjs +3 -3
- package/src/Rollback.res +2 -2
- package/src/Rollback.res.mjs +3 -3
- package/src/SimulateItems.res +81 -15
- package/src/SimulateItems.res.mjs +63 -20
- package/src/TestIndexer.res +77 -39
- package/src/TestIndexer.res.mjs +45 -31
- package/src/bindings/Performance.res +7 -0
- package/src/bindings/Performance.res.mjs +21 -0
- package/src/bindings/Performance.resi +7 -0
- package/src/sources/EventRouter.res +17 -21
- package/src/sources/EventRouter.res.mjs +6 -9
- package/src/sources/Evm.res +10 -37
- package/src/sources/Evm.res.mjs +5 -40
- package/src/sources/Fuel.res +0 -4
- package/src/sources/Fuel.res.mjs +0 -7
- package/src/sources/HyperFuelSource.res +10 -11
- package/src/sources/HyperFuelSource.res.mjs +11 -11
- package/src/sources/HyperSync.res +3 -0
- package/src/sources/HyperSync.res.mjs +1 -0
- package/src/sources/HyperSync.resi +1 -0
- package/src/sources/HyperSyncClient.res +5 -1
- package/src/sources/HyperSyncSource.res +42 -24
- package/src/sources/HyperSyncSource.res.mjs +30 -26
- package/src/sources/RpcSource.res +7 -8
- package/src/sources/RpcSource.res.mjs +8 -8
- package/src/sources/SimulateSource.res +1 -1
- package/src/sources/Source.res +1 -1
- package/src/sources/SourceManager.res +17 -16
- package/src/sources/SourceManager.res.mjs +10 -15
- package/src/sources/Svm.res +6 -11
- package/src/sources/Svm.res.mjs +6 -14
- package/src/sources/SvmHyperSyncSource.res +24 -18
- package/src/sources/SvmHyperSyncSource.res.mjs +22 -15
- package/src/sources/TransactionStore.res +62 -35
- package/src/sources/TransactionStore.res.mjs +44 -18
- package/svm.schema.json +30 -37
- package/src/bindings/Hrtime.res +0 -58
- package/src/bindings/Hrtime.res.mjs +0 -90
- package/src/bindings/Hrtime.resi +0 -30
package/src/TestIndexer.res.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
|
12
12
|
import * as Persistence from "./Persistence.res.mjs";
|
|
13
13
|
import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
|
|
14
14
|
import * as EntityFilter from "./db/EntityFilter.res.mjs";
|
|
15
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
15
16
|
import * as InternalTable from "./db/InternalTable.res.mjs";
|
|
16
17
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
17
18
|
import * as SimulateItems from "./SimulateItems.res.mjs";
|
|
@@ -32,6 +33,27 @@ function toIndexingAddress(dc) {
|
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
function getIndexingAddressesByChain(state) {
|
|
37
|
+
let byChain = {};
|
|
38
|
+
let dcDict = state.entities[Config.EnvioAddresses.name];
|
|
39
|
+
if (dcDict !== undefined) {
|
|
40
|
+
Object.values(dcDict).forEach(entity => {
|
|
41
|
+
let chainIdStr = entity.chain_id.toString();
|
|
42
|
+
let arr = byChain[chainIdStr];
|
|
43
|
+
let contracts;
|
|
44
|
+
if (arr !== undefined) {
|
|
45
|
+
contracts = arr;
|
|
46
|
+
} else {
|
|
47
|
+
let arr$1 = [];
|
|
48
|
+
byChain[chainIdStr] = arr$1;
|
|
49
|
+
contracts = arr$1;
|
|
50
|
+
}
|
|
51
|
+
contracts.push(toIndexingAddress(entity));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return byChain;
|
|
55
|
+
}
|
|
56
|
+
|
|
35
57
|
function handleLoad(state, tableName, filter) {
|
|
36
58
|
let entityConfig = state.entityConfigs[tableName];
|
|
37
59
|
if (entityConfig === undefined) {
|
|
@@ -403,17 +425,11 @@ function makeCreateTestIndexer(config, workerPath) {
|
|
|
403
425
|
if (state.processInProgress) {
|
|
404
426
|
Stdlib_JsError.throwWithMessage(`Cannot access ` + contract.name + `.addresses while indexer.process() is running. ` + "Wait for process() to complete before reading contract addresses.");
|
|
405
427
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
addresses.push(Config.EnvioAddresses.getAddress(entity));
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
return addresses;
|
|
428
|
+
return Stdlib_Array.filterMap(Stdlib_Option.getOr(getIndexingAddressesByChain(state)[chainConfig.id.toString()], []), ia => {
|
|
429
|
+
if (ia.contractName === contract.name) {
|
|
430
|
+
return Primitive_option.some(ia.address);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
417
433
|
}
|
|
418
434
|
});
|
|
419
435
|
Object.defineProperty(chainObj, contract.name, {
|
|
@@ -484,23 +500,7 @@ function makeCreateTestIndexer(config, workerPath) {
|
|
|
484
500
|
let chainId = param[1];
|
|
485
501
|
let chains = {};
|
|
486
502
|
chains[param[0]] = processChainConfig;
|
|
487
|
-
let indexingAddressesByChain =
|
|
488
|
-
let dcDict = state.entities[Config.EnvioAddresses.name];
|
|
489
|
-
if (dcDict !== undefined) {
|
|
490
|
-
Object.values(dcDict).forEach(entity => {
|
|
491
|
-
let dcChainIdStr = entity.chain_id.toString();
|
|
492
|
-
let arr = indexingAddressesByChain[dcChainIdStr];
|
|
493
|
-
let contracts;
|
|
494
|
-
if (arr !== undefined) {
|
|
495
|
-
contracts = arr;
|
|
496
|
-
} else {
|
|
497
|
-
let arr$1 = [];
|
|
498
|
-
indexingAddressesByChain[dcChainIdStr] = arr$1;
|
|
499
|
-
contracts = arr$1;
|
|
500
|
-
}
|
|
501
|
-
contracts.push(toIndexingAddress(entity));
|
|
502
|
-
});
|
|
503
|
-
}
|
|
503
|
+
let indexingAddressesByChain = getIndexingAddressesByChain(state);
|
|
504
504
|
let initialState = makeInitialState(config, chains, indexingAddressesByChain);
|
|
505
505
|
return new Promise((resolve, reject) => {
|
|
506
506
|
let workerData_startBlock = processChainConfig.startBlock;
|
|
@@ -586,9 +586,11 @@ function initTestWorker() {
|
|
|
586
586
|
Process.exit(1);
|
|
587
587
|
return;
|
|
588
588
|
}
|
|
589
|
+
let initialState = workerData.initialState;
|
|
589
590
|
let simulate = workerData.simulate;
|
|
590
591
|
let endBlock = workerData.endBlock;
|
|
591
|
-
let
|
|
592
|
+
let chainId = workerData.chainId;
|
|
593
|
+
let chainIdStr = chainId.toString();
|
|
592
594
|
let exitAfterFirstEventBlock = Stdlib_Option.isNone(endBlock);
|
|
593
595
|
let resolvedChainDict = {};
|
|
594
596
|
resolvedChainDict["startBlock"] = workerData.startBlock;
|
|
@@ -603,7 +605,7 @@ function initTestWorker() {
|
|
|
603
605
|
let processConfig = {
|
|
604
606
|
chains: resolvedChainsDict
|
|
605
607
|
};
|
|
606
|
-
let proxy = TestIndexerProxyStorage.make(parentPort,
|
|
608
|
+
let proxy = TestIndexerProxyStorage.make(parentPort, initialState);
|
|
607
609
|
let storage = TestIndexerProxyStorage.makeStorage(proxy);
|
|
608
610
|
let config = Config.loadWithoutRegistrations();
|
|
609
611
|
let persistence = Persistence.make(config.userEntities, config.allEnums, storage);
|
|
@@ -613,6 +615,11 @@ function initTestWorker() {
|
|
|
613
615
|
Logging.setLogLevel("silent");
|
|
614
616
|
}
|
|
615
617
|
let patchConfig = (config, _registrations) => {
|
|
618
|
+
if (simulate !== undefined) {
|
|
619
|
+
let chainConfig = ChainMap.get(config.chainMap, ChainMap.Chain.makeUnsafe(chainId));
|
|
620
|
+
let indexingAddresses = Stdlib_Option.mapOr(initialState.chains.find(c => c.id === chainId), [], c => c.indexingAddresses);
|
|
621
|
+
SimulateItems.validateSrcAddresses(simulate, config, chainConfig, indexingAddresses);
|
|
622
|
+
}
|
|
616
623
|
let config$1 = SimulateItems.patchConfig(config, processConfig);
|
|
617
624
|
if (exitAfterFirstEventBlock) {
|
|
618
625
|
return {
|
|
@@ -640,11 +647,18 @@ function initTestWorker() {
|
|
|
640
647
|
return config$1;
|
|
641
648
|
}
|
|
642
649
|
};
|
|
643
|
-
Main.start(persistence, undefined, true, exitAfterFirstEventBlock, patchConfig)
|
|
650
|
+
Stdlib_Promise.$$catch(Main.start(persistence, undefined, true, exitAfterFirstEventBlock, patchConfig), exn => {
|
|
651
|
+
let toThrow = exn.RE_EXN_ID === Main.FatalError ? exn._1 : Utils.prettifyExn(exn);
|
|
652
|
+
setImmediate(() => {
|
|
653
|
+
throw toThrow;
|
|
654
|
+
});
|
|
655
|
+
return Promise.resolve();
|
|
656
|
+
});
|
|
644
657
|
}
|
|
645
658
|
|
|
646
659
|
export {
|
|
647
660
|
toIndexingAddress,
|
|
661
|
+
getIndexingAddressesByChain,
|
|
648
662
|
handleLoad,
|
|
649
663
|
handleWriteBatch,
|
|
650
664
|
makeInitialState,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
function secondsSince(from) {
|
|
5
|
+
return (performance.now() - from) / 1000;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function secondsBetween(from, to) {
|
|
9
|
+
return (to - from) / 1000;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function now(prim) {
|
|
13
|
+
return performance.now();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
now,
|
|
18
|
+
secondsSince,
|
|
19
|
+
secondsBetween,
|
|
20
|
+
}
|
|
21
|
+
/* No side effect */
|
|
@@ -28,29 +28,25 @@ module Group = {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
) =>
|
|
31
|
+
// Ownership only: resolve the owning contract from the partition's reverse
|
|
32
|
+
// index (the partition that fetched the log), not a chain-wide snapshot. The
|
|
33
|
+
// `effectiveStartBlock` temporal gate now lives in `clientAddressFilter`. The
|
|
34
|
+
// wildcard partition has an empty index → every log falls back to `wildcard`,
|
|
35
|
+
// so it can never claim an address-bound contract's logs.
|
|
36
|
+
let get = (group: t<'a>, ~contractAddress, ~contractNameByAddress: dict<string>) =>
|
|
37
37
|
switch group {
|
|
38
38
|
| {wildcard, byContractName} =>
|
|
39
|
-
switch
|
|
39
|
+
switch contractNameByAddress->Utils.Dict.dangerouslyGetNonOption(
|
|
40
40
|
contractAddress->Address.toString,
|
|
41
41
|
) {
|
|
42
|
-
| Some(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
| Some(_) as event => event
|
|
51
|
-
}
|
|
52
|
-
} else {
|
|
53
|
-
None
|
|
42
|
+
| Some(contractName) =>
|
|
43
|
+
switch byContractName->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
44
|
+
// Fall back to the wildcard handler when the owning contract has no
|
|
45
|
+
// matching event for this tag. This covers addresses registered for
|
|
46
|
+
// contracts without events (persisted for future config changes) as
|
|
47
|
+
// well as addresses whose contract has other events but not this one.
|
|
48
|
+
| None => wildcard
|
|
49
|
+
| Some(_) as event => event
|
|
54
50
|
}
|
|
55
51
|
| None => wildcard
|
|
56
52
|
}
|
|
@@ -89,10 +85,10 @@ let addOrThrow = (
|
|
|
89
85
|
}
|
|
90
86
|
}
|
|
91
87
|
|
|
92
|
-
let get = (router: t<'a>, ~tag, ~contractAddress, ~
|
|
88
|
+
let get = (router: t<'a>, ~tag, ~contractAddress, ~contractNameByAddress) => {
|
|
93
89
|
switch router->Utils.Dict.dangerouslyGetNonOption(tag) {
|
|
94
90
|
| None => None
|
|
95
|
-
| Some(group) => group->Group.get(~contractAddress, ~
|
|
91
|
+
| Some(group) => group->Group.get(~contractAddress, ~contractNameByAddress)
|
|
96
92
|
}
|
|
97
93
|
}
|
|
98
94
|
|
|
@@ -39,16 +39,13 @@ function addOrThrow(group, event, contractName, isWildcard) {
|
|
|
39
39
|
byContractName[contractName] = event;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
function get(group, contractAddress,
|
|
42
|
+
function get(group, contractAddress, contractNameByAddress) {
|
|
43
43
|
let wildcard = group.wildcard;
|
|
44
|
-
let
|
|
45
|
-
if (
|
|
44
|
+
let contractName = contractNameByAddress[contractAddress];
|
|
45
|
+
if (contractName === undefined) {
|
|
46
46
|
return wildcard;
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
let event = group.byContractName[indexingContract.contractName];
|
|
48
|
+
let event = group.byContractName[contractName];
|
|
52
49
|
if (event !== undefined) {
|
|
53
50
|
return event;
|
|
54
51
|
} else {
|
|
@@ -93,10 +90,10 @@ function addOrThrow$1(router, eventId, event, contractName, isWildcard, eventNam
|
|
|
93
90
|
}
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
function get$1(router, tag, contractAddress,
|
|
93
|
+
function get$1(router, tag, contractAddress, contractNameByAddress) {
|
|
97
94
|
let group = router[tag];
|
|
98
95
|
if (group !== undefined) {
|
|
99
|
-
return get(group, contractAddress,
|
|
96
|
+
return get(group, contractAddress, contractNameByAddress);
|
|
100
97
|
}
|
|
101
98
|
}
|
|
102
99
|
|
package/src/sources/Evm.res
CHANGED
|
@@ -52,11 +52,9 @@ let transactionFields = [
|
|
|
52
52
|
"authorizationList",
|
|
53
53
|
]
|
|
54
54
|
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
let transactionFieldMask = (eventConfigs: array<Internal.eventConfig>): float =>
|
|
59
|
-
eventConfigs->TransactionStore.mask(~codes=transactionFieldCodes)
|
|
55
|
+
// One event's selected transaction fields → store selection bitmask. Computed
|
|
56
|
+
// per event at config build and cached on the event config.
|
|
57
|
+
let eventTransactionFieldMask = TransactionStore.makeMaskFn(transactionFields)
|
|
60
58
|
|
|
61
59
|
let cleanUpRawEventFieldsInPlace: JSON.t => unit = %raw(`fields => {
|
|
62
60
|
delete fields.hash
|
|
@@ -66,36 +64,6 @@ let cleanUpRawEventFieldsInPlace: JSON.t => unit = %raw(`fields => {
|
|
|
66
64
|
|
|
67
65
|
let make = (~logger: Pino.t): Ecosystem.t => {
|
|
68
66
|
name: Evm,
|
|
69
|
-
blockFields: [
|
|
70
|
-
"number",
|
|
71
|
-
"timestamp",
|
|
72
|
-
"hash",
|
|
73
|
-
"parentHash",
|
|
74
|
-
"nonce",
|
|
75
|
-
"sha3Uncles",
|
|
76
|
-
"logsBloom",
|
|
77
|
-
"transactionsRoot",
|
|
78
|
-
"stateRoot",
|
|
79
|
-
"receiptsRoot",
|
|
80
|
-
"miner",
|
|
81
|
-
"difficulty",
|
|
82
|
-
"totalDifficulty",
|
|
83
|
-
"extraData",
|
|
84
|
-
"size",
|
|
85
|
-
"gasLimit",
|
|
86
|
-
"gasUsed",
|
|
87
|
-
"uncles",
|
|
88
|
-
"baseFeePerGas",
|
|
89
|
-
"blobGasUsed",
|
|
90
|
-
"excessBlobGas",
|
|
91
|
-
"parentBeaconBlockRoot",
|
|
92
|
-
"withdrawalsRoot",
|
|
93
|
-
"l1BlockNumber",
|
|
94
|
-
"sendCount",
|
|
95
|
-
"sendRoot",
|
|
96
|
-
"mixHash",
|
|
97
|
-
],
|
|
98
|
-
transactionFields,
|
|
99
67
|
blockNumberName: "number",
|
|
100
68
|
blockTimestampName: "timestamp",
|
|
101
69
|
blockHashName: "hash",
|
|
@@ -117,7 +85,6 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
117
85
|
s.field("block", S.option(S.object(s2 => s2.field("number", S.unknown))))
|
|
118
86
|
),
|
|
119
87
|
logger,
|
|
120
|
-
transactionFieldMask,
|
|
121
88
|
// The payload carries `transaction` by batch prep (HyperSync) or inline
|
|
122
89
|
// (RPC/simulate), so the event is the payload as-is.
|
|
123
90
|
toEvent: eventItem => eventItem.payload->(Utils.magic: Internal.eventPayload => Internal.event),
|
|
@@ -135,10 +102,16 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
135
102
|
),
|
|
136
103
|
toRawEvent: eventItem => {
|
|
137
104
|
let payload = eventItem.payload->toPayload
|
|
105
|
+
let eventConfig =
|
|
106
|
+
eventItem.eventConfig->(Utils.magic: Internal.eventConfig => Internal.evmEventConfig)
|
|
138
107
|
eventItem->RawEvent.make(
|
|
139
108
|
~block=payload.block,
|
|
140
109
|
~transaction=payload.transaction,
|
|
141
|
-
|
|
110
|
+
// The decoder emits `{}` for zero-parameter events, which the params
|
|
111
|
+
// schema rejects; pass unit so it serializes to the "null" sentinel.
|
|
112
|
+
~params=eventConfig.paramsMetadata->Array.length == 0
|
|
113
|
+
? ()->(Utils.magic: unit => Internal.eventParams)
|
|
114
|
+
: payload.params,
|
|
142
115
|
~srcAddress=payload.srcAddress,
|
|
143
116
|
~cleanUpRawEventFieldsInPlace,
|
|
144
117
|
)
|
package/src/sources/Evm.res.mjs
CHANGED
|
@@ -40,11 +40,7 @@ let transactionFields = [
|
|
|
40
40
|
"authorizationList"
|
|
41
41
|
];
|
|
42
42
|
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
function transactionFieldMask(eventConfigs) {
|
|
46
|
-
return TransactionStore.mask(eventConfigs, transactionFieldCodes);
|
|
47
|
-
}
|
|
43
|
+
let eventTransactionFieldMask = TransactionStore.makeMaskFn(transactionFields);
|
|
48
44
|
|
|
49
45
|
let cleanUpRawEventFieldsInPlace = (fields => {
|
|
50
46
|
delete fields.hash
|
|
@@ -55,36 +51,6 @@ let cleanUpRawEventFieldsInPlace = (fields => {
|
|
|
55
51
|
function make(logger) {
|
|
56
52
|
return {
|
|
57
53
|
name: "evm",
|
|
58
|
-
blockFields: [
|
|
59
|
-
"number",
|
|
60
|
-
"timestamp",
|
|
61
|
-
"hash",
|
|
62
|
-
"parentHash",
|
|
63
|
-
"nonce",
|
|
64
|
-
"sha3Uncles",
|
|
65
|
-
"logsBloom",
|
|
66
|
-
"transactionsRoot",
|
|
67
|
-
"stateRoot",
|
|
68
|
-
"receiptsRoot",
|
|
69
|
-
"miner",
|
|
70
|
-
"difficulty",
|
|
71
|
-
"totalDifficulty",
|
|
72
|
-
"extraData",
|
|
73
|
-
"size",
|
|
74
|
-
"gasLimit",
|
|
75
|
-
"gasUsed",
|
|
76
|
-
"uncles",
|
|
77
|
-
"baseFeePerGas",
|
|
78
|
-
"blobGasUsed",
|
|
79
|
-
"excessBlobGas",
|
|
80
|
-
"parentBeaconBlockRoot",
|
|
81
|
-
"withdrawalsRoot",
|
|
82
|
-
"l1BlockNumber",
|
|
83
|
-
"sendCount",
|
|
84
|
-
"sendRoot",
|
|
85
|
-
"mixHash"
|
|
86
|
-
],
|
|
87
|
-
transactionFields: transactionFields,
|
|
88
54
|
blockNumberName: "number",
|
|
89
55
|
blockTimestampName: "timestamp",
|
|
90
56
|
blockHashName: "hash",
|
|
@@ -94,7 +60,6 @@ function make(logger) {
|
|
|
94
60
|
onEventBlockFilterSchema: S$RescriptSchema.object(s => s.f("block", S$RescriptSchema.option(S$RescriptSchema.object(s2 => s2.f("number", S$RescriptSchema.unknown))))),
|
|
95
61
|
logger: logger,
|
|
96
62
|
toEvent: eventItem => eventItem.payload,
|
|
97
|
-
transactionFieldMask: transactionFieldMask,
|
|
98
63
|
toEventLogger: eventItem => Logging.createChildFrom(logger, {
|
|
99
64
|
contract: eventItem.eventConfig.contractName,
|
|
100
65
|
event: eventItem.eventConfig.name,
|
|
@@ -105,16 +70,16 @@ function make(logger) {
|
|
|
105
70
|
}),
|
|
106
71
|
toRawEvent: eventItem => {
|
|
107
72
|
let payload = eventItem.payload;
|
|
108
|
-
|
|
73
|
+
let eventConfig = eventItem.eventConfig;
|
|
74
|
+
return RawEvent.make(eventItem, payload.block, payload.transaction, eventConfig.paramsMetadata.length === 0 ? undefined : payload.params, payload.srcAddress, cleanUpRawEventFieldsInPlace);
|
|
109
75
|
}
|
|
110
76
|
};
|
|
111
77
|
}
|
|
112
78
|
|
|
113
79
|
export {
|
|
114
80
|
transactionFields,
|
|
115
|
-
|
|
116
|
-
transactionFieldMask,
|
|
81
|
+
eventTransactionFieldMask,
|
|
117
82
|
cleanUpRawEventFieldsInPlace,
|
|
118
83
|
make,
|
|
119
84
|
}
|
|
120
|
-
/*
|
|
85
|
+
/* eventTransactionFieldMask Not a pure module */
|
package/src/sources/Fuel.res
CHANGED
|
@@ -21,8 +21,6 @@ let cleanUpRawEventFieldsInPlace: JSON.t => unit = %raw(`fields => {
|
|
|
21
21
|
|
|
22
22
|
let make = (~logger: Pino.t): Ecosystem.t => {
|
|
23
23
|
name: Fuel,
|
|
24
|
-
blockFields: ["id", "height", "time"],
|
|
25
|
-
transactionFields: ["id"],
|
|
26
24
|
blockNumberName: "height",
|
|
27
25
|
blockTimestampName: "time",
|
|
28
26
|
blockHashName: "id",
|
|
@@ -41,8 +39,6 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
41
39
|
s.field("block", S.option(S.object(s2 => s2.field("height", S.unknown))))
|
|
42
40
|
),
|
|
43
41
|
logger,
|
|
44
|
-
// Fuel carries the transaction inline on the payload.
|
|
45
|
-
transactionFieldMask: _ => 0.,
|
|
46
42
|
toEvent: eventItem => eventItem.payload->(Utils.magic: Internal.eventPayload => Internal.event),
|
|
47
43
|
toEventLogger: eventItem =>
|
|
48
44
|
Logging.createChildFrom(
|
package/src/sources/Fuel.res.mjs
CHANGED
|
@@ -13,12 +13,6 @@ let cleanUpRawEventFieldsInPlace = (fields => {
|
|
|
13
13
|
function make(logger) {
|
|
14
14
|
return {
|
|
15
15
|
name: "fuel",
|
|
16
|
-
blockFields: [
|
|
17
|
-
"id",
|
|
18
|
-
"height",
|
|
19
|
-
"time"
|
|
20
|
-
],
|
|
21
|
-
transactionFields: ["id"],
|
|
22
16
|
blockNumberName: "height",
|
|
23
17
|
blockTimestampName: "time",
|
|
24
18
|
blockHashName: "id",
|
|
@@ -28,7 +22,6 @@ function make(logger) {
|
|
|
28
22
|
onEventBlockFilterSchema: S$RescriptSchema.object(s => s.f("block", S$RescriptSchema.option(S$RescriptSchema.object(s2 => s2.f("height", S$RescriptSchema.unknown))))),
|
|
29
23
|
logger: logger,
|
|
30
24
|
toEvent: eventItem => eventItem.payload,
|
|
31
|
-
transactionFieldMask: param => 0,
|
|
32
25
|
toEventLogger: eventItem => Logging.createChildFrom(logger, {
|
|
33
26
|
contract: eventItem.eventConfig.contractName,
|
|
34
27
|
event: eventItem.eventConfig.name,
|
|
@@ -235,19 +235,19 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
235
235
|
~fromBlock,
|
|
236
236
|
~toBlock,
|
|
237
237
|
~addressesByContractName,
|
|
238
|
-
~
|
|
238
|
+
~contractNameByAddress,
|
|
239
239
|
~knownHeight,
|
|
240
240
|
~partitionId as _,
|
|
241
241
|
~selection: FetchState.selection,
|
|
242
242
|
~retry,
|
|
243
243
|
~logger,
|
|
244
244
|
) => {
|
|
245
|
-
let totalTimeRef =
|
|
245
|
+
let totalTimeRef = Performance.now()
|
|
246
246
|
|
|
247
247
|
let selectionConfig = getSelectionConfig(selection)
|
|
248
248
|
let recieptsSelection = selectionConfig.getRecieptsSelection(~addressesByContractName)
|
|
249
249
|
|
|
250
|
-
let startFetchingBatchTimeRef =
|
|
250
|
+
let startFetchingBatchTimeRef = Performance.now()
|
|
251
251
|
|
|
252
252
|
//fetch batch
|
|
253
253
|
Prometheus.SourceRequestCount.increment(
|
|
@@ -305,7 +305,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
305
305
|
)
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
-
let pageFetchTime = startFetchingBatchTimeRef->
|
|
308
|
+
let pageFetchTime = startFetchingBatchTimeRef->Performance.secondsSince
|
|
309
309
|
|
|
310
310
|
//set height and next from block
|
|
311
311
|
let knownHeight = pageUnsafe.archiveHeight
|
|
@@ -315,7 +315,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
315
315
|
//In the query
|
|
316
316
|
let heighestBlockQueried = pageUnsafe.nextBlock - 1
|
|
317
317
|
|
|
318
|
-
let parsingTimeRef =
|
|
318
|
+
let parsingTimeRef = Performance.now()
|
|
319
319
|
|
|
320
320
|
let parsedQueueItems = pageUnsafe.items->Array.map(item => {
|
|
321
321
|
let {contractId: contractAddress, receipt, block, receiptIndex} = item
|
|
@@ -332,9 +332,8 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
332
332
|
|
|
333
333
|
let eventConfig = switch selectionConfig.eventRouter->EventRouter.get(
|
|
334
334
|
~tag=eventId,
|
|
335
|
-
~
|
|
335
|
+
~contractNameByAddress,
|
|
336
336
|
~contractAddress,
|
|
337
|
-
~blockNumber=block.height,
|
|
338
337
|
) {
|
|
339
338
|
| None => {
|
|
340
339
|
let logger = Logging.createChildFrom(
|
|
@@ -432,7 +431,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
432
431
|
})
|
|
433
432
|
})
|
|
434
433
|
|
|
435
|
-
let parsingTimeElapsed = parsingTimeRef->
|
|
434
|
+
let parsingTimeElapsed = parsingTimeRef->Performance.secondsSince
|
|
436
435
|
|
|
437
436
|
// Fuel never rolls back on reorg, so block hashes here are purely informational
|
|
438
437
|
// for detect-only logging via ReorgDetection.
|
|
@@ -448,7 +447,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
448
447
|
| _ => 0
|
|
449
448
|
}
|
|
450
449
|
|
|
451
|
-
let totalTimeElapsed = totalTimeRef->
|
|
450
|
+
let totalTimeElapsed = totalTimeRef->Performance.secondsSince
|
|
452
451
|
|
|
453
452
|
let stats = {
|
|
454
453
|
totalTimeElapsed,
|
|
@@ -480,7 +479,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
480
479
|
pollingInterval: 100,
|
|
481
480
|
poweredByHyperSync: true,
|
|
482
481
|
getHeightOrThrow: async () => {
|
|
483
|
-
let timerRef =
|
|
482
|
+
let timerRef = Performance.now()
|
|
484
483
|
let height = try await client->HyperFuelClient.getHeight catch {
|
|
485
484
|
| JsExn(e) =>
|
|
486
485
|
switch e->JsExn.message {
|
|
@@ -492,7 +491,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
492
491
|
| _ => throw(JsExn(e))
|
|
493
492
|
}
|
|
494
493
|
}
|
|
495
|
-
let seconds = timerRef->
|
|
494
|
+
let seconds = timerRef->Performance.secondsSince
|
|
496
495
|
Prometheus.SourceRequestCount.increment(
|
|
497
496
|
~sourceName=name,
|
|
498
497
|
~chainId=chain->ChainMap.Chain.toChainId,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as Hrtime from "../bindings/Hrtime.res.mjs";
|
|
4
3
|
import * as Source from "./Source.res.mjs";
|
|
5
4
|
import * as Logging from "../Logging.res.mjs";
|
|
6
5
|
import * as HyperFuel from "./HyperFuel.res.mjs";
|
|
7
6
|
import * as Prometheus from "../Prometheus.res.mjs";
|
|
8
7
|
import * as EventRouter from "./EventRouter.res.mjs";
|
|
8
|
+
import * as Performance from "../bindings/Performance.res.mjs";
|
|
9
9
|
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
10
10
|
import * as ErrorHandling from "../ErrorHandling.res.mjs";
|
|
11
11
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
@@ -196,11 +196,11 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
196
196
|
client = ErrorHandling.mkLogAndRaise(undefined, "Failed to instantiate the HyperFuel client", exn);
|
|
197
197
|
}
|
|
198
198
|
let getSelectionConfig = memoGetSelectionConfig(chain);
|
|
199
|
-
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName,
|
|
200
|
-
let totalTimeRef =
|
|
199
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, retry, logger) => {
|
|
200
|
+
let totalTimeRef = Performance.now();
|
|
201
201
|
let selectionConfig = getSelectionConfig(selection);
|
|
202
202
|
let recieptsSelection = selectionConfig.getRecieptsSelection(addressesByContractName);
|
|
203
|
-
let startFetchingBatchTimeRef =
|
|
203
|
+
let startFetchingBatchTimeRef = Performance.now();
|
|
204
204
|
Prometheus.SourceRequestCount.increment(name, chain, "getLogs");
|
|
205
205
|
let pageUnsafe;
|
|
206
206
|
try {
|
|
@@ -249,10 +249,10 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
249
249
|
Error: new Error()
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
|
-
let pageFetchTime =
|
|
252
|
+
let pageFetchTime = Performance.secondsSince(startFetchingBatchTimeRef);
|
|
253
253
|
let knownHeight$1 = pageUnsafe.archiveHeight;
|
|
254
254
|
let heighestBlockQueried = pageUnsafe.nextBlock - 1 | 0;
|
|
255
|
-
let parsingTimeRef =
|
|
255
|
+
let parsingTimeRef = Performance.now();
|
|
256
256
|
let parsedQueueItems = pageUnsafe.items.map(item => {
|
|
257
257
|
let block = item.block;
|
|
258
258
|
let receiptIndex = item.receiptIndex;
|
|
@@ -277,7 +277,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
277
277
|
eventId = burnEventTag;
|
|
278
278
|
break;
|
|
279
279
|
}
|
|
280
|
-
let eventConfig = EventRouter.get(selectionConfig.eventRouter, eventId, contractAddress,
|
|
280
|
+
let eventConfig = EventRouter.get(selectionConfig.eventRouter, eventId, contractAddress, contractNameByAddress);
|
|
281
281
|
let eventConfig$1;
|
|
282
282
|
if (eventConfig !== undefined) {
|
|
283
283
|
eventConfig$1 = eventConfig;
|
|
@@ -370,7 +370,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
370
370
|
}
|
|
371
371
|
};
|
|
372
372
|
});
|
|
373
|
-
let parsingTimeElapsed =
|
|
373
|
+
let parsingTimeElapsed = Performance.secondsSince(parsingTimeRef);
|
|
374
374
|
let blockHashes = pageUnsafe.items.map(param => {
|
|
375
375
|
let block = param.block;
|
|
376
376
|
return {
|
|
@@ -386,7 +386,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
386
386
|
} else {
|
|
387
387
|
latestFetchedBlockTimestamp = 0;
|
|
388
388
|
}
|
|
389
|
-
let totalTimeElapsed =
|
|
389
|
+
let totalTimeElapsed = Performance.secondsSince(totalTimeRef);
|
|
390
390
|
let stats_parsing$unknowntime$unknown$lpars$rpar = parsingTimeElapsed;
|
|
391
391
|
let stats_page$unknownfetch$unknowntime$unknown$lpars$rpar = pageFetchTime;
|
|
392
392
|
let stats = {
|
|
@@ -414,7 +414,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
414
414
|
pollingInterval: 100,
|
|
415
415
|
getBlockHashes: getBlockHashes,
|
|
416
416
|
getHeightOrThrow: async () => {
|
|
417
|
-
let timerRef =
|
|
417
|
+
let timerRef = Performance.now();
|
|
418
418
|
let height;
|
|
419
419
|
try {
|
|
420
420
|
height = await client.getHeight();
|
|
@@ -446,7 +446,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
446
446
|
throw e;
|
|
447
447
|
}
|
|
448
448
|
}
|
|
449
|
-
let seconds =
|
|
449
|
+
let seconds = Performance.secondsSince(timerRef);
|
|
450
450
|
Prometheus.SourceRequestCount.increment(name, chain, "getHeight");
|
|
451
451
|
Prometheus.SourceRequestCount.addSeconds(name, chain, "getHeight", seconds);
|
|
452
452
|
return height;
|
|
@@ -16,6 +16,8 @@ let reraisIfRateLimited = exn =>
|
|
|
16
16
|
|
|
17
17
|
type logsQueryPage = {
|
|
18
18
|
items: array<HyperSyncClient.EventItems.item>,
|
|
19
|
+
// Blocks referenced by `items`, deduplicated by block number.
|
|
20
|
+
blocks: array<HyperSyncClient.ResponseTypes.block>,
|
|
19
21
|
nextBlock: int,
|
|
20
22
|
archiveHeight: int,
|
|
21
23
|
rollbackGuard: option<HyperSyncClient.ResponseTypes.rollbackGuard>,
|
|
@@ -139,6 +141,7 @@ module GetLogs = {
|
|
|
139
141
|
|
|
140
142
|
{
|
|
141
143
|
items: res.items,
|
|
144
|
+
blocks: res.blocks,
|
|
142
145
|
nextBlock: res.nextBlock,
|
|
143
146
|
archiveHeight: res.archiveHeight->Option.getOr(0), //Archive Height is only None if height is 0
|
|
144
147
|
rollbackGuard: res.rollbackGuard,
|
|
@@ -130,6 +130,7 @@ async function query(client, fromBlock, toBlock, logSelections, fieldSelection)
|
|
|
130
130
|
}
|
|
131
131
|
return {
|
|
132
132
|
items: res.items,
|
|
133
|
+
blocks: res.blocks,
|
|
133
134
|
nextBlock: res.nextBlock,
|
|
134
135
|
archiveHeight: Stdlib_Option.getOr(res.archiveHeight, 0),
|
|
135
136
|
rollbackGuard: res.rollbackGuard,
|