envio 3.13.0-alpha.0 → 3.13.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.
Files changed (94) hide show
  1. package/package.json +6 -8
  2. package/src/BatchProcessing.res +4 -5
  3. package/src/BatchProcessing.res.mjs +4 -11
  4. package/src/ChainFetching.res +18 -38
  5. package/src/ChainFetching.res.mjs +14 -20
  6. package/src/ChainState.res +113 -77
  7. package/src/ChainState.res.mjs +90 -73
  8. package/src/ChainState.resi +14 -5
  9. package/src/Config.res +14 -17
  10. package/src/Config.res.mjs +5 -20
  11. package/src/CrossChainState.res +68 -20
  12. package/src/CrossChainState.res.mjs +48 -5
  13. package/src/CrossChainState.resi +1 -0
  14. package/src/Env.res +2 -2
  15. package/src/ErrorHandling.res +15 -4
  16. package/src/ErrorHandling.res.mjs +16 -5
  17. package/src/FinalizeBackfill.res +21 -9
  18. package/src/FinalizeBackfill.res.mjs +17 -4
  19. package/src/HandlerRegister.res +0 -37
  20. package/src/HandlerRegister.res.mjs +0 -18
  21. package/src/IndexerState.res +2 -0
  22. package/src/IndexerState.res.mjs +5 -0
  23. package/src/IndexerState.resi +1 -0
  24. package/src/Logging.res +6 -38
  25. package/src/Logging.res.mjs +5 -32
  26. package/src/Main.res +6 -9
  27. package/src/Main.res.mjs +3 -5
  28. package/src/Metrics.res +9 -4
  29. package/src/Metrics.res.mjs +3 -3
  30. package/src/Persistence.res +6 -3
  31. package/src/Persistence.res.mjs +5 -3
  32. package/src/PgStorage.res +2 -2
  33. package/src/PgStorage.res.mjs +2 -2
  34. package/src/Rollback.res +3 -3
  35. package/src/Server.res +0 -3
  36. package/src/SimulateItems.res +1 -1
  37. package/src/SimulateItems.res.mjs +1 -1
  38. package/src/Supervisor.res +236 -109
  39. package/src/Supervisor.res.mjs +185 -55
  40. package/src/TestIndexer.res +6 -3
  41. package/src/TestIndexer.res.mjs +3 -3
  42. package/src/Worker.res +6 -0
  43. package/src/Worker.res.mjs +2 -1
  44. package/src/bindings/NodeJs.res +25 -16
  45. package/src/bindings/NodeJs.res.mjs +8 -1
  46. package/src/sources/AddressSet.res +5 -3
  47. package/src/sources/AddressStore.res +19 -11
  48. package/src/sources/AddressStore.res.mjs +2 -7
  49. package/src/sources/BlockStore.res +10 -9
  50. package/src/sources/BlockStore.res.mjs +4 -4
  51. package/src/sources/ChainSources.res +4 -0
  52. package/src/sources/ChainSources.res.mjs +2 -2
  53. package/src/sources/EvmChain.res +4 -0
  54. package/src/sources/EvmChain.res.mjs +3 -1
  55. package/src/sources/EvmEventItem.res +56 -0
  56. package/src/sources/EvmEventItem.res.mjs +32 -0
  57. package/src/sources/EvmHyperSyncSource.res +7 -37
  58. package/src/sources/EvmHyperSyncSource.res.mjs +8 -29
  59. package/src/sources/EvmRpcClient.res +41 -59
  60. package/src/sources/EvmRpcClient.res.mjs +4 -54
  61. package/src/sources/EvmRpcWs.res +4 -1
  62. package/src/sources/EvmRpcWs.res.mjs +6 -2
  63. package/src/sources/FuelHyperSyncSource.res +6 -4
  64. package/src/sources/FuelHyperSyncSource.res.mjs +7 -9
  65. package/src/sources/HeightFeed.res +7 -1
  66. package/src/sources/HeightFeed.res.mjs +9 -7
  67. package/src/sources/HyperSyncClient.res +1 -14
  68. package/src/sources/RequestStat.res +7 -0
  69. package/src/sources/RequestStat.res.mjs +14 -1
  70. package/src/sources/RpcSource.res +100 -1043
  71. package/src/sources/RpcSource.res.mjs +81 -1056
  72. package/src/sources/SimulateSource.res +2 -5
  73. package/src/sources/SimulateSource.res.mjs +2 -3
  74. package/src/sources/Source.res +34 -12
  75. package/src/sources/Source.res.mjs +11 -0
  76. package/src/sources/SourceManager.res +111 -31
  77. package/src/sources/SourceManager.res.mjs +65 -31
  78. package/src/sources/SourceManager.resi +4 -0
  79. package/src/sources/StartBlockResolver.res +8 -5
  80. package/src/sources/StartBlockResolver.res.mjs +4 -2
  81. package/src/sources/SvmHyperSyncSource.res +4 -2
  82. package/src/sources/SvmHyperSyncSource.res.mjs +4 -6
  83. package/src/sources/TransactionStore.res +9 -6
  84. package/src/sources/TransactionStore.res.mjs +2 -2
  85. package/src/tui/Tui.res +4 -18
  86. package/src/tui/Tui.res.mjs +3 -6
  87. package/src/LazyLoader.res +0 -135
  88. package/src/LazyLoader.res.mjs +0 -118
  89. package/src/bindings/SDSL.res +0 -12
  90. package/src/bindings/SDSL.res.mjs +0 -9
  91. package/src/bindings/Yargs.res +0 -8
  92. package/src/bindings/Yargs.res.mjs +0 -2
  93. package/src/sources/Rpc.res +0 -185
  94. package/src/sources/Rpc.res.mjs +0 -183
package/src/Metrics.res CHANGED
@@ -174,8 +174,10 @@ let sumByKey = (items: array<'item>, ~key: 'item => string, ~add: ('item, 'item)
174
174
  // unsplit run would have produced. Series keyed by chain concatenate, since a
175
175
  // chain belongs to exactly one worker; series keyed by name are summed, since
176
176
  // every worker runs the same handlers and effects over its own chains. The
177
- // clock is the caller's: it belongs to the group, not to any worker.
178
- let merge = (snapshots: array<t>, ~startTime, ~metricTime, ~elapsedSeconds) => {
177
+ // clock and the buffer target are the caller's: both belong to the group, and
178
+ // the target is what the run was configured with rather than anything a worker
179
+ // could add up to.
180
+ let merge = (snapshots: array<t>, ~startTime, ~metricTime, ~elapsedSeconds, ~targetBufferSize) => {
179
181
  let concat = select => snapshots->Array.flatMap(select)
180
182
  let sumInt = select => snapshots->Array.reduce(0, (acc, snapshot) => acc + snapshot->select)
181
183
  let sumFloat = select => snapshots->Array.reduce(0., (acc, snapshot) => acc +. snapshot->select)
@@ -184,8 +186,11 @@ let merge = (snapshots: array<t>, ~startTime, ~metricTime, ~elapsedSeconds) => {
184
186
  startTime,
185
187
  metricTime,
186
188
  elapsedSeconds,
187
- targetBufferSize: sumInt(s => s.targetBufferSize),
188
- isInReorgThreshold: snapshots->Array.some(s => s.isInReorgThreshold),
189
+ targetBufferSize,
190
+ // Chains cross into the threshold as one indexer, so a run is in it once
191
+ // every process is, the same reading as the arrival below.
192
+ isInReorgThreshold: snapshots->Utils.Array.notEmpty &&
193
+ snapshots->Array.every(s => s.isInReorgThreshold),
189
194
  // The run has arrived only once every process has: one still backfilling
190
195
  // speaks for the whole indexer.
191
196
  hasArrivedAtHead: snapshots->Utils.Array.notEmpty &&
@@ -35,15 +35,15 @@ function sumByKey(items, key, add) {
35
35
  return order.map(k => byKey[k]);
36
36
  }
37
37
 
38
- function merge(snapshots, startTime, metricTime, elapsedSeconds) {
38
+ function merge(snapshots, startTime, metricTime, elapsedSeconds, targetBufferSize) {
39
39
  let sumInt = select => Stdlib_Array.reduce(snapshots, 0, (acc, snapshot) => acc + select(snapshot) | 0);
40
40
  let sumFloat = select => Stdlib_Array.reduce(snapshots, 0, (acc, snapshot) => acc + select(snapshot));
41
41
  return {
42
42
  startTime: startTime,
43
43
  metricTime: metricTime,
44
44
  elapsedSeconds: elapsedSeconds,
45
- targetBufferSize: sumInt(s => s.targetBufferSize),
46
- isInReorgThreshold: snapshots.some(s => s.isInReorgThreshold),
45
+ targetBufferSize: targetBufferSize,
46
+ isInReorgThreshold: Utils.$$Array.notEmpty(snapshots) && snapshots.every(s => s.isInReorgThreshold),
47
47
  hasArrivedAtHead: Utils.$$Array.notEmpty(snapshots) && snapshots.every(s => s.hasArrivedAtHead),
48
48
  rollbackEnabled: snapshots.some(s => s.rollbackEnabled),
49
49
  maxBatchSize: Stdlib_Array.reduce(snapshots, 0, (acc, s) => Primitive_int.max(acc, s.maxBatchSize)),
@@ -275,6 +275,10 @@ let init = {
275
275
  // would create rows for this process's chains only, leaving the ones it
276
276
  // skipped with no state for their own processes to resume.
277
277
  ~requireInitialized=false,
278
+ // Whether this process is the one that tells the operator the run resumed.
279
+ // A supervisor says it once for the whole run, so the workers it forked
280
+ // keep it to their own log files.
281
+ ~announceResume=true,
278
282
  ~startBlockRetry=StartBlockResolver.UntilItAnswers,
279
283
  ) => {
280
284
  try {
@@ -324,9 +328,7 @@ let init = {
324
328
  | _ => false
325
329
  }
326
330
  ) {
327
- // An isolated process resumes state its supervisor already announced
328
- // for the whole run, so it says so only to its own log file.
329
- let logResume = requireInitialized ? Logging.debug : Logging.info
331
+ let logResume = announceResume ? Logging.info : Logging.trace
330
332
  logResume(`Found existing indexer storage. Resuming indexing state...`)
331
333
  let initialState = await persistence.storage.resumeInitialState(
332
334
  ~entities=persistence.allEntities,
@@ -371,6 +373,7 @@ let initForRun = (
371
373
  ~requireInitialized,
372
374
  ) =>
373
375
  persistence->init(
376
+ ~announceResume=!Worker.isEnabled,
374
377
  ~reset,
375
378
  ~chainConfigs=config.chainMap->ChainMap.values,
376
379
  ~contractMapping=config.contractMapping,
@@ -2,6 +2,7 @@
2
2
 
3
3
  import * as Batch from "./Batch.res.mjs";
4
4
  import * as Config from "./Config.res.mjs";
5
+ import * as Worker from "./Worker.res.mjs";
5
6
  import * as Logging from "./Logging.res.mjs";
6
7
  import * as ChainMap from "./ChainMap.res.mjs";
7
8
  import * as Frontier from "./db/Frontier.res.mjs";
@@ -32,10 +33,11 @@ function make(userEntities, allEnums, storage) {
32
33
  };
33
34
  }
34
35
 
35
- async function init(persistence, chainConfigs, contractMapping, envioInfo, resetCommand, runCommand, resetOpt, lowercaseAddressesOpt, requireInitializedOpt, startBlockRetryOpt) {
36
+ async function init(persistence, chainConfigs, contractMapping, envioInfo, resetCommand, runCommand, resetOpt, lowercaseAddressesOpt, requireInitializedOpt, announceResumeOpt, startBlockRetryOpt) {
36
37
  let reset = resetOpt !== undefined ? resetOpt : false;
37
38
  let lowercaseAddresses = lowercaseAddressesOpt !== undefined ? lowercaseAddressesOpt : false;
38
39
  let requireInitialized = requireInitializedOpt !== undefined ? requireInitializedOpt : false;
40
+ let announceResume = announceResumeOpt !== undefined ? announceResumeOpt : true;
39
41
  let startBlockRetry = startBlockRetryOpt !== undefined ? startBlockRetryOpt : "UntilItAnswers";
40
42
  try {
41
43
  let promise = persistence.storageStatus;
@@ -78,7 +80,7 @@ async function init(persistence, chainConfigs, contractMapping, envioInfo, reset
78
80
  let tmp;
79
81
  tmp = typeof match !== "object" ? false : match.TAG === "Initializing";
80
82
  if (tmp) {
81
- let logResume = requireInitialized ? Logging.debug : Logging.info;
83
+ let logResume = announceResume ? Logging.info : Logging.trace;
82
84
  logResume(`Found existing indexer storage. Resuming indexing state...`);
83
85
  let initialState$1 = await persistence.storage.resumeInitialState(persistence.allEntities, chainConfigs.map(chain => chain.id), (storedEnvioInfo, storedContractMapping) => Config.throwIfResumeIncompatible(storedEnvioInfo, storedContractMapping, envioInfo, contractMapping, resetCommand, runCommand));
84
86
  persistence.storageStatus = {
@@ -103,7 +105,7 @@ async function init(persistence, chainConfigs, contractMapping, envioInfo, reset
103
105
  }
104
106
 
105
107
  function initForRun(persistence, config, reset, isDevelopmentMode, requireInitialized) {
106
- return init(persistence, ChainMap.values(config.chainMap), config.contractMapping, Config.envioInfo(), isDevelopmentMode ? "envio dev -r" : "envio start -r", isDevelopmentMode ? "envio dev" : "envio start", reset, config.lowercaseAddresses, requireInitialized, undefined);
108
+ return init(persistence, ChainMap.values(config.chainMap), config.contractMapping, Config.envioInfo(), isDevelopmentMode ? "envio dev -r" : "envio start -r", isDevelopmentMode ? "envio dev" : "envio start", reset, config.lowercaseAddresses, requireInitialized, !Worker.isEnabled, undefined);
107
109
  }
108
110
 
109
111
  function getInitializedStorageOrThrow(persistence) {
package/src/PgStorage.res CHANGED
@@ -1857,7 +1857,7 @@ let make = (
1857
1857
  if withUpload {
1858
1858
  // Try to restore cache tables from the .envio/cache TSV files
1859
1859
  switch await scanCacheDir() {
1860
- | [] => Logging.info("No cache found to upload.")
1860
+ | [] => Logging.info("No saved effect cache to load from .envio/cache.")
1861
1861
  | entries =>
1862
1862
  switch await getConnectedPsqlExec(~pgUser, ~pgHost, ~pgDatabase, ~pgPort, ~containerName) {
1863
1863
  | Ok(psqlExec) =>
@@ -2104,7 +2104,7 @@ let make = (
2104
2104
  switch await sql->loadCatalogRows(~indexName=name) {
2105
2105
  | rows => indexManager->IndexManager.resync(~name, ~rows)
2106
2106
  | exception exn =>
2107
- Logging.debug({
2107
+ Logging.trace({
2108
2108
  "storage": storageName,
2109
2109
  "msg": `Could not re-read the index "${name}" after a failed build. The next attempt reads it again.`,
2110
2110
  "err": exn->Utils.prettifyExn,
@@ -1183,7 +1183,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1183
1183
  Logging.error(`Failed to upload cache, continuing without it. ` + psqlExec._0);
1184
1184
  }
1185
1185
  } else {
1186
- Logging.info("No cache found to upload.");
1186
+ Logging.info("No saved effect cache to load from .envio/cache.");
1187
1187
  }
1188
1188
  }
1189
1189
  let cacheTableInfo = await queryCacheTableInfo();
@@ -1311,7 +1311,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1311
1311
  rows = await loadCatalogRows(sql, name);
1312
1312
  } catch (raw_exn) {
1313
1313
  let exn = Primitive_exceptions.internalToException(raw_exn);
1314
- return Logging.debug({
1314
+ return Logging.trace({
1315
1315
  storage: storageName,
1316
1316
  msg: `Could not re-read the index "` + name + `" after a failed build. The next attempt reads it again.`,
1317
1317
  err: Utils.prettifyExn(exn)
package/src/Rollback.res CHANGED
@@ -11,9 +11,9 @@ let getLastKnownValidBlock = async (
11
11
  ~isRealtime: bool,
12
12
  ) => {
13
13
  // Before the search, not after: it re-fetches the scanned hashes through the
14
- // sources, and a source answering from a cache it filled on the orphaned
15
- // chain would confirm blocks that no longer exist - stopping the rollback
16
- // short of the real fork.
14
+ // sources, and a read still in flight from before the reorg describes the
15
+ // orphaned chain — joining one would confirm blocks that no longer exist and
16
+ // stop the rollback short of the real fork.
17
17
  chainState->ChainState.sourceManager->SourceManager.onReorg
18
18
 
19
19
  // Don't include the reorg block itself - different source instances
package/src/Server.res CHANGED
@@ -77,9 +77,6 @@ let stateSchema = S.union([
77
77
  })),
78
78
  ])
79
79
 
80
- // Runtime state lives in the process-wide `EnvioGlobal` record (shared
81
- // across duplicate envio module instances); the slots are opaque there, so
82
- // cast them to the real types here.
83
80
  let startServer = (
84
81
  ~getMetrics: unit => option<Metrics.t>,
85
82
  ~envioVersion: string,
@@ -657,7 +657,7 @@ let parse = (
657
657
  | Svm => {
658
658
  items,
659
659
  transactionStore: Some(TransactionStore.fromSvmJs(svmTxs, svmActivities)),
660
- blockStore: Some(BlockStore.fromJs(svmBlocks, ~ecosystem=Svm, ~shouldChecksum=false)),
660
+ blockStore: Some(BlockStore.fromJs(svmBlocks, ~ecosystem=Svm)),
661
661
  }
662
662
  | _ => {
663
663
  items,
@@ -459,7 +459,7 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
459
459
  return {
460
460
  items: items,
461
461
  transactionStore: Primitive_option.some(TransactionStore.fromSvmJs(svmTxs, svmActivities)),
462
- blockStore: Primitive_option.some(BlockStore.fromJs(svmBlocks, "svm", false))
462
+ blockStore: Primitive_option.some(BlockStore.fromJs(svmBlocks, "svm"))
463
463
  };
464
464
  }
465
465
  }