envio 3.0.2 → 3.1.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.
Files changed (91) hide show
  1. package/README.md +0 -1
  2. package/evm.schema.json +15 -8
  3. package/fuel.schema.json +19 -12
  4. package/index.d.ts +0 -2
  5. package/package.json +6 -7
  6. package/rescript.json +1 -1
  7. package/src/Batch.res +4 -214
  8. package/src/Batch.res.mjs +6 -165
  9. package/src/ChainFetcher.res +4 -5
  10. package/src/ChainFetcher.res.mjs +6 -7
  11. package/src/ChainManager.res +10 -9
  12. package/src/ChainManager.res.mjs +6 -10
  13. package/src/Config.res +9 -25
  14. package/src/Config.res.mjs +17 -27
  15. package/src/Core.res +7 -0
  16. package/src/Ctx.res +1 -0
  17. package/src/Env.res +0 -1
  18. package/src/Env.res.mjs +0 -3
  19. package/src/EventConfigBuilder.res +13 -123
  20. package/src/EventConfigBuilder.res.mjs +6 -73
  21. package/src/EventProcessing.res +5 -29
  22. package/src/EventProcessing.res.mjs +11 -20
  23. package/src/EventUtils.res +0 -27
  24. package/src/EventUtils.res.mjs +0 -24
  25. package/src/FetchState.res +1 -11
  26. package/src/FetchState.res.mjs +2 -16
  27. package/src/GlobalState.res +23 -37
  28. package/src/GlobalState.res.mjs +10 -38
  29. package/src/HandlerLoader.res +6 -5
  30. package/src/HandlerLoader.res.mjs +27 -9
  31. package/src/HandlerRegister.res +1 -12
  32. package/src/HandlerRegister.res.mjs +1 -6
  33. package/src/HandlerRegister.resi +1 -1
  34. package/src/Hasura.res +96 -32
  35. package/src/Hasura.res.mjs +93 -38
  36. package/src/InMemoryStore.res +181 -45
  37. package/src/InMemoryStore.res.mjs +143 -40
  38. package/src/InMemoryTable.res +147 -247
  39. package/src/InMemoryTable.res.mjs +131 -230
  40. package/src/Internal.res +10 -34
  41. package/src/Internal.res.mjs +9 -3
  42. package/src/LoadLayer.res +5 -5
  43. package/src/LoadLayer.res.mjs +5 -5
  44. package/src/Main.res +4 -6
  45. package/src/Main.res.mjs +26 -15
  46. package/src/Persistence.res +7 -132
  47. package/src/Persistence.res.mjs +1 -102
  48. package/src/PgStorage.res +57 -40
  49. package/src/PgStorage.res.mjs +60 -34
  50. package/src/ReorgDetection.res +35 -58
  51. package/src/ReorgDetection.res.mjs +21 -29
  52. package/src/SimulateItems.res.mjs +21 -3
  53. package/src/Sink.res +2 -2
  54. package/src/Sink.res.mjs +1 -1
  55. package/src/TableIndices.res +9 -2
  56. package/src/TableIndices.res.mjs +7 -1
  57. package/src/TestIndexer.res +53 -60
  58. package/src/TestIndexer.res.mjs +77 -63
  59. package/src/TestIndexerProxyStorage.res +4 -14
  60. package/src/TestIndexerProxyStorage.res.mjs +1 -5
  61. package/src/UserContext.res +2 -4
  62. package/src/UserContext.res.mjs +4 -5
  63. package/src/Utils.res +0 -2
  64. package/src/Utils.res.mjs +0 -3
  65. package/src/bindings/ClickHouse.res +45 -38
  66. package/src/bindings/ClickHouse.res.mjs +16 -17
  67. package/src/bindings/Vitest.res +3 -0
  68. package/src/db/InternalTable.res +59 -18
  69. package/src/db/InternalTable.res.mjs +82 -51
  70. package/src/db/Table.res +9 -2
  71. package/src/db/Table.res.mjs +10 -7
  72. package/src/sources/EvmChain.res +32 -9
  73. package/src/sources/EvmChain.res.mjs +31 -4
  74. package/src/sources/HyperFuelSource.res +14 -57
  75. package/src/sources/HyperFuelSource.res.mjs +18 -38
  76. package/src/sources/HyperSync.res +36 -101
  77. package/src/sources/HyperSync.res.mjs +42 -96
  78. package/src/sources/HyperSync.resi +4 -22
  79. package/src/sources/HyperSyncClient.res +67 -245
  80. package/src/sources/HyperSyncClient.res.mjs +47 -46
  81. package/src/sources/HyperSyncSource.res +76 -147
  82. package/src/sources/HyperSyncSource.res.mjs +61 -114
  83. package/src/sources/RpcSource.res +43 -22
  84. package/src/sources/RpcSource.res.mjs +50 -35
  85. package/src/sources/SimulateSource.res +1 -7
  86. package/src/sources/SimulateSource.res.mjs +1 -7
  87. package/src/sources/Source.res +8 -1
  88. package/src/sources/SourceManager.res +9 -0
  89. package/src/sources/SourceManager.res.mjs +10 -0
  90. package/src/sources/SourceManager.resi +2 -0
  91. package/svm.schema.json +11 -4
@@ -7,6 +7,7 @@ type blockInfo = {
7
7
  number: int,
8
8
  timestamp: int,
9
9
  hash: string,
10
+ parentHash: string,
10
11
  }
11
12
 
12
13
  let getKnownRawBlock = async (~client, ~blockNumber) =>
@@ -29,6 +30,9 @@ let parseBlockInfo = (json: JSON.t): blockInfo => {
29
30
  hash: jsonDict
30
31
  ->Dict.getUnsafe("hash")
31
32
  ->S.parseOrThrow(S.string),
33
+ parentHash: jsonDict
34
+ ->Dict.getUnsafe("parentHash")
35
+ ->S.parseOrThrow(S.string),
32
36
  }
33
37
  }
34
38
 
@@ -838,7 +842,7 @@ type options = {
838
842
  url: string,
839
843
  chain: ChainMap.Chain.t,
840
844
  eventRouter: EventRouter.t<Internal.evmEventConfig>,
841
- allEventSignatures: array<string>,
845
+ allEventParams: array<HyperSyncClient.Decoder.eventParamsInput>,
842
846
  lowercaseAddresses: bool,
843
847
  ws?: string,
844
848
  }
@@ -850,7 +854,7 @@ let make = (
850
854
  url,
851
855
  chain,
852
856
  eventRouter,
853
- allEventSignatures,
857
+ allEventParams,
854
858
  lowercaseAddresses,
855
859
  ?ws,
856
860
  }: options,
@@ -993,12 +997,16 @@ let make = (
993
997
  {log: hyperSyncLog}
994
998
  }
995
999
 
996
- let hscDecoder: ref<option<HyperSyncClient.Decoder.t>> = ref(None)
1000
+ let hscDecoder: ref<option<HyperSyncClient.Decoder.tWithParams>> = ref(None)
997
1001
  let getHscDecoder = () => {
998
1002
  switch hscDecoder.contents {
999
1003
  | Some(decoder) => decoder
1000
1004
  | None => {
1001
- let decoder = HyperSyncClient.Decoder.fromSignatures(allEventSignatures)
1005
+ let decoder = HyperSyncClient.Decoder.fromParams(
1006
+ allEventParams,
1007
+ ~checksumAddresses=!lowercaseAddresses,
1008
+ )
1009
+ hscDecoder := Some(decoder)
1002
1010
  decoder
1003
1011
  }
1004
1012
  }
@@ -1071,7 +1079,7 @@ let make = (
1071
1079
  // We also don't care about it when we have a hard max block interval
1072
1080
  if (
1073
1081
  executedBlockInterval >= suggestedBlockInterval &&
1074
- !(mutSuggestedBlockIntervals->Utils.Dict.has(maxSuggestedBlockIntervalKey))
1082
+ !(mutSuggestedBlockIntervals->Dict.has(maxSuggestedBlockIntervalKey))
1075
1083
  ) {
1076
1084
  // Increase batch size going forward, but do not increase past a configured maximum
1077
1085
  // See: https://en.wikipedia.org/wiki/Additive_increase/multiplicative_decrease
@@ -1088,7 +1096,7 @@ let make = (
1088
1096
  let hyperSyncEvents = logs->Belt.Array.map(convertLogToHyperSyncEvent)
1089
1097
 
1090
1098
  // Decode using HyperSyncClient decoder
1091
- let parsedEvents = try await getHscDecoder().decodeEvents(hyperSyncEvents) catch {
1099
+ let parsedEvents = try await getHscDecoder().decodeLogs(hyperSyncEvents) catch {
1092
1100
  | exn =>
1093
1101
  throw(
1094
1102
  Source.GetItemsError(
@@ -1107,7 +1115,7 @@ let make = (
1107
1115
  ->Array.zip(parsedEvents)
1108
1116
  ->Array.filterMap(((
1109
1117
  log: Rpc.GetLogs.log,
1110
- maybeDecodedEvent: Nullable.t<HyperSyncClient.Decoder.decodedEvent>,
1118
+ maybeDecodedEvent: Nullable.t<Internal.eventParams>,
1111
1119
  )) => {
1112
1120
  let topic0 = log.topics[0]->Option.getOr("0x0")
1113
1121
  let routedAddress = if lowercaseAddresses {
@@ -1158,7 +1166,7 @@ let make = (
1158
1166
  contractName: eventConfig.contractName,
1159
1167
  eventName: eventConfig.name,
1160
1168
  chainId: chain->ChainMap.Chain.toChainId,
1161
- params: decoded->eventConfig.convertHyperSyncEventArgs,
1169
+ params: decoded,
1162
1170
  transaction,
1163
1171
  block,
1164
1172
  srcAddress: routedAddress,
@@ -1178,16 +1186,27 @@ let make = (
1178
1186
 
1179
1187
  let totalTimeElapsed = startFetchingBatchTimeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
1180
1188
 
1181
- let reorgGuard: ReorgDetection.reorgGuard = {
1182
- prevRangeLastBlock: optFirstBlockParent->Option.map(b => {
1183
- ReorgDetection.blockNumber: b.number,
1184
- blockHash: b.hash,
1185
- }),
1186
- rangeLastBlock: {
1187
- blockNumber: latestFetchedBlockInfo.number,
1188
- blockHash: latestFetchedBlockInfo.hash,
1189
- },
1189
+ // Every fetched block carries `hash` and `parentHash`, so each one yields
1190
+ // two confirmed (number, hash) pairs for reorg detection at no extra cost.
1191
+ let blockHashes = []
1192
+ let pushBlockInfo = (b: blockInfo) => {
1193
+ blockHashes->Array.push({ReorgDetection.blockNumber: b.number, blockHash: b.hash})->ignore
1194
+ if b.number > 0 {
1195
+ blockHashes
1196
+ ->Array.push({ReorgDetection.blockNumber: b.number - 1, blockHash: b.parentHash})
1197
+ ->ignore
1198
+ }
1199
+ }
1200
+ pushBlockInfo(latestFetchedBlockInfo)
1201
+ switch optFirstBlockParent {
1202
+ | Some(b) => pushBlockInfo(b)
1203
+ | None => ()
1190
1204
  }
1205
+ logs->Belt.Array.forEach(log =>
1206
+ blockHashes
1207
+ ->Array.push({ReorgDetection.blockNumber: log.blockNumber, blockHash: log.blockHash})
1208
+ ->ignore
1209
+ )
1191
1210
 
1192
1211
  {
1193
1212
  latestFetchedBlockTimestamp: latestFetchedBlockInfo.timestamp,
@@ -1197,19 +1216,20 @@ let make = (
1197
1216
  totalTimeElapsed: totalTimeElapsed,
1198
1217
  },
1199
1218
  knownHeight,
1200
- reorgGuard,
1219
+ blockHashes,
1201
1220
  fromBlockQueried: fromBlock,
1202
1221
  }
1203
1222
  }
1204
1223
 
1205
- let getBlockHashes = (~blockNumbers, ~logger as _currentlyUnusedLogger) => {
1206
- // Clear cache by creating a fresh LazyLoader
1207
- // This is important, since we call this
1208
- // function when a reorg is detected
1224
+ let onReorg = (~rollbackTargetBlock as _) => {
1225
+ // Drop cached block/transaction/receipt data — after a reorg the cached
1226
+ // entries may refer to orphaned-chain values.
1209
1227
  blockLoader := makeBlockLoader()
1210
1228
  transactionLoader := makeTransactionLoader()
1211
1229
  receiptLoader := makeReceiptLoader()
1230
+ }
1212
1231
 
1232
+ let getBlockHashes = (~blockNumbers, ~logger as _currentlyUnusedLogger) => {
1213
1233
  blockNumbers
1214
1234
  ->Array.map(blockNum => blockLoader.contents->LazyLoader.get(blockNum))
1215
1235
  ->Promise.all
@@ -1243,6 +1263,7 @@ let make = (
1243
1263
  poweredByHyperSync: false,
1244
1264
  pollingInterval: syncConfig.pollingInterval,
1245
1265
  getBlockHashes,
1266
+ onReorg,
1246
1267
  getHeightOrThrow: async () => {
1247
1268
  let timerRef = Hrtime.makeTimer()
1248
1269
  let height = try {
@@ -43,7 +43,8 @@ function parseBlockInfo(json) {
43
43
  return {
44
44
  number: S$RescriptSchema.parseOrThrow(json["number"], Rpc.hexIntSchema),
45
45
  timestamp: S$RescriptSchema.parseOrThrow(json["timestamp"], Rpc.hexIntSchema),
46
- hash: S$RescriptSchema.parseOrThrow(json["hash"], S$RescriptSchema.string)
46
+ hash: S$RescriptSchema.parseOrThrow(json["hash"], S$RescriptSchema.string),
47
+ parentHash: S$RescriptSchema.parseOrThrow(json["parentHash"], S$RescriptSchema.string)
47
48
  };
48
49
  }
49
50
 
@@ -917,7 +918,7 @@ function makeThrowingGetEventTransaction(getTransactionJson, getReceiptJson, low
917
918
 
918
919
  function make(param) {
919
920
  let lowercaseAddresses = param.lowercaseAddresses;
920
- let allEventSignatures = param.allEventSignatures;
921
+ let allEventParams = param.allEventParams;
921
922
  let eventRouter = param.eventRouter;
922
923
  let chain = param.chain;
923
924
  let url = param.url;
@@ -1021,9 +1022,10 @@ function make(param) {
1021
1022
  let decoder = hscDecoder.contents;
1022
1023
  if (decoder !== undefined) {
1023
1024
  return decoder;
1024
- } else {
1025
- return HyperSyncClient.Decoder.fromSignatures(allEventSignatures);
1026
1025
  }
1026
+ let decoder$1 = HyperSyncClient.Decoder.fromParams(allEventParams, !lowercaseAddresses);
1027
+ hscDecoder.contents = decoder$1;
1028
+ return decoder$1;
1027
1029
  };
1028
1030
  let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, indexingAddresses, knownHeight, partitionId, selection, param, param$1) => {
1029
1031
  let startFetchingBatchTimeRef = Hrtime.makeTimer();
@@ -1038,13 +1040,13 @@ function make(param) {
1038
1040
  let latestFetchedBlockInfo = match$2.latestFetchedBlockInfo;
1039
1041
  let logs = match$2.logs;
1040
1042
  let executedBlockInterval = (suggestedToBlock - fromBlock | 0) + 1 | 0;
1041
- if (executedBlockInterval >= suggestedBlockInterval && !Utils.Dict.has(mutSuggestedBlockIntervals, maxSuggestedBlockIntervalKey)) {
1043
+ if (executedBlockInterval >= suggestedBlockInterval && !(maxSuggestedBlockIntervalKey in mutSuggestedBlockIntervals)) {
1042
1044
  mutSuggestedBlockIntervals[partitionId] = Primitive_int.min(executedBlockInterval + syncConfig.accelerationAdditive | 0, syncConfig.intervalCeiling);
1043
1045
  }
1044
1046
  let hyperSyncEvents = Belt_Array.map(logs, convertLogToHyperSyncEvent);
1045
1047
  let parsedEvents;
1046
1048
  try {
1047
- parsedEvents = await getHscDecoder().decodeEvents(hyperSyncEvents);
1049
+ parsedEvents = await getHscDecoder().decodeLogs(hyperSyncEvents);
1048
1050
  } catch (raw_exn) {
1049
1051
  let exn = Primitive_exceptions.internalToException(raw_exn);
1050
1052
  throw {
@@ -1100,7 +1102,7 @@ function make(param) {
1100
1102
  event: {
1101
1103
  contractName: eventConfig.contractName,
1102
1104
  eventName: eventConfig.name,
1103
- params: eventConfig.convertHyperSyncEventArgs(maybeDecodedEvent),
1105
+ params: maybeDecodedEvent,
1104
1106
  chainId: chain,
1105
1107
  srcAddress: routedAddress,
1106
1108
  logIndex: log.logIndex,
@@ -1113,21 +1115,33 @@ function make(param) {
1113
1115
  }));
1114
1116
  let optFirstBlockParent = await firstBlockParentPromise;
1115
1117
  let totalTimeElapsed = Hrtime.toSecondsFloat(Hrtime.timeSince(startFetchingBatchTimeRef));
1116
- let reorgGuard_rangeLastBlock = {
1117
- blockHash: latestFetchedBlockInfo.hash,
1118
- blockNumber: latestFetchedBlockInfo.number
1119
- };
1120
- let reorgGuard_prevRangeLastBlock = Stdlib_Option.map(optFirstBlockParent, b => ({
1121
- blockHash: b.hash,
1122
- blockNumber: b.number
1123
- }));
1124
- let reorgGuard = {
1125
- rangeLastBlock: reorgGuard_rangeLastBlock,
1126
- prevRangeLastBlock: reorgGuard_prevRangeLastBlock
1118
+ let blockHashes = [];
1119
+ let pushBlockInfo = b => {
1120
+ blockHashes.push({
1121
+ blockHash: b.hash,
1122
+ blockNumber: b.number
1123
+ });
1124
+ if (b.number > 0) {
1125
+ blockHashes.push({
1126
+ blockHash: b.parentHash,
1127
+ blockNumber: b.number - 1 | 0
1128
+ });
1129
+ return;
1130
+ }
1127
1131
  };
1132
+ pushBlockInfo(latestFetchedBlockInfo);
1133
+ if (optFirstBlockParent !== undefined) {
1134
+ pushBlockInfo(optFirstBlockParent);
1135
+ }
1136
+ Belt_Array.forEach(logs, log => {
1137
+ blockHashes.push({
1138
+ blockHash: log.blockHash,
1139
+ blockNumber: log.blockNumber
1140
+ });
1141
+ });
1128
1142
  return {
1129
1143
  knownHeight: knownHeight,
1130
- reorgGuard: reorgGuard,
1144
+ blockHashes: blockHashes,
1131
1145
  parsedQueueItems: parsedQueueItems,
1132
1146
  fromBlockQueried: fromBlock,
1133
1147
  latestFetchedBlockNumber: latestFetchedBlockInfo.number,
@@ -1137,25 +1151,25 @@ function make(param) {
1137
1151
  }
1138
1152
  };
1139
1153
  };
1140
- let getBlockHashes = (blockNumbers, _currentlyUnusedLogger) => {
1154
+ let onReorg = param => {
1141
1155
  blockLoader.contents = makeBlockLoader();
1142
1156
  transactionLoader.contents = makeTransactionLoader();
1143
1157
  receiptLoader.contents = makeReceiptLoader();
1144
- return Stdlib_Promise.$$catch(Promise.all(blockNumbers.map(blockNum => LazyLoader.get(blockLoader.contents, blockNum))).then(rawBlocks => ({
1145
- TAG: "Ok",
1146
- _0: rawBlocks.map(json => {
1147
- let b = parseBlockInfo(json);
1148
- return {
1149
- blockHash: b.hash,
1150
- blockNumber: b.number,
1151
- blockTimestamp: b.timestamp
1152
- };
1153
- })
1154
- })), exn => Promise.resolve({
1155
- TAG: "Error",
1156
- _0: exn
1157
- }));
1158
1158
  };
1159
+ let getBlockHashes = (blockNumbers, _currentlyUnusedLogger) => Stdlib_Promise.$$catch(Promise.all(blockNumbers.map(blockNum => LazyLoader.get(blockLoader.contents, blockNum))).then(rawBlocks => ({
1160
+ TAG: "Ok",
1161
+ _0: rawBlocks.map(json => {
1162
+ let b = parseBlockInfo(json);
1163
+ return {
1164
+ blockHash: b.hash,
1165
+ blockNumber: b.number,
1166
+ blockTimestamp: b.timestamp
1167
+ };
1168
+ })
1169
+ })), exn => Promise.resolve({
1170
+ TAG: "Error",
1171
+ _0: exn
1172
+ }));
1159
1173
  let createHeightSubscription = Belt_Option.map(param.ws, wsUrl => (onHeight => RpcWebSocketHeightStream.subscribe(wsUrl, chain, onHeight)));
1160
1174
  return {
1161
1175
  name: name,
@@ -1181,7 +1195,8 @@ function make(param) {
1181
1195
  return height;
1182
1196
  },
1183
1197
  getItemsOrThrow: getItemsOrThrow,
1184
- createHeightSubscription: createHeightSubscription
1198
+ createHeightSubscription: createHeightSubscription,
1199
+ onReorg: onReorg
1185
1200
  };
1186
1201
  }
1187
1202
 
@@ -39,13 +39,7 @@ let make = (~items: array<Internal.item>, ~endBlock: int, ~chain: ChainMap.Chain
39
39
  let reportedHeight = max(endBlock, 1)
40
40
  Promise.resolve({
41
41
  Source.knownHeight: reportedHeight,
42
- reorgGuard: {
43
- rangeLastBlock: {
44
- blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
45
- blockNumber: reportedHeight,
46
- },
47
- prevRangeLastBlock: None,
48
- },
42
+ blockHashes: [],
49
43
  parsedQueueItems: result,
50
44
  fromBlockQueried: 0,
51
45
  latestFetchedBlockNumber: reportedHeight,
@@ -22,13 +22,7 @@ function make(items, endBlock, chain) {
22
22
  let reportedHeight = Primitive_int.max(endBlock, 1);
23
23
  return Promise.resolve({
24
24
  knownHeight: reportedHeight,
25
- reorgGuard: {
26
- rangeLastBlock: {
27
- blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
28
- blockNumber: reportedHeight
29
- },
30
- prevRangeLastBlock: undefined
31
- },
25
+ blockHashes: [],
32
26
  parsedQueueItems: result,
33
27
  fromBlockQueried: 0,
34
28
  latestFetchedBlockNumber: reportedHeight,
@@ -12,7 +12,11 @@ Thes response returned from a block range fetch
12
12
  */
13
13
  type blockRangeFetchResponse = {
14
14
  knownHeight: int,
15
- reorgGuard: ReorgDetection.reorgGuard,
15
+ // Best-effort (blockNumber, blockHash) pairs observed while fetching this range.
16
+ // Used by reorg detection; gaps are OK, no extra requests are made to fill them.
17
+ // Duplicates with the same block number are allowed — registerReorgGuard treats
18
+ // a within-array hash mismatch on the same block number as a reorg.
19
+ blockHashes: array<ReorgDetection.blockData>,
16
20
  parsedQueueItems: array<Internal.item>,
17
21
  fromBlockQueried: int,
18
22
  latestFetchedBlockNumber: int,
@@ -58,4 +62,7 @@ type t = {
58
62
  ~logger: Pino.t,
59
63
  ) => promise<blockRangeFetchResponse>,
60
64
  createHeightSubscription?: (~onHeight: int => unit) => unit => unit,
65
+ // Invoked by SourceManager once a rollback target is known so the source can
66
+ // drop any state that may now point at an orphaned chain (e.g. RPC block cache).
67
+ onReorg?: (~rollbackTargetBlock: int) => unit,
61
68
  }
@@ -36,6 +36,15 @@ type t = {
36
36
 
37
37
  let getActiveSource = sourceManager => sourceManager.activeSource
38
38
 
39
+ let onReorg = (sourceManager: t, ~rollbackTargetBlock) => {
40
+ sourceManager.sourcesState->Array.forEach(({source}) => {
41
+ switch source.onReorg {
42
+ | Some(cb) => cb(~rollbackTargetBlock)
43
+ | None => ()
44
+ }
45
+ })
46
+ }
47
+
39
48
  type sourceRole = Primary | Secondary
40
49
 
41
50
  // Determines whether a source is Primary or Secondary given the current mode.
@@ -17,6 +17,15 @@ function getActiveSource(sourceManager) {
17
17
  return sourceManager.activeSource;
18
18
  }
19
19
 
20
+ function onReorg(sourceManager, rollbackTargetBlock) {
21
+ sourceManager.sourcesState.forEach(param => {
22
+ let cb = param.source.onReorg;
23
+ if (cb !== undefined) {
24
+ return cb(rollbackTargetBlock);
25
+ }
26
+ });
27
+ }
28
+
20
29
  function getSourceRole(sourceFor, isRealtime, hasRealtime) {
21
30
  if (isRealtime) {
22
31
  switch (sourceFor) {
@@ -547,6 +556,7 @@ export {
547
556
  getSourceRole,
548
557
  make,
549
558
  getActiveSource,
559
+ onReorg,
550
560
  fetchNext,
551
561
  waitForNewBlock,
552
562
  executeQuery,
@@ -22,6 +22,8 @@ let make: (
22
22
 
23
23
  let getActiveSource: t => Source.t
24
24
 
25
+ let onReorg: (t, ~rollbackTargetBlock: int) => unit
26
+
25
27
  let fetchNext: (
26
28
  t,
27
29
  ~fetchState: FetchState.t,
package/svm.schema.json CHANGED
@@ -4,6 +4,10 @@
4
4
  "description": "Schema for a YAML config for an envio Svm indexer",
5
5
  "type": "object",
6
6
  "properties": {
7
+ "name": {
8
+ "description": "Name of the project",
9
+ "type": "string"
10
+ },
7
11
  "description": {
8
12
  "description": "Description of the project",
9
13
  "type": [
@@ -11,10 +15,6 @@
11
15
  "null"
12
16
  ]
13
17
  },
14
- "name": {
15
- "description": "Name of the project",
16
- "type": "string"
17
- },
18
18
  "schema": {
19
19
  "description": "Custom path to schema.graphql file",
20
20
  "type": [
@@ -133,6 +133,13 @@
133
133
  "Chain": {
134
134
  "type": "object",
135
135
  "properties": {
136
+ "skip": {
137
+ "description": "Excludes the chain from indexing and migrations. Code generation is unaffected. For testing, prefer using a test framework instead.",
138
+ "type": [
139
+ "boolean",
140
+ "null"
141
+ ]
142
+ },
136
143
  "rpc": {
137
144
  "description": "RPC endpoint URL for connecting to the Svm cluster to fetch blockchain data.",
138
145
  "type": "string"