envio 2.28.0 → 2.29.0-alpha.1

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.
@@ -1,32 +1,26 @@
1
- type multiChainEventIndex = {
2
- timestamp: int,
3
- chainId: int,
4
- blockNumber: int,
5
- logIndex: int,
6
- }
7
-
8
1
  //Comparator used when ordering multichain events
9
- let getEventComparator = (multiChainEventIndex: multiChainEventIndex) => {
10
- let {timestamp, chainId, blockNumber, logIndex} = multiChainEventIndex
11
- (timestamp, chainId, blockNumber, logIndex)
12
- }
13
-
14
- let getEventComparatorFromQueueItem = (
15
- {chain, timestamp, blockNumber, logIndex}: Internal.eventItem,
16
- ) => {
17
- let chainId = chain->ChainMap.Chain.toChainId
18
- (timestamp, chainId, blockNumber, logIndex)
2
+ let getOrderedBatchItemComparator = (item: Internal.item) => {
3
+ switch item {
4
+ | Internal.Event({timestamp, chain, blockNumber, logIndex}) => (
5
+ timestamp,
6
+ chain->ChainMap.Chain.toChainId,
7
+ blockNumber,
8
+ logIndex,
9
+ )
10
+ | Internal.Block(_) =>
11
+ Js.Exn.raiseError("Block handlers are not supported for ordered multichain mode.")
12
+ }
19
13
  }
20
14
 
21
- //Function used to determine if one event is earlier than another
22
- let isEarlierEvent = (event1: multiChainEventIndex, event2: multiChainEventIndex) => {
23
- event1->getEventComparator < event2->getEventComparator
15
+ let isEarlier = (item1: (int, int, int, int), item2: (int, int, int, int)) => {
16
+ item1 < item2
24
17
  }
25
18
 
26
- type eventIndex = {
27
- blockNumber: int,
28
- logIndex: int,
29
- }
19
+ // type eventIndex = {
20
+ // blockNumber: int,
21
+ // logIndex: int,
22
+ // }
23
+ //
30
24
 
31
25
  // takes blockNumber, logIndex and packs them into a number with
32
26
  //32 bits, 16 bits and 16 bits respectively
@@ -38,44 +32,44 @@ let packEventIndex = (~blockNumber, ~logIndex) => {
38
32
  blockNumber->BigInt.Bitwise.logor(logIndex)
39
33
  }
40
34
 
41
- //Currently not used but keeping in utils
42
- //using @live flag for dead code analyser
43
- @live
44
- let packMultiChainEventIndex = (~timestamp, ~chainId, ~blockNumber, ~logIndex) => {
45
- let timestamp = timestamp->BigInt.fromInt
46
- let chainId = chainId->BigInt.fromInt
47
- let blockNumber = blockNumber->BigInt.fromInt
48
- let logIndex = logIndex->BigInt.fromInt
35
+ // //Currently not used but keeping in utils
36
+ // //using @live flag for dead code analyser
37
+ // @live
38
+ // let packMultiChainEventIndex = (~timestamp, ~chainId, ~blockNumber, ~logIndex) => {
39
+ // let timestamp = timestamp->BigInt.fromInt
40
+ // let chainId = chainId->BigInt.fromInt
41
+ // let blockNumber = blockNumber->BigInt.fromInt
42
+ // let logIndex = logIndex->BigInt.fromInt
49
43
 
50
- let timestamp = BigInt.Bitwise.shift_left(timestamp, 48->BigInt.fromInt)
51
- let chainId = BigInt.Bitwise.shift_left(chainId, 16->BigInt.fromInt)
52
- let blockNumber = BigInt.Bitwise.shift_left(blockNumber, 16->BigInt.fromInt)
44
+ // let timestamp = BigInt.Bitwise.shift_left(timestamp, 48->BigInt.fromInt)
45
+ // let chainId = BigInt.Bitwise.shift_left(chainId, 16->BigInt.fromInt)
46
+ // let blockNumber = BigInt.Bitwise.shift_left(blockNumber, 16->BigInt.fromInt)
53
47
 
54
- timestamp
55
- ->BigInt.Bitwise.logor(chainId)
56
- ->BigInt.Bitwise.logor(blockNumber)
57
- ->BigInt.Bitwise.logor(logIndex)
58
- }
48
+ // timestamp
49
+ // ->BigInt.Bitwise.logor(chainId)
50
+ // ->BigInt.Bitwise.logor(blockNumber)
51
+ // ->BigInt.Bitwise.logor(logIndex)
52
+ // }
59
53
 
60
- //Currently not used but keeping in utils
61
- //using @live flag for dead code analyser
62
- @live
63
- let unpackEventIndex = (packedEventIndex: bigint) => {
64
- let blockNumber = packedEventIndex->BigInt.Bitwise.shift_right(16->BigInt.fromInt)
65
- let logIndexMask = 65535->BigInt.fromInt
66
- let logIndex = packedEventIndex->BigInt.Bitwise.logand(logIndexMask)
67
- {
68
- blockNumber: blockNumber->BigInt.toString->Belt.Int.fromString->Belt.Option.getUnsafe,
69
- logIndex: logIndex->BigInt.toString->Belt.Int.fromString->Belt.Option.getUnsafe,
70
- }
71
- }
54
+ // //Currently not used but keeping in utils
55
+ // //using @live flag for dead code analyser
56
+ // @live
57
+ // let unpackEventIndex = (packedEventIndex: bigint) => {
58
+ // let blockNumber = packedEventIndex->BigInt.Bitwise.shift_right(16->BigInt.fromInt)
59
+ // let logIndexMask = 65535->BigInt.fromInt
60
+ // let logIndex = packedEventIndex->BigInt.Bitwise.logand(logIndexMask)
61
+ // {
62
+ // blockNumber: blockNumber->BigInt.toString->Belt.Int.fromString->Belt.Option.getUnsafe,
63
+ // logIndex: logIndex->BigInt.toString->Belt.Int.fromString->Belt.Option.getUnsafe,
64
+ // }
65
+ // }
72
66
 
73
- //takes an eventIndex record and returnts a packed event index
74
- //used in TS tests
75
- @live
76
- let packEventIndexFromRecord = (eventIndex: eventIndex) => {
77
- packEventIndex(~blockNumber=eventIndex.blockNumber, ~logIndex=eventIndex.logIndex)
78
- }
67
+ // //takes an eventIndex record and returnts a packed event index
68
+ // //used in TS tests
69
+ // @live
70
+ // let packEventIndexFromRecord = (eventIndex: eventIndex) => {
71
+ // packEventIndex(~blockNumber=eventIndex.blockNumber, ~logIndex=eventIndex.logIndex)
72
+ // }
79
73
 
80
74
  //Returns unique string id for an event using its chain id combined with event id
81
75
  //Used in IO for the key in the in mem rawEvents table
@@ -2,30 +2,23 @@
2
2
  'use strict';
3
3
 
4
4
  var $$BigInt = require("./bindings/BigInt.res.js");
5
- var Belt_Int = require("rescript/lib/js/belt_Int.js");
5
+ var Js_exn = require("rescript/lib/js/js_exn.js");
6
6
  var Caml_obj = require("rescript/lib/js/caml_obj.js");
7
7
 
8
- function getEventComparator(multiChainEventIndex) {
9
- return [
10
- multiChainEventIndex.timestamp,
11
- multiChainEventIndex.chainId,
12
- multiChainEventIndex.blockNumber,
13
- multiChainEventIndex.logIndex
14
- ];
8
+ function getOrderedBatchItemComparator(item) {
9
+ if (item.kind === 0) {
10
+ return [
11
+ item.timestamp,
12
+ item.chain,
13
+ item.blockNumber,
14
+ item.logIndex
15
+ ];
16
+ } else {
17
+ return Js_exn.raiseError("Block handlers are not supported for ordered multichain mode.");
18
+ }
15
19
  }
16
20
 
17
- function getEventComparatorFromQueueItem(param) {
18
- return [
19
- param.timestamp,
20
- param.chain,
21
- param.blockNumber,
22
- param.logIndex
23
- ];
24
- }
25
-
26
- function isEarlierEvent(event1, event2) {
27
- return Caml_obj.lessthan(getEventComparator(event1), getEventComparator(event2));
28
- }
21
+ var isEarlier = Caml_obj.lessthan;
29
22
 
30
23
  function packEventIndex(blockNumber, logIndex) {
31
24
  var blockNumber$1 = BigInt(blockNumber);
@@ -34,42 +27,13 @@ function packEventIndex(blockNumber, logIndex) {
34
27
  return $$BigInt.Bitwise.logor(blockNumber$2, logIndex$1);
35
28
  }
36
29
 
37
- function packMultiChainEventIndex(timestamp, chainId, blockNumber, logIndex) {
38
- var timestamp$1 = BigInt(timestamp);
39
- var chainId$1 = BigInt(chainId);
40
- var blockNumber$1 = BigInt(blockNumber);
41
- var logIndex$1 = BigInt(logIndex);
42
- var timestamp$2 = $$BigInt.Bitwise.shift_left(timestamp$1, BigInt(48));
43
- var chainId$2 = $$BigInt.Bitwise.shift_left(chainId$1, BigInt(16));
44
- var blockNumber$2 = $$BigInt.Bitwise.shift_left(blockNumber$1, BigInt(16));
45
- return $$BigInt.Bitwise.logor($$BigInt.Bitwise.logor($$BigInt.Bitwise.logor(timestamp$2, chainId$2), blockNumber$2), logIndex$1);
46
- }
47
-
48
- function unpackEventIndex(packedEventIndex) {
49
- var blockNumber = $$BigInt.Bitwise.shift_right(packedEventIndex, BigInt(16));
50
- var logIndexMask = BigInt(65535);
51
- var logIndex = $$BigInt.Bitwise.logand(packedEventIndex, logIndexMask);
52
- return {
53
- blockNumber: Belt_Int.fromString(blockNumber.toString()),
54
- logIndex: Belt_Int.fromString(logIndex.toString())
55
- };
56
- }
57
-
58
- function packEventIndexFromRecord(eventIndex) {
59
- return packEventIndex(eventIndex.blockNumber, eventIndex.logIndex);
60
- }
61
-
62
30
  function getEventIdKeyString(chainId, eventId) {
63
31
  var chainIdStr = String(chainId);
64
32
  return chainIdStr + "_" + eventId;
65
33
  }
66
34
 
67
- exports.getEventComparator = getEventComparator;
68
- exports.getEventComparatorFromQueueItem = getEventComparatorFromQueueItem;
69
- exports.isEarlierEvent = isEarlierEvent;
35
+ exports.getOrderedBatchItemComparator = getOrderedBatchItemComparator;
36
+ exports.isEarlier = isEarlier;
70
37
  exports.packEventIndex = packEventIndex;
71
- exports.packMultiChainEventIndex = packMultiChainEventIndex;
72
- exports.unpackEventIndex = unpackEventIndex;
73
- exports.packEventIndexFromRecord = packEventIndexFromRecord;
74
38
  exports.getEventIdKeyString = getEventIdKeyString;
75
39
  /* BigInt Not a pure module */
@@ -54,7 +54,6 @@ type t = {
54
54
  isFetchingAtHead: bool,
55
55
  endBlock: option<int>,
56
56
  maxAddrInPartition: int,
57
- firstEventBlockNumber: option<int>,
58
57
  normalSelection: selection,
59
58
  // By address
60
59
  indexingContracts: dict<indexingContract>,
@@ -71,7 +70,8 @@ type t = {
71
70
  // Needed to query before entering reorg threshold
72
71
  blockLag: int,
73
72
  //Items ordered from latest to earliest
74
- queue: array<Internal.eventItem>,
73
+ queue: array<Internal.item>,
74
+ onBlockConfigs: option<array<Internal.onBlockConfig>>,
75
75
  }
76
76
 
77
77
  let copy = (fetchState: t) => {
@@ -83,13 +83,13 @@ let copy = (fetchState: t) => {
83
83
  isFetchingAtHead: fetchState.isFetchingAtHead,
84
84
  latestFullyFetchedBlock: fetchState.latestFullyFetchedBlock,
85
85
  normalSelection: fetchState.normalSelection,
86
- firstEventBlockNumber: fetchState.firstEventBlockNumber,
87
86
  chainId: fetchState.chainId,
88
87
  contractConfigs: fetchState.contractConfigs,
89
88
  indexingContracts: fetchState.indexingContracts,
90
89
  dcsToStore: fetchState.dcsToStore,
91
90
  blockLag: fetchState.blockLag,
92
91
  queue: fetchState.queue->Array.copy,
92
+ onBlockConfigs: fetchState.onBlockConfigs,
93
93
  }
94
94
  }
95
95
 
@@ -256,11 +256,8 @@ let updateInternal = (
256
256
  contractConfigs: fetchState.contractConfigs,
257
257
  normalSelection: fetchState.normalSelection,
258
258
  chainId: fetchState.chainId,
259
+ onBlockConfigs: fetchState.onBlockConfigs,
259
260
  nextPartitionIndex,
260
- firstEventBlockNumber: switch queue->Utils.Array.last {
261
- | Some(item) => Utils.Math.minOptInt(fetchState.firstEventBlockNumber, Some(item.blockNumber))
262
- | None => fetchState.firstEventBlockNumber
263
- },
264
261
  partitions,
265
262
  isFetchingAtHead,
266
263
  latestFullyFetchedBlock,
@@ -549,15 +546,18 @@ exception UnexpectedMergeQueryResponse({message: string})
549
546
  /*
550
547
  Comparitor for two events from the same chain. No need for chain id or timestamp
551
548
  */
552
- let compareBufferItem = (a: Internal.eventItem, b: Internal.eventItem) => {
553
- let blockDiff = b.blockNumber - a.blockNumber
549
+ let compareBufferItem = (a: Internal.item, b: Internal.item) => {
550
+ let blockDiff = b->Internal.getItemBlockNumber - a->Internal.getItemBlockNumber
554
551
  if blockDiff === 0 {
555
- b.logIndex - a.logIndex
552
+ b->Internal.getItemLogIndex - a->Internal.getItemLogIndex
556
553
  } else {
557
554
  blockDiff
558
555
  }
559
556
  }
560
557
 
558
+ // Some big number which should be bigger than any log index
559
+ let blockItemLogIndex = 16777216
560
+
561
561
  /*
562
562
  Updates fetchState with a response for a given query.
563
563
  Returns Error if the partition with given query cannot be found (unexpected)
@@ -623,11 +623,39 @@ let handleQueryResult = (
623
623
  )
624
624
  }
625
625
  }->Result.map(partitions => {
626
+ let newQueue = fetchState.queue->Array.concat(newItems)
627
+
628
+ switch fetchState.onBlockConfigs {
629
+ | Some(onBlockConfigs) => {
630
+ let prevLatestFetchedBlockNumber = fetchState.latestFullyFetchedBlock.blockNumber
631
+ let nextLatestFullyFetchedBlockNumber = {
632
+ let nextLatestFullyFetchedBlockNumber = ref(latestFetchedBlock.blockNumber)
633
+ for idx in 0 to partitions->Array.length - 1 {
634
+ let p = partitions->Js.Array2.unsafe_get(idx)
635
+ if nextLatestFullyFetchedBlockNumber.contents > p.latestFetchedBlock.blockNumber {
636
+ nextLatestFullyFetchedBlockNumber := p.latestFetchedBlock.blockNumber
637
+ }
638
+ }
639
+ nextLatestFullyFetchedBlockNumber.contents
640
+ }
641
+
642
+ if nextLatestFullyFetchedBlockNumber > prevLatestFetchedBlockNumber {
643
+ for blockNumber in prevLatestFetchedBlockNumber + 1 to nextLatestFullyFetchedBlockNumber {
644
+ for configIdx in 0 to onBlockConfigs->Array.length - 1 {
645
+ let onBlockConfig = onBlockConfigs->Js.Array2.unsafe_get(configIdx)
646
+ newQueue->Array.push(Block({onBlockConfig, blockNumber, logIndex: blockItemLogIndex}))
647
+ }
648
+ }
649
+ }
650
+ }
651
+
652
+ | None => ()
653
+ }
654
+
626
655
  fetchState->updateInternal(
627
656
  ~partitions,
628
657
  ~currentBlockHeight,
629
- ~queue=fetchState.queue
630
- ->Array.concat(newItems)
658
+ ~queue=newQueue
631
659
  // Theoretically it could be faster to asume that
632
660
  // the items are sorted, but there are cases
633
661
  // when the data source returns them unsorted
@@ -807,7 +835,7 @@ let getNextQuery = (
807
835
  currentBlockHeight
808
836
  } else {
809
837
  switch queue->Array.get(targetBlockIdx) {
810
- | Some(item) => Pervasives.min(item.blockNumber, currentBlockHeight) // Just in case check that we don't query beyond the current block
838
+ | Some(item) => Pervasives.min(item->Internal.getItemBlockNumber, currentBlockHeight) // Just in case check that we don't query beyond the current block
811
839
  | None => currentBlockHeight
812
840
  }
813
841
  }
@@ -881,7 +909,7 @@ let getNextQuery = (
881
909
  }
882
910
  }
883
911
 
884
- type itemWithPopFn = {item: Internal.eventItem, popItemOffQueue: unit => unit}
912
+ type itemWithPopFn = {item: Internal.item, popItemOffQueue: unit => unit}
885
913
 
886
914
  /**
887
915
  Represents a fetchState partitions head of the fetchedEventQueue as either
@@ -891,13 +919,6 @@ type queueItem =
891
919
  | Item(itemWithPopFn)
892
920
  | NoItem({latestFetchedBlock: blockNumberAndTimestamp})
893
921
 
894
- let queueItemBlockNumber = (queueItem: queueItem) => {
895
- switch queueItem {
896
- | Item({item}) => item.blockNumber
897
- | NoItem({latestFetchedBlock: {blockNumber}}) => blockNumber === 0 ? 0 : blockNumber + 1
898
- }
899
- }
900
-
901
922
  /**
902
923
  Simple constructor for no item from partition
903
924
  */
@@ -905,30 +926,6 @@ let makeNoItem = ({latestFetchedBlock}: partition) => NoItem({
905
926
  latestFetchedBlock: latestFetchedBlock,
906
927
  })
907
928
 
908
- /**
909
- Creates a compareable value for items and no items on partition queues.
910
- Block number takes priority here. Since a latest fetched timestamp could
911
- be zero from initialization of partition but a higher latest fetched block number exists
912
-
913
- Note: on the chain manager, when comparing multi chain, the timestamp is the highest priority compare value
914
- */
915
- let qItemLt = (a, b) => {
916
- let aBlockNumber = a->queueItemBlockNumber
917
- let bBlockNumber = b->queueItemBlockNumber
918
- if aBlockNumber < bBlockNumber {
919
- true
920
- } else if aBlockNumber === bBlockNumber {
921
- switch (a, b) {
922
- | (Item(a), Item(b)) => a.item.logIndex < b.item.logIndex
923
- | (NoItem(_), Item(_)) => true
924
- | (Item(_), NoItem(_))
925
- | (NoItem(_), NoItem(_)) => false
926
- }
927
- } else {
928
- false
929
- }
930
- }
931
-
932
929
  /**
933
930
  Gets the earliest queueItem from thgetNodeEarliestEventWithUpdatedQueue.
934
931
 
@@ -938,7 +935,7 @@ queue item with an update fetch state.
938
935
  let getEarliestEvent = ({queue, latestFullyFetchedBlock}: t) => {
939
936
  switch queue->Utils.Array.last {
940
937
  | Some(item) =>
941
- if item.blockNumber <= latestFullyFetchedBlock.blockNumber {
938
+ if item->Internal.getItemBlockNumber <= latestFullyFetchedBlock.blockNumber {
942
939
  Item({item, popItemOffQueue: () => queue->Js.Array2.pop->ignore})
943
940
  } else {
944
941
  NoItem({
@@ -962,6 +959,7 @@ let make = (
962
959
  ~contracts: array<indexingContract>,
963
960
  ~maxAddrInPartition,
964
961
  ~chainId,
962
+ ~onBlockConfigs=?,
965
963
  ~blockLag=0,
966
964
  ): t => {
967
965
  let latestFetchedBlock = {
@@ -1082,11 +1080,11 @@ let make = (
1082
1080
  chainId,
1083
1081
  endBlock,
1084
1082
  latestFullyFetchedBlock: latestFetchedBlock,
1085
- firstEventBlockNumber: None,
1086
1083
  normalSelection,
1087
1084
  indexingContracts,
1088
1085
  dcsToStore: None,
1089
1086
  blockLag,
1087
+ onBlockConfigs,
1090
1088
  queue: [],
1091
1089
  }
1092
1090
  }
@@ -1099,11 +1097,15 @@ let bufferSize = ({queue}: t) => queue->Array.length
1099
1097
  let getLatestFullyFetchedBlock = ({latestFullyFetchedBlock}: t) => latestFullyFetchedBlock
1100
1098
 
1101
1099
  let pruneQueueFromFirstChangeEvent = (
1102
- queue: array<Internal.eventItem>,
1100
+ queue: array<Internal.item>,
1103
1101
  ~firstChangeEvent: blockNumberAndLogIndex,
1104
1102
  ) => {
1105
1103
  queue->Array.keep(item =>
1106
- (item.blockNumber, item.logIndex) < (firstChangeEvent.blockNumber, firstChangeEvent.logIndex)
1104
+ switch item {
1105
+ | Event({blockNumber, logIndex})
1106
+ | Block({blockNumber, logIndex}) => (blockNumber, logIndex)
1107
+ } <
1108
+ (firstChangeEvent.blockNumber, firstChangeEvent.logIndex)
1107
1109
  )
1108
1110
  }
1109
1111
 
@@ -1235,7 +1237,7 @@ let isReadyToEnterReorgThreshold = (
1235
1237
  let filterAndSortForUnorderedBatch = {
1236
1238
  let hasBatchItem = ({queue, latestFullyFetchedBlock}: t) => {
1237
1239
  switch queue->Utils.Array.last {
1238
- | Some(item) => item.blockNumber <= latestFullyFetchedBlock.blockNumber
1240
+ | Some(item) => item->Internal.getItemBlockNumber <= latestFullyFetchedBlock.blockNumber
1239
1241
  | None => false
1240
1242
  }
1241
1243
  }
@@ -1251,8 +1253,8 @@ let filterAndSortForUnorderedBatch = {
1251
1253
  } else {
1252
1254
  // Unsafe can fail when maxBatchSize is 0,
1253
1255
  // but we ignore the case
1254
- (queue->Js.Array2.unsafe_get(targetBlockIdx)).blockNumber <=
1255
- latestFullyFetchedBlock.blockNumber
1256
+ queue->Js.Array2.unsafe_get(targetBlockIdx)->Internal.getItemBlockNumber <=
1257
+ latestFullyFetchedBlock.blockNumber
1256
1258
  }
1257
1259
  }
1258
1260
 
@@ -1264,7 +1266,15 @@ let filterAndSortForUnorderedBatch = {
1264
1266
  | (true, true)
1265
1267
  | (false, false) =>
1266
1268
  // Use unsafe since we filtered out all queues without batch items
1267
- (a.queue->Utils.Array.lastUnsafe).timestamp - (b.queue->Utils.Array.lastUnsafe).timestamp
1269
+ switch (a.queue->Utils.Array.lastUnsafe, b.queue->Utils.Array.lastUnsafe) {
1270
+ | (Event({timestamp: aTimestamp}), Event({timestamp: bTimestamp})) =>
1271
+ aTimestamp - bTimestamp
1272
+ | (Block(_), _)
1273
+ | (_, Block(_)) =>
1274
+ // Currently block items don't have a timestamp,
1275
+ // so we sort chains with them in a random order
1276
+ Js.Math.random_int(-1, 1)
1277
+ }
1268
1278
  | (true, false) => -1
1269
1279
  | (false, true) => 1
1270
1280
  }
@@ -1274,15 +1284,17 @@ let filterAndSortForUnorderedBatch = {
1274
1284
 
1275
1285
  let getProgressBlockNumber = ({latestFullyFetchedBlock, queue}: t) => {
1276
1286
  switch queue->Utils.Array.last {
1277
- | Some(item) if latestFullyFetchedBlock.blockNumber >= item.blockNumber => item.blockNumber - 1
1287
+ | Some(item) if latestFullyFetchedBlock.blockNumber >= item->Internal.getItemBlockNumber =>
1288
+ item->Internal.getItemBlockNumber - 1
1278
1289
  | _ => latestFullyFetchedBlock.blockNumber
1279
1290
  }
1280
1291
  }
1281
1292
 
1282
1293
  let getProgressNextBlockLogIndex = ({queue, latestFullyFetchedBlock}: t) => {
1283
1294
  switch queue->Utils.Array.last {
1284
- | Some(item) if latestFullyFetchedBlock.blockNumber >= item.blockNumber && item.logIndex > 0 =>
1285
- Some(item.logIndex - 1)
1295
+ | Some(Event({logIndex, blockNumber}))
1296
+ if latestFullyFetchedBlock.blockNumber >= blockNumber && logIndex > 0 =>
1297
+ Some(logIndex - 1)
1286
1298
  | _ => None
1287
1299
  }
1288
1300
  }