envio 3.3.0-alpha.6 → 3.3.0-alpha.7

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.
@@ -97,16 +97,24 @@ let getErrorMessage = (exn: exn): option<string> =>
97
97
  // never helps — the same range always re-trips the same cap. The reaction is to
98
98
  // shrink the range and retry immediately, ratcheting the max range down.
99
99
  let isResponseTooLargeError = {
100
+ // Provider-specific "too many logs" messages, matched loosely since each names
101
+ // it differently: HyperRPC ("More than 50000 logs returned"), ZkEVM ("query
102
+ // returned more than N results"), LlamaRPC ("query exceeds max results"),
103
+ // 1RPC ("response size should not..."), Optimism ("(backend) response too
104
+ // large"), Arbitrum ("logs matched by query exceeds limit"), Ankr ("block
105
+ // range is too wide"). Kept as one block rather than per-line comments — the
106
+ // ReScript formatter doesn't preserve comments attached to regex literals in
107
+ // an array.
100
108
  let patterns = [
101
- /more than \d+ logs/i, // HyperRPC: "More than 50000 logs returned"
109
+ /more than \d+ logs/i,
102
110
  /\d+ logs returned/i,
103
111
  /too many logs/i,
104
- /query returned more than \d+ results/i, // ZkEVM
105
- /query exceeds max results/i, // LlamaRPC
106
- /response size should not/i, // 1RPC
107
- /(backend )?response too large/i, // Optimism
108
- /logs matched by query exceeds limit/i, // Arbitrum
109
- /block range is too wide/i, // Ankr
112
+ /query returned more than \d+ results/i,
113
+ /query exceeds max results/i,
114
+ /response size should not/i,
115
+ /(backend )?response too large/i,
116
+ /logs matched by query exceeds limit/i,
117
+ /block range is too wide/i,
110
118
  ]
111
119
  (exn: exn) =>
112
120
  switch exn->getErrorMessage {
@@ -353,8 +361,10 @@ let getNextPage = (
353
361
  ->Promise.race
354
362
  ->Promise.catch(err => {
355
363
  let executedBlockInterval = toBlock - fromBlock + 1
356
- let shrunkBlockInterval =
357
- Pervasives.max(1, (executedBlockInterval->Int.toFloat *. sc.backoffMultiplicative)->Float.toInt)
364
+ let shrunkBlockInterval = Pervasives.max(
365
+ 1,
366
+ (executedBlockInterval->Int.toFloat *. sc.backoffMultiplicative)->Float.toInt,
367
+ )
358
368
 
359
369
  let throwFailedGettingItems = retry =>
360
370
  throw(Source.GetItemsError(FailedGettingItems({exn: err, attemptedToBlock: toBlock, retry})))
@@ -1152,13 +1162,16 @@ let make = (
1152
1162
  ~knownHeight,
1153
1163
  ~partitionId,
1154
1164
  ~selection: FetchState.selection,
1165
+ ~itemsTarget as _,
1155
1166
  ~retry,
1156
1167
  ~logger as _,
1157
1168
  ) => {
1158
1169
  let startFetchingBatchTimeRef = Performance.now()
1159
1170
 
1160
1171
  let sourceMaxBlockInterval =
1161
- mutSuggestedBlockIntervals->getSourceMaxBlockInterval(~intervalCeiling=syncConfig.intervalCeiling)
1172
+ mutSuggestedBlockIntervals->getSourceMaxBlockInterval(
1173
+ ~intervalCeiling=syncConfig.intervalCeiling,
1174
+ )
1162
1175
  let suggestedBlockInterval = Pervasives.min(
1163
1176
  mutSuggestedBlockIntervals
1164
1177
  ->Utils.Dict.dangerouslyGetNonOption(partitionId)
@@ -1040,7 +1040,7 @@ function make(param) {
1040
1040
  Error: new Error()
1041
1041
  };
1042
1042
  }, lowercaseAddresses);
1043
- let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, partitionId, selection, retry, param) => {
1043
+ let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, partitionId, selection, param, retry, param$1) => {
1044
1044
  let startFetchingBatchTimeRef = Performance.now();
1045
1045
  let sourceMaxBlockInterval = getSourceMaxBlockInterval(mutSuggestedBlockIntervals, syncConfig.intervalCeiling);
1046
1046
  let suggestedBlockInterval = Primitive_int.min(Stdlib_Option.getOr(mutSuggestedBlockIntervals[partitionId], syncConfig.initialBlockInterval), sourceMaxBlockInterval);
@@ -26,6 +26,7 @@ let make = (~items: array<Internal.item>, ~endBlock: int, ~chain: ChainMap.Chain
26
26
  ~knownHeight as _,
27
27
  ~partitionId as _,
28
28
  ~selection as _,
29
+ ~itemsTarget as _,
29
30
  ~retry as _,
30
31
  ~logger as _,
31
32
  ) => {
@@ -17,7 +17,7 @@ function make(items, endBlock, chain) {
17
17
  _0: []
18
18
  }),
19
19
  getHeightOrThrow: () => Promise.resolve(Primitive_int.max(endBlock, 1)),
20
- getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8) => {
20
+ getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8, param$9) => {
21
21
  let result = delivered.contents ? [] : (delivered.contents = true, items);
22
22
  let reportedHeight = Primitive_int.max(endBlock, 1);
23
23
  return Promise.resolve({
@@ -64,6 +64,12 @@ type t = {
64
64
  ~knownHeight: int,
65
65
  ~partitionId: string,
66
66
  ~selection: FetchState.selection,
67
+ // Soft cap on the number of primary items (logs/instructions/receipts) the
68
+ // source should ask its backend for, from the query's own estResponseSize.
69
+ // A HyperSync-backed source enforces it server-side, so a wrong estimate
70
+ // truncates the response instead of overshooting the shared buffer. Sources
71
+ // without an equivalent lever (RPC, Fuel, Simulate) ignore it.
72
+ ~itemsTarget: int,
67
73
  ~retry: int,
68
74
  ~logger: Pino.t,
69
75
  ) => promise<blockRangeFetchResponse>,
@@ -680,6 +680,13 @@ let executeQuery = async (
680
680
  ~partitionId=query.partitionId,
681
681
  ~knownHeight,
682
682
  ~selection=query.selection,
683
+ // Ceil (not truncate) so a sub-1 estimate from a sparse partition over a
684
+ // small range doesn't round down to 0 and ask the backend to cap the
685
+ // response at nothing — 0 items is indistinguishable from "no signal".
686
+ ~itemsTarget={
687
+ let est = query.estResponseSize->Math.ceil->Float.toInt
688
+ est > 0 ? est : FetchState.minEstResponseSize->Float.toInt
689
+ },
683
690
  ~retry,
684
691
  ~logger,
685
692
  )
@@ -500,7 +500,8 @@ async function executeQuery(sourceManager, query, knownHeight, isRealtime) {
500
500
  retry: retry
501
501
  });
502
502
  try {
503
- let response = await source.getItemsOrThrow(query.fromBlock, toBlock, query.addressesByContractName, FetchState.deriveContractNameByAddress(query.addressesByContractName), knownHeight, query.partitionId, query.selection, retry, logger$2);
503
+ let est = Math.ceil(query.estResponseSize) | 0;
504
+ let response = await source.getItemsOrThrow(query.fromBlock, toBlock, query.addressesByContractName, FetchState.deriveContractNameByAddress(query.addressesByContractName), knownHeight, query.partitionId, query.selection, est > 0 ? est : FetchState.minEstResponseSize | 0, retry, logger$2);
504
505
  sourceState.lastFailedAt = undefined;
505
506
  responseRef = response;
506
507
  } catch (raw_error) {
@@ -101,6 +101,7 @@ let makeRPCSource = (~chain, ~rpc: string, ~sourceFor: Source.sourceFor=Sync): S
101
101
  ~knownHeight as _,
102
102
  ~partitionId as _,
103
103
  ~selection as _,
104
+ ~itemsTarget as _,
104
105
  ~retry as _,
105
106
  ~logger as _,
106
107
  ) => JsError.throwWithMessage("Svm does not support getting items"),
@@ -76,7 +76,7 @@ function makeRPCSource(chain, rpc, sourceForOpt) {
76
76
  Prometheus.SourceRequestCount.addSeconds(name, chain, "getSlot", seconds);
77
77
  return height;
78
78
  },
79
- getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8) => Stdlib_JsError.throwWithMessage("Svm does not support getting items")
79
+ getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8, param$9) => Stdlib_JsError.throwWithMessage("Svm does not support getting items")
80
80
  };
81
81
  }
82
82
 
@@ -340,6 +340,7 @@ let make = ({chain, endpointUrl, apiToken, eventConfigs, clientTimeoutMillis}: o
340
340
  ~knownHeight,
341
341
  ~partitionId as _,
342
342
  ~selection as _,
343
+ ~itemsTarget,
343
344
  ~retry,
344
345
  ~logger,
345
346
  ) => {
@@ -368,6 +369,7 @@ let make = ({chain, endpointUrl, apiToken, eventConfigs, clientTimeoutMillis}: o
368
369
  toSlot: ?(toBlock->Option.map(toBlock => toBlock + 1)),
369
370
  instructions: instructionSelections,
370
371
  fields,
372
+ maxNumInstructions: itemsTarget,
371
373
  }
372
374
 
373
375
  Prometheus.SourceRequestCount.increment(~sourceName=name, ~chainId, ~method="getInstructions")
@@ -288,7 +288,7 @@ function make(param) {
288
288
  return true;
289
289
  }
290
290
  });
291
- let getItemsOrThrow = async (fromBlock, toBlock, param, contractNameByAddress, knownHeight, param$1, param$2, retry, logger) => {
291
+ let getItemsOrThrow = async (fromBlock, toBlock, param, contractNameByAddress, knownHeight, param$1, param$2, itemsTarget, retry, logger) => {
292
292
  let totalTimeRef = Performance.now();
293
293
  let pageFetchRef = Performance.now();
294
294
  let instructionSelections = buildInstructionSelections(eventConfigs);
@@ -323,11 +323,13 @@ function make(param) {
323
323
  let query_toSlot = Stdlib_Option.map(toBlock, toBlock => toBlock + 1 | 0);
324
324
  let query_instructions = instructionSelections;
325
325
  let query_fields = fields$1;
326
+ let query_maxNumInstructions = itemsTarget;
326
327
  let query = {
327
328
  fromSlot: fromBlock,
328
329
  toSlot: query_toSlot,
329
330
  instructions: query_instructions,
330
- fields: query_fields
331
+ fields: query_fields,
332
+ maxNumInstructions: query_maxNumInstructions
331
333
  };
332
334
  Prometheus.SourceRequestCount.increment(name, chain, "getInstructions");
333
335
  let match;