envio 2.29.0-alpha.2 → 2.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -5
- package/src/Batch.res +12 -0
- package/src/Batch.res.js +15 -0
- package/src/EventRegister.res +14 -1
- package/src/EventRegister.res.js +11 -4
- package/src/EventUtils.res +4 -0
- package/src/EventUtils.res.js +3 -0
- package/src/FetchState.res +189 -160
- package/src/FetchState.res.js +212 -130
- package/src/Logging.res.js +3 -4
- package/src/Utils.res +2 -0
- package/src/bindings/Pino.res +1 -0
- package/src/bindings/Pino.res.js +10 -3
- package/src/db/EntityHistory.res +0 -3
- package/src/db/EntityHistory.res.js +30 -33
- package/src/db/InternalTable.res +0 -6
- package/src/db/InternalTable.res.js +0 -1
- package/src/sources/SourceManager.res +0 -2
- package/src/sources/SourceManager.res.js +2 -2
- package/src/sources/SourceManager.resi +0 -1
package/src/FetchState.res
CHANGED
|
@@ -51,7 +51,6 @@ type t = {
|
|
|
51
51
|
// Used for the incremental partition id. Can't use the partitions length,
|
|
52
52
|
// since partitions might be deleted on merge or cleaned up
|
|
53
53
|
nextPartitionIndex: int,
|
|
54
|
-
isFetchingAtHead: bool,
|
|
55
54
|
startBlock: int,
|
|
56
55
|
endBlock: option<int>,
|
|
57
56
|
maxAddrInPartition: int,
|
|
@@ -65,14 +64,23 @@ type t = {
|
|
|
65
64
|
dcsToStore: option<array<indexingContract>>,
|
|
66
65
|
// Not used for logic - only metadata
|
|
67
66
|
chainId: int,
|
|
68
|
-
//
|
|
67
|
+
// The block number of the latest block fetched
|
|
68
|
+
// which added all its events to the queue
|
|
69
69
|
latestFullyFetchedBlock: blockNumberAndTimestamp,
|
|
70
|
+
// The block number of the latest block which was added to the queue
|
|
71
|
+
// by the onBlock configs
|
|
72
|
+
// Need a separate pointer for this
|
|
73
|
+
// to prevent OOM when adding too many items to the queue
|
|
74
|
+
latestOnBlockBlockNumber: int,
|
|
70
75
|
// How much blocks behind the head we should query
|
|
71
76
|
// Needed to query before entering reorg threshold
|
|
72
77
|
blockLag: int,
|
|
73
78
|
//Items ordered from latest to earliest
|
|
74
79
|
queue: array<Internal.item>,
|
|
75
|
-
|
|
80
|
+
// How many items we should aim to have in the buffer
|
|
81
|
+
// ready for processing
|
|
82
|
+
targetBufferSize: int,
|
|
83
|
+
onBlockConfigs: array<Internal.onBlockConfig>,
|
|
76
84
|
}
|
|
77
85
|
|
|
78
86
|
let copy = (fetchState: t) => {
|
|
@@ -82,8 +90,8 @@ let copy = (fetchState: t) => {
|
|
|
82
90
|
startBlock: fetchState.startBlock,
|
|
83
91
|
endBlock: fetchState.endBlock,
|
|
84
92
|
nextPartitionIndex: fetchState.nextPartitionIndex,
|
|
85
|
-
isFetchingAtHead: fetchState.isFetchingAtHead,
|
|
86
93
|
latestFullyFetchedBlock: fetchState.latestFullyFetchedBlock,
|
|
94
|
+
latestOnBlockBlockNumber: fetchState.latestOnBlockBlockNumber,
|
|
87
95
|
normalSelection: fetchState.normalSelection,
|
|
88
96
|
chainId: fetchState.chainId,
|
|
89
97
|
contractConfigs: fetchState.contractConfigs,
|
|
@@ -92,6 +100,7 @@ let copy = (fetchState: t) => {
|
|
|
92
100
|
blockLag: fetchState.blockLag,
|
|
93
101
|
queue: fetchState.queue->Array.copy,
|
|
94
102
|
onBlockConfigs: fetchState.onBlockConfigs,
|
|
103
|
+
targetBufferSize: fetchState.targetBufferSize,
|
|
95
104
|
}
|
|
96
105
|
}
|
|
97
106
|
|
|
@@ -173,33 +182,40 @@ let mergeIntoPartition = (p: partition, ~target: partition, ~maxAddrInPartition)
|
|
|
173
182
|
}
|
|
174
183
|
}
|
|
175
184
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
let
|
|
201
|
-
|
|
202
|
-
|
|
185
|
+
@inline
|
|
186
|
+
let bufferBlockNumber = ({latestFullyFetchedBlock, latestOnBlockBlockNumber}: t) => {
|
|
187
|
+
latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber
|
|
188
|
+
? latestOnBlockBlockNumber
|
|
189
|
+
: latestFullyFetchedBlock.blockNumber
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Returns the latest block which is ready to be consumed
|
|
194
|
+
*/
|
|
195
|
+
@inline
|
|
196
|
+
let bufferBlock = ({latestFullyFetchedBlock, latestOnBlockBlockNumber}: t) => {
|
|
197
|
+
latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber
|
|
198
|
+
? {
|
|
199
|
+
blockNumber: latestOnBlockBlockNumber,
|
|
200
|
+
blockTimestamp: 0,
|
|
201
|
+
}
|
|
202
|
+
: latestFullyFetchedBlock
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/*
|
|
206
|
+
Comparitor for two events from the same chain. No need for chain id or timestamp
|
|
207
|
+
*/
|
|
208
|
+
let compareBufferItem = (a: Internal.item, b: Internal.item) => {
|
|
209
|
+
let blockDiff = b->Internal.getItemBlockNumber - a->Internal.getItemBlockNumber
|
|
210
|
+
if blockDiff === 0 {
|
|
211
|
+
b->Internal.getItemLogIndex - a->Internal.getItemLogIndex
|
|
212
|
+
} else {
|
|
213
|
+
blockDiff
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Some big number which should be bigger than any log index
|
|
218
|
+
let blockItemLogIndex = 16777216
|
|
203
219
|
|
|
204
220
|
/*
|
|
205
221
|
Update fetchState, merge registers and recompute derived values
|
|
@@ -210,8 +226,7 @@ let updateInternal = (
|
|
|
210
226
|
~nextPartitionIndex=fetchState.nextPartitionIndex,
|
|
211
227
|
~indexingContracts=fetchState.indexingContracts,
|
|
212
228
|
~dcsToStore=fetchState.dcsToStore,
|
|
213
|
-
~
|
|
214
|
-
~queue=fetchState.queue,
|
|
229
|
+
~mutItems=?,
|
|
215
230
|
~blockLag=fetchState.blockLag,
|
|
216
231
|
): t => {
|
|
217
232
|
let firstPartition = partitions->Js.Array2.unsafe_get(0)
|
|
@@ -224,35 +239,79 @@ let updateInternal = (
|
|
|
224
239
|
}
|
|
225
240
|
let latestFullyFetchedBlock = latestFullyFetchedBlock.contents
|
|
226
241
|
|
|
227
|
-
let
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
//
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
242
|
+
let mutItemsRef = ref(mutItems)
|
|
243
|
+
|
|
244
|
+
let latestOnBlockBlockNumber = switch fetchState.onBlockConfigs {
|
|
245
|
+
| [] => latestFullyFetchedBlock.blockNumber
|
|
246
|
+
| onBlockConfigs => {
|
|
247
|
+
// Calculate the max block number we are going to create items for
|
|
248
|
+
// Use -targetBufferSize to get the last target item in the queue (which is reversed)
|
|
249
|
+
//
|
|
250
|
+
// mutItems is not very reliable, since it might not be sorted,
|
|
251
|
+
// but the chances for it happen are very low and not critical
|
|
252
|
+
//
|
|
253
|
+
// All this needed to prevent OOM when adding too many block items to the queue
|
|
254
|
+
let maxBlockNumber = switch switch mutItemsRef.contents {
|
|
255
|
+
| Some(mutItems) => mutItems
|
|
256
|
+
| None => fetchState.queue
|
|
257
|
+
}->Utils.Array.at(-fetchState.targetBufferSize) {
|
|
258
|
+
| Some(item) => item->Internal.getItemBlockNumber
|
|
259
|
+
| None => latestFullyFetchedBlock.blockNumber
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
let mutItems = switch mutItemsRef.contents {
|
|
263
|
+
| Some(mutItems) => mutItems
|
|
264
|
+
| None => fetchState.queue->Array.copy
|
|
265
|
+
}
|
|
266
|
+
mutItemsRef := Some(mutItems)
|
|
267
|
+
|
|
268
|
+
let newItemsCounter = ref(0)
|
|
269
|
+
let latestOnBlockBlockNumber = ref(fetchState.latestOnBlockBlockNumber)
|
|
270
|
+
|
|
271
|
+
// Simply iterate over every block
|
|
272
|
+
// could have a better algorithm to iterate over blocks in a more efficient way
|
|
273
|
+
// but raw loops are fast enough
|
|
274
|
+
while (
|
|
275
|
+
latestOnBlockBlockNumber.contents < maxBlockNumber &&
|
|
276
|
+
// Additional safeguard to prevent OOM
|
|
277
|
+
newItemsCounter.contents <= fetchState.targetBufferSize
|
|
278
|
+
) {
|
|
279
|
+
let blockNumber = latestOnBlockBlockNumber.contents + 1
|
|
280
|
+
latestOnBlockBlockNumber := blockNumber
|
|
281
|
+
|
|
282
|
+
for configIdx in 0 to onBlockConfigs->Array.length - 1 {
|
|
283
|
+
let onBlockConfig = onBlockConfigs->Js.Array2.unsafe_get(configIdx)
|
|
284
|
+
|
|
285
|
+
let handlerStartBlock = switch onBlockConfig.startBlock {
|
|
286
|
+
| Some(startBlock) => startBlock
|
|
287
|
+
| None => fetchState.startBlock
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (
|
|
291
|
+
blockNumber >= handlerStartBlock &&
|
|
292
|
+
switch onBlockConfig.endBlock {
|
|
293
|
+
| Some(endBlock) => blockNumber <= endBlock
|
|
294
|
+
| None => true
|
|
295
|
+
} &&
|
|
296
|
+
(blockNumber - handlerStartBlock)->Pervasives.mod(onBlockConfig.interval) === 0
|
|
297
|
+
) {
|
|
298
|
+
mutItems->Array.push(
|
|
299
|
+
Block({
|
|
300
|
+
onBlockConfig,
|
|
301
|
+
blockNumber,
|
|
302
|
+
logIndex: blockItemLogIndex + onBlockConfig.index,
|
|
303
|
+
}),
|
|
304
|
+
)
|
|
305
|
+
newItemsCounter := newItemsCounter.contents + 1
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
latestOnBlockBlockNumber.contents
|
|
241
311
|
}
|
|
242
312
|
}
|
|
243
313
|
|
|
244
|
-
let
|
|
245
|
-
Prometheus.IndexingPartitions.set(
|
|
246
|
-
~partitionsCount=partitions->Array.length,
|
|
247
|
-
~chainId=fetchState.chainId,
|
|
248
|
-
)
|
|
249
|
-
Prometheus.IndexingBufferSize.set(~bufferSize, ~chainId=fetchState.chainId)
|
|
250
|
-
Prometheus.IndexingBufferBlockNumber.set(
|
|
251
|
-
~blockNumber=latestFullyFetchedBlock.blockNumber,
|
|
252
|
-
~chainId=fetchState.chainId,
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
{
|
|
314
|
+
let updatedFetchState = {
|
|
256
315
|
maxAddrInPartition: fetchState.maxAddrInPartition,
|
|
257
316
|
startBlock: fetchState.startBlock,
|
|
258
317
|
endBlock: fetchState.endBlock,
|
|
@@ -260,15 +319,37 @@ let updateInternal = (
|
|
|
260
319
|
normalSelection: fetchState.normalSelection,
|
|
261
320
|
chainId: fetchState.chainId,
|
|
262
321
|
onBlockConfigs: fetchState.onBlockConfigs,
|
|
322
|
+
targetBufferSize: fetchState.targetBufferSize,
|
|
263
323
|
nextPartitionIndex,
|
|
264
324
|
partitions,
|
|
265
|
-
|
|
325
|
+
latestOnBlockBlockNumber,
|
|
266
326
|
latestFullyFetchedBlock,
|
|
267
327
|
indexingContracts,
|
|
268
328
|
dcsToStore,
|
|
269
329
|
blockLag,
|
|
270
|
-
queue
|
|
330
|
+
queue: switch mutItemsRef.contents {
|
|
331
|
+
// Theoretically it could be faster to asume that
|
|
332
|
+
// the items are sorted, but there are cases
|
|
333
|
+
// when the data source returns them unsorted
|
|
334
|
+
| Some(mutItems) => mutItems->Js.Array2.sortInPlaceWith(compareBufferItem)
|
|
335
|
+
| None => fetchState.queue
|
|
336
|
+
},
|
|
271
337
|
}
|
|
338
|
+
|
|
339
|
+
Prometheus.IndexingPartitions.set(
|
|
340
|
+
~partitionsCount=partitions->Array.length,
|
|
341
|
+
~chainId=fetchState.chainId,
|
|
342
|
+
)
|
|
343
|
+
Prometheus.IndexingBufferSize.set(
|
|
344
|
+
~bufferSize=updatedFetchState.queue->Array.length,
|
|
345
|
+
~chainId=fetchState.chainId,
|
|
346
|
+
)
|
|
347
|
+
Prometheus.IndexingBufferBlockNumber.set(
|
|
348
|
+
~blockNumber=updatedFetchState->bufferBlockNumber,
|
|
349
|
+
~chainId=fetchState.chainId,
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
updatedFetchState
|
|
272
353
|
}
|
|
273
354
|
|
|
274
355
|
let numAddresses = fetchState => fetchState.indexingContracts->Js.Dict.keys->Array.length
|
|
@@ -290,7 +371,6 @@ let registerDynamicContracts = (
|
|
|
290
371
|
// These are raw dynamic contracts received from contractRegister call.
|
|
291
372
|
// Might contain duplicates which we should filter out
|
|
292
373
|
dynamicContracts: array<indexingContract>,
|
|
293
|
-
~currentBlockHeight,
|
|
294
374
|
) => {
|
|
295
375
|
if fetchState.normalSelection.eventConfigs->Utils.Array.isEmpty {
|
|
296
376
|
// Can the normalSelection be empty?
|
|
@@ -509,7 +589,6 @@ let registerDynamicContracts = (
|
|
|
509
589
|
|
|
510
590
|
fetchState->updateInternal(
|
|
511
591
|
~partitions=fetchState.partitions->Js.Array2.concat(newPartitions),
|
|
512
|
-
~currentBlockHeight,
|
|
513
592
|
~dcsToStore=switch fetchState.dcsToStore {
|
|
514
593
|
| Some(existingDcs) => Some(Array.concat(existingDcs, dcsToStore))
|
|
515
594
|
| None => Some(dcsToStore)
|
|
@@ -546,21 +625,6 @@ type query = {
|
|
|
546
625
|
exception UnexpectedPartitionNotFound({partitionId: string})
|
|
547
626
|
exception UnexpectedMergeQueryResponse({message: string})
|
|
548
627
|
|
|
549
|
-
/*
|
|
550
|
-
Comparitor for two events from the same chain. No need for chain id or timestamp
|
|
551
|
-
*/
|
|
552
|
-
let compareBufferItem = (a: Internal.item, b: Internal.item) => {
|
|
553
|
-
let blockDiff = b->Internal.getItemBlockNumber - a->Internal.getItemBlockNumber
|
|
554
|
-
if blockDiff === 0 {
|
|
555
|
-
b->Internal.getItemLogIndex - a->Internal.getItemLogIndex
|
|
556
|
-
} else {
|
|
557
|
-
blockDiff
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// Some big number which should be bigger than any log index
|
|
562
|
-
let blockItemLogIndex = 16777216
|
|
563
|
-
|
|
564
628
|
/*
|
|
565
629
|
Updates fetchState with a response for a given query.
|
|
566
630
|
Returns Error if the partition with given query cannot be found (unexpected)
|
|
@@ -573,7 +637,6 @@ let handleQueryResult = (
|
|
|
573
637
|
~query: query,
|
|
574
638
|
~latestFetchedBlock: blockNumberAndTimestamp,
|
|
575
639
|
~newItems,
|
|
576
|
-
~currentBlockHeight,
|
|
577
640
|
): result<t, exn> =>
|
|
578
641
|
{
|
|
579
642
|
let partitionId = query.partitionId
|
|
@@ -626,59 +689,14 @@ let handleQueryResult = (
|
|
|
626
689
|
)
|
|
627
690
|
}
|
|
628
691
|
}->Result.map(partitions => {
|
|
629
|
-
let newQueue = fetchState.queue->Array.concat(newItems)
|
|
630
|
-
|
|
631
|
-
switch fetchState.onBlockConfigs {
|
|
632
|
-
| Some(onBlockConfigs) => {
|
|
633
|
-
let prevLatestFetchedBlockNumber = fetchState.latestFullyFetchedBlock.blockNumber
|
|
634
|
-
let nextLatestFullyFetchedBlockNumber = {
|
|
635
|
-
let nextLatestFullyFetchedBlockNumber = ref(latestFetchedBlock.blockNumber)
|
|
636
|
-
for idx in 0 to partitions->Array.length - 1 {
|
|
637
|
-
let p = partitions->Js.Array2.unsafe_get(idx)
|
|
638
|
-
if nextLatestFullyFetchedBlockNumber.contents > p.latestFetchedBlock.blockNumber {
|
|
639
|
-
nextLatestFullyFetchedBlockNumber := p.latestFetchedBlock.blockNumber
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
nextLatestFullyFetchedBlockNumber.contents
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
if nextLatestFullyFetchedBlockNumber > prevLatestFetchedBlockNumber {
|
|
646
|
-
for configIdx in 0 to onBlockConfigs->Array.length - 1 {
|
|
647
|
-
let onBlockConfig = onBlockConfigs->Js.Array2.unsafe_get(configIdx)
|
|
648
|
-
|
|
649
|
-
let handlerStartBlock = switch onBlockConfig.startBlock {
|
|
650
|
-
| Some(startBlock) => startBlock
|
|
651
|
-
| None => fetchState.startBlock
|
|
652
|
-
}
|
|
653
|
-
let rangeStart = Pervasives.max(handlerStartBlock, prevLatestFetchedBlockNumber + 1)
|
|
654
|
-
let rangeEnd = switch onBlockConfig.endBlock {
|
|
655
|
-
| Some(endBlock) => Pervasives.min(endBlock, nextLatestFullyFetchedBlockNumber)
|
|
656
|
-
| None => nextLatestFullyFetchedBlockNumber
|
|
657
|
-
}
|
|
658
|
-
if rangeStart <= rangeEnd {
|
|
659
|
-
for blockNumber in rangeStart to rangeEnd {
|
|
660
|
-
if (blockNumber - handlerStartBlock)->Pervasives.mod(onBlockConfig.interval) === 0 {
|
|
661
|
-
newQueue->Array.push(
|
|
662
|
-
Block({onBlockConfig, blockNumber, logIndex: blockItemLogIndex}),
|
|
663
|
-
)
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
| None => ()
|
|
672
|
-
}
|
|
673
|
-
|
|
674
692
|
fetchState->updateInternal(
|
|
675
693
|
~partitions,
|
|
676
|
-
~
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
694
|
+
~mutItems=?{
|
|
695
|
+
switch newItems {
|
|
696
|
+
| [] => None
|
|
697
|
+
| _ => Some(fetchState.queue->Array.concat(newItems))
|
|
698
|
+
}
|
|
699
|
+
},
|
|
682
700
|
)
|
|
683
701
|
})
|
|
684
702
|
|
|
@@ -757,9 +775,16 @@ let isFullPartition = (p: partition, ~maxAddrInPartition) => {
|
|
|
757
775
|
}
|
|
758
776
|
|
|
759
777
|
let getNextQuery = (
|
|
760
|
-
{
|
|
778
|
+
{
|
|
779
|
+
queue,
|
|
780
|
+
partitions,
|
|
781
|
+
targetBufferSize,
|
|
782
|
+
maxAddrInPartition,
|
|
783
|
+
endBlock,
|
|
784
|
+
indexingContracts,
|
|
785
|
+
blockLag,
|
|
786
|
+
}: t,
|
|
761
787
|
~concurrencyLimit,
|
|
762
|
-
~targetBufferSize,
|
|
763
788
|
~currentBlockHeight,
|
|
764
789
|
~stateId,
|
|
765
790
|
) => {
|
|
@@ -951,19 +976,20 @@ Gets the earliest queueItem from thgetNodeEarliestEventWithUpdatedQueue.
|
|
|
951
976
|
Finds the earliest queue item across all partitions and then returns that
|
|
952
977
|
queue item with an update fetch state.
|
|
953
978
|
*/
|
|
954
|
-
let getEarliestEvent = (
|
|
955
|
-
|
|
979
|
+
let getEarliestEvent = (fetchState: t) => {
|
|
980
|
+
let {queue} = fetchState
|
|
981
|
+
switch fetchState.queue->Utils.Array.last {
|
|
956
982
|
| Some(item) =>
|
|
957
|
-
if item->Internal.getItemBlockNumber <=
|
|
983
|
+
if item->Internal.getItemBlockNumber <= fetchState->bufferBlockNumber {
|
|
958
984
|
Item({item, popItemOffQueue: () => queue->Js.Array2.pop->ignore})
|
|
959
985
|
} else {
|
|
960
986
|
NoItem({
|
|
961
|
-
latestFetchedBlock:
|
|
987
|
+
latestFetchedBlock: fetchState->bufferBlock,
|
|
962
988
|
})
|
|
963
989
|
}
|
|
964
990
|
| None =>
|
|
965
991
|
NoItem({
|
|
966
|
-
latestFetchedBlock:
|
|
992
|
+
latestFetchedBlock: fetchState->bufferBlock,
|
|
967
993
|
})
|
|
968
994
|
}
|
|
969
995
|
}
|
|
@@ -978,8 +1004,9 @@ let make = (
|
|
|
978
1004
|
~contracts: array<indexingContract>,
|
|
979
1005
|
~maxAddrInPartition,
|
|
980
1006
|
~chainId,
|
|
1007
|
+
~targetBufferSize,
|
|
981
1008
|
~progressBlockNumber=startBlock - 1,
|
|
982
|
-
~onBlockConfigs
|
|
1009
|
+
~onBlockConfigs=[],
|
|
983
1010
|
~blockLag=0,
|
|
984
1011
|
): t => {
|
|
985
1012
|
let latestFetchedBlock = {
|
|
@@ -1095,28 +1122,24 @@ let make = (
|
|
|
1095
1122
|
partitions,
|
|
1096
1123
|
nextPartitionIndex: partitions->Array.length,
|
|
1097
1124
|
contractConfigs,
|
|
1098
|
-
isFetchingAtHead: false,
|
|
1099
1125
|
maxAddrInPartition,
|
|
1100
1126
|
chainId,
|
|
1101
1127
|
startBlock,
|
|
1102
1128
|
endBlock,
|
|
1103
1129
|
latestFullyFetchedBlock: latestFetchedBlock,
|
|
1130
|
+
latestOnBlockBlockNumber: progressBlockNumber,
|
|
1104
1131
|
normalSelection,
|
|
1105
1132
|
indexingContracts,
|
|
1106
1133
|
dcsToStore: None,
|
|
1107
1134
|
blockLag,
|
|
1108
1135
|
onBlockConfigs,
|
|
1136
|
+
targetBufferSize,
|
|
1109
1137
|
queue: [],
|
|
1110
1138
|
}
|
|
1111
1139
|
}
|
|
1112
1140
|
|
|
1113
1141
|
let bufferSize = ({queue}: t) => queue->Array.length
|
|
1114
1142
|
|
|
1115
|
-
/**
|
|
1116
|
-
* Returns the latest block number fetched for the lowest fetcher queue (ie the earliest un-fetched dynamic contract)
|
|
1117
|
-
*/
|
|
1118
|
-
let getLatestFullyFetchedBlock = ({latestFullyFetchedBlock}: t) => latestFullyFetchedBlock
|
|
1119
|
-
|
|
1120
1143
|
let pruneQueueFromFirstChangeEvent = (
|
|
1121
1144
|
queue: array<Internal.item>,
|
|
1122
1145
|
~firstChangeEvent: blockNumberAndLogIndex,
|
|
@@ -1142,6 +1165,7 @@ let rollbackPartition = (
|
|
|
1142
1165
|
| {selection: {dependsOnAddresses: false}} =>
|
|
1143
1166
|
Some({
|
|
1144
1167
|
...p,
|
|
1168
|
+
// FIXME: Should rollback latestFetchedBlock???
|
|
1145
1169
|
status: {
|
|
1146
1170
|
fetchingStateId: None,
|
|
1147
1171
|
},
|
|
@@ -1209,10 +1233,13 @@ let rollback = (fetchState: t, ~firstChangeEvent) => {
|
|
|
1209
1233
|
p->rollbackPartition(~firstChangeEvent, ~addressesToRemove)
|
|
1210
1234
|
)
|
|
1211
1235
|
|
|
1212
|
-
|
|
1236
|
+
{
|
|
1237
|
+
...fetchState,
|
|
1238
|
+
latestOnBlockBlockNumber: firstChangeEvent.blockNumber - 1, // TODO: This is not tested
|
|
1239
|
+
}->updateInternal(
|
|
1213
1240
|
~partitions,
|
|
1214
1241
|
~indexingContracts,
|
|
1215
|
-
~
|
|
1242
|
+
~mutItems=fetchState.queue->pruneQueueFromFirstChangeEvent(~firstChangeEvent),
|
|
1216
1243
|
~dcsToStore=switch fetchState.dcsToStore {
|
|
1217
1244
|
| Some(dcsToStore) =>
|
|
1218
1245
|
let filtered =
|
|
@@ -1230,10 +1257,10 @@ let rollback = (fetchState: t, ~firstChangeEvent) => {
|
|
|
1230
1257
|
* Returns a boolean indicating whether the fetch state is actively indexing
|
|
1231
1258
|
* used for comparing event queues in the chain manager
|
|
1232
1259
|
*/
|
|
1233
|
-
let isActivelyIndexing = ({
|
|
1260
|
+
let isActivelyIndexing = ({endBlock} as fetchState: t) => {
|
|
1234
1261
|
switch endBlock {
|
|
1235
1262
|
| Some(endBlock) =>
|
|
1236
|
-
let isPastEndblock =
|
|
1263
|
+
let isPastEndblock = fetchState->bufferBlockNumber >= endBlock
|
|
1237
1264
|
if isPastEndblock {
|
|
1238
1265
|
fetchState->bufferSize > 0
|
|
1239
1266
|
} else {
|
|
@@ -1244,26 +1271,27 @@ let isActivelyIndexing = ({latestFullyFetchedBlock, endBlock} as fetchState: t)
|
|
|
1244
1271
|
}
|
|
1245
1272
|
|
|
1246
1273
|
let isReadyToEnterReorgThreshold = (
|
|
1247
|
-
{
|
|
1274
|
+
{endBlock, blockLag, queue} as fetchState: t,
|
|
1248
1275
|
~currentBlockHeight,
|
|
1249
1276
|
) => {
|
|
1277
|
+
let bufferBlockNumber = fetchState->bufferBlockNumber
|
|
1250
1278
|
currentBlockHeight !== 0 &&
|
|
1251
1279
|
switch endBlock {
|
|
1252
|
-
| Some(endBlock) if
|
|
1253
|
-
| _ =>
|
|
1280
|
+
| Some(endBlock) if bufferBlockNumber >= endBlock => true
|
|
1281
|
+
| _ => bufferBlockNumber >= currentBlockHeight - blockLag
|
|
1254
1282
|
} &&
|
|
1255
1283
|
queue->Utils.Array.isEmpty
|
|
1256
1284
|
}
|
|
1257
1285
|
|
|
1258
1286
|
let filterAndSortForUnorderedBatch = {
|
|
1259
|
-
let hasBatchItem = ({queue
|
|
1287
|
+
let hasBatchItem = ({queue} as fetchState: t) => {
|
|
1260
1288
|
switch queue->Utils.Array.last {
|
|
1261
|
-
| Some(item) => item->Internal.getItemBlockNumber <=
|
|
1289
|
+
| Some(item) => item->Internal.getItemBlockNumber <= fetchState->bufferBlockNumber
|
|
1262
1290
|
| None => false
|
|
1263
1291
|
}
|
|
1264
1292
|
}
|
|
1265
1293
|
|
|
1266
|
-
let hasFullBatch = ({queue
|
|
1294
|
+
let hasFullBatch = ({queue} as fetchState: t, ~maxBatchSize) => {
|
|
1267
1295
|
// Queue is ordered from latest to earliest, so the earliest eligible
|
|
1268
1296
|
// item for a full batch of size B is at index (length - B).
|
|
1269
1297
|
// Do NOT subtract an extra 1 here; when length === B we should still
|
|
@@ -1275,7 +1303,7 @@ let filterAndSortForUnorderedBatch = {
|
|
|
1275
1303
|
// Unsafe can fail when maxBatchSize is 0,
|
|
1276
1304
|
// but we ignore the case
|
|
1277
1305
|
queue->Js.Array2.unsafe_get(targetBlockIdx)->Internal.getItemBlockNumber <=
|
|
1278
|
-
|
|
1306
|
+
fetchState->bufferBlockNumber
|
|
1279
1307
|
}
|
|
1280
1308
|
}
|
|
1281
1309
|
|
|
@@ -1303,18 +1331,19 @@ let filterAndSortForUnorderedBatch = {
|
|
|
1303
1331
|
}
|
|
1304
1332
|
}
|
|
1305
1333
|
|
|
1306
|
-
let getProgressBlockNumber = ({
|
|
1334
|
+
let getProgressBlockNumber = ({queue} as fetchState: t) => {
|
|
1335
|
+
let bufferBlockNumber = fetchState->bufferBlockNumber
|
|
1307
1336
|
switch queue->Utils.Array.last {
|
|
1308
|
-
| Some(item) if
|
|
1337
|
+
| Some(item) if bufferBlockNumber >= item->Internal.getItemBlockNumber =>
|
|
1309
1338
|
item->Internal.getItemBlockNumber - 1
|
|
1310
|
-
| _ =>
|
|
1339
|
+
| _ => bufferBlockNumber
|
|
1311
1340
|
}
|
|
1312
1341
|
}
|
|
1313
1342
|
|
|
1314
|
-
let getProgressNextBlockLogIndex = ({queue
|
|
1343
|
+
let getProgressNextBlockLogIndex = ({queue} as fetchState: t) => {
|
|
1315
1344
|
switch queue->Utils.Array.last {
|
|
1316
1345
|
| Some(Event({logIndex, blockNumber}))
|
|
1317
|
-
if
|
|
1346
|
+
if fetchState->bufferBlockNumber >= blockNumber && logIndex > 0 =>
|
|
1318
1347
|
Some(logIndex - 1)
|
|
1319
1348
|
| _ => None
|
|
1320
1349
|
}
|