envio 3.0.0-alpha.2 → 3.0.0-alpha.20

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 (175) hide show
  1. package/README.md +164 -30
  2. package/bin.mjs +49 -0
  3. package/evm.schema.json +79 -169
  4. package/fuel.schema.json +50 -21
  5. package/index.d.ts +497 -1
  6. package/index.js +4 -0
  7. package/package.json +42 -31
  8. package/rescript.json +4 -1
  9. package/src/Batch.res +11 -8
  10. package/src/Batch.res.mjs +11 -9
  11. package/src/ChainFetcher.res +531 -0
  12. package/src/ChainFetcher.res.mjs +339 -0
  13. package/src/ChainManager.res +190 -0
  14. package/src/ChainManager.res.mjs +166 -0
  15. package/src/Change.res +3 -3
  16. package/src/Config.gen.ts +19 -0
  17. package/src/Config.res +737 -22
  18. package/src/Config.res.mjs +703 -26
  19. package/src/{Indexer.res → Ctx.res} +1 -1
  20. package/src/Ecosystem.res +9 -124
  21. package/src/Ecosystem.res.mjs +19 -160
  22. package/src/Env.res +30 -74
  23. package/src/Env.res.mjs +25 -87
  24. package/src/Envio.gen.ts +3 -1
  25. package/src/Envio.res +20 -9
  26. package/src/EventProcessing.res +469 -0
  27. package/src/EventProcessing.res.mjs +337 -0
  28. package/src/EvmTypes.gen.ts +6 -0
  29. package/src/EvmTypes.res +1 -0
  30. package/src/FetchState.res +1256 -639
  31. package/src/FetchState.res.mjs +1135 -612
  32. package/src/GlobalState.res +1190 -0
  33. package/src/GlobalState.res.mjs +1183 -0
  34. package/src/GlobalStateManager.res +68 -0
  35. package/src/GlobalStateManager.res.mjs +75 -0
  36. package/src/GlobalStateManager.resi +7 -0
  37. package/src/HandlerLoader.res +89 -0
  38. package/src/HandlerLoader.res.mjs +79 -0
  39. package/src/HandlerRegister.res +357 -0
  40. package/src/HandlerRegister.res.mjs +299 -0
  41. package/src/{EventRegister.resi → HandlerRegister.resi} +13 -13
  42. package/src/Hasura.res +111 -175
  43. package/src/Hasura.res.mjs +88 -150
  44. package/src/InMemoryStore.res +1 -1
  45. package/src/InMemoryStore.res.mjs +3 -3
  46. package/src/InMemoryTable.res +1 -1
  47. package/src/InMemoryTable.res.mjs +1 -1
  48. package/src/Internal.gen.ts +4 -0
  49. package/src/Internal.res +230 -12
  50. package/src/Internal.res.mjs +115 -1
  51. package/src/LoadLayer.res +444 -0
  52. package/src/LoadLayer.res.mjs +296 -0
  53. package/src/LoadLayer.resi +32 -0
  54. package/src/LogSelection.res +33 -27
  55. package/src/LogSelection.res.mjs +6 -0
  56. package/src/Logging.res +21 -7
  57. package/src/Logging.res.mjs +16 -8
  58. package/src/Main.res +377 -0
  59. package/src/Main.res.mjs +339 -0
  60. package/src/Persistence.res +7 -21
  61. package/src/Persistence.res.mjs +3 -3
  62. package/src/PgStorage.gen.ts +10 -0
  63. package/src/PgStorage.res +116 -69
  64. package/src/PgStorage.res.d.mts +5 -0
  65. package/src/PgStorage.res.mjs +93 -50
  66. package/src/Prometheus.res +294 -224
  67. package/src/Prometheus.res.mjs +353 -340
  68. package/src/ReorgDetection.res +6 -10
  69. package/src/ReorgDetection.res.mjs +6 -6
  70. package/src/SafeCheckpointTracking.res +4 -4
  71. package/src/SafeCheckpointTracking.res.mjs +2 -2
  72. package/src/Sink.res +4 -2
  73. package/src/Sink.res.mjs +2 -1
  74. package/src/TableIndices.res +0 -1
  75. package/src/TestIndexer.res +692 -0
  76. package/src/TestIndexer.res.mjs +527 -0
  77. package/src/TestIndexerProxyStorage.res +205 -0
  78. package/src/TestIndexerProxyStorage.res.mjs +151 -0
  79. package/src/TopicFilter.res +1 -1
  80. package/src/Types.ts +1 -1
  81. package/src/UserContext.res +424 -0
  82. package/src/UserContext.res.mjs +279 -0
  83. package/src/Utils.res +97 -26
  84. package/src/Utils.res.mjs +91 -44
  85. package/src/bindings/BigInt.res +10 -0
  86. package/src/bindings/BigInt.res.mjs +15 -0
  87. package/src/bindings/ClickHouse.res +120 -23
  88. package/src/bindings/ClickHouse.res.mjs +118 -28
  89. package/src/bindings/DateFns.res +74 -0
  90. package/src/bindings/DateFns.res.mjs +22 -0
  91. package/src/bindings/EventSource.res +8 -1
  92. package/src/bindings/EventSource.res.mjs +8 -1
  93. package/src/bindings/Express.res +1 -0
  94. package/src/bindings/Hrtime.res +14 -1
  95. package/src/bindings/Hrtime.res.mjs +22 -2
  96. package/src/bindings/Hrtime.resi +4 -0
  97. package/src/bindings/Lodash.res +0 -1
  98. package/src/bindings/NodeJs.res +49 -3
  99. package/src/bindings/NodeJs.res.mjs +11 -3
  100. package/src/bindings/Pino.res +24 -10
  101. package/src/bindings/Pino.res.mjs +14 -8
  102. package/src/bindings/Postgres.gen.ts +8 -0
  103. package/src/bindings/Postgres.res +5 -1
  104. package/src/bindings/Postgres.res.d.mts +5 -0
  105. package/src/bindings/PromClient.res +0 -10
  106. package/src/bindings/PromClient.res.mjs +0 -3
  107. package/src/bindings/Vitest.res +142 -0
  108. package/src/bindings/Vitest.res.mjs +9 -0
  109. package/src/bindings/WebSocket.res +27 -0
  110. package/src/bindings/WebSocket.res.mjs +2 -0
  111. package/src/bindings/Yargs.res +8 -0
  112. package/src/bindings/Yargs.res.mjs +2 -0
  113. package/src/db/EntityHistory.res +7 -7
  114. package/src/db/EntityHistory.res.mjs +9 -9
  115. package/src/db/InternalTable.res +59 -111
  116. package/src/db/InternalTable.res.mjs +73 -104
  117. package/src/db/Table.res +27 -8
  118. package/src/db/Table.res.mjs +25 -14
  119. package/src/sources/Evm.res +84 -0
  120. package/src/sources/Evm.res.mjs +105 -0
  121. package/src/sources/EvmChain.res +94 -0
  122. package/src/sources/EvmChain.res.mjs +60 -0
  123. package/src/sources/Fuel.res +19 -34
  124. package/src/sources/Fuel.res.mjs +34 -16
  125. package/src/sources/FuelSDK.res +38 -0
  126. package/src/sources/FuelSDK.res.mjs +29 -0
  127. package/src/sources/HyperFuel.res +2 -2
  128. package/src/sources/HyperFuel.resi +1 -1
  129. package/src/sources/HyperFuelClient.res +2 -2
  130. package/src/sources/HyperFuelSource.res +33 -13
  131. package/src/sources/HyperFuelSource.res.mjs +24 -16
  132. package/src/sources/HyperSync.res +36 -6
  133. package/src/sources/HyperSync.res.mjs +9 -7
  134. package/src/sources/HyperSync.resi +4 -0
  135. package/src/sources/HyperSyncClient.res +1 -1
  136. package/src/sources/HyperSyncHeightStream.res +47 -116
  137. package/src/sources/HyperSyncHeightStream.res.mjs +46 -73
  138. package/src/sources/HyperSyncSource.res +118 -139
  139. package/src/sources/HyperSyncSource.res.mjs +104 -121
  140. package/src/sources/Rpc.res +86 -14
  141. package/src/sources/Rpc.res.mjs +101 -9
  142. package/src/sources/RpcSource.res +621 -364
  143. package/src/sources/RpcSource.res.mjs +843 -410
  144. package/src/sources/RpcWebSocketHeightStream.res +181 -0
  145. package/src/sources/RpcWebSocketHeightStream.res.mjs +196 -0
  146. package/src/sources/Source.res +7 -5
  147. package/src/sources/SourceManager.res +325 -225
  148. package/src/sources/SourceManager.res.mjs +314 -171
  149. package/src/sources/SourceManager.resi +17 -6
  150. package/src/sources/Svm.res +81 -0
  151. package/src/sources/Svm.res.mjs +90 -0
  152. package/src/tui/Tui.res +247 -0
  153. package/src/tui/Tui.res.mjs +337 -0
  154. package/src/tui/bindings/Ink.res +371 -0
  155. package/src/tui/bindings/Ink.res.mjs +72 -0
  156. package/src/tui/bindings/Style.res +123 -0
  157. package/src/tui/bindings/Style.res.mjs +2 -0
  158. package/src/tui/components/BufferedProgressBar.res +40 -0
  159. package/src/tui/components/BufferedProgressBar.res.mjs +57 -0
  160. package/src/tui/components/CustomHooks.res +122 -0
  161. package/src/tui/components/CustomHooks.res.mjs +179 -0
  162. package/src/tui/components/Messages.res +41 -0
  163. package/src/tui/components/Messages.res.mjs +75 -0
  164. package/src/tui/components/SyncETA.res +174 -0
  165. package/src/tui/components/SyncETA.res.mjs +263 -0
  166. package/src/tui/components/TuiData.res +47 -0
  167. package/src/tui/components/TuiData.res.mjs +34 -0
  168. package/svm.schema.json +112 -0
  169. package/bin.js +0 -48
  170. package/src/EventRegister.res +0 -241
  171. package/src/EventRegister.res.mjs +0 -240
  172. package/src/bindings/Ethers.gen.ts +0 -14
  173. package/src/bindings/Ethers.res +0 -204
  174. package/src/bindings/Ethers.res.mjs +0 -130
  175. /package/src/{Indexer.res.mjs → Ctx.res.mjs} +0 -0
@@ -11,104 +11,418 @@ import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
11
11
  import * as Caml_int32 from "rescript/lib/es6/caml_int32.js";
12
12
  import * as Prometheus from "./Prometheus.res.mjs";
13
13
  import * as Belt_Option from "rescript/lib/es6/belt_Option.js";
14
- import * as Belt_Result from "rescript/lib/es6/belt_Result.js";
15
- import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js";
14
+ import * as Caml_option from "rescript/lib/es6/caml_option.js";
16
15
 
17
- function mergeIntoPartition(p, target, maxAddrInPartition) {
18
- if (!p.selection.dependsOnAddresses) {
19
- return [
20
- p,
21
- target
22
- ];
16
+ function getMinHistoryRange(p) {
17
+ var match = p.prevQueryRange;
18
+ var match$1 = p.prevPrevQueryRange;
19
+ if (match !== 0 && match$1 !== 0) {
20
+ return match < match$1 ? match : match$1;
23
21
  }
24
- if (!target.selection.dependsOnAddresses) {
25
- return [
26
- p,
27
- target
28
- ];
22
+
23
+ }
24
+
25
+ function getMinQueryRange(partitions) {
26
+ var min = 0;
27
+ for(var i = 0 ,i_finish = partitions.length; i < i_finish; ++i){
28
+ var p = partitions[i];
29
+ var a = p.prevQueryRange;
30
+ var b = p.prevPrevQueryRange;
31
+ if (a > 0 && (min === 0 || a < min)) {
32
+ min = a;
33
+ }
34
+ if (b > 0 && (min === 0 || b < min)) {
35
+ min = b;
36
+ }
37
+
38
+ }
39
+ return min;
40
+ }
41
+
42
+ function count(optimizedPartitions) {
43
+ return optimizedPartitions.idsInAscOrder.length;
44
+ }
45
+
46
+ function getOrThrow(optimizedPartitions, partitionId) {
47
+ var p = Js_dict.get(optimizedPartitions.entities, partitionId);
48
+ if (p !== undefined) {
49
+ return p;
50
+ } else {
51
+ return Js_exn.raiseError("Unexpected case: Couldn't find partition " + partitionId);
52
+ }
53
+ }
54
+
55
+ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAddrInPartition, nextPartitionIndexRef) {
56
+ var combinedAddresses = p1.addressesByContractName[contractName].concat(p2.addressesByContractName[contractName]);
57
+ var p1Below = p1.latestFetchedBlock.blockNumber < potentialMergeBlock;
58
+ var p2Below = p2.latestFetchedBlock.blockNumber < potentialMergeBlock;
59
+ var completed = [];
60
+ var continuingBase;
61
+ if (p1Below) {
62
+ completed.push({
63
+ id: p1.id,
64
+ latestFetchedBlock: p1.latestFetchedBlock,
65
+ selection: p1.selection,
66
+ addressesByContractName: p1.addressesByContractName,
67
+ mergeBlock: potentialMergeBlock,
68
+ dynamicContract: p1.dynamicContract,
69
+ mutPendingQueries: p1.mutPendingQueries,
70
+ prevQueryRange: p1.prevQueryRange,
71
+ prevPrevQueryRange: p1.prevPrevQueryRange,
72
+ latestBlockRangeUpdateBlock: p1.latestBlockRangeUpdateBlock
73
+ });
74
+ if (p2Below) {
75
+ completed.push({
76
+ id: p2.id,
77
+ latestFetchedBlock: p2.latestFetchedBlock,
78
+ selection: p2.selection,
79
+ addressesByContractName: p2.addressesByContractName,
80
+ mergeBlock: potentialMergeBlock,
81
+ dynamicContract: p2.dynamicContract,
82
+ mutPendingQueries: p2.mutPendingQueries,
83
+ prevQueryRange: p2.prevQueryRange,
84
+ prevPrevQueryRange: p2.prevPrevQueryRange,
85
+ latestBlockRangeUpdateBlock: p2.latestBlockRangeUpdateBlock
86
+ });
87
+ var newId = nextPartitionIndexRef.contents.toString();
88
+ nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
89
+ var minRange = getMinQueryRange([
90
+ p1,
91
+ p2
92
+ ]);
93
+ continuingBase = {
94
+ id: newId,
95
+ latestFetchedBlock: {
96
+ blockNumber: potentialMergeBlock,
97
+ blockTimestamp: 0
98
+ },
99
+ selection: p1.selection,
100
+ addressesByContractName: {},
101
+ mergeBlock: undefined,
102
+ dynamicContract: contractName,
103
+ mutPendingQueries: [],
104
+ prevQueryRange: minRange,
105
+ prevPrevQueryRange: minRange,
106
+ latestBlockRangeUpdateBlock: 0
107
+ };
108
+ } else {
109
+ continuingBase = p2;
110
+ }
111
+ } else if (p2Below) {
112
+ completed.push({
113
+ id: p2.id,
114
+ latestFetchedBlock: p2.latestFetchedBlock,
115
+ selection: p2.selection,
116
+ addressesByContractName: p2.addressesByContractName,
117
+ mergeBlock: potentialMergeBlock,
118
+ dynamicContract: p2.dynamicContract,
119
+ mutPendingQueries: p2.mutPendingQueries,
120
+ prevQueryRange: p2.prevQueryRange,
121
+ prevPrevQueryRange: p2.prevPrevQueryRange,
122
+ latestBlockRangeUpdateBlock: p2.latestBlockRangeUpdateBlock
123
+ });
124
+ continuingBase = p1;
125
+ } else {
126
+ continuingBase = p1;
29
127
  }
30
- var latestFetchedBlock = target.latestFetchedBlock;
31
- var mergedAddresses = {};
32
- var allowedAddressesNumber = {
33
- contents: maxAddrInPartition
128
+ if (combinedAddresses.length > maxAddrInPartition) {
129
+ var addressesFull = combinedAddresses.slice(0, maxAddrInPartition);
130
+ var addressesRest = combinedAddresses.slice(maxAddrInPartition);
131
+ var abcFull = {};
132
+ abcFull[contractName] = addressesFull;
133
+ var abcRest = {};
134
+ abcRest[contractName] = addressesRest;
135
+ completed.push({
136
+ id: continuingBase.id,
137
+ latestFetchedBlock: continuingBase.latestFetchedBlock,
138
+ selection: continuingBase.selection,
139
+ addressesByContractName: abcFull,
140
+ mergeBlock: continuingBase.mergeBlock,
141
+ dynamicContract: continuingBase.dynamicContract,
142
+ mutPendingQueries: continuingBase.mutPendingQueries,
143
+ prevQueryRange: continuingBase.prevQueryRange,
144
+ prevPrevQueryRange: continuingBase.prevPrevQueryRange,
145
+ latestBlockRangeUpdateBlock: continuingBase.latestBlockRangeUpdateBlock
146
+ });
147
+ var restId = nextPartitionIndexRef.contents.toString();
148
+ nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
149
+ completed.push({
150
+ id: restId,
151
+ latestFetchedBlock: continuingBase.latestFetchedBlock,
152
+ selection: continuingBase.selection,
153
+ addressesByContractName: abcRest,
154
+ mergeBlock: continuingBase.mergeBlock,
155
+ dynamicContract: continuingBase.dynamicContract,
156
+ mutPendingQueries: [],
157
+ prevQueryRange: continuingBase.prevQueryRange,
158
+ prevPrevQueryRange: continuingBase.prevPrevQueryRange,
159
+ latestBlockRangeUpdateBlock: continuingBase.latestBlockRangeUpdateBlock
160
+ });
161
+ return completed;
162
+ }
163
+ var abc = {};
164
+ abc[contractName] = combinedAddresses;
165
+ completed.push({
166
+ id: continuingBase.id,
167
+ latestFetchedBlock: continuingBase.latestFetchedBlock,
168
+ selection: continuingBase.selection,
169
+ addressesByContractName: abc,
170
+ mergeBlock: continuingBase.mergeBlock,
171
+ dynamicContract: continuingBase.dynamicContract,
172
+ mutPendingQueries: continuingBase.mutPendingQueries,
173
+ prevQueryRange: continuingBase.prevQueryRange,
174
+ prevPrevQueryRange: continuingBase.prevPrevQueryRange,
175
+ latestBlockRangeUpdateBlock: continuingBase.latestBlockRangeUpdateBlock
176
+ });
177
+ return completed;
178
+ }
179
+
180
+ function ascSortFn(a, b) {
181
+ return a.latestFetchedBlock.blockNumber - b.latestFetchedBlock.blockNumber | 0;
182
+ }
183
+
184
+ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContracts) {
185
+ var newPartitions = [];
186
+ var mergingPartitions = {};
187
+ var nextPartitionIndexRef = {
188
+ contents: nextPartitionIndex
34
189
  };
35
- Utils.Dict.forEachWithKey(target.addressesByContractName, (function (addresses, contractName) {
36
- allowedAddressesNumber.contents = allowedAddressesNumber.contents - addresses.length | 0;
37
- mergedAddresses[contractName] = addresses;
38
- }));
39
- Utils.Dict.forEachWithKey(p.addressesByContractName, (function (addresses, contractName) {
40
- allowedAddressesNumber.contents = allowedAddressesNumber.contents - addresses.length | 0;
41
- var targetAddresses = mergedAddresses[contractName];
42
- if (targetAddresses !== undefined) {
43
- mergedAddresses[contractName] = Belt_Array.concat(targetAddresses, addresses);
44
- } else {
45
- mergedAddresses[contractName] = addresses;
190
+ for(var idx = 0 ,idx_finish = partitions.length; idx < idx_finish; ++idx){
191
+ var p = partitions[idx];
192
+ if (p.dynamicContract !== undefined && !(p.mergeBlock !== undefined || !p.selection.dependsOnAddresses)) {
193
+ var contractName = p.dynamicContract;
194
+ var pAddressesCount = p.addressesByContractName[contractName].length;
195
+ var match = Utils.$$Array.last(p.mutPendingQueries);
196
+ var potentialMergeBlock;
197
+ if (match !== undefined) {
198
+ var toBlock = match.toBlock;
199
+ potentialMergeBlock = toBlock !== undefined && match.isChunk ? toBlock : undefined;
200
+ } else {
201
+ potentialMergeBlock = p.latestFetchedBlock.blockNumber;
202
+ }
203
+ if (potentialMergeBlock !== undefined && pAddressesCount < maxAddrInPartition) {
204
+ var partitionsByMergeBlock = Utils.Dict.getOrInsertEmptyDict(mergingPartitions, contractName);
205
+ var existingPartition = partitionsByMergeBlock[potentialMergeBlock];
206
+ if (existingPartition !== undefined) {
207
+ var result = mergePartitionsAtBlock(existingPartition, p, potentialMergeBlock, contractName, maxAddrInPartition, nextPartitionIndexRef);
208
+ for(var i = 0 ,i_finish = result.length - 2 | 0; i <= i_finish; ++i){
209
+ newPartitions.push(result[i]);
46
210
  }
47
- }));
48
- var rest;
49
- if (allowedAddressesNumber.contents < 0) {
50
- var restAddresses = {};
51
- Utils.Dict.forEachWithKey(mergedAddresses, (function (addresses, contractName) {
52
- if (allowedAddressesNumber.contents === 0) {
53
- return ;
54
- }
55
- if (addresses.length <= (-allowedAddressesNumber.contents | 0)) {
56
- allowedAddressesNumber.contents = allowedAddressesNumber.contents + addresses.length | 0;
57
- Utils.Dict.deleteInPlace(mergedAddresses, contractName);
58
- restAddresses[contractName] = addresses;
59
- return ;
60
- }
61
- var restFrom = addresses.length + allowedAddressesNumber.contents | 0;
62
- mergedAddresses[contractName] = addresses.slice(0, restFrom);
63
- restAddresses[contractName] = addresses.slice(restFrom);
64
- allowedAddressesNumber.contents = 0;
65
- }));
66
- rest = {
67
- id: p.id,
68
- status: {
69
- fetchingStateId: undefined
70
- },
71
- latestFetchedBlock: latestFetchedBlock,
72
- selection: target.selection,
73
- addressesByContractName: restAddresses
211
+ partitionsByMergeBlock[potentialMergeBlock] = Utils.$$Array.lastUnsafe(result);
212
+ } else {
213
+ partitionsByMergeBlock[potentialMergeBlock] = p;
214
+ }
215
+ } else {
216
+ newPartitions.push(p);
217
+ }
218
+ } else {
219
+ newPartitions.push(p);
220
+ }
221
+ }
222
+ var merginDynamicContracts = Object.keys(mergingPartitions);
223
+ for(var idx$1 = 0 ,idx_finish$1 = merginDynamicContracts.length; idx$1 < idx_finish$1; ++idx$1){
224
+ var contractName$1 = merginDynamicContracts[idx$1];
225
+ var partitionsByMergeBlock$1 = mergingPartitions[contractName$1];
226
+ var ascPartitionKeys = Object.keys(partitionsByMergeBlock$1);
227
+ if (ascPartitionKeys[ascPartitionKeys.length - 1 | 0] === "-1") {
228
+ ascPartitionKeys.unshift(Caml_option.undefined_to_opt(ascPartitionKeys.pop()));
229
+ }
230
+ var currentPRef = partitionsByMergeBlock$1[Utils.$$Array.firstUnsafe(ascPartitionKeys)];
231
+ var currentPMergeBlockRef = Belt_Int.fromString(Utils.$$Array.firstUnsafe(ascPartitionKeys));
232
+ var nextJdx = 1;
233
+ while(nextJdx < ascPartitionKeys.length) {
234
+ var nextKey = ascPartitionKeys[nextJdx];
235
+ var currentP = currentPRef;
236
+ var nextP = partitionsByMergeBlock$1[nextKey];
237
+ var nextPMergeBlock = Belt_Int.fromString(nextKey);
238
+ var currentPMergeBlock = currentPMergeBlockRef;
239
+ var isTooFar = (currentPMergeBlock + 20000 | 0) < nextPMergeBlock;
240
+ if (isTooFar) {
241
+ newPartitions.push(currentP);
242
+ currentPRef = nextP;
243
+ currentPMergeBlockRef = nextPMergeBlock;
244
+ } else {
245
+ var result$1 = mergePartitionsAtBlock(nextP, currentP, nextPMergeBlock, contractName$1, maxAddrInPartition, nextPartitionIndexRef);
246
+ for(var i$1 = 0 ,i_finish$1 = result$1.length - 2 | 0; i$1 <= i_finish$1; ++i$1){
247
+ newPartitions.push(result$1[i$1]);
248
+ }
249
+ currentPRef = Utils.$$Array.lastUnsafe(result$1);
250
+ currentPMergeBlockRef = nextPMergeBlock;
251
+ }
252
+ nextJdx = nextJdx + 1 | 0;
74
253
  };
254
+ newPartitions.push(currentPRef);
255
+ }
256
+ newPartitions.sort(ascSortFn);
257
+ var partitionsCount = newPartitions.length;
258
+ var idsInAscOrder = new Array(partitionsCount);
259
+ var entities = {};
260
+ for(var idx$2 = 0; idx$2 < partitionsCount; ++idx$2){
261
+ var p$1 = newPartitions[idx$2];
262
+ idsInAscOrder[idx$2] = p$1.id;
263
+ entities[p$1.id] = p$1;
264
+ }
265
+ return {
266
+ idsInAscOrder: idsInAscOrder,
267
+ entities: entities,
268
+ maxAddrInPartition: maxAddrInPartition,
269
+ nextPartitionIndex: nextPartitionIndexRef.contents,
270
+ dynamicContracts: dynamicContracts
271
+ };
272
+ }
273
+
274
+ function consumeFetchedQueries(mutPendingQueries, initialLatestFetchedBlock) {
275
+ var latestFetchedBlock = initialLatestFetchedBlock;
276
+ while((function () {
277
+ var tmp = false;
278
+ if (mutPendingQueries.length !== 0) {
279
+ var pq = Utils.$$Array.firstUnsafe(mutPendingQueries);
280
+ tmp = pq.fetchedBlock !== undefined && pq.fromBlock <= (latestFetchedBlock.blockNumber + 1 | 0);
281
+ }
282
+ return tmp;
283
+ })()) {
284
+ var removedQuery = mutPendingQueries.shift();
285
+ latestFetchedBlock = (
286
+ removedQuery === undefined ? undefined : Caml_option.some(removedQuery)
287
+ ).fetchedBlock;
288
+ };
289
+ return latestFetchedBlock;
290
+ }
291
+
292
+ function getPendingQueryOrThrow(p, fromBlock) {
293
+ var idxRef = 0;
294
+ var pendingQueryRef;
295
+ while(idxRef < p.mutPendingQueries.length && pendingQueryRef === undefined) {
296
+ var pq = p.mutPendingQueries[idxRef];
297
+ if (pq.fromBlock === fromBlock) {
298
+ pendingQueryRef = pq;
299
+ }
300
+ idxRef = idxRef + 1 | 0;
301
+ };
302
+ var pq$1 = pendingQueryRef;
303
+ if (pq$1 !== undefined) {
304
+ return pq$1;
75
305
  } else {
76
- rest = undefined;
306
+ return Js_exn.raiseError("Pending query not found for partition " + p.id + " fromBlock " + String(fromBlock));
77
307
  }
78
- return [
79
- {
80
- id: target.id,
81
- status: {
82
- fetchingStateId: undefined
83
- },
84
- latestFetchedBlock: latestFetchedBlock,
85
- selection: target.selection,
86
- addressesByContractName: mergedAddresses
87
- },
88
- rest
89
- ];
90
308
  }
91
309
 
310
+ function handleQueryResponse(optimizedPartitions, query, knownHeight, latestFetchedBlock) {
311
+ var partitionId = query.partitionId;
312
+ var p = Js_dict.get(optimizedPartitions.entities, partitionId);
313
+ var p$1 = p !== undefined ? p : Js_exn.raiseError("Unexpected case: Couldn't find partition " + partitionId);
314
+ var mutEntities = Utils.Dict.shallowCopy(optimizedPartitions.entities);
315
+ var pendingQuery = getPendingQueryOrThrow(p$1, query.fromBlock);
316
+ pendingQuery.fetchedBlock = latestFetchedBlock;
317
+ var blockRange = (latestFetchedBlock.blockNumber - query.fromBlock | 0) + 1 | 0;
318
+ var shouldUpdateBlockRange = false;
319
+ if (latestFetchedBlock.blockNumber > p$1.latestBlockRangeUpdateBlock) {
320
+ var queryToBlock = query.toBlock;
321
+ var tmp;
322
+ if (queryToBlock !== undefined) {
323
+ if (latestFetchedBlock.blockNumber >= queryToBlock) {
324
+ var minHistoryRange = getMinHistoryRange(p$1);
325
+ tmp = minHistoryRange !== undefined ? ((queryToBlock - query.fromBlock | 0) + 1 | 0) >= minHistoryRange : false;
326
+ } else {
327
+ tmp = true;
328
+ }
329
+ } else {
330
+ tmp = latestFetchedBlock.blockNumber < (knownHeight - 10 | 0);
331
+ }
332
+ shouldUpdateBlockRange = tmp;
333
+ }
334
+ var updatedPrevQueryRange = shouldUpdateBlockRange ? blockRange : p$1.prevQueryRange;
335
+ var updatedPrevPrevQueryRange = shouldUpdateBlockRange ? p$1.prevQueryRange : p$1.prevPrevQueryRange;
336
+ var mutPendingQueries = p$1.mutPendingQueries;
337
+ var latestFetchedBlock$1 = p$1.latestFetchedBlock;
338
+ while((function () {
339
+ var tmp = false;
340
+ if (mutPendingQueries.length !== 0) {
341
+ var pq = Utils.$$Array.firstUnsafe(mutPendingQueries);
342
+ tmp = pq.fetchedBlock !== undefined && pq.fromBlock <= (latestFetchedBlock$1.blockNumber + 1 | 0);
343
+ }
344
+ return tmp;
345
+ })()) {
346
+ var removedQuery = mutPendingQueries.shift();
347
+ latestFetchedBlock$1 = (
348
+ removedQuery === undefined ? undefined : Caml_option.some(removedQuery)
349
+ ).fetchedBlock;
350
+ };
351
+ var updatedLatestFetchedBlock = latestFetchedBlock$1;
352
+ var mergeBlock = p$1.mergeBlock;
353
+ var partitionReachedMergeBlock = mergeBlock !== undefined ? updatedLatestFetchedBlock.blockNumber >= mergeBlock : false;
354
+ if (partitionReachedMergeBlock) {
355
+ Utils.Dict.deleteInPlace(mutEntities, p$1.id);
356
+ } else {
357
+ var updatedMainPartition_id = p$1.id;
358
+ var updatedMainPartition_selection = p$1.selection;
359
+ var updatedMainPartition_addressesByContractName = p$1.addressesByContractName;
360
+ var updatedMainPartition_mergeBlock = p$1.mergeBlock;
361
+ var updatedMainPartition_dynamicContract = p$1.dynamicContract;
362
+ var updatedMainPartition_mutPendingQueries = p$1.mutPendingQueries;
363
+ var updatedMainPartition_latestBlockRangeUpdateBlock = shouldUpdateBlockRange ? latestFetchedBlock.blockNumber : p$1.latestBlockRangeUpdateBlock;
364
+ var updatedMainPartition = {
365
+ id: updatedMainPartition_id,
366
+ latestFetchedBlock: updatedLatestFetchedBlock,
367
+ selection: updatedMainPartition_selection,
368
+ addressesByContractName: updatedMainPartition_addressesByContractName,
369
+ mergeBlock: updatedMainPartition_mergeBlock,
370
+ dynamicContract: updatedMainPartition_dynamicContract,
371
+ mutPendingQueries: updatedMainPartition_mutPendingQueries,
372
+ prevQueryRange: updatedPrevQueryRange,
373
+ prevPrevQueryRange: updatedPrevPrevQueryRange,
374
+ latestBlockRangeUpdateBlock: updatedMainPartition_latestBlockRangeUpdateBlock
375
+ };
376
+ mutEntities[p$1.id] = updatedMainPartition;
377
+ }
378
+ return make(Js_dict.values(mutEntities), optimizedPartitions.maxAddrInPartition, optimizedPartitions.nextPartitionIndex, optimizedPartitions.dynamicContracts);
379
+ }
380
+
381
+ function getLatestFullyFetchedBlock(optimizedPartitions) {
382
+ var id = Belt_Array.get(optimizedPartitions.idsInAscOrder, 0);
383
+ if (id !== undefined) {
384
+ return optimizedPartitions.entities[id].latestFetchedBlock;
385
+ }
386
+
387
+ }
388
+
389
+ var OptimizedPartitions = {
390
+ count: count,
391
+ getOrThrow: getOrThrow,
392
+ mergePartitionsAtBlock: mergePartitionsAtBlock,
393
+ tooFarBlockRange: 20000,
394
+ ascSortFn: ascSortFn,
395
+ make: make,
396
+ consumeFetchedQueries: consumeFetchedQueries,
397
+ getPendingQueryOrThrow: getPendingQueryOrThrow,
398
+ handleQueryResponse: handleQueryResponse,
399
+ getLatestFullyFetchedBlock: getLatestFullyFetchedBlock
400
+ };
401
+
92
402
  function bufferBlockNumber(param) {
93
403
  var latestOnBlockBlockNumber = param.latestOnBlockBlockNumber;
94
- var latestFullyFetchedBlock = param.latestFullyFetchedBlock;
95
- if (latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber) {
96
- return latestOnBlockBlockNumber;
97
- } else {
404
+ var optimizedPartitions = param.optimizedPartitions;
405
+ var id = Belt_Array.get(optimizedPartitions.idsInAscOrder, 0);
406
+ var latestFullyFetchedBlock = id !== undefined ? optimizedPartitions.entities[id].latestFetchedBlock : undefined;
407
+ if (latestFullyFetchedBlock !== undefined && latestOnBlockBlockNumber >= latestFullyFetchedBlock.blockNumber) {
98
408
  return latestFullyFetchedBlock.blockNumber;
409
+ } else {
410
+ return latestOnBlockBlockNumber;
99
411
  }
100
412
  }
101
413
 
102
414
  function bufferBlock(param) {
103
415
  var latestOnBlockBlockNumber = param.latestOnBlockBlockNumber;
104
- var latestFullyFetchedBlock = param.latestFullyFetchedBlock;
105
- if (latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber) {
416
+ var optimizedPartitions = param.optimizedPartitions;
417
+ var id = Belt_Array.get(optimizedPartitions.idsInAscOrder, 0);
418
+ var latestFullyFetchedBlock = id !== undefined ? optimizedPartitions.entities[id].latestFetchedBlock : undefined;
419
+ if (latestFullyFetchedBlock !== undefined && latestOnBlockBlockNumber >= latestFullyFetchedBlock.blockNumber) {
420
+ return latestFullyFetchedBlock;
421
+ } else {
106
422
  return {
107
423
  blockNumber: latestOnBlockBlockNumber,
108
424
  blockTimestamp: 0
109
425
  };
110
- } else {
111
- return latestFullyFetchedBlock;
112
426
  }
113
427
  }
114
428
 
@@ -121,28 +435,29 @@ function compareBufferItem(a, b) {
121
435
  }
122
436
  }
123
437
 
124
- function updateInternal(fetchState, partitionsOpt, nextPartitionIndexOpt, indexingContractsOpt, mutItems, blockLagOpt) {
125
- var partitions = partitionsOpt !== undefined ? partitionsOpt : fetchState.partitions;
126
- var nextPartitionIndex = nextPartitionIndexOpt !== undefined ? nextPartitionIndexOpt : fetchState.nextPartitionIndex;
438
+ function numAddresses(fetchState) {
439
+ return Object.keys(fetchState.indexingContracts).length;
440
+ }
441
+
442
+ function updateInternal(fetchState, optimizedPartitionsOpt, indexingContractsOpt, mutItems, blockLagOpt, knownHeightOpt) {
443
+ var optimizedPartitions = optimizedPartitionsOpt !== undefined ? optimizedPartitionsOpt : fetchState.optimizedPartitions;
127
444
  var indexingContracts = indexingContractsOpt !== undefined ? indexingContractsOpt : fetchState.indexingContracts;
128
445
  var blockLag = blockLagOpt !== undefined ? blockLagOpt : fetchState.blockLag;
129
- var firstPartition = partitions[0];
130
- var latestFullyFetchedBlock = firstPartition.latestFetchedBlock;
131
- for(var idx = 0 ,idx_finish = partitions.length; idx < idx_finish; ++idx){
132
- var p = partitions[idx];
133
- if (latestFullyFetchedBlock.blockNumber > p.latestFetchedBlock.blockNumber) {
134
- latestFullyFetchedBlock = p.latestFetchedBlock;
135
- }
136
-
137
- }
138
- var latestFullyFetchedBlock$1 = latestFullyFetchedBlock;
446
+ var knownHeight = knownHeightOpt !== undefined ? knownHeightOpt : fetchState.knownHeight;
139
447
  var mutItemsRef = mutItems;
140
448
  var onBlockConfigs = fetchState.onBlockConfigs;
141
449
  var latestOnBlockBlockNumber;
142
450
  if (onBlockConfigs.length !== 0) {
143
451
  var mutItems$1 = mutItemsRef;
144
452
  var item = Belt_Array.get(mutItems$1 !== undefined ? mutItems$1 : fetchState.buffer, fetchState.targetBufferSize - 1 | 0);
145
- var maxBlockNumber = item !== undefined ? item.blockNumber : latestFullyFetchedBlock$1.blockNumber;
453
+ var maxBlockNumber;
454
+ if (item !== undefined) {
455
+ maxBlockNumber = item.blockNumber;
456
+ } else {
457
+ var id = Belt_Array.get(optimizedPartitions.idsInAscOrder, 0);
458
+ var latestFullyFetchedBlock = id !== undefined ? optimizedPartitions.entities[id].latestFetchedBlock : undefined;
459
+ maxBlockNumber = latestFullyFetchedBlock !== undefined ? latestFullyFetchedBlock.blockNumber : knownHeight;
460
+ }
146
461
  var mutItems$2 = mutItemsRef;
147
462
  var mutItems$3 = mutItems$2 !== undefined ? mutItems$2 : fetchState.buffer.slice(0);
148
463
  mutItemsRef = mutItems$3;
@@ -174,45 +489,43 @@ function updateInternal(fetchState, partitionsOpt, nextPartitionIndexOpt, indexi
174
489
  };
175
490
  latestOnBlockBlockNumber = latestOnBlockBlockNumber$1;
176
491
  } else {
177
- latestOnBlockBlockNumber = latestFullyFetchedBlock$1.blockNumber;
492
+ latestOnBlockBlockNumber = knownHeight;
178
493
  }
179
494
  var mutItems$4 = mutItemsRef;
180
495
  var updatedFetchState_startBlock = fetchState.startBlock;
181
496
  var updatedFetchState_endBlock = fetchState.endBlock;
182
- var updatedFetchState_maxAddrInPartition = fetchState.maxAddrInPartition;
183
497
  var updatedFetchState_normalSelection = fetchState.normalSelection;
184
498
  var updatedFetchState_contractConfigs = fetchState.contractConfigs;
185
499
  var updatedFetchState_chainId = fetchState.chainId;
186
500
  var updatedFetchState_buffer = mutItems$4 !== undefined ? mutItems$4.sort(compareBufferItem) : fetchState.buffer;
187
501
  var updatedFetchState_targetBufferSize = fetchState.targetBufferSize;
188
502
  var updatedFetchState_onBlockConfigs = fetchState.onBlockConfigs;
503
+ var updatedFetchState_firstEventBlock = fetchState.firstEventBlock;
189
504
  var updatedFetchState = {
190
- partitions: partitions,
191
- nextPartitionIndex: nextPartitionIndex,
505
+ optimizedPartitions: optimizedPartitions,
192
506
  startBlock: updatedFetchState_startBlock,
193
507
  endBlock: updatedFetchState_endBlock,
194
- maxAddrInPartition: updatedFetchState_maxAddrInPartition,
195
508
  normalSelection: updatedFetchState_normalSelection,
196
509
  indexingContracts: indexingContracts,
197
510
  contractConfigs: updatedFetchState_contractConfigs,
198
511
  chainId: updatedFetchState_chainId,
199
- latestFullyFetchedBlock: latestFullyFetchedBlock$1,
200
512
  latestOnBlockBlockNumber: latestOnBlockBlockNumber,
201
513
  blockLag: blockLag,
202
514
  buffer: updatedFetchState_buffer,
203
515
  targetBufferSize: updatedFetchState_targetBufferSize,
204
- onBlockConfigs: updatedFetchState_onBlockConfigs
516
+ onBlockConfigs: updatedFetchState_onBlockConfigs,
517
+ knownHeight: knownHeight,
518
+ firstEventBlock: updatedFetchState_firstEventBlock
205
519
  };
206
- Prometheus.IndexingPartitions.set(partitions.length, fetchState.chainId);
520
+ Prometheus.IndexingPartitions.set(optimizedPartitions.idsInAscOrder.length, fetchState.chainId);
207
521
  Prometheus.IndexingBufferSize.set(updatedFetchState_buffer.length, fetchState.chainId);
208
- Prometheus.IndexingBufferBlockNumber.set(latestOnBlockBlockNumber < latestFullyFetchedBlock$1.blockNumber ? latestOnBlockBlockNumber : latestFullyFetchedBlock$1.blockNumber, fetchState.chainId);
522
+ Prometheus.IndexingBufferBlockNumber.set(bufferBlockNumber(updatedFetchState), fetchState.chainId);
523
+ if (indexingContracts !== fetchState.indexingContracts) {
524
+ Prometheus.IndexingAddresses.set(Object.keys(indexingContracts).length, fetchState.chainId);
525
+ }
209
526
  return updatedFetchState;
210
527
  }
211
528
 
212
- function numAddresses(fetchState) {
213
- return Object.keys(fetchState.indexingContracts).length;
214
- }
215
-
216
529
  function warnDifferentContractType(fetchState, existingContract, dc) {
217
530
  var logger = Logging.createChild({
218
531
  chainId: fetchState.chainId,
@@ -223,13 +536,181 @@ function warnDifferentContractType(fetchState, existingContract, dc) {
223
536
  Logging.childWarn(logger, "Skipping contract registration: Contract address is already registered for one contract and cannot be registered for another contract.");
224
537
  }
225
538
 
539
+ function addressesByContractNameCount(addressesByContractName) {
540
+ var numAddresses = 0;
541
+ var contractNames = Object.keys(addressesByContractName);
542
+ for(var idx = 0 ,idx_finish = contractNames.length; idx < idx_finish; ++idx){
543
+ var contractName = contractNames[idx];
544
+ numAddresses = numAddresses + addressesByContractName[contractName].length | 0;
545
+ }
546
+ return numAddresses;
547
+ }
548
+
549
+ function addressesByContractNameGetAll(addressesByContractName) {
550
+ var all = [];
551
+ var contractNames = Object.keys(addressesByContractName);
552
+ for(var idx = 0 ,idx_finish = contractNames.length; idx < idx_finish; ++idx){
553
+ var contractName = contractNames[idx];
554
+ all = Belt_Array.concat(all, addressesByContractName[contractName]);
555
+ }
556
+ return all;
557
+ }
558
+
559
+ function createPartitionsFromIndexingAddresses(registeringContractsByContract, contractConfigs, dynamicContracts, normalSelection, maxAddrInPartition, nextPartitionIndex, existingPartitions, progressBlockNumber) {
560
+ var nextPartitionIndexRef = nextPartitionIndex;
561
+ var dynamicPartitions = [];
562
+ var nonDynamicPartitions = [];
563
+ var contractNames = Object.keys(registeringContractsByContract);
564
+ for(var cIdx = 0 ,cIdx_finish = contractNames.length; cIdx < cIdx_finish; ++cIdx){
565
+ var contractName = contractNames[cIdx];
566
+ var registeringContracts = registeringContractsByContract[contractName];
567
+ var addresses = Object.keys(registeringContracts);
568
+ var contractConfig = contractConfigs[contractName];
569
+ var isDynamic = dynamicContracts.has(contractName);
570
+ var partitions = isDynamic ? dynamicPartitions : nonDynamicPartitions;
571
+ var byStartBlock = {};
572
+ for(var jdx = 0 ,jdx_finish = addresses.length; jdx < jdx_finish; ++jdx){
573
+ var address = addresses[jdx];
574
+ var indexingContract = registeringContracts[address];
575
+ Utils.Dict.push(byStartBlock, String(indexingContract.startBlock), address);
576
+ }
577
+ var ascKeys = Object.keys(byStartBlock);
578
+ var initialKey = Utils.$$Array.firstUnsafe(ascKeys);
579
+ var startBlockRef = Belt_Int.fromString(initialKey);
580
+ var addressesRef = byStartBlock[initialKey];
581
+ for(var idx = 0 ,idx_finish = ascKeys.length; idx < idx_finish; ++idx){
582
+ var maybeNextStartBlockKey = ascKeys[idx + 1 | 0];
583
+ var shouldAllocateNewPartition;
584
+ if (contractConfig.filterByAddresses || maybeNextStartBlockKey === undefined) {
585
+ shouldAllocateNewPartition = true;
586
+ } else {
587
+ var nextStartBlock = Belt_Int.fromString(maybeNextStartBlockKey);
588
+ var shouldJoinCurrentStartBlock = (nextStartBlock - startBlockRef | 0) < 20000;
589
+ if (shouldJoinCurrentStartBlock) {
590
+ addressesRef = Belt_Array.concat(addressesRef, byStartBlock[maybeNextStartBlockKey]);
591
+ shouldAllocateNewPartition = false;
592
+ } else {
593
+ shouldAllocateNewPartition = true;
594
+ }
595
+ }
596
+ if (shouldAllocateNewPartition) {
597
+ var latestFetchedBlock_blockNumber = Caml.int_max(startBlockRef - 1 | 0, progressBlockNumber);
598
+ var latestFetchedBlock = {
599
+ blockNumber: latestFetchedBlock_blockNumber,
600
+ blockTimestamp: 0
601
+ };
602
+ while(addressesRef.length !== 0) {
603
+ var pAddresses = addressesRef.slice(0, maxAddrInPartition);
604
+ addressesRef = addressesRef.slice(maxAddrInPartition);
605
+ var addressesByContractName = {};
606
+ addressesByContractName[contractName] = pAddresses;
607
+ partitions.push({
608
+ id: String(nextPartitionIndexRef),
609
+ latestFetchedBlock: latestFetchedBlock,
610
+ selection: normalSelection,
611
+ addressesByContractName: addressesByContractName,
612
+ mergeBlock: undefined,
613
+ dynamicContract: isDynamic ? contractName : undefined,
614
+ mutPendingQueries: [],
615
+ prevQueryRange: 0,
616
+ prevPrevQueryRange: 0,
617
+ latestBlockRangeUpdateBlock: 0
618
+ });
619
+ nextPartitionIndexRef = nextPartitionIndexRef + 1 | 0;
620
+ };
621
+ if (maybeNextStartBlockKey !== undefined) {
622
+ startBlockRef = Belt_Int.fromString(maybeNextStartBlockKey);
623
+ addressesRef = byStartBlock[maybeNextStartBlockKey];
624
+ }
625
+
626
+ }
627
+
628
+ }
629
+ }
630
+ var mergedNonDynamic = [];
631
+ if (nonDynamicPartitions.length !== 0) {
632
+ nonDynamicPartitions.sort(ascSortFn);
633
+ var currentPRef = nonDynamicPartitions[0];
634
+ var nextIdx = 1;
635
+ while(nextIdx < nonDynamicPartitions.length) {
636
+ var nextP = nonDynamicPartitions[nextIdx];
637
+ var currentP = currentPRef;
638
+ var currentPBlock = currentP.latestFetchedBlock.blockNumber;
639
+ var nextPBlock = nextP.latestFetchedBlock.blockNumber;
640
+ var totalCount = addressesByContractNameCount(currentP.addressesByContractName) + addressesByContractNameCount(nextP.addressesByContractName) | 0;
641
+ if (totalCount > maxAddrInPartition) {
642
+ mergedNonDynamic.push(currentP);
643
+ currentPRef = nextP;
644
+ } else {
645
+ var mergedAddresses = Utils.Dict.shallowCopy(nextP.addressesByContractName);
646
+ var currentContractNames = Object.keys(currentP.addressesByContractName);
647
+ for(var jdx$1 = 0 ,jdx_finish$1 = currentContractNames.length; jdx$1 < jdx_finish$1; ++jdx$1){
648
+ var cn = currentContractNames[jdx$1];
649
+ var currentAddrs = currentP.addressesByContractName[cn];
650
+ var existingAddrs = mergedAddresses[cn];
651
+ if (existingAddrs !== undefined) {
652
+ mergedAddresses[cn] = Belt_Array.concat(existingAddrs, currentAddrs);
653
+ } else {
654
+ mergedAddresses[cn] = currentAddrs;
655
+ }
656
+ }
657
+ var nextContractName = Utils.$$Array.firstUnsafe(Object.keys(nextP.addressesByContractName));
658
+ var hasFilterByAddresses = contractConfigs[nextContractName].filterByAddresses;
659
+ var isTooFar = (currentPBlock + 20000 | 0) < nextPBlock;
660
+ if (isTooFar || hasFilterByAddresses) {
661
+ mergedNonDynamic.push({
662
+ id: currentP.id,
663
+ latestFetchedBlock: currentP.latestFetchedBlock,
664
+ selection: currentP.selection,
665
+ addressesByContractName: currentP.addressesByContractName,
666
+ mergeBlock: currentPBlock < nextPBlock ? nextPBlock : undefined,
667
+ dynamicContract: currentP.dynamicContract,
668
+ mutPendingQueries: currentP.mutPendingQueries,
669
+ prevQueryRange: currentP.prevQueryRange,
670
+ prevPrevQueryRange: currentP.prevPrevQueryRange,
671
+ latestBlockRangeUpdateBlock: currentP.latestBlockRangeUpdateBlock
672
+ });
673
+ currentPRef = {
674
+ id: nextP.id,
675
+ latestFetchedBlock: nextP.latestFetchedBlock,
676
+ selection: nextP.selection,
677
+ addressesByContractName: mergedAddresses,
678
+ mergeBlock: nextP.mergeBlock,
679
+ dynamicContract: nextP.dynamicContract,
680
+ mutPendingQueries: nextP.mutPendingQueries,
681
+ prevQueryRange: nextP.prevQueryRange,
682
+ prevPrevQueryRange: nextP.prevPrevQueryRange,
683
+ latestBlockRangeUpdateBlock: nextP.latestBlockRangeUpdateBlock
684
+ };
685
+ } else {
686
+ currentPRef = {
687
+ id: currentP.id,
688
+ latestFetchedBlock: currentP.latestFetchedBlock,
689
+ selection: currentP.selection,
690
+ addressesByContractName: mergedAddresses,
691
+ mergeBlock: currentP.mergeBlock,
692
+ dynamicContract: currentP.dynamicContract,
693
+ mutPendingQueries: currentP.mutPendingQueries,
694
+ prevQueryRange: currentP.prevQueryRange,
695
+ prevPrevQueryRange: currentP.prevPrevQueryRange,
696
+ latestBlockRangeUpdateBlock: currentP.latestBlockRangeUpdateBlock
697
+ };
698
+ }
699
+ }
700
+ nextIdx = nextIdx + 1 | 0;
701
+ };
702
+ mergedNonDynamic.push(currentPRef);
703
+ }
704
+ var mergedPartitions = mergedNonDynamic.concat(dynamicPartitions);
705
+ return make(existingPartitions.concat(mergedPartitions), maxAddrInPartition, nextPartitionIndexRef, dynamicContracts);
706
+ }
707
+
226
708
  function registerDynamicContracts(fetchState, items) {
227
709
  if (Utils.$$Array.isEmpty(fetchState.normalSelection.eventConfigs)) {
228
710
  Js_exn.raiseError("Invalid configuration. No events to fetch for the dynamic contract registration.");
229
711
  }
230
712
  var indexingContracts = fetchState.indexingContracts;
231
- var registeringContracts = {};
232
- var addressesByContractName = {};
713
+ var registeringContractsByContract = {};
233
714
  var earliestRegisteringEventBlockNumber = Infinity;
234
715
  var hasDCWithFilterByAddresses = false;
235
716
  for(var itemIdx = 0 ,itemIdx_finish = items.length; itemIdx < itemIdx_finish; ++itemIdx){
@@ -257,6 +738,7 @@ function registerDynamicContracts(fetchState, items) {
257
738
  }
258
739
  shouldRemove = true;
259
740
  } else {
741
+ var registeringContracts = Utils.Dict.getOrInsertEmptyDict(registeringContractsByContract, dc.contractName);
260
742
  var registeringContract = registeringContracts[dc.address];
261
743
  var shouldUpdate;
262
744
  if (registeringContract !== undefined) {
@@ -268,7 +750,6 @@ function registerDynamicContracts(fetchState, items) {
268
750
  }
269
751
  } else {
270
752
  hasDCWithFilterByAddresses = hasDCWithFilterByAddresses || match.filterByAddresses;
271
- Utils.Dict.push(addressesByContractName, dc.contractName, dc.address);
272
753
  shouldUpdate = true;
273
754
  }
274
755
  if (shouldUpdate) {
@@ -296,390 +777,364 @@ function registerDynamicContracts(fetchState, items) {
296
777
  }
297
778
 
298
779
  }
299
- var dcsToStore = Js_dict.values(registeringContracts);
300
- if (dcsToStore.length === 0) {
780
+ var dcContractNamesToStore = Object.keys(registeringContractsByContract);
781
+ if (dcContractNamesToStore.length === 0) {
301
782
  return fetchState;
302
783
  }
303
- var newPartitions;
304
- if (dcsToStore.length <= fetchState.maxAddrInPartition && !hasDCWithFilterByAddresses) {
305
- newPartitions = [{
306
- id: String(fetchState.nextPartitionIndex),
307
- status: {
308
- fetchingStateId: undefined
309
- },
310
- latestFetchedBlock: {
311
- blockNumber: earliestRegisteringEventBlockNumber - 1 | 0,
312
- blockTimestamp: 0
313
- },
314
- selection: fetchState.normalSelection,
315
- addressesByContractName: addressesByContractName
316
- }];
317
- } else {
318
- var partitions = [];
319
- var earliestRegisteringEventBlockNumber$1 = {
320
- contents: Infinity
321
- };
322
- var pendingAddressesByContractName = {
323
- contents: {}
324
- };
325
- var pendingCount = 0;
326
- var addPartition = function () {
327
- partitions.push({
328
- id: String(fetchState.nextPartitionIndex + partitions.length | 0),
329
- status: {
330
- fetchingStateId: undefined
331
- },
332
- latestFetchedBlock: {
333
- blockNumber: earliestRegisteringEventBlockNumber$1.contents - 1 | 0,
334
- blockTimestamp: 0
335
- },
336
- selection: fetchState.normalSelection,
337
- addressesByContractName: pendingAddressesByContractName.contents
338
- });
339
- };
340
- for(var idx$1 = 0 ,idx_finish = Object.keys(addressesByContractName).length; idx$1 < idx_finish; ++idx$1){
341
- var contractName = Object.keys(addressesByContractName)[idx$1];
342
- var addresses = addressesByContractName[contractName];
343
- var contractConfig = fetchState.contractConfigs[contractName];
344
- if (contractConfig.filterByAddresses) {
345
- var byStartBlock = {};
346
- for(var jdx = 0 ,jdx_finish = addresses.length; jdx < jdx_finish; ++jdx){
347
- var address = addresses[jdx];
348
- var indexingContract = registeringContracts[address];
349
- Utils.Dict.push(byStartBlock, String(indexingContract.startBlock), address);
350
- }
351
- Object.keys(byStartBlock).forEach((function(contractName,byStartBlock){
352
- return function (startBlockKey) {
353
- var addresses = byStartBlock[startBlockKey];
784
+ var newPartitions = [];
785
+ var newIndexingContracts = Utils.Dict.shallowCopy(indexingContracts);
786
+ var dynamicContractsRef = fetchState.optimizedPartitions.dynamicContracts;
787
+ var mutExistingPartitions = Js_dict.values(fetchState.optimizedPartitions.entities);
788
+ for(var idx$1 = 0 ,idx_finish = dcContractNamesToStore.length; idx$1 < idx_finish; ++idx$1){
789
+ var contractName = dcContractNamesToStore[idx$1];
790
+ if (!dynamicContractsRef.has(contractName)) {
791
+ dynamicContractsRef = Utils.$$Set.immutableAdd(dynamicContractsRef, contractName);
792
+ for(var idx$2 = 0 ,idx_finish$1 = mutExistingPartitions.length; idx$2 < idx_finish$1; ++idx$2){
793
+ var p = mutExistingPartitions[idx$2];
794
+ var addresses = p.addressesByContractName[contractName];
795
+ if (addresses !== undefined && p.selection.dependsOnAddresses && p.mergeBlock === undefined) {
796
+ var allPartitionContractNames = Object.keys(p.addressesByContractName);
797
+ if (allPartitionContractNames.length !== 1) {
798
+ var isFetching = p.mutPendingQueries.length !== 0;
799
+ if (!isFetching) {
800
+ var newPartitionId = String(fetchState.optimizedPartitions.nextPartitionIndex + newPartitions.length | 0);
801
+ var restAddressesByContractName = Utils.Dict.shallowCopy(p.addressesByContractName);
802
+ Utils.Dict.deleteInPlace(restAddressesByContractName, contractName);
803
+ mutExistingPartitions[idx$2] = {
804
+ id: p.id,
805
+ latestFetchedBlock: p.latestFetchedBlock,
806
+ selection: p.selection,
807
+ addressesByContractName: restAddressesByContractName,
808
+ mergeBlock: p.mergeBlock,
809
+ dynamicContract: p.dynamicContract,
810
+ mutPendingQueries: p.mutPendingQueries,
811
+ prevQueryRange: p.prevQueryRange,
812
+ prevPrevQueryRange: p.prevPrevQueryRange,
813
+ latestBlockRangeUpdateBlock: p.latestBlockRangeUpdateBlock
814
+ };
354
815
  var addressesByContractName = {};
355
816
  addressesByContractName[contractName] = addresses;
356
- partitions.push({
357
- id: String(fetchState.nextPartitionIndex + partitions.length | 0),
358
- status: {
359
- fetchingStateId: undefined
360
- },
361
- latestFetchedBlock: {
362
- blockNumber: Caml.int_max(Belt_Option.getExn(Belt_Int.fromString(startBlockKey)) - 1 | 0, 0),
363
- blockTimestamp: 0
364
- },
817
+ newPartitions.push({
818
+ id: newPartitionId,
819
+ latestFetchedBlock: p.latestFetchedBlock,
365
820
  selection: fetchState.normalSelection,
366
- addressesByContractName: addressesByContractName
821
+ addressesByContractName: addressesByContractName,
822
+ mergeBlock: undefined,
823
+ dynamicContract: contractName,
824
+ mutPendingQueries: p.mutPendingQueries,
825
+ prevQueryRange: p.prevQueryRange,
826
+ prevPrevQueryRange: p.prevPrevQueryRange,
827
+ latestBlockRangeUpdateBlock: p.latestBlockRangeUpdateBlock
367
828
  });
368
829
  }
369
- }(contractName,byStartBlock)));
370
- } else {
371
- for(var jdx$1 = 0 ,jdx_finish$1 = addresses.length; jdx$1 < jdx_finish$1; ++jdx$1){
372
- var address$1 = addresses[jdx$1];
373
- if (pendingCount === fetchState.maxAddrInPartition) {
374
- addPartition();
375
- pendingAddressesByContractName.contents = {};
376
- pendingCount = 0;
377
- earliestRegisteringEventBlockNumber$1.contents = Infinity;
830
+
831
+ } else {
832
+ mutExistingPartitions[idx$2] = {
833
+ id: p.id,
834
+ latestFetchedBlock: p.latestFetchedBlock,
835
+ selection: p.selection,
836
+ addressesByContractName: p.addressesByContractName,
837
+ mergeBlock: p.mergeBlock,
838
+ dynamicContract: contractName,
839
+ mutPendingQueries: p.mutPendingQueries,
840
+ prevQueryRange: p.prevQueryRange,
841
+ prevPrevQueryRange: p.prevPrevQueryRange,
842
+ latestBlockRangeUpdateBlock: p.latestBlockRangeUpdateBlock
843
+ };
378
844
  }
379
- var indexingContract$1 = registeringContracts[address$1];
380
- pendingCount = pendingCount + 1 | 0;
381
- Utils.Dict.push(pendingAddressesByContractName.contents, contractName, address$1);
382
- earliestRegisteringEventBlockNumber$1.contents = earliestRegisteringEventBlockNumber$1.contents < indexingContract$1.startBlock ? earliestRegisteringEventBlockNumber$1.contents : indexingContract$1.startBlock;
383
845
  }
846
+
384
847
  }
385
848
  }
386
- if (pendingCount > 0) {
387
- addPartition();
388
- }
389
- newPartitions = partitions;
849
+ var registeringContracts$1 = registeringContractsByContract[contractName];
850
+ Object.assign(newIndexingContracts, registeringContracts$1);
390
851
  }
391
- Prometheus.IndexingAddresses.set(Object.keys(fetchState.indexingContracts).length + dcsToStore.length | 0, fetchState.chainId);
392
- return updateInternal(fetchState, fetchState.partitions.concat(newPartitions), fetchState.nextPartitionIndex + newPartitions.length | 0, Object.assign(registeringContracts, indexingContracts), undefined, undefined);
852
+ var optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, fetchState.contractConfigs, dynamicContractsRef, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, fetchState.optimizedPartitions.nextPartitionIndex + newPartitions.length | 0, mutExistingPartitions.concat(newPartitions), 0);
853
+ return updateInternal(fetchState, optimizedPartitions, newIndexingContracts, undefined, undefined, undefined);
393
854
  }
394
855
 
395
- var UnexpectedPartitionNotFound = /* @__PURE__ */Caml_exceptions.create("FetchState.UnexpectedPartitionNotFound");
396
-
397
- var UnexpectedMergeQueryResponse = /* @__PURE__ */Caml_exceptions.create("FetchState.UnexpectedMergeQueryResponse");
398
-
399
856
  function handleQueryResult(fetchState, query, latestFetchedBlock, newItems) {
400
- var partitions = fetchState.partitions;
401
- var partitionId = query.partitionId;
402
- var pIndex = Belt_Array.getIndexBy(partitions, (function (p) {
403
- return p.id === partitionId;
404
- }));
405
- var tmp;
406
- if (pIndex !== undefined) {
407
- var p = partitions[pIndex];
408
- var updatedPartition_id = p.id;
409
- var updatedPartition_status = {
410
- fetchingStateId: undefined
411
- };
412
- var updatedPartition_selection = p.selection;
413
- var updatedPartition_addressesByContractName = p.addressesByContractName;
414
- var updatedPartition = {
415
- id: updatedPartition_id,
416
- status: updatedPartition_status,
417
- latestFetchedBlock: latestFetchedBlock,
418
- selection: updatedPartition_selection,
419
- addressesByContractName: updatedPartition_addressesByContractName
857
+ return updateInternal(fetchState, handleQueryResponse(fetchState.optimizedPartitions, query, fetchState.knownHeight, latestFetchedBlock), undefined, newItems.length !== 0 ? Belt_Array.concat(fetchState.buffer, newItems) : undefined, undefined, undefined);
858
+ }
859
+
860
+ function startFetchingQueries(param, queries) {
861
+ var optimizedPartitions = param.optimizedPartitions;
862
+ for(var qIdx = 0 ,qIdx_finish = queries.length; qIdx < qIdx_finish; ++qIdx){
863
+ var q = queries[qIdx];
864
+ var partitionId = q.partitionId;
865
+ var p = Js_dict.get(optimizedPartitions.entities, partitionId);
866
+ var p$1 = p !== undefined ? p : Js_exn.raiseError("Unexpected case: Couldn't find partition " + partitionId);
867
+ var pq = {
868
+ fromBlock: q.fromBlock,
869
+ toBlock: q.toBlock,
870
+ isChunk: q.isChunk,
871
+ fetchedBlock: undefined
420
872
  };
421
- var match = query.target;
422
- var exit = 0;
423
- if (typeof match !== "object" || match.TAG === "EndBlock") {
424
- exit = 1;
425
- } else {
426
- var intoPartitionId = match.intoPartitionId;
427
- var targetIndex = Belt_Array.getIndexBy(partitions, (function (p) {
428
- return p.id === intoPartitionId;
429
- }));
430
- var exit$1 = 0;
431
- if (targetIndex !== undefined && partitions[targetIndex].latestFetchedBlock.blockNumber === latestFetchedBlock.blockNumber) {
432
- var target = partitions[targetIndex];
433
- var match$1 = mergeIntoPartition(updatedPartition, target, fetchState.maxAddrInPartition);
434
- var rest = match$1[1];
435
- var updatedPartitions = Utils.$$Array.setIndexImmutable(partitions, targetIndex, match$1[0]);
436
- var updatedPartitions$1 = rest !== undefined ? (updatedPartitions[pIndex] = rest, updatedPartitions) : Utils.$$Array.removeAtIndex(updatedPartitions, pIndex);
437
- tmp = {
438
- TAG: "Ok",
439
- _0: updatedPartitions$1
440
- };
441
- } else {
442
- exit$1 = 2;
443
- }
444
- if (exit$1 === 2) {
445
- tmp = {
446
- TAG: "Ok",
447
- _0: Utils.$$Array.setIndexImmutable(partitions, pIndex, updatedPartition)
448
- };
449
- }
450
-
451
- }
452
- if (exit === 1) {
453
- tmp = {
454
- TAG: "Ok",
455
- _0: Utils.$$Array.setIndexImmutable(partitions, pIndex, updatedPartition)
456
- };
457
- }
458
-
459
- } else {
460
- tmp = {
461
- TAG: "Error",
462
- _0: {
463
- RE_EXN_ID: UnexpectedPartitionNotFound,
464
- partitionId: partitionId
873
+ var inserted = false;
874
+ var i = 0;
875
+ while(i < p$1.mutPendingQueries.length && !inserted) {
876
+ if (p$1.mutPendingQueries[i].fromBlock > q.fromBlock) {
877
+ p$1.mutPendingQueries.splice(i, 0, pq);
878
+ inserted = true;
465
879
  }
880
+ i = i + 1 | 0;
466
881
  };
467
- }
468
- return Belt_Result.map(tmp, (function (partitions) {
469
- return updateInternal(fetchState, partitions, undefined, undefined, newItems.length !== 0 ? Belt_Array.concat(fetchState.buffer, newItems) : undefined, undefined);
470
- }));
471
- }
472
-
473
- function makePartitionQuery(p, indexingContracts, endBlock, mergeTarget) {
474
- var latestFetchedBlockNumber = p.latestFetchedBlock.blockNumber;
475
- var fromBlock = latestFetchedBlockNumber !== 0 ? latestFetchedBlockNumber + 1 | 0 : 0;
476
- var tmp;
477
- var exit = 0;
478
- if (endBlock !== undefined) {
479
- if (fromBlock > endBlock) {
480
- tmp = undefined;
481
- } else if (mergeTarget !== undefined) {
482
- exit = 1;
483
- } else {
484
- tmp = {
485
- TAG: "EndBlock",
486
- toBlock: endBlock
487
- };
882
+ if (!inserted) {
883
+ p$1.mutPendingQueries.push(pq);
488
884
  }
489
- } else if (mergeTarget !== undefined) {
490
- exit = 1;
491
- } else {
492
- tmp = "Head";
493
- }
494
- if (exit === 1) {
495
- tmp = {
496
- TAG: "Merge",
497
- intoPartitionId: mergeTarget.id,
498
- toBlock: mergeTarget.latestFetchedBlock.blockNumber
499
- };
885
+
500
886
  }
501
- return Belt_Option.map(tmp, (function (target) {
502
- return {
503
- partitionId: p.id,
504
- fromBlock: fromBlock,
505
- selection: p.selection,
506
- addressesByContractName: p.addressesByContractName,
507
- target: target,
508
- indexingContracts: indexingContracts
509
- };
510
- }));
511
- }
512
-
513
- function startFetchingQueries(param, queries, stateId) {
514
- var partitions = param.partitions;
515
- Belt_Array.forEach(queries, (function (q) {
516
- var p = partitions.find(function (p) {
517
- return p.id === q.partitionId;
518
- });
519
- if (p !== undefined) {
520
- p.status.fetchingStateId = stateId;
521
- return ;
522
- } else {
523
- return Js_exn.raiseError("Unexpected case: Couldn't find partition for the fetching query");
524
- }
525
- }));
526
887
  }
527
888
 
528
- function addressesByContractNameCount(addressesByContractName) {
529
- var numAddresses = 0;
530
- var contractNames = Object.keys(addressesByContractName);
531
- for(var idx = 0 ,idx_finish = contractNames.length; idx < idx_finish; ++idx){
532
- var contractName = contractNames[idx];
533
- numAddresses = numAddresses + addressesByContractName[contractName].length | 0;
889
+ function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock, maxQueryBlockNumber, maybeChunkRange, selection, addressesByContractName, indexingContracts) {
890
+ if (rangeFromBlock > maxQueryBlockNumber) {
891
+ return ;
534
892
  }
535
- return numAddresses;
536
- }
537
-
538
- function addressesByContractNameGetAll(addressesByContractName) {
539
- var all = [];
540
- var contractNames = Object.keys(addressesByContractName);
541
- for(var idx = 0 ,idx_finish = contractNames.length; idx < idx_finish; ++idx){
542
- var contractName = contractNames[idx];
543
- all = Belt_Array.concat(all, addressesByContractName[contractName]);
893
+ if (rangeEndBlock !== undefined && rangeFromBlock > rangeEndBlock) {
894
+ return ;
544
895
  }
545
- return all;
546
- }
547
-
548
- function isFullPartition(p, maxAddrInPartition) {
549
- if (p.selection.dependsOnAddresses) {
550
- return addressesByContractNameCount(p.addressesByContractName) >= maxAddrInPartition;
551
- } else {
552
- return true;
896
+ if (maybeChunkRange !== undefined) {
897
+ var maxBlock = rangeEndBlock !== undefined ? rangeEndBlock : maxQueryBlockNumber;
898
+ var chunkSize = Js_math.ceil_int(maybeChunkRange * 1.8);
899
+ if (((rangeFromBlock + (chunkSize << 1) | 0) - 1 | 0) <= maxBlock) {
900
+ queries.push({
901
+ partitionId: partitionId,
902
+ fromBlock: rangeFromBlock,
903
+ toBlock: (rangeFromBlock + chunkSize | 0) - 1 | 0,
904
+ isChunk: true,
905
+ selection: selection,
906
+ addressesByContractName: addressesByContractName,
907
+ indexingContracts: indexingContracts
908
+ });
909
+ queries.push({
910
+ partitionId: partitionId,
911
+ fromBlock: rangeFromBlock + chunkSize | 0,
912
+ toBlock: (rangeFromBlock + (chunkSize << 1) | 0) - 1 | 0,
913
+ isChunk: true,
914
+ selection: selection,
915
+ addressesByContractName: addressesByContractName,
916
+ indexingContracts: indexingContracts
917
+ });
918
+ } else {
919
+ queries.push({
920
+ partitionId: partitionId,
921
+ fromBlock: rangeFromBlock,
922
+ toBlock: rangeEndBlock,
923
+ isChunk: rangeEndBlock !== undefined,
924
+ selection: selection,
925
+ addressesByContractName: addressesByContractName,
926
+ indexingContracts: indexingContracts
927
+ });
928
+ }
929
+ return ;
553
930
  }
931
+ queries.push({
932
+ partitionId: partitionId,
933
+ fromBlock: rangeFromBlock,
934
+ toBlock: rangeEndBlock,
935
+ isChunk: false,
936
+ selection: selection,
937
+ addressesByContractName: addressesByContractName,
938
+ indexingContracts: indexingContracts
939
+ });
554
940
  }
555
941
 
556
- function getNextQuery(param, concurrencyLimit, currentBlockHeight, stateId) {
557
- var blockLag = param.blockLag;
558
- var indexingContracts = param.indexingContracts;
559
- var maxAddrInPartition = param.maxAddrInPartition;
560
- var endBlock = param.endBlock;
561
- var partitions = param.partitions;
562
- var headBlock = currentBlockHeight - blockLag | 0;
563
- if (headBlock <= 0) {
942
+ function getNextQuery(fetchState, concurrencyLimit) {
943
+ var knownHeight = fetchState.knownHeight;
944
+ var blockLag = fetchState.blockLag;
945
+ var indexingContracts = fetchState.indexingContracts;
946
+ var optimizedPartitions = fetchState.optimizedPartitions;
947
+ var headBlockNumber = knownHeight - blockLag | 0;
948
+ if (headBlockNumber <= 0) {
564
949
  return "WaitingForNewBlock";
565
950
  }
566
951
  if (concurrencyLimit === 0) {
567
952
  return "ReachedMaxConcurrency";
568
953
  }
569
- var fullPartitions = [];
570
- var mergingPartitions = [];
571
- var areMergingPartitionsFetching = false;
572
- var mostBehindMergingPartition;
573
- var mergingPartitionTarget;
574
- var shouldWaitForNewBlock = endBlock !== undefined ? headBlock < endBlock : true;
575
- var checkIsFetchingPartition = function (p) {
576
- var fetchingStateId = p.status.fetchingStateId;
577
- if (fetchingStateId !== undefined) {
578
- return stateId <= fetchingStateId;
579
- } else {
580
- return false;
581
- }
582
- };
583
- for(var idx = 0 ,idx_finish = partitions.length; idx < idx_finish; ++idx){
584
- var p = partitions[idx];
585
- var isFetching = checkIsFetchingPartition(p);
586
- var hasReachedTheHead = p.latestFetchedBlock.blockNumber >= headBlock;
587
- if (isFetching || !hasReachedTheHead) {
954
+ var isOnBlockBehindTheHead = fetchState.latestOnBlockBlockNumber < headBlockNumber;
955
+ var endBlock = fetchState.endBlock;
956
+ var shouldWaitForNewBlock = (
957
+ endBlock !== undefined ? headBlockNumber < endBlock : true
958
+ ) && !isOnBlockBehindTheHead;
959
+ var item = Belt_Array.get(fetchState.buffer, fetchState.targetBufferSize - 1 | 0);
960
+ var maxQueryBlockNumber = item !== undefined && item.blockNumber < knownHeight ? item.blockNumber : knownHeight;
961
+ var queries = [];
962
+ var partitionsCount = optimizedPartitions.idsInAscOrder.length;
963
+ var idxRef = 0;
964
+ while(idxRef < partitionsCount) {
965
+ var idx = idxRef;
966
+ var partitionId = optimizedPartitions.idsInAscOrder[idx];
967
+ var p = optimizedPartitions.entities[partitionId];
968
+ var isBehindTheHead = p.latestFetchedBlock.blockNumber < headBlockNumber;
969
+ var hasPendingQueries = Utils.$$Array.notEmpty(p.mutPendingQueries);
970
+ if (hasPendingQueries || isBehindTheHead) {
588
971
  shouldWaitForNewBlock = false;
589
972
  }
590
- if (p.selection.dependsOnAddresses ? addressesByContractNameCount(p.addressesByContractName) >= maxAddrInPartition : true) {
591
- fullPartitions.push(p);
592
- } else {
593
- mergingPartitions.push(p);
594
- var mostBehindMergingPartition$1 = mostBehindMergingPartition;
595
- var tmp;
596
- if (mostBehindMergingPartition$1 !== undefined) {
597
- if (mostBehindMergingPartition$1.latestFetchedBlock.blockNumber === p.latestFetchedBlock.blockNumber) {
598
- tmp = mostBehindMergingPartition$1;
599
- } else if (mostBehindMergingPartition$1.latestFetchedBlock.blockNumber < p.latestFetchedBlock.blockNumber) {
600
- var mergingPartitionTarget$1 = mergingPartitionTarget;
601
- mergingPartitionTarget = mergingPartitionTarget$1 !== undefined && mergingPartitionTarget$1.latestFetchedBlock.blockNumber < p.latestFetchedBlock.blockNumber ? mergingPartitionTarget$1 : p;
602
- tmp = mostBehindMergingPartition$1;
973
+ var queryEndBlock = Utils.$$Math.minOptInt(fetchState.endBlock, p.mergeBlock);
974
+ var queryEndBlock$1 = blockLag !== 0 ? Utils.$$Math.minOptInt(headBlockNumber, queryEndBlock) : queryEndBlock;
975
+ var match = maxQueryBlockNumber < knownHeight;
976
+ var queryEndBlock$2 = queryEndBlock$1 !== undefined ? (
977
+ match ? (
978
+ maxQueryBlockNumber < queryEndBlock$1 ? maxQueryBlockNumber : queryEndBlock$1
979
+ ) : queryEndBlock$1
980
+ ) : (
981
+ match ? maxQueryBlockNumber : queryEndBlock$1
982
+ );
983
+ var maybeChunkRange = getMinHistoryRange(p);
984
+ var cursor = p.latestFetchedBlock.blockNumber + 1 | 0;
985
+ var canContinue = true;
986
+ var pqIdx = 0;
987
+ while(pqIdx < p.mutPendingQueries.length && canContinue) {
988
+ var pq = p.mutPendingQueries[pqIdx];
989
+ if (pq.fromBlock > cursor) {
990
+ var addressesByContractName = p.addressesByContractName;
991
+ var selection = p.selection;
992
+ var rangeEndBlock = Utils.$$Math.minOptInt(pq.fromBlock - 1 | 0, queryEndBlock$2);
993
+ var rangeFromBlock = cursor;
994
+ if (rangeFromBlock <= maxQueryBlockNumber) {
995
+ var exit = 0;
996
+ if (!(rangeEndBlock !== undefined && rangeFromBlock > rangeEndBlock)) {
997
+ exit = 1;
998
+ }
999
+ if (exit === 1) {
1000
+ if (maybeChunkRange !== undefined) {
1001
+ var maxBlock = rangeEndBlock !== undefined ? rangeEndBlock : maxQueryBlockNumber;
1002
+ var chunkSize = Js_math.ceil_int(maybeChunkRange * 1.8);
1003
+ if (((rangeFromBlock + (chunkSize << 1) | 0) - 1 | 0) <= maxBlock) {
1004
+ queries.push({
1005
+ partitionId: partitionId,
1006
+ fromBlock: rangeFromBlock,
1007
+ toBlock: (rangeFromBlock + chunkSize | 0) - 1 | 0,
1008
+ isChunk: true,
1009
+ selection: selection,
1010
+ addressesByContractName: addressesByContractName,
1011
+ indexingContracts: indexingContracts
1012
+ });
1013
+ queries.push({
1014
+ partitionId: partitionId,
1015
+ fromBlock: rangeFromBlock + chunkSize | 0,
1016
+ toBlock: (rangeFromBlock + (chunkSize << 1) | 0) - 1 | 0,
1017
+ isChunk: true,
1018
+ selection: selection,
1019
+ addressesByContractName: addressesByContractName,
1020
+ indexingContracts: indexingContracts
1021
+ });
1022
+ } else {
1023
+ queries.push({
1024
+ partitionId: partitionId,
1025
+ fromBlock: rangeFromBlock,
1026
+ toBlock: rangeEndBlock,
1027
+ isChunk: rangeEndBlock !== undefined,
1028
+ selection: selection,
1029
+ addressesByContractName: addressesByContractName,
1030
+ indexingContracts: indexingContracts
1031
+ });
1032
+ }
1033
+ } else {
1034
+ queries.push({
1035
+ partitionId: partitionId,
1036
+ fromBlock: rangeFromBlock,
1037
+ toBlock: rangeEndBlock,
1038
+ isChunk: false,
1039
+ selection: selection,
1040
+ addressesByContractName: addressesByContractName,
1041
+ indexingContracts: indexingContracts
1042
+ });
1043
+ }
1044
+ }
1045
+
1046
+ }
1047
+
1048
+ }
1049
+ var toBlock = pq.toBlock;
1050
+ if (toBlock !== undefined && pq.isChunk) {
1051
+ var match$1 = pq.fetchedBlock;
1052
+ if (match$1 !== undefined) {
1053
+ var blockNumber = match$1.blockNumber;
1054
+ cursor = blockNumber < toBlock ? blockNumber + 1 | 0 : toBlock + 1 | 0;
603
1055
  } else {
604
- mergingPartitionTarget = mostBehindMergingPartition$1;
605
- tmp = p;
1056
+ cursor = toBlock + 1 | 0;
606
1057
  }
607
1058
  } else {
608
- tmp = p;
609
- }
610
- mostBehindMergingPartition = tmp;
611
- if (isFetching) {
612
- areMergingPartitionsFetching = true;
1059
+ canContinue = false;
613
1060
  }
614
-
615
- }
616
- }
617
- var item = Belt_Array.get(param.buffer, param.targetBufferSize - 1 | 0);
618
- var maxQueryBlockNumber = item !== undefined && item.blockNumber < currentBlockHeight ? item.blockNumber : currentBlockHeight;
619
- var queries = [];
620
- var registerPartitionQuery = function (p, mergeTarget) {
621
- if (!(!checkIsFetchingPartition(p) && p.latestFetchedBlock.blockNumber < maxQueryBlockNumber)) {
622
- return ;
623
- }
624
- var endBlock$1 = blockLag !== 0 ? (
625
- endBlock !== undefined ? (
626
- headBlock < endBlock ? headBlock : endBlock
627
- ) : headBlock
628
- ) : endBlock;
629
- var match = maxQueryBlockNumber < currentBlockHeight;
630
- var endBlock$2 = endBlock$1 !== undefined ? (
631
- match ? (
632
- maxQueryBlockNumber < endBlock$1 ? maxQueryBlockNumber : endBlock$1
633
- ) : endBlock$1
634
- ) : (
635
- match ? maxQueryBlockNumber : endBlock$1
636
- );
637
- var q = makePartitionQuery(p, indexingContracts, endBlock$2, mergeTarget);
638
- if (q !== undefined) {
639
- queries.push(q);
640
- return ;
641
- }
642
-
643
- };
644
- Belt_Array.forEach(fullPartitions, (function (p) {
645
- registerPartitionQuery(p, undefined);
646
- }));
647
- if (!areMergingPartitionsFetching) {
648
- var len = mergingPartitions.length;
649
- if (len !== 1) {
650
- if (len !== 0) {
651
- var match = mostBehindMergingPartition;
652
- var match$1 = mergingPartitionTarget;
653
- if (match !== undefined) {
654
- if (match$1 !== undefined) {
655
- registerPartitionQuery(match, match$1);
1061
+ pqIdx = pqIdx + 1 | 0;
1062
+ };
1063
+ if (canContinue) {
1064
+ var addressesByContractName$1 = p.addressesByContractName;
1065
+ var selection$1 = p.selection;
1066
+ var rangeFromBlock$1 = cursor;
1067
+ if (rangeFromBlock$1 <= maxQueryBlockNumber) {
1068
+ var exit$1 = 0;
1069
+ if (!(queryEndBlock$2 !== undefined && rangeFromBlock$1 > queryEndBlock$2)) {
1070
+ exit$1 = 1;
1071
+ }
1072
+ if (exit$1 === 1) {
1073
+ if (maybeChunkRange !== undefined) {
1074
+ var maxBlock$1 = queryEndBlock$2 !== undefined ? queryEndBlock$2 : maxQueryBlockNumber;
1075
+ var chunkSize$1 = Js_math.ceil_int(maybeChunkRange * 1.8);
1076
+ if (((rangeFromBlock$1 + (chunkSize$1 << 1) | 0) - 1 | 0) <= maxBlock$1) {
1077
+ queries.push({
1078
+ partitionId: partitionId,
1079
+ fromBlock: rangeFromBlock$1,
1080
+ toBlock: (rangeFromBlock$1 + chunkSize$1 | 0) - 1 | 0,
1081
+ isChunk: true,
1082
+ selection: selection$1,
1083
+ addressesByContractName: addressesByContractName$1,
1084
+ indexingContracts: indexingContracts
1085
+ });
1086
+ queries.push({
1087
+ partitionId: partitionId,
1088
+ fromBlock: rangeFromBlock$1 + chunkSize$1 | 0,
1089
+ toBlock: (rangeFromBlock$1 + (chunkSize$1 << 1) | 0) - 1 | 0,
1090
+ isChunk: true,
1091
+ selection: selection$1,
1092
+ addressesByContractName: addressesByContractName$1,
1093
+ indexingContracts: indexingContracts
1094
+ });
1095
+ } else {
1096
+ queries.push({
1097
+ partitionId: partitionId,
1098
+ fromBlock: rangeFromBlock$1,
1099
+ toBlock: queryEndBlock$2,
1100
+ isChunk: queryEndBlock$2 !== undefined,
1101
+ selection: selection$1,
1102
+ addressesByContractName: addressesByContractName$1,
1103
+ indexingContracts: indexingContracts
1104
+ });
1105
+ }
656
1106
  } else {
657
- registerPartitionQuery(match, undefined);
1107
+ queries.push({
1108
+ partitionId: partitionId,
1109
+ fromBlock: rangeFromBlock$1,
1110
+ toBlock: queryEndBlock$2,
1111
+ isChunk: false,
1112
+ selection: selection$1,
1113
+ addressesByContractName: addressesByContractName$1,
1114
+ indexingContracts: indexingContracts
1115
+ });
658
1116
  }
659
- } else {
660
- Js_exn.raiseError("Unexpected case, should always have a most behind partition.");
661
1117
  }
1118
+
662
1119
  }
663
1120
 
664
- } else {
665
- var p$1 = mergingPartitions[0];
666
- registerPartitionQuery(p$1, undefined);
667
1121
  }
668
- }
1122
+ idxRef = idxRef + 1 | 0;
1123
+ };
669
1124
  if (Utils.$$Array.isEmpty(queries)) {
670
1125
  if (shouldWaitForNewBlock) {
671
1126
  return "WaitingForNewBlock";
672
1127
  } else {
673
1128
  return "NothingToQuery";
674
1129
  }
675
- } else {
676
- return {
677
- TAG: "Ready",
678
- _0: queries.length > concurrencyLimit ? queries.sort(function (a, b) {
679
- return a.fromBlock - b.fromBlock | 0;
680
- }).slice(0, concurrencyLimit) : queries
681
- };
682
1130
  }
1131
+ var queries$1 = queries.length > concurrencyLimit ? (queries.sort(function (a, b) {
1132
+ return a.fromBlock - b.fromBlock | 0;
1133
+ }), queries.slice(0, concurrencyLimit)) : queries;
1134
+ return {
1135
+ TAG: "Ready",
1136
+ _0: queries$1
1137
+ };
683
1138
  }
684
1139
 
685
1140
  function getTimestampAt(fetchState, index) {
@@ -690,33 +1145,22 @@ function getTimestampAt(fetchState, index) {
690
1145
  } else {
691
1146
  return Js_exn.raiseError("Block handlers are not supported for ordered multichain mode.");
692
1147
  }
1148
+ } else {
1149
+ return bufferBlock(fetchState).blockTimestamp;
693
1150
  }
694
- var latestOnBlockBlockNumber = fetchState.latestOnBlockBlockNumber;
695
- var latestFullyFetchedBlock = fetchState.latestFullyFetchedBlock;
696
- return (
697
- latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber ? ({
698
- blockNumber: latestOnBlockBlockNumber,
699
- blockTimestamp: 0
700
- }) : latestFullyFetchedBlock
701
- ).blockTimestamp;
702
1151
  }
703
1152
 
704
1153
  function hasReadyItem(fetchState) {
705
1154
  var item = Belt_Array.get(fetchState.buffer, 0);
706
- if (item === undefined) {
1155
+ if (item !== undefined) {
1156
+ return item.blockNumber <= bufferBlockNumber(fetchState);
1157
+ } else {
707
1158
  return false;
708
1159
  }
709
- var latestOnBlockBlockNumber = fetchState.latestOnBlockBlockNumber;
710
- var latestFullyFetchedBlock = fetchState.latestFullyFetchedBlock;
711
- return item.blockNumber <= (
712
- latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber ? latestOnBlockBlockNumber : latestFullyFetchedBlock.blockNumber
713
- );
714
1160
  }
715
1161
 
716
1162
  function getReadyItemsCount(fetchState, targetSize, fromItem) {
717
- var latestOnBlockBlockNumber = fetchState.latestOnBlockBlockNumber;
718
- var latestFullyFetchedBlock = fetchState.latestFullyFetchedBlock;
719
- var readyBlockNumber = latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber ? latestOnBlockBlockNumber : latestFullyFetchedBlock.blockNumber;
1163
+ var readyBlockNumber = bufferBlockNumber(fetchState);
720
1164
  var acc = 0;
721
1165
  var isFinished = false;
722
1166
  while(!isFinished) {
@@ -739,10 +1183,11 @@ function getReadyItemsCount(fetchState, targetSize, fromItem) {
739
1183
  return acc;
740
1184
  }
741
1185
 
742
- function make(startBlock, endBlock, eventConfigs, contracts, maxAddrInPartition, chainId, targetBufferSize, progressBlockNumberOpt, onBlockConfigsOpt, blockLagOpt) {
1186
+ function make$1(startBlock, endBlock, eventConfigs, contracts, maxAddrInPartition, chainId, targetBufferSize, knownHeight, progressBlockNumberOpt, onBlockConfigsOpt, blockLagOpt, firstEventBlockOpt) {
743
1187
  var progressBlockNumber = progressBlockNumberOpt !== undefined ? progressBlockNumberOpt : startBlock - 1 | 0;
744
1188
  var onBlockConfigs = onBlockConfigsOpt !== undefined ? onBlockConfigsOpt : [];
745
1189
  var blockLag = blockLagOpt !== undefined ? blockLagOpt : 0;
1190
+ var firstEventBlock = firstEventBlockOpt !== undefined ? Caml_option.valFromOption(firstEventBlockOpt) : undefined;
746
1191
  var latestFetchedBlock = {
747
1192
  blockNumber: progressBlockNumber,
748
1193
  blockTimestamp: 0
@@ -774,83 +1219,69 @@ function make(startBlock, endBlock, eventConfigs, contracts, maxAddrInPartition,
774
1219
  if (notDependingOnAddresses.length !== 0) {
775
1220
  partitions.push({
776
1221
  id: String(partitions.length),
777
- status: {
778
- fetchingStateId: undefined
779
- },
780
1222
  latestFetchedBlock: latestFetchedBlock,
781
1223
  selection: {
782
1224
  eventConfigs: notDependingOnAddresses,
783
1225
  dependsOnAddresses: false
784
1226
  },
785
- addressesByContractName: {}
1227
+ addressesByContractName: {},
1228
+ mergeBlock: undefined,
1229
+ dynamicContract: undefined,
1230
+ mutPendingQueries: [],
1231
+ prevQueryRange: 0,
1232
+ prevPrevQueryRange: 0,
1233
+ latestBlockRangeUpdateBlock: 0
786
1234
  });
787
1235
  }
788
1236
  var normalSelection = {
789
1237
  eventConfigs: normalEventConfigs,
790
1238
  dependsOnAddresses: true
791
1239
  };
1240
+ var registeringContractsByContract = {};
1241
+ var dynamicContracts = new Set();
792
1242
  if (normalEventConfigs.length !== 0) {
793
- var makePendingNormalPartition = function () {
794
- return {
795
- id: String(partitions.length),
796
- status: {
797
- fetchingStateId: undefined
798
- },
799
- latestFetchedBlock: latestFetchedBlock,
800
- selection: normalSelection,
801
- addressesByContractName: {}
802
- };
803
- };
804
- var pendingNormalPartition = {
805
- contents: makePendingNormalPartition()
806
- };
807
1243
  Belt_Array.forEach(contracts, (function (contract) {
808
1244
  var contractName = contract.contractName;
809
1245
  if (!contractNamesWithNormalEvents.has(contractName)) {
810
1246
  return ;
811
1247
  }
812
- var pendingPartition = pendingNormalPartition.contents;
813
- Utils.Dict.push(pendingPartition.addressesByContractName, contractName, contract.address);
1248
+ var registeringContracts = Utils.Dict.getOrInsertEmptyDict(registeringContractsByContract, contractName);
1249
+ registeringContracts[contract.address] = contract;
814
1250
  indexingContracts[contract.address] = contract;
815
- if (addressesByContractNameCount(pendingPartition.addressesByContractName) === maxAddrInPartition) {
816
- partitions.push(pendingPartition);
817
- pendingNormalPartition.contents = makePendingNormalPartition();
1251
+ if (contract.registrationBlock !== undefined) {
1252
+ dynamicContracts.add(contractName);
818
1253
  return ;
819
1254
  }
820
1255
 
821
1256
  }));
822
- if (addressesByContractNameCount(pendingNormalPartition.contents.addressesByContractName) > 0) {
823
- partitions.push(pendingNormalPartition.contents);
824
- }
825
-
826
1257
  }
827
- if (partitions.length === 0) {
828
- Js_exn.raiseError("Invalid configuration: Nothing to fetch. Make sure that you provided at least one contract address to index, or have events with Wildcard mode enabled.");
1258
+ var optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, contractConfigs, dynamicContracts, normalSelection, maxAddrInPartition, partitions.length, partitions, progressBlockNumber);
1259
+ if (optimizedPartitions.idsInAscOrder.length === 0 && Utils.$$Array.isEmpty(onBlockConfigs)) {
1260
+ Js_exn.raiseError("Invalid configuration: Nothing to fetch. Make sure that you provided at least one contract address to index, or have events with Wildcard mode enabled, or have onBlock handlers.");
829
1261
  }
830
1262
  var numAddresses = Object.keys(indexingContracts).length;
831
1263
  Prometheus.IndexingAddresses.set(numAddresses, chainId);
832
- Prometheus.IndexingPartitions.set(partitions.length, chainId);
1264
+ Prometheus.IndexingPartitions.set(optimizedPartitions.idsInAscOrder.length, chainId);
833
1265
  Prometheus.IndexingBufferSize.set(0, chainId);
834
1266
  Prometheus.IndexingBufferBlockNumber.set(progressBlockNumber, chainId);
835
1267
  if (endBlock !== undefined) {
836
1268
  Prometheus.IndexingEndBlock.set(endBlock, chainId);
837
1269
  }
838
1270
  return {
839
- partitions: partitions,
840
- nextPartitionIndex: partitions.length,
1271
+ optimizedPartitions: optimizedPartitions,
841
1272
  startBlock: startBlock,
842
1273
  endBlock: endBlock,
843
- maxAddrInPartition: maxAddrInPartition,
844
1274
  normalSelection: normalSelection,
845
1275
  indexingContracts: indexingContracts,
846
1276
  contractConfigs: contractConfigs,
847
1277
  chainId: chainId,
848
- latestFullyFetchedBlock: latestFetchedBlock,
849
1278
  latestOnBlockBlockNumber: progressBlockNumber,
850
1279
  blockLag: blockLag,
851
1280
  buffer: [],
852
1281
  targetBufferSize: targetBufferSize,
853
- onBlockConfigs: onBlockConfigs
1282
+ onBlockConfigs: onBlockConfigs,
1283
+ knownHeight: knownHeight,
1284
+ firstEventBlock: firstEventBlock
854
1285
  };
855
1286
  }
856
1287
 
@@ -858,47 +1289,33 @@ function bufferSize(param) {
858
1289
  return param.buffer.length;
859
1290
  }
860
1291
 
861
- function rollbackPartition(p, targetBlockNumber, addressesToRemove) {
862
- var shouldRollbackFetched = p.latestFetchedBlock.blockNumber > targetBlockNumber;
863
- var latestFetchedBlock = shouldRollbackFetched ? ({
864
- blockNumber: targetBlockNumber,
865
- blockTimestamp: 0
866
- }) : p.latestFetchedBlock;
867
- if (!p.selection.dependsOnAddresses) {
868
- return {
869
- id: p.id,
870
- status: {
871
- fetchingStateId: undefined
872
- },
873
- latestFetchedBlock: latestFetchedBlock,
874
- selection: p.selection,
875
- addressesByContractName: p.addressesByContractName
876
- };
877
- }
878
- var rollbackedAddressesByContractName = {};
879
- Utils.Dict.forEachWithKey(p.addressesByContractName, (function (addresses, contractName) {
880
- var keptAddresses = Belt_Array.keep(addresses, (function (address) {
881
- return !addressesToRemove.has(address);
882
- }));
883
- if (keptAddresses.length !== 0) {
884
- rollbackedAddressesByContractName[contractName] = keptAddresses;
885
- return ;
886
- }
887
-
888
- }));
889
- if (Object.keys(rollbackedAddressesByContractName).length === 0) {
890
- return ;
891
- } else {
892
- return {
893
- id: p.id,
894
- status: {
895
- fetchingStateId: undefined
896
- },
897
- latestFetchedBlock: latestFetchedBlock,
898
- selection: p.selection,
899
- addressesByContractName: rollbackedAddressesByContractName
900
- };
1292
+ function rollbackPendingQueries(mutPendingQueries, targetBlockNumber) {
1293
+ var adjusted = [];
1294
+ for(var qIdx = 0 ,qIdx_finish = mutPendingQueries.length; qIdx < qIdx_finish; ++qIdx){
1295
+ var pq = mutPendingQueries[qIdx];
1296
+ if (pq.fromBlock <= targetBlockNumber) {
1297
+ var match = pq.fetchedBlock;
1298
+ if (match !== undefined) {
1299
+ if (match.blockNumber > targetBlockNumber) {
1300
+ adjusted.push({
1301
+ fromBlock: pq.fromBlock,
1302
+ toBlock: pq.toBlock,
1303
+ isChunk: pq.isChunk,
1304
+ fetchedBlock: {
1305
+ blockNumber: targetBlockNumber,
1306
+ blockTimestamp: 0
1307
+ }
1308
+ });
1309
+ } else {
1310
+ adjusted.push(pq);
1311
+ }
1312
+ } else {
1313
+ Js_exn.raiseError("Internal error: Must not have a fetching query during rollback");
1314
+ }
1315
+ }
1316
+
901
1317
  }
1318
+ return adjusted;
902
1319
  }
903
1320
 
904
1321
  function rollback(fetchState, targetBlockNumber) {
@@ -913,30 +1330,147 @@ function rollback(fetchState, targetBlockNumber) {
913
1330
  indexingContracts[address] = indexingContract;
914
1331
  }
915
1332
  }));
916
- var partitions = Belt_Array.keepMap(fetchState.partitions, (function (p) {
917
- return rollbackPartition(p, targetBlockNumber, addressesToRemove);
918
- }));
1333
+ var keptPartitions = [];
1334
+ var nextKeptIdRef = 0;
1335
+ var registeringContractsByContract = {};
1336
+ var partitions = Js_dict.values(fetchState.optimizedPartitions.entities);
1337
+ for(var idx = 0 ,idx_finish = partitions.length; idx < idx_finish; ++idx){
1338
+ var p = partitions[idx];
1339
+ if (p.selection.dependsOnAddresses) {
1340
+ if (p.latestFetchedBlock.blockNumber > targetBlockNumber) {
1341
+ Utils.Dict.forEachWithKey(p.addressesByContractName, (function (addresses, contractName) {
1342
+ Belt_Array.forEach(addresses, (function (address) {
1343
+ if (!(!addressesToRemove.has(address) && Belt_Option.isSome(indexingContracts[address]))) {
1344
+ return ;
1345
+ }
1346
+ var registeringContracts = Utils.Dict.getOrInsertEmptyDict(registeringContractsByContract, contractName);
1347
+ registeringContracts[address] = indexingContracts[address];
1348
+ }));
1349
+ }));
1350
+ } else {
1351
+ var mergeBlock = p.mergeBlock;
1352
+ var mergeBlock$1 = mergeBlock !== undefined && mergeBlock > targetBlockNumber ? targetBlockNumber : mergeBlock;
1353
+ var rollbackedAddressesByContractName = {};
1354
+ Utils.Dict.forEachWithKey(p.addressesByContractName, (function(rollbackedAddressesByContractName){
1355
+ return function (addresses, contractName) {
1356
+ var keptAddresses = Belt_Array.keep(addresses, (function (address) {
1357
+ return !addressesToRemove.has(address);
1358
+ }));
1359
+ if (keptAddresses.length !== 0) {
1360
+ rollbackedAddressesByContractName[contractName] = keptAddresses;
1361
+ return ;
1362
+ }
1363
+
1364
+ }
1365
+ }(rollbackedAddressesByContractName)));
1366
+ if (Object.keys(rollbackedAddressesByContractName).length !== 0) {
1367
+ var id = String(nextKeptIdRef);
1368
+ nextKeptIdRef = nextKeptIdRef + 1 | 0;
1369
+ keptPartitions.push({
1370
+ id: id,
1371
+ latestFetchedBlock: p.latestFetchedBlock,
1372
+ selection: p.selection,
1373
+ addressesByContractName: rollbackedAddressesByContractName,
1374
+ mergeBlock: mergeBlock$1,
1375
+ dynamicContract: p.dynamicContract,
1376
+ mutPendingQueries: rollbackPendingQueries(p.mutPendingQueries, targetBlockNumber),
1377
+ prevQueryRange: p.prevQueryRange,
1378
+ prevPrevQueryRange: p.prevPrevQueryRange,
1379
+ latestBlockRangeUpdateBlock: p.latestBlockRangeUpdateBlock
1380
+ });
1381
+ }
1382
+
1383
+ }
1384
+ } else {
1385
+ var id$1 = String(nextKeptIdRef);
1386
+ nextKeptIdRef = nextKeptIdRef + 1 | 0;
1387
+ keptPartitions.push({
1388
+ id: id$1,
1389
+ latestFetchedBlock: p.latestFetchedBlock.blockNumber > targetBlockNumber ? ({
1390
+ blockNumber: targetBlockNumber,
1391
+ blockTimestamp: 0
1392
+ }) : p.latestFetchedBlock,
1393
+ selection: p.selection,
1394
+ addressesByContractName: p.addressesByContractName,
1395
+ mergeBlock: p.mergeBlock,
1396
+ dynamicContract: p.dynamicContract,
1397
+ mutPendingQueries: rollbackPendingQueries(p.mutPendingQueries, targetBlockNumber),
1398
+ prevQueryRange: p.prevQueryRange,
1399
+ prevPrevQueryRange: p.prevPrevQueryRange,
1400
+ latestBlockRangeUpdateBlock: p.latestBlockRangeUpdateBlock
1401
+ });
1402
+ }
1403
+ }
1404
+ var optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, fetchState.contractConfigs, fetchState.optimizedPartitions.dynamicContracts, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, nextKeptIdRef, keptPartitions, targetBlockNumber);
919
1405
  return updateInternal({
920
- partitions: fetchState.partitions,
921
- nextPartitionIndex: fetchState.nextPartitionIndex,
1406
+ optimizedPartitions: fetchState.optimizedPartitions,
922
1407
  startBlock: fetchState.startBlock,
923
1408
  endBlock: fetchState.endBlock,
924
- maxAddrInPartition: fetchState.maxAddrInPartition,
925
1409
  normalSelection: fetchState.normalSelection,
926
1410
  indexingContracts: fetchState.indexingContracts,
927
1411
  contractConfigs: fetchState.contractConfigs,
928
1412
  chainId: fetchState.chainId,
929
- latestFullyFetchedBlock: fetchState.latestFullyFetchedBlock,
930
- latestOnBlockBlockNumber: targetBlockNumber,
1413
+ latestOnBlockBlockNumber: fetchState.latestOnBlockBlockNumber < targetBlockNumber ? fetchState.latestOnBlockBlockNumber : targetBlockNumber,
931
1414
  blockLag: fetchState.blockLag,
932
1415
  buffer: fetchState.buffer,
933
1416
  targetBufferSize: fetchState.targetBufferSize,
934
- onBlockConfigs: fetchState.onBlockConfigs
935
- }, partitions, undefined, indexingContracts, Belt_Array.keep(fetchState.buffer, (function (item) {
1417
+ onBlockConfigs: fetchState.onBlockConfigs,
1418
+ knownHeight: fetchState.knownHeight,
1419
+ firstEventBlock: fetchState.firstEventBlock
1420
+ }, optimizedPartitions, indexingContracts, Belt_Array.keep(fetchState.buffer, (function (item) {
936
1421
  var tmp;
937
1422
  tmp = item.kind === 0 ? item.blockNumber : item.blockNumber;
938
1423
  return tmp <= targetBlockNumber;
939
- })), undefined);
1424
+ })), undefined, undefined);
1425
+ }
1426
+
1427
+ function resetPendingQueries(fetchState) {
1428
+ var newEntities = Utils.Dict.shallowCopy(fetchState.optimizedPartitions.entities);
1429
+ for(var idx = 0 ,idx_finish = fetchState.optimizedPartitions.idsInAscOrder.length; idx < idx_finish; ++idx){
1430
+ var partitionId = fetchState.optimizedPartitions.idsInAscOrder[idx];
1431
+ var partition = fetchState.optimizedPartitions.entities[partitionId];
1432
+ if (partition.mutPendingQueries.length !== 0) {
1433
+ var kept = Belt_Array.keep(partition.mutPendingQueries, (function (pq) {
1434
+ return pq.fetchedBlock !== undefined;
1435
+ }));
1436
+ newEntities[partitionId] = {
1437
+ id: partition.id,
1438
+ latestFetchedBlock: partition.latestFetchedBlock,
1439
+ selection: partition.selection,
1440
+ addressesByContractName: partition.addressesByContractName,
1441
+ mergeBlock: partition.mergeBlock,
1442
+ dynamicContract: partition.dynamicContract,
1443
+ mutPendingQueries: kept,
1444
+ prevQueryRange: partition.prevQueryRange,
1445
+ prevPrevQueryRange: partition.prevPrevQueryRange,
1446
+ latestBlockRangeUpdateBlock: partition.latestBlockRangeUpdateBlock
1447
+ };
1448
+ }
1449
+
1450
+ }
1451
+ var init = fetchState.optimizedPartitions;
1452
+ return {
1453
+ optimizedPartitions: {
1454
+ idsInAscOrder: init.idsInAscOrder,
1455
+ entities: newEntities,
1456
+ maxAddrInPartition: init.maxAddrInPartition,
1457
+ nextPartitionIndex: init.nextPartitionIndex,
1458
+ dynamicContracts: init.dynamicContracts
1459
+ },
1460
+ startBlock: fetchState.startBlock,
1461
+ endBlock: fetchState.endBlock,
1462
+ normalSelection: fetchState.normalSelection,
1463
+ indexingContracts: fetchState.indexingContracts,
1464
+ contractConfigs: fetchState.contractConfigs,
1465
+ chainId: fetchState.chainId,
1466
+ latestOnBlockBlockNumber: fetchState.latestOnBlockBlockNumber,
1467
+ blockLag: fetchState.blockLag,
1468
+ buffer: fetchState.buffer,
1469
+ targetBufferSize: fetchState.targetBufferSize,
1470
+ onBlockConfigs: fetchState.onBlockConfigs,
1471
+ knownHeight: fetchState.knownHeight,
1472
+ firstEventBlock: fetchState.firstEventBlock
1473
+ };
940
1474
  }
941
1475
 
942
1476
  function isActivelyIndexing(fetchState) {
@@ -944,11 +1478,7 @@ function isActivelyIndexing(fetchState) {
944
1478
  if (endBlock === undefined) {
945
1479
  return true;
946
1480
  }
947
- var latestOnBlockBlockNumber = fetchState.latestOnBlockBlockNumber;
948
- var latestFullyFetchedBlock = fetchState.latestFullyFetchedBlock;
949
- var isPastEndblock = (
950
- latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber ? latestOnBlockBlockNumber : latestFullyFetchedBlock.blockNumber
951
- ) >= endBlock;
1481
+ var isPastEndblock = bufferBlockNumber(fetchState) >= endBlock;
952
1482
  if (isPastEndblock) {
953
1483
  return bufferSize(fetchState) > 0;
954
1484
  } else {
@@ -956,14 +1486,13 @@ function isActivelyIndexing(fetchState) {
956
1486
  }
957
1487
  }
958
1488
 
959
- function isReadyToEnterReorgThreshold(fetchState, currentBlockHeight) {
1489
+ function isReadyToEnterReorgThreshold(fetchState) {
1490
+ var knownHeight = fetchState.knownHeight;
960
1491
  var blockLag = fetchState.blockLag;
961
1492
  var endBlock = fetchState.endBlock;
962
- var latestOnBlockBlockNumber = fetchState.latestOnBlockBlockNumber;
963
- var latestFullyFetchedBlock = fetchState.latestFullyFetchedBlock;
964
- var bufferBlockNumber = latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber ? latestOnBlockBlockNumber : latestFullyFetchedBlock.blockNumber;
965
- if (currentBlockHeight !== 0 && (
966
- endBlock !== undefined && bufferBlockNumber >= endBlock ? true : bufferBlockNumber >= (currentBlockHeight - blockLag | 0)
1493
+ var bufferBlockNumber$1 = bufferBlockNumber(fetchState);
1494
+ if (knownHeight !== 0 && (
1495
+ endBlock !== undefined && bufferBlockNumber$1 >= endBlock ? true : bufferBlockNumber$1 >= (knownHeight - blockLag | 0)
967
1496
  )) {
968
1497
  return Utils.$$Array.isEmpty(fetchState.buffer);
969
1498
  } else {
@@ -973,109 +1502,103 @@ function isReadyToEnterReorgThreshold(fetchState, currentBlockHeight) {
973
1502
 
974
1503
  function hasFullBatch(fetchState, batchSizeTarget) {
975
1504
  var item = Belt_Array.get(fetchState.buffer, batchSizeTarget - 1 | 0);
976
- if (item === undefined) {
1505
+ if (item !== undefined) {
1506
+ return item.blockNumber <= bufferBlockNumber(fetchState);
1507
+ } else {
977
1508
  return false;
978
1509
  }
979
- var latestOnBlockBlockNumber = fetchState.latestOnBlockBlockNumber;
980
- var latestFullyFetchedBlock = fetchState.latestFullyFetchedBlock;
981
- return item.blockNumber <= (
982
- latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber ? latestOnBlockBlockNumber : latestFullyFetchedBlock.blockNumber
983
- );
1510
+ }
1511
+
1512
+ function getProgressPercentage(fetchState) {
1513
+ var firstEventBlock = fetchState.firstEventBlock;
1514
+ if (firstEventBlock === undefined) {
1515
+ return 0;
1516
+ }
1517
+ var totalRange = fetchState.knownHeight - firstEventBlock | 0;
1518
+ if (totalRange <= 0) {
1519
+ return 0;
1520
+ }
1521
+ var item = Belt_Array.get(fetchState.buffer, 0);
1522
+ var progress = item !== undefined ? item.blockNumber - firstEventBlock | 0 : bufferBlockNumber(fetchState) - firstEventBlock | 0;
1523
+ return progress / totalRange;
984
1524
  }
985
1525
 
986
1526
  function sortForUnorderedBatch(fetchStates, batchSizeTarget) {
987
1527
  return fetchStates.slice(0).sort(function (a, b) {
988
1528
  var match = hasFullBatch(a, batchSizeTarget);
989
1529
  var match$1 = hasFullBatch(b, batchSizeTarget);
990
- var exit = 0;
991
1530
  if (match) {
992
1531
  if (!match$1) {
993
1532
  return -1;
994
1533
  }
995
- exit = 1;
996
- } else {
997
- if (match$1) {
998
- return 1;
999
- }
1000
- exit = 1;
1001
- }
1002
- if (exit === 1) {
1003
- var match$2 = Belt_Array.get(a.buffer, 0);
1004
- var match$3 = Belt_Array.get(b.buffer, 0);
1005
- var exit$1 = 0;
1006
- if (match$2 !== undefined) {
1007
- if (match$2.kind !== 0) {
1008
- return Js_math.random_int(-1, 1);
1009
- }
1010
- if (match$3 === undefined) {
1011
- return -1;
1012
- }
1013
- if (match$3.kind === 0) {
1014
- return match$2.timestamp - match$3.timestamp | 0;
1015
- }
1016
- exit$1 = 2;
1017
- } else {
1018
- if (match$3 === undefined) {
1019
- return 0;
1020
- }
1021
- exit$1 = 2;
1022
- }
1023
- if (exit$1 === 2) {
1024
- if (match$3.kind === 0) {
1025
- return 1;
1026
- } else {
1027
- return Js_math.random_int(-1, 1);
1028
- }
1029
- }
1030
1534
 
1535
+ } else if (match$1) {
1536
+ return 1;
1537
+ }
1538
+ var aProgress = getProgressPercentage(a);
1539
+ var bProgress = getProgressPercentage(b);
1540
+ if (aProgress < bProgress) {
1541
+ return -1;
1542
+ } else if (aProgress > bProgress) {
1543
+ return 1;
1544
+ } else {
1545
+ return 0;
1031
1546
  }
1032
-
1033
1547
  });
1034
1548
  }
1035
1549
 
1036
1550
  function getUnorderedMultichainProgressBlockNumberAt(fetchState, index) {
1037
- var latestOnBlockBlockNumber = fetchState.latestOnBlockBlockNumber;
1038
- var latestFullyFetchedBlock = fetchState.latestFullyFetchedBlock;
1039
- var bufferBlockNumber = latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber ? latestOnBlockBlockNumber : latestFullyFetchedBlock.blockNumber;
1551
+ var bufferBlockNumber$1 = bufferBlockNumber(fetchState);
1040
1552
  var item = Belt_Array.get(fetchState.buffer, index);
1041
- if (item !== undefined && bufferBlockNumber >= item.blockNumber) {
1553
+ if (item !== undefined && bufferBlockNumber$1 >= item.blockNumber) {
1042
1554
  return item.blockNumber - 1 | 0;
1043
1555
  } else {
1044
- return bufferBlockNumber;
1556
+ return bufferBlockNumber$1;
1557
+ }
1558
+ }
1559
+
1560
+ function updateKnownHeight(fetchState, knownHeight) {
1561
+ if (knownHeight > fetchState.knownHeight) {
1562
+ Prometheus.IndexingKnownHeight.set(knownHeight, fetchState.chainId);
1563
+ return updateInternal(fetchState, undefined, undefined, undefined, undefined, knownHeight);
1564
+ } else {
1565
+ return fetchState;
1045
1566
  }
1046
1567
  }
1047
1568
 
1048
1569
  var blockItemLogIndex = 16777216;
1049
1570
 
1050
1571
  export {
1051
- mergeIntoPartition ,
1572
+ getMinHistoryRange ,
1573
+ getMinQueryRange ,
1574
+ OptimizedPartitions ,
1052
1575
  bufferBlockNumber ,
1053
1576
  bufferBlock ,
1054
1577
  compareBufferItem ,
1055
1578
  blockItemLogIndex ,
1056
- updateInternal ,
1057
1579
  numAddresses ,
1580
+ updateInternal ,
1058
1581
  warnDifferentContractType ,
1582
+ addressesByContractNameCount ,
1583
+ addressesByContractNameGetAll ,
1584
+ createPartitionsFromIndexingAddresses ,
1059
1585
  registerDynamicContracts ,
1060
- UnexpectedPartitionNotFound ,
1061
- UnexpectedMergeQueryResponse ,
1062
1586
  handleQueryResult ,
1063
- makePartitionQuery ,
1064
1587
  startFetchingQueries ,
1065
- addressesByContractNameCount ,
1066
- addressesByContractNameGetAll ,
1067
- isFullPartition ,
1588
+ pushQueriesForRange ,
1068
1589
  getNextQuery ,
1069
1590
  getTimestampAt ,
1070
1591
  hasReadyItem ,
1071
1592
  getReadyItemsCount ,
1072
- make ,
1593
+ make$1 as make,
1073
1594
  bufferSize ,
1074
- rollbackPartition ,
1595
+ rollbackPendingQueries ,
1075
1596
  rollback ,
1597
+ resetPendingQueries ,
1076
1598
  isActivelyIndexing ,
1077
1599
  isReadyToEnterReorgThreshold ,
1078
1600
  sortForUnorderedBatch ,
1079
1601
  getUnorderedMultichainProgressBlockNumberAt ,
1602
+ updateKnownHeight ,
1080
1603
  }
1081
1604
  /* Utils Not a pure module */