envio 3.4.0 → 3.5.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,5 +1,6 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
+ import * as Env from "./Env.res.mjs";
3
4
  import * as Utils from "./Utils.res.mjs";
4
5
  import * as Js_math from "@rescript/runtime/lib/es6/Js_math.js";
5
6
  import * as Logging from "./Logging.res.mjs";
@@ -223,7 +224,7 @@ function ascSortFn(a, b) {
223
224
  return Primitive_int.compare(a.latestFetchedBlock.blockNumber, b.latestFetchedBlock.blockNumber);
224
225
  }
225
226
 
226
- function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContracts) {
227
+ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContracts, clientFilteredContracts) {
227
228
  let newPartitions = [];
228
229
  let mergingPartitions = {};
229
230
  let nextPartitionIndexRef = {
@@ -313,7 +314,8 @@ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContrac
313
314
  entities: entities,
314
315
  maxAddrInPartition: maxAddrInPartition,
315
316
  nextPartitionIndex: nextPartitionIndexRef.contents,
316
- dynamicContracts: dynamicContracts
317
+ dynamicContracts: dynamicContracts,
318
+ clientFilteredContracts: clientFilteredContracts
317
319
  };
318
320
  }
319
321
 
@@ -359,26 +361,24 @@ function getPendingQueryOrThrow(p, fromBlock) {
359
361
  }
360
362
  }
361
363
 
362
- function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount, latestFetchedBlock) {
363
- let partitionId = query.partitionId;
364
- let p = optimizedPartitions.entities[partitionId];
365
- let p$1 = p !== undefined ? p : Stdlib_JsError.throwWithMessage(`Unexpected case: Couldn't find partition ` + partitionId);
364
+ function handleQueryResponseForPartition(optimizedPartitions, p, query, knownHeight, itemsCount, latestFetchedBlock) {
366
365
  let mutEntities = Utils.Dict.shallowCopy(optimizedPartitions.entities);
367
- let pendingQuery = getPendingQueryOrThrow(p$1, query.fromBlock);
366
+ let pendingQuery = getPendingQueryOrThrow(p, query.fromBlock);
368
367
  pendingQuery.fetchedBlock = latestFetchedBlock;
369
368
  let blockRange = (latestFetchedBlock.blockNumber - query.fromBlock | 0) + 1 | 0;
370
369
  let observedEventDensity = itemsCount / blockRange;
371
- let eventDensity = p$1.eventDensity;
370
+ let eventDensity = p.eventDensity;
372
371
  let updatedEventDensity = eventDensity !== undefined ? (eventDensity + observedEventDensity) / 2 : observedEventDensity;
373
372
  let shouldUpdateSourceRangeCapacity = false;
374
- if (latestFetchedBlock.blockNumber > p$1.latestSourceRangeCapacityUpdateBlock) {
373
+ if (latestFetchedBlock.blockNumber > p.latestSourceRangeCapacityUpdateBlock) {
375
374
  let queryToBlock = query.toBlock;
376
375
  let tmp;
377
376
  if (queryToBlock !== undefined) {
378
377
  if (latestFetchedBlock.blockNumber < queryToBlock) {
379
- tmp = itemsCount < query.itemsTarget;
378
+ let itemsTarget = query.itemsTarget;
379
+ tmp = itemsTarget !== undefined ? itemsCount < itemsTarget : true;
380
380
  } else {
381
- let minHistoryRange = getMinHistoryRange(p$1);
381
+ let minHistoryRange = getMinHistoryRange(p);
382
382
  tmp = minHistoryRange !== undefined ? ((queryToBlock - query.fromBlock | 0) + 1 | 0) >= minHistoryRange : false;
383
383
  }
384
384
  } else {
@@ -386,10 +386,10 @@ function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount
386
386
  }
387
387
  shouldUpdateSourceRangeCapacity = tmp;
388
388
  }
389
- let updatedSourceRangeCapacity = shouldUpdateSourceRangeCapacity ? blockRange : p$1.sourceRangeCapacity;
390
- let updatedPrevSourceRangeCapacity = shouldUpdateSourceRangeCapacity ? p$1.sourceRangeCapacity : p$1.prevSourceRangeCapacity;
391
- let mutPendingQueries = p$1.mutPendingQueries;
392
- let latestFetchedBlock$1 = p$1.latestFetchedBlock;
389
+ let updatedSourceRangeCapacity = shouldUpdateSourceRangeCapacity ? blockRange : p.sourceRangeCapacity;
390
+ let updatedPrevSourceRangeCapacity = shouldUpdateSourceRangeCapacity ? p.sourceRangeCapacity : p.prevSourceRangeCapacity;
391
+ let mutPendingQueries = p.mutPendingQueries;
392
+ let latestFetchedBlock$1 = p.latestFetchedBlock;
393
393
  let consumedCount = 0;
394
394
  let canContinue = true;
395
395
  while (canContinue) {
@@ -410,19 +410,19 @@ function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount
410
410
  mutPendingQueries.splice(0, consumedCount);
411
411
  }
412
412
  let updatedLatestFetchedBlock = latestFetchedBlock$1;
413
- let mergeBlock = p$1.mergeBlock;
413
+ let mergeBlock = p.mergeBlock;
414
414
  let partitionReachedMergeBlock = mergeBlock !== undefined ? updatedLatestFetchedBlock.blockNumber >= mergeBlock : false;
415
415
  if (partitionReachedMergeBlock) {
416
- Utils.Dict.deleteInPlace(mutEntities, p$1.id);
417
- return make(Object.values(mutEntities), optimizedPartitions.maxAddrInPartition, optimizedPartitions.nextPartitionIndex, optimizedPartitions.dynamicContracts);
416
+ Utils.Dict.deleteInPlace(mutEntities, p.id);
417
+ return make(Object.values(mutEntities), optimizedPartitions.maxAddrInPartition, optimizedPartitions.nextPartitionIndex, optimizedPartitions.dynamicContracts, optimizedPartitions.clientFilteredContracts);
418
418
  }
419
- let updatedMainPartition_id = p$1.id;
420
- let updatedMainPartition_selection = p$1.selection;
421
- let updatedMainPartition_addressesByContractName = p$1.addressesByContractName;
422
- let updatedMainPartition_mergeBlock = p$1.mergeBlock;
423
- let updatedMainPartition_dynamicContract = p$1.dynamicContract;
424
- let updatedMainPartition_mutPendingQueries = p$1.mutPendingQueries;
425
- let updatedMainPartition_latestSourceRangeCapacityUpdateBlock = shouldUpdateSourceRangeCapacity ? latestFetchedBlock.blockNumber : p$1.latestSourceRangeCapacityUpdateBlock;
419
+ let updatedMainPartition_id = p.id;
420
+ let updatedMainPartition_selection = p.selection;
421
+ let updatedMainPartition_addressesByContractName = p.addressesByContractName;
422
+ let updatedMainPartition_mergeBlock = p.mergeBlock;
423
+ let updatedMainPartition_dynamicContract = p.dynamicContract;
424
+ let updatedMainPartition_mutPendingQueries = p.mutPendingQueries;
425
+ let updatedMainPartition_latestSourceRangeCapacityUpdateBlock = shouldUpdateSourceRangeCapacity ? latestFetchedBlock.blockNumber : p.latestSourceRangeCapacityUpdateBlock;
426
426
  let updatedMainPartition = {
427
427
  id: updatedMainPartition_id,
428
428
  latestFetchedBlock: updatedLatestFetchedBlock,
@@ -436,13 +436,13 @@ function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount
436
436
  eventDensity: updatedEventDensity,
437
437
  latestSourceRangeCapacityUpdateBlock: updatedMainPartition_latestSourceRangeCapacityUpdateBlock
438
438
  };
439
- mutEntities[p$1.id] = updatedMainPartition;
439
+ mutEntities[p.id] = updatedMainPartition;
440
440
  if (optimizedPartitions.dynamicContracts.size !== 0) {
441
- return make(Object.values(mutEntities), optimizedPartitions.maxAddrInPartition, optimizedPartitions.nextPartitionIndex, optimizedPartitions.dynamicContracts);
441
+ return make(Object.values(mutEntities), optimizedPartitions.maxAddrInPartition, optimizedPartitions.nextPartitionIndex, optimizedPartitions.dynamicContracts, optimizedPartitions.clientFilteredContracts);
442
442
  }
443
443
  let ids = optimizedPartitions.idsInAscOrder;
444
444
  let count = ids.length;
445
- let idx = ids.indexOf(p$1.id);
445
+ let idx = ids.indexOf(p.id);
446
446
  let isAfter = jdx => {
447
447
  if (jdx < count) {
448
448
  return mutEntities[ids[jdx]].latestFetchedBlock.blockNumber < updatedLatestFetchedBlock.blockNumber;
@@ -456,7 +456,8 @@ function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount
456
456
  entities: mutEntities,
457
457
  maxAddrInPartition: optimizedPartitions.maxAddrInPartition,
458
458
  nextPartitionIndex: optimizedPartitions.nextPartitionIndex,
459
- dynamicContracts: optimizedPartitions.dynamicContracts
459
+ dynamicContracts: optimizedPartitions.dynamicContracts,
460
+ clientFilteredContracts: optimizedPartitions.clientFilteredContracts
460
461
  };
461
462
  }
462
463
  let reordered = ids.slice();
@@ -465,16 +466,26 @@ function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount
465
466
  reordered[jdx] = ids[jdx + 1 | 0];
466
467
  jdx = jdx + 1 | 0;
467
468
  };
468
- reordered[jdx] = p$1.id;
469
+ reordered[jdx] = p.id;
469
470
  return {
470
471
  idsInAscOrder: reordered,
471
472
  entities: mutEntities,
472
473
  maxAddrInPartition: optimizedPartitions.maxAddrInPartition,
473
474
  nextPartitionIndex: optimizedPartitions.nextPartitionIndex,
474
- dynamicContracts: optimizedPartitions.dynamicContracts
475
+ dynamicContracts: optimizedPartitions.dynamicContracts,
476
+ clientFilteredContracts: optimizedPartitions.clientFilteredContracts
475
477
  };
476
478
  }
477
479
 
480
+ function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount, latestFetchedBlock) {
481
+ let p = optimizedPartitions.entities[query.partitionId];
482
+ if (p !== undefined) {
483
+ return handleQueryResponseForPartition(optimizedPartitions, p, query, knownHeight, itemsCount, latestFetchedBlock);
484
+ } else {
485
+ return optimizedPartitions;
486
+ }
487
+ }
488
+
478
489
  function getLatestFullyFetchedBlock(optimizedPartitions) {
479
490
  let id = optimizedPartitions.idsInAscOrder[0];
480
491
  if (id !== undefined) {
@@ -492,6 +503,7 @@ let OptimizedPartitions = {
492
503
  consumeFetchedQueries: consumeFetchedQueries,
493
504
  getPendingQueryOrThrow: getPendingQueryOrThrow,
494
505
  handleQueryResponse: handleQueryResponse,
506
+ handleQueryResponseForPartition: handleQueryResponseForPartition,
495
507
  getLatestFullyFetchedBlock: getLatestFullyFetchedBlock
496
508
  };
497
509
 
@@ -691,7 +703,8 @@ function updateInternal(fetchState, optimizedPartitionsOpt, mutItems, mutItemsSo
691
703
  maxOnBlockBufferSize: fetchState.maxOnBlockBufferSize,
692
704
  onBlockRegistrations: fetchState.onBlockRegistrations,
693
705
  knownHeight: knownHeight,
694
- firstEventBlock: fetchState.firstEventBlock
706
+ firstEventBlock: fetchState.firstEventBlock,
707
+ clientFilterAddressThreshold: fetchState.clientFilterAddressThreshold
695
708
  };
696
709
  }
697
710
 
@@ -725,8 +738,178 @@ function addressesByContractNameGetAll(addressesByContractName) {
725
738
  return all;
726
739
  }
727
740
 
728
- function createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContracts, normalSelection, maxAddrInPartition, nextPartitionIndex, existingPartitions, progressBlockNumber) {
729
- let nextPartitionIndexRef = nextPartitionIndex;
741
+ function addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, threshold) {
742
+ clientFilteredContracts.add(contractName);
743
+ Logging.childTrace(Logging.createChild({
744
+ chainId: chainId,
745
+ contractName: contractName,
746
+ addressCount: addressCount,
747
+ threshold: threshold
748
+ }), "Switching contract to client-side address filtering: registered address count crossed the server-side threshold.");
749
+ }
750
+
751
+ function collapseClientFilteredContracts(partitions, clientFilteredContracts, normalSelection, nextPartitionIndexRef) {
752
+ if (clientFilteredContracts.size === 0) {
753
+ return partitions;
754
+ }
755
+ let kept = [];
756
+ let standingRef = {
757
+ contents: undefined
758
+ };
759
+ let backfills = [];
760
+ let absorbedPartitions = [];
761
+ let strippedFrontiers = [];
762
+ partitions.forEach(p => {
763
+ if (!p.selection.dependsOnAddresses) {
764
+ if (p.mergeBlock !== undefined) {
765
+ backfills.push(p);
766
+ } else if (Stdlib_Option.isNone(standingRef.contents)) {
767
+ standingRef.contents = p;
768
+ } else {
769
+ absorbedPartitions.push(p);
770
+ }
771
+ return;
772
+ }
773
+ let contractNames = Object.keys(p.addressesByContractName);
774
+ let clientFilteredNames = contractNames.filter(c => clientFilteredContracts.has(c));
775
+ if (Utils.$$Array.isEmpty(clientFilteredNames)) {
776
+ kept.push(p);
777
+ return;
778
+ }
779
+ if (clientFilteredNames.length === contractNames.length) {
780
+ absorbedPartitions.push(p);
781
+ return;
782
+ }
783
+ let stripped = Utils.Dict.shallowCopy(p.addressesByContractName);
784
+ clientFilteredNames.forEach(c => Utils.Dict.deleteInPlace(stripped, c));
785
+ strippedFrontiers.push(p.latestFetchedBlock);
786
+ kept.push({
787
+ id: p.id,
788
+ latestFetchedBlock: p.latestFetchedBlock,
789
+ selection: p.selection,
790
+ addressesByContractName: stripped,
791
+ mergeBlock: p.mergeBlock,
792
+ dynamicContract: p.dynamicContract,
793
+ mutPendingQueries: p.mutPendingQueries,
794
+ sourceRangeCapacity: p.sourceRangeCapacity,
795
+ prevSourceRangeCapacity: p.prevSourceRangeCapacity,
796
+ eventDensity: p.eventDensity,
797
+ latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
798
+ });
799
+ });
800
+ let standing = standingRef.contents;
801
+ let selectionChanged = standing !== undefined ? Stdlib_Option.mapOr(standing.selection.clientFilteredContracts, 0, prim => prim.length) !== clientFilteredContracts.size : true;
802
+ if (Utils.$$Array.isEmpty(absorbedPartitions) && Utils.$$Array.isEmpty(strippedFrontiers) && !selectionChanged) {
803
+ return partitions;
804
+ }
805
+ let minFrontierRef = {
806
+ contents: undefined
807
+ };
808
+ let considerFrontier = b => {
809
+ let m = minFrontierRef.contents;
810
+ if (m !== undefined && m.blockNumber <= b.blockNumber) {
811
+ return;
812
+ } else {
813
+ minFrontierRef.contents = b;
814
+ return;
815
+ }
816
+ };
817
+ absorbedPartitions.forEach(p => considerFrontier(p.latestFetchedBlock));
818
+ backfills.forEach(p => considerFrontier(p.latestFetchedBlock));
819
+ strippedFrontiers.forEach(considerFrontier);
820
+ let regByIndex = {};
821
+ let addRegs = regs => {
822
+ regs.forEach(reg => {
823
+ regByIndex[reg.index.toString()] = reg;
824
+ });
825
+ };
826
+ let standing$1 = standingRef.contents;
827
+ if (standing$1 !== undefined) {
828
+ addRegs(standing$1.selection.onEventRegistrations);
829
+ }
830
+ absorbedPartitions.forEach(p => {
831
+ if (!p.selection.dependsOnAddresses) {
832
+ return addRegs(p.selection.onEventRegistrations);
833
+ }
834
+ });
835
+ addRegs(normalSelection.onEventRegistrations.filter(reg => clientFilteredContracts.has(reg.eventConfig.contractName)));
836
+ let newSelection_onEventRegistrations = Object.values(regByIndex);
837
+ let newSelection_clientFilteredContracts = Array.from(clientFilteredContracts);
838
+ let newSelection = {
839
+ onEventRegistrations: newSelection_onEventRegistrations,
840
+ dependsOnAddresses: false,
841
+ clientFilteredContracts: newSelection_clientFilteredContracts
842
+ };
843
+ let standing$2 = standingRef.contents;
844
+ if (standing$2 !== undefined) {
845
+ let standingOut;
846
+ if (selectionChanged) {
847
+ let id = nextPartitionIndexRef.contents.toString();
848
+ nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
849
+ standingOut = {
850
+ id: id,
851
+ latestFetchedBlock: standing$2.latestFetchedBlock,
852
+ selection: newSelection,
853
+ addressesByContractName: standing$2.addressesByContractName,
854
+ mergeBlock: standing$2.mergeBlock,
855
+ dynamicContract: standing$2.dynamicContract,
856
+ mutPendingQueries: [],
857
+ sourceRangeCapacity: standing$2.sourceRangeCapacity,
858
+ prevSourceRangeCapacity: standing$2.prevSourceRangeCapacity,
859
+ eventDensity: standing$2.eventDensity,
860
+ latestSourceRangeCapacityUpdateBlock: standing$2.latestSourceRangeCapacityUpdateBlock
861
+ };
862
+ } else {
863
+ standingOut = standing$2;
864
+ }
865
+ kept.push(standingOut);
866
+ let minFrontier = minFrontierRef.contents;
867
+ if (minFrontier !== undefined && minFrontier.blockNumber < standing$2.latestFetchedBlock.blockNumber) {
868
+ let id$1 = nextPartitionIndexRef.contents.toString();
869
+ nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
870
+ kept.push({
871
+ id: id$1,
872
+ latestFetchedBlock: minFrontier,
873
+ selection: newSelection,
874
+ addressesByContractName: {},
875
+ mergeBlock: standing$2.latestFetchedBlock.blockNumber,
876
+ dynamicContract: undefined,
877
+ mutPendingQueries: [],
878
+ sourceRangeCapacity: standing$2.sourceRangeCapacity,
879
+ prevSourceRangeCapacity: standing$2.prevSourceRangeCapacity,
880
+ eventDensity: standing$2.eventDensity,
881
+ latestSourceRangeCapacityUpdateBlock: 0
882
+ });
883
+ }
884
+ return kept;
885
+ }
886
+ let minFrontier$1 = minFrontierRef.contents;
887
+ if (minFrontier$1 === undefined) {
888
+ return kept;
889
+ }
890
+ let minRange = getMinQueryRange(absorbedPartitions);
891
+ let id$2 = nextPartitionIndexRef.contents.toString();
892
+ nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
893
+ kept.push({
894
+ id: id$2,
895
+ latestFetchedBlock: minFrontier$1,
896
+ selection: newSelection,
897
+ addressesByContractName: {},
898
+ mergeBlock: undefined,
899
+ dynamicContract: undefined,
900
+ mutPendingQueries: [],
901
+ sourceRangeCapacity: minRange,
902
+ prevSourceRangeCapacity: minRange,
903
+ eventDensity: undefined,
904
+ latestSourceRangeCapacityUpdateBlock: 0
905
+ });
906
+ return kept;
907
+ }
908
+
909
+ function createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContracts, clientFilteredContracts, normalSelection, maxAddrInPartition, nextPartitionIndex, existingPartitions, progressBlockNumber) {
910
+ let nextPartitionIndexRef = {
911
+ contents: nextPartitionIndex
912
+ };
730
913
  let dynamicPartitions = [];
731
914
  let nonDynamicPartitions = [];
732
915
  let contractNames = Object.keys(registeringContractsByContract);
@@ -773,7 +956,7 @@ function createPartitionsFromIndexingAddresses(registeringContractsByContract, d
773
956
  let addressesByContractName = {};
774
957
  addressesByContractName[contractName] = pAddresses;
775
958
  partitions.push({
776
- id: nextPartitionIndexRef.toString(),
959
+ id: nextPartitionIndexRef.contents.toString(),
777
960
  latestFetchedBlock: latestFetchedBlock,
778
961
  selection: normalSelection,
779
962
  addressesByContractName: addressesByContractName,
@@ -785,7 +968,7 @@ function createPartitionsFromIndexingAddresses(registeringContractsByContract, d
785
968
  eventDensity: undefined,
786
969
  latestSourceRangeCapacityUpdateBlock: 0
787
970
  });
788
- nextPartitionIndexRef = nextPartitionIndexRef + 1 | 0;
971
+ nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
789
972
  };
790
973
  if (maybeNextStartBlockKey !== undefined) {
791
974
  startBlockRef = Stdlib_Int.fromString(maybeNextStartBlockKey, undefined);
@@ -870,7 +1053,8 @@ function createPartitionsFromIndexingAddresses(registeringContractsByContract, d
870
1053
  mergedNonDynamic.push(currentPRef);
871
1054
  }
872
1055
  let mergedPartitions = mergedNonDynamic.concat(dynamicPartitions);
873
- return make(existingPartitions.concat(mergedPartitions), maxAddrInPartition, nextPartitionIndexRef, dynamicContracts);
1056
+ let allPartitions = collapseClientFilteredContracts(existingPartitions.concat(mergedPartitions), clientFilteredContracts, normalSelection, nextPartitionIndexRef);
1057
+ return make(allPartitions, maxAddrInPartition, nextPartitionIndexRef.contents, dynamicContracts, clientFilteredContracts);
874
1058
  }
875
1059
 
876
1060
  function registerDynamicContracts(fetchState, indexingAddresses, items) {
@@ -1051,7 +1235,21 @@ function registerDynamicContracts(fetchState, indexingAddresses, items) {
1051
1235
  IndexingAddresses.register(indexingAddresses, registeringContracts);
1052
1236
  }
1053
1237
  IndexingAddresses.register(indexingAddresses, noEventsAddresses);
1054
- let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContractsRef, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, fetchState.optimizedPartitions.nextPartitionIndex + newPartitions.length | 0, mutExistingPartitions.concat(newPartitions), 0);
1238
+ let threshold = fetchState.clientFilterAddressThreshold;
1239
+ let clientFilteredContracts;
1240
+ if (threshold !== undefined) {
1241
+ let clientFilteredContracts$1 = new Set(Array.from(fetchState.optimizedPartitions.clientFilteredContracts));
1242
+ Array.from(dynamicContractsRef).forEach(contractName => {
1243
+ let addressCount = IndexingAddresses.contractCount(indexingAddresses, contractName);
1244
+ if (!clientFilteredContracts$1.has(contractName) && addressCount > threshold) {
1245
+ return addClientFilteredContract(clientFilteredContracts$1, contractName, fetchState.chainId, addressCount, threshold);
1246
+ }
1247
+ });
1248
+ clientFilteredContracts = clientFilteredContracts$1;
1249
+ } else {
1250
+ clientFilteredContracts = fetchState.optimizedPartitions.clientFilteredContracts;
1251
+ }
1252
+ let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContractsRef, clientFilteredContracts, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, fetchState.optimizedPartitions.nextPartitionIndex + newPartitions.length | 0, mutExistingPartitions.concat(newPartitions), 0);
1055
1253
  return updateInternal(fetchState, optimizedPartitions, undefined, undefined, undefined, undefined);
1056
1254
  }
1057
1255
 
@@ -1060,9 +1258,10 @@ function filterByClientAddress(items, indexingAddresses) {
1060
1258
  if (item.kind !== 0) {
1061
1259
  return true;
1062
1260
  }
1063
- let filter = item.onEventRegistration.clientAddressFilter;
1261
+ let reg = item.onEventRegistration;
1262
+ let filter = reg.clientAddressFilter;
1064
1263
  if (filter !== undefined) {
1065
- return filter(item.payload, item.blockNumber, IndexingAddresses.rawForFilter(indexingAddresses));
1264
+ return filter(item.payload, item.blockNumber, IndexingAddresses.forContract(indexingAddresses, reg.eventConfig.contractName));
1066
1265
  } else {
1067
1266
  return true;
1068
1267
  }
@@ -1103,15 +1302,14 @@ function startFetchingQueries(param, queries) {
1103
1302
  }
1104
1303
  }
1105
1304
 
1106
- function pushDensityPricedQuery(queries, partitionId, fromBlock, toBlock, isChunk, density, chunkItemsMultiplier, chainTargetBlock, itemsTargetFloor, selection, addressesByContractName) {
1305
+ function pushDensityPricedQuery(queries, partitionId, fromBlock, toBlock, isChunk, density, chainTargetBlock, selection, addressesByContractName) {
1107
1306
  let itemsEst = densityItemsTarget(density, fromBlock, toBlock, chainTargetBlock);
1108
- let itemsTarget = densityItemsTarget(density * chunkItemsMultiplier, fromBlock, toBlock, chainTargetBlock);
1109
1307
  queries.push({
1110
1308
  partitionId: partitionId,
1111
1309
  fromBlock: fromBlock,
1112
1310
  toBlock: toBlock,
1113
1311
  isChunk: isChunk,
1114
- itemsTarget: toBlock !== undefined ? Primitive_int.max(itemsTarget, itemsTargetFloor) : itemsTarget,
1312
+ itemsTarget: toBlock !== undefined ? undefined : itemsEst,
1115
1313
  itemsEst: itemsEst,
1116
1314
  selection: selection,
1117
1315
  addressesByContractName: addressesByContractName
@@ -1119,7 +1317,7 @@ function pushDensityPricedQuery(queries, partitionId, fromBlock, toBlock, isChun
1119
1317
  return itemsEst;
1120
1318
  }
1121
1319
 
1122
- function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock, headBlockNumber, chainTargetBlock, maybeChunkRange, maxChunks, partition, partitionBudget, chunkItemsMultiplier, itemsTargetFloor, selection, addressesByContractName) {
1320
+ function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock, headBlockNumber, chainTargetBlock, maybeChunkRange, maxChunks, partition, partitionBudget, selection, addressesByContractName) {
1123
1321
  if (!(rangeFromBlock <= Primitive_int.min(headBlockNumber, chainTargetBlock) && maxChunks > 0)) {
1124
1322
  return;
1125
1323
  }
@@ -1135,7 +1333,7 @@ function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock,
1135
1333
  if (exit === 1) {
1136
1334
  let maxBlock = rangeEndBlock !== undefined ? rangeEndBlock : chainTargetBlock;
1137
1335
  let pushSingleQuery = (density, isChunk) => {
1138
- pushDensityPricedQuery(queries, partitionId, rangeFromBlock, rangeEndBlock, isChunk, density, chunkItemsMultiplier, chainTargetBlock, itemsTargetFloor, selection, addressesByContractName);
1336
+ pushDensityPricedQuery(queries, partitionId, rangeFromBlock, rangeEndBlock, isChunk, density, chainTargetBlock, selection, addressesByContractName);
1139
1337
  };
1140
1338
  let match = partition.eventDensity;
1141
1339
  let exit$1 = 0;
@@ -1150,7 +1348,7 @@ function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock,
1150
1348
  let chunkIdx = 0;
1151
1349
  while (chunkIdx < maxChunks && ((chunkFromBlock + chunkSize | 0) - 1 | 0) <= maxBlock) {
1152
1350
  let chunkToBlock = (chunkFromBlock + chunkSize | 0) - 1 | 0;
1153
- pushDensityPricedQuery(queries, partitionId, chunkFromBlock, chunkToBlock, true, match, chunkItemsMultiplier, chainTargetBlock, itemsTargetFloor, selection, addressesByContractName);
1351
+ pushDensityPricedQuery(queries, partitionId, chunkFromBlock, chunkToBlock, true, match, chainTargetBlock, selection, addressesByContractName);
1154
1352
  chunkFromBlock = chunkToBlock + 1 | 0;
1155
1353
  chunkIdx = chunkIdx + 1 | 0;
1156
1354
  };
@@ -1173,7 +1371,7 @@ function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock,
1173
1371
  }
1174
1372
  }
1175
1373
 
1176
- function walkPartitionPending(p, partitionId, inFlightCount, candidates, headBlockNumber, chainTargetBlock, chunkItemsMultiplier, itemsTargetFloor, partitionBudget, queryEndBlock) {
1374
+ function walkPartitionPending(p, partitionId, inFlightCount, candidates, headBlockNumber, chainTargetBlock, partitionBudget, queryEndBlock) {
1177
1375
  let maybeChunkRange = getMinHistoryRange(p);
1178
1376
  let pendingCount = p.mutPendingQueries.length;
1179
1377
  let cursor = p.latestFetchedBlock.blockNumber + 1 | 0;
@@ -1184,7 +1382,7 @@ function walkPartitionPending(p, partitionId, inFlightCount, candidates, headBlo
1184
1382
  let pq = p.mutPendingQueries[pqIdx];
1185
1383
  if (pq.fromBlock > cursor) {
1186
1384
  let beforeLen = candidates.length;
1187
- pushGapFillQueries(candidates, partitionId, cursor, Utils.$$Math.minOptInt(pq.fromBlock - 1 | 0, queryEndBlock), headBlockNumber, chainTargetBlock, maybeChunkRange, (12 - inFlightCount | 0) - chunksUsedThisCall | 0, p, partitionBudget, chunkItemsMultiplier, itemsTargetFloor, p.selection, p.addressesByContractName);
1385
+ pushGapFillQueries(candidates, partitionId, cursor, Utils.$$Math.minOptInt(pq.fromBlock - 1 | 0, queryEndBlock), headBlockNumber, chainTargetBlock, maybeChunkRange, (12 - inFlightCount | 0) - chunksUsedThisCall | 0, p, partitionBudget, p.selection, p.addressesByContractName);
1188
1386
  chunksUsedThisCall = chunksUsedThisCall + (candidates.length - beforeLen | 0) | 0;
1189
1387
  }
1190
1388
  let toBlock = pq.toBlock;
@@ -1214,7 +1412,7 @@ function walkPartitionPending(p, partitionId, inFlightCount, candidates, headBlo
1214
1412
  }
1215
1413
  }
1216
1414
 
1217
- function pushForwardCandidates(candidates, inRangeStates, inRangeCount, chainTargetBlock, freshBudget, chunkItemsMultiplier, itemsTargetFloor) {
1415
+ function pushForwardCandidates(candidates, inRangeStates, inRangeCount, chainTargetBlock, freshBudget) {
1218
1416
  let probeShare = inRangeCount === 0 ? 0 : freshBudget / inRangeCount;
1219
1417
  let frontierCursor = Stdlib_Array.reduce(inRangeStates, chainTargetBlock, (min, fs) => {
1220
1418
  if (fs.cursor < min) {
@@ -1240,21 +1438,21 @@ function pushForwardCandidates(candidates, inRangeStates, inRangeCount, chainTar
1240
1438
  let generatedItems = 0;
1241
1439
  while (created < maxChunksRemaining && chunkFromBlock <= chunkStartCeiling && generatedItems <= freshBudget) {
1242
1440
  let chunkToBlock = Primitive_int.min((chunkFromBlock + chunkSize | 0) - 1 | 0, maxBlock);
1243
- let itemsEst = pushDensityPricedQuery(candidates, fs.partitionId, chunkFromBlock, chunkToBlock, true, match$1, chunkItemsMultiplier, chainTargetBlock, itemsTargetFloor, p.selection, p.addressesByContractName);
1441
+ let itemsEst = pushDensityPricedQuery(candidates, fs.partitionId, chunkFromBlock, chunkToBlock, true, match$1, chainTargetBlock, p.selection, p.addressesByContractName);
1244
1442
  generatedItems = generatedItems + itemsEst;
1245
1443
  chunkFromBlock = chunkToBlock + 1 | 0;
1246
1444
  created = created + 1 | 0;
1247
1445
  };
1248
1446
  return;
1249
1447
  }
1250
- let itemsTarget = rangeToTarget > 0 ? Primitive_int.max(1, Math.round(rangeTargetDensity * ((chainTargetBlock - fs.cursor | 0) + 1 | 0) / inRangeCount) | 0) : Primitive_int.max(1, Math.round(probeShare) | 0);
1448
+ let itemsEst$1 = rangeToTarget > 0 ? Primitive_int.max(1, Math.round(rangeTargetDensity * ((chainTargetBlock - fs.cursor | 0) + 1 | 0) / inRangeCount) | 0) : Primitive_int.max(1, Math.round(probeShare) | 0);
1251
1449
  candidates.push({
1252
1450
  partitionId: fs.partitionId,
1253
1451
  fromBlock: fs.cursor,
1254
1452
  toBlock: fs.queryEndBlock,
1255
1453
  isChunk: false,
1256
- itemsTarget: itemsTarget,
1257
- itemsEst: itemsTarget,
1454
+ itemsTarget: itemsEst$1,
1455
+ itemsEst: itemsEst$1,
1258
1456
  selection: p.selection,
1259
1457
  addressesByContractName: p.addressesByContractName
1260
1458
  });
@@ -1300,7 +1498,7 @@ function acceptCandidates(candidates, reservations, chainTargetItems, partitionI
1300
1498
  let remainingBudget = chainTargetItems;
1301
1499
  let acceptIdx = 0;
1302
1500
  let usedConcurrency = reservations.length;
1303
- while (remainingBudget > 0 && acceptIdx < streamCount && usedConcurrency < 100) {
1501
+ while (remainingBudget > 0 && acceptIdx < streamCount && usedConcurrency < Env.maxChainConcurrency) {
1304
1502
  let match = acceptanceStream[acceptIdx];
1305
1503
  let maybeQuery = match[2];
1306
1504
  if (maybeQuery !== undefined) {
@@ -1313,12 +1511,10 @@ function acceptCandidates(candidates, reservations, chainTargetItems, partitionI
1313
1511
  };
1314
1512
  }
1315
1513
 
1316
- function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star, $staropt$star$1) {
1514
+ function getNextQuery(param, chainTargetBlock, chainTargetItems) {
1317
1515
  let blockLag = param.blockLag;
1318
1516
  let endBlock = param.endBlock;
1319
1517
  let optimizedPartitions = param.optimizedPartitions;
1320
- let chunkItemsMultiplier = $staropt$star !== undefined ? $staropt$star : 1;
1321
- let itemsTargetFloor = $staropt$star$1 !== undefined ? $staropt$star$1 : 0;
1322
1518
  let headBlockNumber = param.knownHeight - blockLag | 0;
1323
1519
  if (headBlockNumber <= 0) {
1324
1520
  return "WaitingForNewBlock";
@@ -1353,7 +1549,7 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star,
1353
1549
  shouldWaitForNewBlock = false;
1354
1550
  }
1355
1551
  }
1356
- let availableConcurrency = 100 - reservations.length | 0;
1552
+ let availableConcurrency = Env.maxChainConcurrency - reservations.length | 0;
1357
1553
  let partitionsCount$1 = chainTargetItems <= 0 || shouldWaitForNewBlock || availableConcurrency <= 0 ? 0 : partitionsCount;
1358
1554
  let queriesByPartitionIndex = Stdlib_Array.fromInitializer(partitionsCount$1, param => []);
1359
1555
  let computeQueryEndBlock = p => {
@@ -1370,7 +1566,7 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star,
1370
1566
  for (let idx$1 = 0; idx$1 < partitionsCount$1; ++idx$1) {
1371
1567
  let partitionId$1 = optimizedPartitions.idsInAscOrder[idx$1];
1372
1568
  let p$1 = optimizedPartitions.entities[partitionId$1];
1373
- let fillState = walkPartitionPending(p$1, partitionId$1, inFlightCounts[idx$1], candidates, headBlockNumber, chainTargetBlock, chunkItemsMultiplier, itemsTargetFloor, partitionBudget, computeQueryEndBlock(p$1));
1569
+ let fillState = walkPartitionPending(p$1, partitionId$1, inFlightCounts[idx$1], candidates, headBlockNumber, chainTargetBlock, partitionBudget, computeQueryEndBlock(p$1));
1374
1570
  if (fillState !== undefined) {
1375
1571
  fillStates.push(fillState);
1376
1572
  }
@@ -1391,7 +1587,7 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star,
1391
1587
  let inRangeStates = fillStates.filter(isInRange);
1392
1588
  let inRangeCount = inRangeStates.length;
1393
1589
  let inRangeStates$1 = inRangeCount > availableConcurrency ? (inRangeStates.sort((a, b) => Primitive_int.compare(a.cursor, b.cursor)), inRangeStates.slice(0, availableConcurrency)) : inRangeStates;
1394
- pushForwardCandidates(candidates, inRangeStates$1, inRangeCount, chainTargetBlock, freshBudget, chunkItemsMultiplier, itemsTargetFloor);
1590
+ pushForwardCandidates(candidates, inRangeStates$1, inRangeCount, chainTargetBlock, freshBudget);
1395
1591
  acceptCandidates(candidates, reservations, chainTargetItems, partitionIndexById, queriesByPartitionIndex);
1396
1592
  let queries = queriesByPartitionIndex.flat();
1397
1593
  if (Utils.$$Array.isEmpty(queries)) {
@@ -1440,11 +1636,12 @@ function getReadyItemsCount(fetchState, targetSize, fromItem) {
1440
1636
  return acc;
1441
1637
  }
1442
1638
 
1443
- function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, addresses, maxAddrInPartition, chainId, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, firstEventBlockOpt) {
1639
+ function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, addresses, maxAddrInPartition, chainId, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, firstEventBlockOpt, clientFilterAddressThresholdOpt) {
1444
1640
  let progressBlockNumber = progressBlockNumberOpt !== undefined ? progressBlockNumberOpt : startBlock - 1 | 0;
1445
1641
  let onBlockRegistrations = onBlockRegistrationsOpt !== undefined ? onBlockRegistrationsOpt : [];
1446
1642
  let blockLag = blockLagOpt !== undefined ? blockLagOpt : 0;
1447
1643
  let firstEventBlock = firstEventBlockOpt !== undefined ? Primitive_option.valFromOption(firstEventBlockOpt) : undefined;
1644
+ let clientFilterAddressThreshold = clientFilterAddressThresholdOpt !== undefined ? Primitive_option.valFromOption(clientFilterAddressThresholdOpt) : undefined;
1448
1645
  let latestFetchedBlock = {
1449
1646
  blockNumber: progressBlockNumber,
1450
1647
  blockTimestamp: 0
@@ -1485,6 +1682,7 @@ function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, add
1485
1682
  };
1486
1683
  let registeringContractsByContract = {};
1487
1684
  let dynamicContracts = new Set();
1685
+ let clientFilteredContracts = new Set();
1488
1686
  addresses.forEach(contract => {
1489
1687
  let contractName = contract.contractName;
1490
1688
  if (contractNamesWithNormalEvents.has(contractName)) {
@@ -1497,7 +1695,15 @@ function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, add
1497
1695
  }
1498
1696
  }
1499
1697
  });
1500
- let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContracts, normalSelection, maxAddrInPartition, partitions.length, partitions, progressBlockNumber);
1698
+ if (clientFilterAddressThreshold !== undefined) {
1699
+ Utils.Dict.forEachWithKey(registeringContractsByContract, (addrs, contractName) => {
1700
+ let addressCount = Utils.Dict.size(addrs);
1701
+ if (addressCount > clientFilterAddressThreshold) {
1702
+ return addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, clientFilterAddressThreshold);
1703
+ }
1704
+ });
1705
+ }
1706
+ let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContracts, clientFilteredContracts, normalSelection, maxAddrInPartition, partitions.length, partitions, progressBlockNumber);
1501
1707
  if (optimizedPartitions.idsInAscOrder.length === 0 && Utils.$$Array.isEmpty(onBlockRegistrations)) {
1502
1708
  Stdlib_JsError.throwWithMessage(`Invalid configuration: Nothing to fetch on chain ` + chainId.toString() + `. ` + (`addresses=` + addresses.length.toString() + `, `) + (`onEventRegistrations=` + onEventRegistrations.length.toString() + `, `) + (`normalRegistrations=` + normalRegistrations.length.toString() + `. `) + `Make sure that you provided at least one contract address to index, or have events with Wildcard mode enabled, or have onBlock handlers.`);
1503
1709
  }
@@ -1524,7 +1730,8 @@ function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, add
1524
1730
  maxOnBlockBufferSize: maxOnBlockBufferSize,
1525
1731
  onBlockRegistrations: onBlockRegistrations,
1526
1732
  knownHeight: knownHeight,
1527
- firstEventBlock: firstEventBlock
1733
+ firstEventBlock: firstEventBlock,
1734
+ clientFilterAddressThreshold: clientFilterAddressThreshold
1528
1735
  };
1529
1736
  }
1530
1737
 
@@ -1636,7 +1843,7 @@ function rollback(fetchState, indexingAddresses, targetBlockNumber) {
1636
1843
  });
1637
1844
  }
1638
1845
  }
1639
- let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, fetchState.optimizedPartitions.dynamicContracts, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, nextKeptIdRef, keptPartitions, targetBlockNumber);
1846
+ let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, fetchState.optimizedPartitions.dynamicContracts, fetchState.optimizedPartitions.clientFilteredContracts, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, nextKeptIdRef, keptPartitions, targetBlockNumber);
1640
1847
  return updateInternal({
1641
1848
  optimizedPartitions: fetchState.optimizedPartitions,
1642
1849
  startBlock: fetchState.startBlock,
@@ -1650,7 +1857,8 @@ function rollback(fetchState, indexingAddresses, targetBlockNumber) {
1650
1857
  maxOnBlockBufferSize: fetchState.maxOnBlockBufferSize,
1651
1858
  onBlockRegistrations: fetchState.onBlockRegistrations,
1652
1859
  knownHeight: fetchState.knownHeight,
1653
- firstEventBlock: fetchState.firstEventBlock
1860
+ firstEventBlock: fetchState.firstEventBlock,
1861
+ clientFilterAddressThreshold: fetchState.clientFilterAddressThreshold
1654
1862
  }, optimizedPartitions, fetchState.buffer.filter(item => {
1655
1863
  let tmp;
1656
1864
  tmp = item.kind === 0 ? item.blockNumber : item.blockNumber;
@@ -1687,7 +1895,8 @@ function resetPendingQueries(fetchState) {
1687
1895
  entities: newEntities,
1688
1896
  maxAddrInPartition: init.maxAddrInPartition,
1689
1897
  nextPartitionIndex: init.nextPartitionIndex,
1690
- dynamicContracts: init.dynamicContracts
1898
+ dynamicContracts: init.dynamicContracts,
1899
+ clientFilteredContracts: init.clientFilteredContracts
1691
1900
  },
1692
1901
  startBlock: fetchState.startBlock,
1693
1902
  endBlock: fetchState.endBlock,
@@ -1700,7 +1909,8 @@ function resetPendingQueries(fetchState) {
1700
1909
  maxOnBlockBufferSize: fetchState.maxOnBlockBufferSize,
1701
1910
  onBlockRegistrations: fetchState.onBlockRegistrations,
1702
1911
  knownHeight: fetchState.knownHeight,
1703
- firstEventBlock: fetchState.firstEventBlock
1912
+ firstEventBlock: fetchState.firstEventBlock,
1913
+ clientFilterAddressThreshold: fetchState.clientFilterAddressThreshold
1704
1914
  };
1705
1915
  }
1706
1916
 
@@ -1817,7 +2027,7 @@ let blockItemLogIndex = 16777216;
1817
2027
 
1818
2028
  let maxInFlightChunksPerPartition = 12;
1819
2029
 
1820
- let maxChainConcurrency = 100;
2030
+ let maxChainConcurrency = Env.maxChainConcurrency;
1821
2031
 
1822
2032
  let chunkRangeGrowthFactor = 1.8;
1823
2033
 
@@ -1840,6 +2050,8 @@ export {
1840
2050
  warnDifferentContractType,
1841
2051
  addressesByContractNameCount,
1842
2052
  addressesByContractNameGetAll,
2053
+ addClientFilteredContract,
2054
+ collapseClientFilteredContracts,
1843
2055
  createPartitionsFromIndexingAddresses,
1844
2056
  registerDynamicContracts,
1845
2057
  filterByClientAddress,