ponder 0.9.4 → 0.9.5

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.
@@ -8379,567 +8379,6 @@ var traceSQL = (filter, db, index) => db.selectFrom("traces").select([
8379
8379
  (qb) => qb.where("blockNumber", "<=", filter.toBlock.toString())
8380
8380
  );
8381
8381
 
8382
- // src/sync/events.ts
8383
- import {
8384
- DecodeLogDataMismatch,
8385
- DecodeLogTopicsMismatch,
8386
- checksumAddress as checksumAddress3,
8387
- decodeAbiParameters,
8388
- decodeFunctionData,
8389
- decodeFunctionResult,
8390
- hexToBigInt as hexToBigInt5,
8391
- hexToNumber as hexToNumber4
8392
- } from "viem";
8393
- var buildEvents = ({
8394
- sources,
8395
- blockWithEventData: {
8396
- block,
8397
- logs,
8398
- transactions,
8399
- transactionReceipts,
8400
- traces
8401
- },
8402
- finalizedChildAddresses,
8403
- unfinalizedChildAddresses,
8404
- chainId
8405
- }) => {
8406
- const events = [];
8407
- const transactionCache = /* @__PURE__ */ new Map();
8408
- const transactionReceiptCache = /* @__PURE__ */ new Map();
8409
- for (const transaction of transactions) {
8410
- transactionCache.set(transaction.hash, transaction);
8411
- }
8412
- for (const transactionReceipt of transactionReceipts) {
8413
- transactionReceiptCache.set(
8414
- transactionReceipt.transactionHash,
8415
- transactionReceipt
8416
- );
8417
- }
8418
- for (let i = 0; i < sources.length; i++) {
8419
- const source = sources[i];
8420
- const filter = source.filter;
8421
- if (chainId !== filter.chainId)
8422
- continue;
8423
- switch (source.type) {
8424
- case "contract": {
8425
- switch (filter.type) {
8426
- case "log": {
8427
- for (const log of logs) {
8428
- if (isLogFilterMatched({ filter, block, log }) && (isAddressFactory(filter.address) ? finalizedChildAddresses.get(filter.address).has(log.address) || unfinalizedChildAddresses.get(filter.address).has(log.address) : true)) {
8429
- events.push({
8430
- chainId: filter.chainId,
8431
- sourceIndex: i,
8432
- checkpoint: encodeCheckpoint({
8433
- blockTimestamp: hexToNumber4(block.timestamp),
8434
- chainId: BigInt(filter.chainId),
8435
- blockNumber: hexToBigInt5(log.blockNumber),
8436
- transactionIndex: hexToBigInt5(log.transactionIndex),
8437
- eventType: EVENT_TYPES.logs,
8438
- eventIndex: hexToBigInt5(log.logIndex)
8439
- }),
8440
- log: convertLog(log),
8441
- block: convertBlock(block),
8442
- transaction: transactionCache.has(log.transactionHash) ? convertTransaction(
8443
- transactionCache.get(log.transactionHash)
8444
- ) : void 0,
8445
- transactionReceipt: transactionReceiptCache.has(log.transactionHash) && shouldGetTransactionReceipt(filter) ? convertTransactionReceipt(
8446
- transactionReceiptCache.get(log.transactionHash)
8447
- ) : void 0,
8448
- trace: void 0
8449
- });
8450
- }
8451
- }
8452
- break;
8453
- }
8454
- case "trace": {
8455
- for (const trace of traces) {
8456
- const fromChildAddresses = isAddressFactory(filter.fromAddress) ? [
8457
- finalizedChildAddresses.get(filter.fromAddress),
8458
- unfinalizedChildAddresses.get(filter.fromAddress)
8459
- ] : void 0;
8460
- const toChildAddresses = isAddressFactory(filter.toAddress) ? [
8461
- finalizedChildAddresses.get(filter.toAddress),
8462
- unfinalizedChildAddresses.get(filter.toAddress)
8463
- ] : void 0;
8464
- if (isTraceFilterMatched({
8465
- filter,
8466
- block,
8467
- trace: trace.trace,
8468
- fromChildAddresses,
8469
- toChildAddresses
8470
- }) && (filter.callType === void 0 ? true : filter.callType === trace.trace.type) && (filter.includeReverted ? true : trace.trace.error === void 0)) {
8471
- const transaction = transactionCache.get(
8472
- trace.transactionHash
8473
- );
8474
- const transactionReceipt = transactionReceiptCache.get(
8475
- trace.transactionHash
8476
- );
8477
- events.push({
8478
- chainId: filter.chainId,
8479
- sourceIndex: i,
8480
- checkpoint: encodeCheckpoint({
8481
- blockTimestamp: hexToNumber4(block.timestamp),
8482
- chainId: BigInt(filter.chainId),
8483
- blockNumber: hexToBigInt5(block.number),
8484
- transactionIndex: BigInt(transaction.transactionIndex),
8485
- eventType: EVENT_TYPES.traces,
8486
- eventIndex: BigInt(trace.trace.index)
8487
- }),
8488
- log: void 0,
8489
- trace: convertTrace(trace),
8490
- block: convertBlock(block),
8491
- transaction: convertTransaction(transaction),
8492
- transactionReceipt: shouldGetTransactionReceipt(filter) ? convertTransactionReceipt(transactionReceipt) : void 0
8493
- });
8494
- }
8495
- }
8496
- break;
8497
- }
8498
- }
8499
- break;
8500
- }
8501
- case "account": {
8502
- switch (filter.type) {
8503
- case "transaction": {
8504
- for (const transaction of transactions) {
8505
- const fromChildAddresses = isAddressFactory(filter.fromAddress) ? [
8506
- finalizedChildAddresses.get(filter.fromAddress),
8507
- unfinalizedChildAddresses.get(filter.fromAddress)
8508
- ] : void 0;
8509
- const toChildAddresses = isAddressFactory(filter.toAddress) ? [
8510
- finalizedChildAddresses.get(filter.toAddress),
8511
- unfinalizedChildAddresses.get(filter.toAddress)
8512
- ] : void 0;
8513
- if (isTransactionFilterMatched({
8514
- filter,
8515
- block,
8516
- transaction,
8517
- fromChildAddresses,
8518
- toChildAddresses
8519
- }) && (filter.includeReverted ? true : transactionReceiptCache.get(transaction.hash).status === "0x1")) {
8520
- events.push({
8521
- chainId: filter.chainId,
8522
- sourceIndex: i,
8523
- checkpoint: encodeCheckpoint({
8524
- blockTimestamp: hexToNumber4(block.timestamp),
8525
- chainId: BigInt(filter.chainId),
8526
- blockNumber: hexToBigInt5(block.number),
8527
- transactionIndex: BigInt(transaction.transactionIndex),
8528
- eventType: EVENT_TYPES.transactions,
8529
- eventIndex: 0n
8530
- }),
8531
- log: void 0,
8532
- trace: void 0,
8533
- block: convertBlock(block),
8534
- transaction: convertTransaction(transaction),
8535
- transactionReceipt: convertTransactionReceipt(
8536
- transactionReceiptCache.get(transaction.hash)
8537
- )
8538
- });
8539
- }
8540
- }
8541
- break;
8542
- }
8543
- case "transfer": {
8544
- for (const trace of traces) {
8545
- const fromChildAddresses = isAddressFactory(filter.fromAddress) ? [
8546
- finalizedChildAddresses.get(filter.fromAddress),
8547
- unfinalizedChildAddresses.get(filter.fromAddress)
8548
- ] : void 0;
8549
- const toChildAddresses = isAddressFactory(filter.toAddress) ? [
8550
- finalizedChildAddresses.get(filter.toAddress),
8551
- unfinalizedChildAddresses.get(filter.toAddress)
8552
- ] : void 0;
8553
- if (isTransferFilterMatched({
8554
- filter,
8555
- block,
8556
- trace: trace.trace,
8557
- fromChildAddresses,
8558
- toChildAddresses
8559
- }) && (filter.includeReverted ? true : trace.trace.error === void 0)) {
8560
- const transaction = transactionCache.get(
8561
- trace.transactionHash
8562
- );
8563
- const transactionReceipt = transactionReceiptCache.get(
8564
- trace.transactionHash
8565
- );
8566
- events.push({
8567
- chainId: filter.chainId,
8568
- sourceIndex: i,
8569
- checkpoint: encodeCheckpoint({
8570
- blockTimestamp: hexToNumber4(block.timestamp),
8571
- chainId: BigInt(filter.chainId),
8572
- blockNumber: hexToBigInt5(block.number),
8573
- transactionIndex: BigInt(transaction.transactionIndex),
8574
- eventType: EVENT_TYPES.traces,
8575
- eventIndex: BigInt(trace.trace.index)
8576
- }),
8577
- log: void 0,
8578
- trace: convertTrace(trace),
8579
- block: convertBlock(block),
8580
- transaction: convertTransaction(transaction),
8581
- transactionReceipt: shouldGetTransactionReceipt(filter) ? convertTransactionReceipt(transactionReceipt) : void 0
8582
- });
8583
- }
8584
- }
8585
- break;
8586
- }
8587
- }
8588
- break;
8589
- }
8590
- case "block": {
8591
- if (isBlockFilterMatched({ filter, block })) {
8592
- events.push({
8593
- chainId: filter.chainId,
8594
- sourceIndex: i,
8595
- checkpoint: encodeCheckpoint({
8596
- blockTimestamp: hexToNumber4(block.timestamp),
8597
- chainId: BigInt(filter.chainId),
8598
- blockNumber: hexToBigInt5(block.number),
8599
- transactionIndex: MAX_CHECKPOINT.transactionIndex,
8600
- eventType: EVENT_TYPES.blocks,
8601
- eventIndex: ZERO_CHECKPOINT.eventIndex
8602
- }),
8603
- block: convertBlock(block),
8604
- log: void 0,
8605
- trace: void 0,
8606
- transaction: void 0,
8607
- transactionReceipt: void 0
8608
- });
8609
- }
8610
- break;
8611
- }
8612
- default:
8613
- never(source);
8614
- }
8615
- }
8616
- return events.sort((a, b) => a.checkpoint < b.checkpoint ? -1 : 1);
8617
- };
8618
- var decodeEvents = (common, sources, rawEvents) => {
8619
- const events = [];
8620
- const endClock = startClock();
8621
- for (const event of rawEvents) {
8622
- const source = sources[event.sourceIndex];
8623
- switch (source.type) {
8624
- case "contract": {
8625
- switch (source.filter.type) {
8626
- case "log": {
8627
- try {
8628
- if (event.log.topics[0] === void 0 || source.abiEvents.bySelector[event.log.topics[0]] === void 0) {
8629
- throw new Error();
8630
- }
8631
- const { safeName, item } = source.abiEvents.bySelector[event.log.topics[0]];
8632
- const args = decodeEventLog({
8633
- abiItem: item,
8634
- data: event.log.data,
8635
- topics: event.log.topics
8636
- });
8637
- events.push({
8638
- type: "log",
8639
- chainId: event.chainId,
8640
- checkpoint: event.checkpoint,
8641
- name: `${source.name}:${safeName}`,
8642
- event: {
8643
- name: safeName,
8644
- args: removeNullCharacters(args),
8645
- log: event.log,
8646
- block: event.block,
8647
- transaction: event.transaction,
8648
- transactionReceipt: event.transactionReceipt
8649
- }
8650
- });
8651
- } catch (err) {
8652
- if (source.filter.address === void 0) {
8653
- common.logger.debug({
8654
- service: "app",
8655
- msg: `Unable to decode log, skipping it. id: ${event.log?.id}, data: ${event.log?.data}, topics: ${event.log?.topics}`
8656
- });
8657
- } else {
8658
- common.logger.warn({
8659
- service: "app",
8660
- msg: `Unable to decode log, skipping it. id: ${event.log?.id}, data: ${event.log?.data}, topics: ${event.log?.topics}`
8661
- });
8662
- }
8663
- }
8664
- break;
8665
- }
8666
- case "trace": {
8667
- try {
8668
- const selector = event.trace.input.slice(0, 10).toLowerCase();
8669
- if (source.abiFunctions.bySelector[selector] === void 0) {
8670
- throw new Error();
8671
- }
8672
- const { item, safeName } = source.abiFunctions.bySelector[selector];
8673
- const { args, functionName } = decodeFunctionData({
8674
- abi: [item],
8675
- data: event.trace.input
8676
- });
8677
- const result = decodeFunctionResult({
8678
- abi: [item],
8679
- data: event.trace.output,
8680
- functionName
8681
- });
8682
- events.push({
8683
- type: "trace",
8684
- chainId: event.chainId,
8685
- checkpoint: event.checkpoint,
8686
- // NOTE: `safename` includes ()
8687
- name: `${source.name}.${safeName}`,
8688
- event: {
8689
- args: removeNullCharacters(args),
8690
- result: removeNullCharacters(result),
8691
- trace: event.trace,
8692
- block: event.block,
8693
- transaction: event.transaction,
8694
- transactionReceipt: event.transactionReceipt
8695
- }
8696
- });
8697
- } catch (err) {
8698
- if (source.filter.toAddress === void 0) {
8699
- common.logger.debug({
8700
- service: "app",
8701
- msg: `Unable to decode trace, skipping it. id: ${event.trace?.id}, input: ${event.trace?.input}, output: ${event.trace?.output}`
8702
- });
8703
- } else {
8704
- common.logger.warn({
8705
- service: "app",
8706
- msg: `Unable to decode trace, skipping it. id: ${event.trace?.id}, input: ${event.trace?.input}, output: ${event.trace?.output}`
8707
- });
8708
- }
8709
- }
8710
- break;
8711
- }
8712
- default:
8713
- never(source.filter);
8714
- }
8715
- break;
8716
- }
8717
- case "account": {
8718
- switch (source.filter.type) {
8719
- case "transaction": {
8720
- const isFrom = source.filter.toAddress === void 0;
8721
- events.push({
8722
- type: "transaction",
8723
- chainId: event.chainId,
8724
- checkpoint: event.checkpoint,
8725
- name: `${source.name}:transaction:${isFrom ? "from" : "to"}`,
8726
- event: {
8727
- block: event.block,
8728
- transaction: event.transaction,
8729
- transactionReceipt: event.transactionReceipt
8730
- }
8731
- });
8732
- break;
8733
- }
8734
- case "transfer": {
8735
- const isFrom = source.filter.toAddress === void 0;
8736
- events.push({
8737
- type: "transfer",
8738
- chainId: event.chainId,
8739
- checkpoint: event.checkpoint,
8740
- name: `${source.name}:transfer:${isFrom ? "from" : "to"}`,
8741
- event: {
8742
- transfer: {
8743
- from: event.trace.from,
8744
- to: event.trace.to,
8745
- value: event.trace.value
8746
- },
8747
- block: event.block,
8748
- transaction: event.transaction,
8749
- transactionReceipt: event.transactionReceipt,
8750
- trace: event.trace
8751
- }
8752
- });
8753
- break;
8754
- }
8755
- }
8756
- break;
8757
- }
8758
- case "block": {
8759
- events.push({
8760
- type: "block",
8761
- chainId: event.chainId,
8762
- checkpoint: event.checkpoint,
8763
- name: `${source.name}:block`,
8764
- event: {
8765
- block: event.block
8766
- }
8767
- });
8768
- break;
8769
- }
8770
- default:
8771
- never(source);
8772
- }
8773
- }
8774
- common.metrics.ponder_indexing_abi_decoding_duration.observe(endClock());
8775
- return events;
8776
- };
8777
- function decodeEventLog({
8778
- abiItem,
8779
- topics,
8780
- data
8781
- }) {
8782
- const { inputs } = abiItem;
8783
- const isUnnamed = inputs?.some((x) => !("name" in x && x.name));
8784
- let args = isUnnamed ? [] : {};
8785
- const [, ...argTopics] = topics;
8786
- const indexedInputs = inputs.filter((x) => "indexed" in x && x.indexed);
8787
- for (let i = 0; i < indexedInputs.length; i++) {
8788
- const param = indexedInputs[i];
8789
- const topic = argTopics[i];
8790
- if (!topic)
8791
- throw new DecodeLogTopicsMismatch({
8792
- abiItem,
8793
- param
8794
- });
8795
- args[isUnnamed ? i : param.name || i] = decodeTopic({
8796
- param,
8797
- value: topic
8798
- });
8799
- }
8800
- const nonIndexedInputs = inputs.filter((x) => !("indexed" in x && x.indexed));
8801
- if (nonIndexedInputs.length > 0) {
8802
- if (data && data !== "0x") {
8803
- const decodedData = decodeAbiParameters(nonIndexedInputs, data);
8804
- if (decodedData) {
8805
- if (isUnnamed)
8806
- args = [...args, ...decodedData];
8807
- else {
8808
- for (let i = 0; i < nonIndexedInputs.length; i++) {
8809
- args[nonIndexedInputs[i].name] = decodedData[i];
8810
- }
8811
- }
8812
- }
8813
- } else {
8814
- throw new DecodeLogDataMismatch({
8815
- abiItem,
8816
- data: "0x",
8817
- params: nonIndexedInputs,
8818
- size: 0
8819
- });
8820
- }
8821
- }
8822
- return Object.values(args).length > 0 ? args : void 0;
8823
- }
8824
- function decodeTopic({ param, value }) {
8825
- if (param.type === "string" || param.type === "bytes" || param.type === "tuple" || param.type.match(/^(.*)\[(\d+)?\]$/))
8826
- return value;
8827
- const decodedArg = decodeAbiParameters([param], value) || [];
8828
- return decodedArg[0];
8829
- }
8830
- function removeNullCharacters(obj) {
8831
- if (typeof obj === "string") {
8832
- return obj.replace(/\0/g, "");
8833
- }
8834
- if (Array.isArray(obj)) {
8835
- return obj.map(removeNullCharacters);
8836
- }
8837
- if (obj && typeof obj === "object") {
8838
- const newObj = {};
8839
- for (const [key, val] of Object.entries(obj)) {
8840
- newObj[key] = removeNullCharacters(val);
8841
- }
8842
- return newObj;
8843
- }
8844
- return obj;
8845
- }
8846
- var convertBlock = (block) => ({
8847
- baseFeePerGas: block.baseFeePerGas ? hexToBigInt5(block.baseFeePerGas) : null,
8848
- difficulty: hexToBigInt5(block.difficulty),
8849
- extraData: block.extraData,
8850
- gasLimit: hexToBigInt5(block.gasLimit),
8851
- gasUsed: hexToBigInt5(block.gasUsed),
8852
- hash: block.hash,
8853
- logsBloom: block.logsBloom,
8854
- miner: checksumAddress3(block.miner),
8855
- mixHash: block.mixHash,
8856
- nonce: block.nonce,
8857
- number: hexToBigInt5(block.number),
8858
- parentHash: block.parentHash,
8859
- receiptsRoot: block.receiptsRoot,
8860
- sha3Uncles: block.sha3Uncles,
8861
- size: hexToBigInt5(block.size),
8862
- stateRoot: block.stateRoot,
8863
- timestamp: hexToBigInt5(block.timestamp),
8864
- totalDifficulty: block.totalDifficulty ? hexToBigInt5(block.totalDifficulty) : null,
8865
- transactionsRoot: block.transactionsRoot
8866
- });
8867
- var convertLog = (log) => ({
8868
- id: `${log.blockHash}-${log.logIndex}`,
8869
- address: checksumAddress3(log.address),
8870
- data: log.data,
8871
- logIndex: Number(log.logIndex),
8872
- removed: false,
8873
- topics: log.topics
8874
- });
8875
- var convertTransaction = (transaction) => ({
8876
- from: checksumAddress3(transaction.from),
8877
- gas: hexToBigInt5(transaction.gas),
8878
- hash: transaction.hash,
8879
- input: transaction.input,
8880
- nonce: Number(transaction.nonce),
8881
- r: transaction.r,
8882
- s: transaction.s,
8883
- to: transaction.to ? checksumAddress3(transaction.to) : transaction.to,
8884
- transactionIndex: Number(transaction.transactionIndex),
8885
- value: hexToBigInt5(transaction.value),
8886
- v: transaction.v ? hexToBigInt5(transaction.v) : null,
8887
- ...transaction.type === "0x0" ? {
8888
- type: "legacy",
8889
- gasPrice: hexToBigInt5(transaction.gasPrice)
8890
- } : transaction.type === "0x1" ? {
8891
- type: "eip2930",
8892
- gasPrice: hexToBigInt5(transaction.gasPrice),
8893
- accessList: transaction.accessList
8894
- } : transaction.type === "0x2" ? {
8895
- type: "eip1559",
8896
- maxFeePerGas: hexToBigInt5(transaction.maxFeePerGas),
8897
- maxPriorityFeePerGas: hexToBigInt5(transaction.maxPriorityFeePerGas)
8898
- } : (
8899
- // @ts-ignore
8900
- transaction.type === "0x7e" ? {
8901
- type: "deposit",
8902
- // @ts-ignore
8903
- maxFeePerGas: transaction.maxFeePerGas ? (
8904
- // @ts-ignore
8905
- hexToBigInt5(transaction.maxFeePerGas)
8906
- ) : void 0,
8907
- // @ts-ignore
8908
- maxPriorityFeePerGas: transaction.maxPriorityFeePerGas ? (
8909
- // @ts-ignore
8910
- hexToBigInt5(transaction.maxPriorityFeePerGas)
8911
- ) : void 0
8912
- } : {
8913
- // @ts-ignore
8914
- type: transaction.type
8915
- }
8916
- )
8917
- });
8918
- var convertTransactionReceipt = (transactionReceipt) => ({
8919
- contractAddress: transactionReceipt.contractAddress ? checksumAddress3(transactionReceipt.contractAddress) : null,
8920
- cumulativeGasUsed: hexToBigInt5(transactionReceipt.cumulativeGasUsed),
8921
- effectiveGasPrice: hexToBigInt5(transactionReceipt.effectiveGasPrice),
8922
- from: checksumAddress3(transactionReceipt.from),
8923
- gasUsed: hexToBigInt5(transactionReceipt.gasUsed),
8924
- logsBloom: transactionReceipt.logsBloom,
8925
- status: transactionReceipt.status === "0x1" ? "success" : transactionReceipt.status === "0x0" ? "reverted" : transactionReceipt.status,
8926
- to: transactionReceipt.to ? checksumAddress3(transactionReceipt.to) : null,
8927
- type: transactionReceipt.type === "0x0" ? "legacy" : transactionReceipt.type === "0x1" ? "eip2930" : transactionReceipt.type === "0x2" ? "eip1559" : transactionReceipt.type === "0x7e" ? "deposit" : transactionReceipt.type
8928
- });
8929
- var convertTrace = (trace) => ({
8930
- id: `${trace.transactionHash}-${trace.trace.index}`,
8931
- type: trace.trace.type,
8932
- from: checksumAddress3(trace.trace.from),
8933
- to: trace.trace.to ? checksumAddress3(trace.trace.to) : null,
8934
- input: trace.trace.input,
8935
- output: trace.trace.output,
8936
- gas: hexToBigInt5(trace.trace.gas),
8937
- gasUsed: hexToBigInt5(trace.trace.gasUsed),
8938
- value: trace.trace.value ? hexToBigInt5(trace.trace.value) : null,
8939
- traceIndex: trace.trace.index,
8940
- subcalls: trace.trace.subcalls
8941
- });
8942
-
8943
8382
  // src/utils/range.ts
8944
8383
  var range = (start2, stop) => Array.from({ length: stop - start2 }, (_, i) => start2 + i);
8945
8384
 
@@ -9212,8 +8651,8 @@ var _debug_traceBlockByHash = (requestQueue, {
9212
8651
  // src/sync-historical/index.ts
9213
8652
  import { getLogsRetryHelper } from "@ponder/utils";
9214
8653
  import {
9215
- hexToBigInt as hexToBigInt6,
9216
- hexToNumber as hexToNumber5,
8654
+ hexToBigInt as hexToBigInt5,
8655
+ hexToNumber as hexToNumber4,
9217
8656
  toHex,
9218
8657
  zeroHash
9219
8658
  } from "viem";
@@ -9224,7 +8663,9 @@ var createHistoricalSync = async (args) => {
9224
8663
  const transactionsCache = /* @__PURE__ */ new Set();
9225
8664
  const blockReceiptsCache = /* @__PURE__ */ new Map();
9226
8665
  const transactionReceiptsCache = /* @__PURE__ */ new Map();
9227
- const getLogsRequestMetadata = /* @__PURE__ */ new Map();
8666
+ let logsRequestMetadata = {
8667
+ estimatedRange: 500
8668
+ };
9228
8669
  let intervalsCache;
9229
8670
  if (args.network.disableCache) {
9230
8671
  intervalsCache = /* @__PURE__ */ new Map();
@@ -9242,11 +8683,10 @@ var createHistoricalSync = async (args) => {
9242
8683
  address,
9243
8684
  interval
9244
8685
  }) => {
9245
- const metadata = getLogsRequestMetadata.get(filter);
9246
- const intervals = metadata ? getChunks({
8686
+ const intervals = getChunks({
9247
8687
  interval,
9248
- maxChunkSize: metadata.confirmedRange ?? metadata.estimatedRange
9249
- }) : [interval];
8688
+ maxChunkSize: logsRequestMetadata.confirmedRange ?? logsRequestMetadata.estimatedRange
8689
+ });
9250
8690
  const topics = "eventSelector" in filter ? [filter.eventSelector] : [
9251
8691
  filter.topic0 ?? null,
9252
8692
  filter.topic1 ?? null,
@@ -9300,15 +8740,15 @@ var createHistoricalSync = async (args) => {
9300
8740
  });
9301
8741
  if (getLogsErrorResponse.shouldRetry === false)
9302
8742
  throw error;
9303
- const range2 = hexToNumber5(getLogsErrorResponse.ranges[0].toBlock) - hexToNumber5(getLogsErrorResponse.ranges[0].fromBlock);
8743
+ const range2 = hexToNumber4(getLogsErrorResponse.ranges[0].toBlock) - hexToNumber4(getLogsErrorResponse.ranges[0].fromBlock);
9304
8744
  args.common.logger.debug({
9305
8745
  service: "sync",
9306
8746
  msg: `Caught eth_getLogs error on '${args.network.name}', updating recommended range to ${range2}.`
9307
8747
  });
9308
- getLogsRequestMetadata.set(filter, {
8748
+ logsRequestMetadata = {
9309
8749
  estimatedRange: range2,
9310
8750
  confirmedRange: getLogsErrorResponse.isSuggestedRange ? range2 : void 0
9311
- });
8751
+ };
9312
8752
  return syncLogsDynamic({ address: address2, interval: interval2, filter });
9313
8753
  })
9314
8754
  )
@@ -9326,9 +8766,9 @@ var createHistoricalSync = async (args) => {
9326
8766
  logIds.add(id);
9327
8767
  }
9328
8768
  }
9329
- if (getLogsRequestMetadata.has(filter) && getLogsRequestMetadata.get(filter).confirmedRange === void 0) {
9330
- getLogsRequestMetadata.get(filter).estimatedRange = Math.round(
9331
- getLogsRequestMetadata.get(filter).estimatedRange * 1.05
8769
+ if (logsRequestMetadata.confirmedRange === void 0) {
8770
+ logsRequestMetadata.estimatedRange = Math.round(
8771
+ logsRequestMetadata.estimatedRange * 1.05
9332
8772
  );
9333
8773
  }
9334
8774
  return logs;
@@ -9343,7 +8783,7 @@ var createHistoricalSync = async (args) => {
9343
8783
  });
9344
8784
  blockCache.set(number, _block);
9345
8785
  block = await _block;
9346
- if (hexToBigInt6(block.number) >= hexToBigInt6(latestBlock?.number ?? "0x0")) {
8786
+ if (hexToBigInt5(block.number) >= hexToBigInt5(latestBlock?.number ?? "0x0")) {
9347
8787
  latestBlock = block;
9348
8788
  }
9349
8789
  }
@@ -9449,7 +8889,7 @@ var createHistoricalSync = async (args) => {
9449
8889
  const address = isAddressFactory(filter.address) ? await syncAddressFactory(filter.address, interval) : filter.address;
9450
8890
  const logs = await syncLogsDynamic({ filter, interval, address });
9451
8891
  const blocks = await Promise.all(
9452
- logs.map((log) => syncBlock(hexToNumber5(log.blockNumber)))
8892
+ logs.map((log) => syncBlock(hexToNumber4(log.blockNumber)))
9453
8893
  );
9454
8894
  const requiredBlocks = new Set(blocks.map((b) => b.hash));
9455
8895
  for (let i = 0; i < logs.length; i++) {
@@ -9464,7 +8904,7 @@ var createHistoricalSync = async (args) => {
9464
8904
  if (log.transactionHash === zeroHash) {
9465
8905
  args.common.logger.warn({
9466
8906
  service: "sync",
9467
- msg: `Detected log with empty transaction hash in block ${block.hash} at log index ${hexToNumber5(log.logIndex)}. This is expected for some networks like ZKsync.`
8907
+ msg: `Detected log with empty transaction hash in block ${block.hash} at log index ${hexToNumber4(log.logIndex)}. This is expected for some networks like ZKsync.`
9468
8908
  });
9469
8909
  } else {
9470
8910
  throw new Error(
@@ -9491,7 +8931,7 @@ var createHistoricalSync = async (args) => {
9491
8931
  if (log.transactionHash === zeroHash) {
9492
8932
  args.common.logger.warn({
9493
8933
  service: "sync",
9494
- msg: `Detected log with empty transaction hash in block ${log.blockHash} at log index ${hexToNumber5(log.logIndex)}. This is expected for some networks like ZKsync.`
8934
+ msg: `Detected log with empty transaction hash in block ${log.blockHash} at log index ${hexToNumber4(log.logIndex)}. This is expected for some networks like ZKsync.`
9495
8935
  });
9496
8936
  } else {
9497
8937
  blockTransactionHashes.add(log.transactionHash);
@@ -9691,6 +9131,9 @@ var createHistoricalSync = async (args) => {
9691
9131
  }
9692
9132
  } catch (_error) {
9693
9133
  const error = _error;
9134
+ if (args.common.shutdown.isKilled) {
9135
+ throw new ShutdownError();
9136
+ }
9694
9137
  args.common.logger.error({
9695
9138
  service: "sync",
9696
9139
  msg: `Fatal error: Unable to sync '${args.network.name}' from ${interval[0]} to ${interval[1]}.`,
@@ -9757,10 +9200,10 @@ var createMutex = () => {
9757
9200
  };
9758
9201
 
9759
9202
  // src/sync-realtime/index.ts
9760
- import { hexToNumber as hexToNumber7, zeroHash as zeroHash2 } from "viem";
9203
+ import { hexToNumber as hexToNumber6, zeroHash as zeroHash2 } from "viem";
9761
9204
 
9762
9205
  // src/sync-realtime/bloom.ts
9763
- import { hexToBytes, hexToNumber as hexToNumber6, keccak256 } from "viem";
9206
+ import { hexToBytes, hexToNumber as hexToNumber5, keccak256 } from "viem";
9764
9207
  var zeroLogsBloom = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
9765
9208
  var BLOOM_SIZE_BYTES = 256;
9766
9209
  var isInBloom = (_bloom, input) => {
@@ -9777,7 +9220,7 @@ function isFilterInBloom({
9777
9220
  block,
9778
9221
  filter
9779
9222
  }) {
9780
- if (hexToNumber6(block.number) < (filter.fromBlock ?? 0) || hexToNumber6(block.number) > (filter.toBlock ?? Number.POSITIVE_INFINITY)) {
9223
+ if (hexToNumber5(block.number) < (filter.fromBlock ?? 0) || hexToNumber5(block.number) > (filter.toBlock ?? Number.POSITIVE_INFINITY)) {
9781
9224
  return false;
9782
9225
  }
9783
9226
  const isTopicsInBloom = [
@@ -9903,7 +9346,7 @@ var createRealtimeSync = (args) => {
9903
9346
  }) => {
9904
9347
  args.common.logger.debug({
9905
9348
  service: "realtime",
9906
- msg: `Started syncing '${args.network.name}' block ${hexToNumber7(block.number)}`
9349
+ msg: `Started syncing '${args.network.name}' block ${hexToNumber6(block.number)}`
9907
9350
  });
9908
9351
  for (const log of factoryLogs) {
9909
9352
  for (const filter of factories) {
@@ -10038,12 +9481,12 @@ var createRealtimeSync = (args) => {
10038
9481
  const text = _text.filter((t) => t !== void 0).join(" and ");
10039
9482
  args.common.logger.info({
10040
9483
  service: "realtime",
10041
- msg: `Synced ${text} from '${args.network.name}' block ${hexToNumber7(block.number)}`
9484
+ msg: `Synced ${text} from '${args.network.name}' block ${hexToNumber6(block.number)}`
10042
9485
  });
10043
9486
  } else {
10044
9487
  args.common.logger.info({
10045
9488
  service: "realtime",
10046
- msg: `Synced block ${hexToNumber7(block.number)} from '${args.network.name}' `
9489
+ msg: `Synced block ${hexToNumber6(block.number)} from '${args.network.name}' `
10047
9490
  });
10048
9491
  }
10049
9492
  unfinalizedBlocks.push(syncBlockToLightBlock(block));
@@ -10059,20 +9502,20 @@ var createRealtimeSync = (args) => {
10059
9502
  transactionReceipts,
10060
9503
  endClock
10061
9504
  });
10062
- const blockMovesFinality = hexToNumber7(block.number) >= hexToNumber7(finalizedBlock.number) + 2 * args.network.finalityBlockCount;
9505
+ const blockMovesFinality = hexToNumber6(block.number) >= hexToNumber6(finalizedBlock.number) + 2 * args.network.finalityBlockCount;
10063
9506
  if (blockMovesFinality) {
10064
9507
  const pendingFinalizedBlock = unfinalizedBlocks.find(
10065
- (lb) => hexToNumber7(lb.number) === hexToNumber7(block.number) - args.network.finalityBlockCount
9508
+ (lb) => hexToNumber6(lb.number) === hexToNumber6(block.number) - args.network.finalityBlockCount
10066
9509
  );
10067
9510
  args.common.logger.debug({
10068
9511
  service: "realtime",
10069
- msg: `Finalized ${hexToNumber7(pendingFinalizedBlock.number) - hexToNumber7(finalizedBlock.number) + 1} '${args.network.name}' blocks [${hexToNumber7(finalizedBlock.number) + 1}, ${hexToNumber7(pendingFinalizedBlock.number)}]`
9512
+ msg: `Finalized ${hexToNumber6(pendingFinalizedBlock.number) - hexToNumber6(finalizedBlock.number) + 1} '${args.network.name}' blocks [${hexToNumber6(finalizedBlock.number) + 1}, ${hexToNumber6(pendingFinalizedBlock.number)}]`
10070
9513
  });
10071
9514
  const finalizedBlocks = unfinalizedBlocks.filter(
10072
- (lb) => hexToNumber7(lb.number) <= hexToNumber7(pendingFinalizedBlock.number)
9515
+ (lb) => hexToNumber6(lb.number) <= hexToNumber6(pendingFinalizedBlock.number)
10073
9516
  );
10074
9517
  unfinalizedBlocks = unfinalizedBlocks.filter(
10075
- (lb) => hexToNumber7(lb.number) > hexToNumber7(pendingFinalizedBlock.number)
9518
+ (lb) => hexToNumber6(lb.number) > hexToNumber6(pendingFinalizedBlock.number)
10076
9519
  );
10077
9520
  for (const filter of factories) {
10078
9521
  for (const { hash } of finalizedBlocks) {
@@ -10100,550 +9543,1113 @@ var createRealtimeSync = (args) => {
10100
9543
  }
10101
9544
  }
10102
9545
  }
10103
- for (const { hash } of finalizedBlocks) {
10104
- factoryLogsPerBlock.delete(hash);
9546
+ for (const { hash } of finalizedBlocks) {
9547
+ factoryLogsPerBlock.delete(hash);
9548
+ }
9549
+ finalizedBlock = pendingFinalizedBlock;
9550
+ await args.onEvent({ type: "finalize", block: pendingFinalizedBlock });
9551
+ }
9552
+ };
9553
+ const handleReorg = async (block) => {
9554
+ args.common.logger.warn({
9555
+ service: "realtime",
9556
+ msg: `Detected forked '${args.network.name}' block at height ${hexToNumber6(block.number)}`
9557
+ });
9558
+ const reorgedBlocks = unfinalizedBlocks.filter(
9559
+ (lb) => hexToNumber6(lb.number) >= hexToNumber6(block.number)
9560
+ );
9561
+ unfinalizedBlocks = unfinalizedBlocks.filter(
9562
+ (lb) => hexToNumber6(lb.number) < hexToNumber6(block.number)
9563
+ );
9564
+ let remoteBlock = block;
9565
+ while (true) {
9566
+ const parentBlock = getLatestUnfinalizedBlock();
9567
+ if (parentBlock.hash === remoteBlock.parentHash)
9568
+ break;
9569
+ if (unfinalizedBlocks.length === 0) {
9570
+ const msg = `Encountered unrecoverable '${args.network.name}' reorg beyond finalized block ${hexToNumber6(finalizedBlock.number)}`;
9571
+ args.common.logger.warn({ service: "realtime", msg });
9572
+ throw new Error(msg);
9573
+ } else {
9574
+ remoteBlock = await _eth_getBlockByHash(args.requestQueue, {
9575
+ hash: remoteBlock.parentHash
9576
+ });
9577
+ reorgedBlocks.push(unfinalizedBlocks.pop());
9578
+ }
9579
+ }
9580
+ const commonAncestor = getLatestUnfinalizedBlock();
9581
+ await args.onEvent({ type: "reorg", block: commonAncestor, reorgedBlocks });
9582
+ args.common.logger.warn({
9583
+ service: "realtime",
9584
+ msg: `Reconciled ${reorgedBlocks.length}-block '${args.network.name}' reorg with common ancestor block ${hexToNumber6(commonAncestor.number)}`
9585
+ });
9586
+ unfinalizedChildAddresses.clear();
9587
+ for (const filter of factories) {
9588
+ unfinalizedChildAddresses.set(filter, /* @__PURE__ */ new Set());
9589
+ for (const { hash } of unfinalizedBlocks) {
9590
+ const factoryLogs = factoryLogsPerBlock.get(hash);
9591
+ if (factoryLogs !== void 0) {
9592
+ for (const log of factoryLogs) {
9593
+ if (isLogFactoryMatched({ filter, log })) {
9594
+ unfinalizedChildAddresses.get(filter).add(getChildAddress({ log, factory: filter }));
9595
+ }
9596
+ }
9597
+ }
9598
+ }
9599
+ }
9600
+ for (const { hash } of reorgedBlocks) {
9601
+ factoryLogsPerBlock.delete(hash);
9602
+ }
9603
+ };
9604
+ const syncTransactionReceipts = async (blockHash, transactionHashes) => {
9605
+ if (transactionHashes.size === 0) {
9606
+ return [];
9607
+ }
9608
+ if (isBlockReceipts === false) {
9609
+ const transactionReceipts2 = await Promise.all(
9610
+ Array.from(transactionHashes).map(
9611
+ async (hash) => _eth_getTransactionReceipt(args.requestQueue, { hash })
9612
+ )
9613
+ );
9614
+ return transactionReceipts2;
9615
+ }
9616
+ let blockReceipts;
9617
+ try {
9618
+ blockReceipts = await _eth_getBlockReceipts(args.requestQueue, {
9619
+ blockHash
9620
+ });
9621
+ } catch (_error) {
9622
+ const error = _error;
9623
+ args.common.logger.warn({
9624
+ service: "realtime",
9625
+ msg: `Caught eth_getBlockReceipts error on '${args.network.name}', switching to eth_getTransactionReceipt method.`,
9626
+ error
9627
+ });
9628
+ isBlockReceipts = false;
9629
+ return syncTransactionReceipts(blockHash, transactionHashes);
9630
+ }
9631
+ const blockReceiptsTransactionHashes = new Set(
9632
+ blockReceipts.map((r) => r.transactionHash)
9633
+ );
9634
+ for (const hash of Array.from(transactionHashes)) {
9635
+ if (blockReceiptsTransactionHashes.has(hash) === false) {
9636
+ throw new Error(
9637
+ `Detected inconsistent RPC responses. 'transaction.hash' ${hash} not found in eth_getBlockReceipts response for block '${blockHash}'`
9638
+ );
9639
+ }
9640
+ }
9641
+ const transactionReceipts = blockReceipts.filter(
9642
+ (receipt) => transactionHashes.has(receipt.transactionHash)
9643
+ );
9644
+ return transactionReceipts;
9645
+ };
9646
+ const fetchBlockEventData = async (block) => {
9647
+ const shouldRequestLogs = block.logsBloom === zeroLogsBloom || logFilters.some((filter) => isFilterInBloom({ block, filter }));
9648
+ let logs = [];
9649
+ if (shouldRequestLogs) {
9650
+ logs = await _eth_getLogs(args.requestQueue, { blockHash: block.hash });
9651
+ if (block.logsBloom !== zeroLogsBloom && logs.length === 0) {
9652
+ throw new Error(
9653
+ "Detected invalid eth_getLogs response. `block.logsBloom` is not empty but zero logs were returned."
9654
+ );
9655
+ }
9656
+ const logIds = /* @__PURE__ */ new Set();
9657
+ for (const log of logs) {
9658
+ if (log.blockHash !== block.hash) {
9659
+ throw new Error(
9660
+ `Detected invalid eth_getLogs response. 'log.blockHash' ${log.blockHash} does not match requested block hash ${block.hash}`
9661
+ );
9662
+ }
9663
+ const id = `${log.blockHash}-${log.logIndex}`;
9664
+ if (logIds.has(id)) {
9665
+ args.common.logger.warn({
9666
+ service: "sync",
9667
+ msg: `Detected invalid eth_getLogs response. Duplicate log index ${log.logIndex} for block ${log.blockHash}.`
9668
+ });
9669
+ } else {
9670
+ logIds.add(id);
9671
+ }
9672
+ if (block.transactions.find((t) => t.hash === log.transactionHash) === void 0) {
9673
+ if (log.transactionHash === zeroHash2) {
9674
+ args.common.logger.warn({
9675
+ service: "sync",
9676
+ msg: `Detected '${args.network.name}' log with empty transaction hash in block ${block.hash} at log index ${hexToNumber6(log.logIndex)}. This is expected for some networks like ZKsync.`
9677
+ });
9678
+ } else {
9679
+ throw new Error(
9680
+ `Detected inconsistent '${args.network.name}' RPC responses. 'log.transactionHash' ${log.transactionHash} not found in 'block.transactions' ${block.hash}`
9681
+ );
9682
+ }
9683
+ }
9684
+ }
9685
+ }
9686
+ if (shouldRequestLogs === false && args.sources.some((s) => s.filter.type === "log")) {
9687
+ args.common.logger.debug({
9688
+ service: "realtime",
9689
+ msg: `Skipped fetching '${args.network.name}' logs for block ${hexToNumber6(block.number)} due to bloom filter result`
9690
+ });
9691
+ }
9692
+ const shouldRequestTraces = traceFilters.length > 0 || transferFilters.length > 0;
9693
+ let traces = [];
9694
+ if (shouldRequestTraces) {
9695
+ traces = await _debug_traceBlockByHash(args.requestQueue, {
9696
+ hash: block.hash
9697
+ });
9698
+ if (block.transactions.length !== 0 && traces.length === 0) {
9699
+ throw new Error(
9700
+ "Detected invalid debug_traceBlock response. `block.transactions` is not empty but zero traces were returned."
9701
+ );
9702
+ }
9703
+ }
9704
+ for (const trace of traces) {
9705
+ if (block.transactions.find((t) => t.hash === trace.transactionHash) === void 0) {
9706
+ throw new Error(
9707
+ `Detected inconsistent RPC responses. 'trace.txHash' ${trace.transactionHash} not found in 'block' ${block.hash}`
9708
+ );
9709
+ }
9710
+ }
9711
+ const factoryLogs = logs.filter((log) => {
9712
+ let isMatched = false;
9713
+ for (const filter of factories) {
9714
+ if (isLogFactoryMatched({ filter, log })) {
9715
+ if (factoryLogsPerBlock.has(block.hash) === false) {
9716
+ factoryLogsPerBlock.set(block.hash, []);
9717
+ }
9718
+ factoryLogsPerBlock.get(block.hash).push(log);
9719
+ isMatched = true;
9720
+ }
9721
+ }
9722
+ return isMatched;
9723
+ });
9724
+ const requiredTransactions = /* @__PURE__ */ new Set();
9725
+ const requiredTransactionReceipts = /* @__PURE__ */ new Set();
9726
+ logs = logs.filter((log) => {
9727
+ let isMatched = false;
9728
+ for (const filter of logFilters) {
9729
+ if (isLogFilterMatched({ filter, block, log })) {
9730
+ isMatched = true;
9731
+ if (log.transactionHash === zeroHash2) {
9732
+ args.common.logger.warn({
9733
+ service: "sync",
9734
+ msg: `Detected '${args.network.name}' log with empty transaction hash in block ${block.hash} at log index ${hexToNumber6(log.logIndex)}. This is expected for some networks like ZKsync.`
9735
+ });
9736
+ } else {
9737
+ requiredTransactions.add(log.transactionHash);
9738
+ if (shouldGetTransactionReceipt(filter)) {
9739
+ requiredTransactionReceipts.add(log.transactionHash);
9740
+ break;
9741
+ }
9742
+ }
9743
+ }
9744
+ }
9745
+ return isMatched;
9746
+ });
9747
+ traces = traces.filter((trace) => {
9748
+ let isMatched = false;
9749
+ for (const filter of transferFilters) {
9750
+ if (isTransferFilterMatched({
9751
+ filter,
9752
+ block: { number: block.number },
9753
+ trace: trace.trace
9754
+ })) {
9755
+ requiredTransactions.add(trace.transactionHash);
9756
+ isMatched = true;
9757
+ if (shouldGetTransactionReceipt(filter)) {
9758
+ requiredTransactionReceipts.add(trace.transactionHash);
9759
+ break;
9760
+ }
9761
+ }
9762
+ }
9763
+ for (const filter of traceFilters) {
9764
+ if (isTraceFilterMatched({
9765
+ filter,
9766
+ block: { number: block.number },
9767
+ trace: trace.trace
9768
+ })) {
9769
+ requiredTransactions.add(trace.transactionHash);
9770
+ isMatched = true;
9771
+ if (shouldGetTransactionReceipt(filter)) {
9772
+ requiredTransactionReceipts.add(trace.transactionHash);
9773
+ break;
9774
+ }
9775
+ }
9776
+ }
9777
+ return isMatched;
9778
+ });
9779
+ const transactions = block.transactions.filter((transaction) => {
9780
+ let isMatched = requiredTransactions.has(transaction.hash);
9781
+ for (const filter of transactionFilters) {
9782
+ if (isTransactionFilterMatched({ filter, block, transaction })) {
9783
+ requiredTransactions.add(transaction.hash);
9784
+ requiredTransactionReceipts.add(transaction.hash);
9785
+ isMatched = true;
9786
+ }
10105
9787
  }
10106
- finalizedBlock = pendingFinalizedBlock;
10107
- await args.onEvent({ type: "finalize", block: pendingFinalizedBlock });
10108
- }
10109
- };
10110
- const handleReorg = async (block) => {
10111
- args.common.logger.warn({
10112
- service: "realtime",
10113
- msg: `Detected forked '${args.network.name}' block at height ${hexToNumber7(block.number)}`
9788
+ return isMatched;
10114
9789
  });
10115
- const reorgedBlocks = unfinalizedBlocks.filter(
10116
- (lb) => hexToNumber7(lb.number) >= hexToNumber7(block.number)
10117
- );
10118
- unfinalizedBlocks = unfinalizedBlocks.filter(
10119
- (lb) => hexToNumber7(lb.number) < hexToNumber7(block.number)
9790
+ const blockTransactionsHashes = new Set(
9791
+ block.transactions.map((t) => t.hash)
10120
9792
  );
10121
- let remoteBlock = block;
10122
- while (true) {
10123
- const parentBlock = getLatestUnfinalizedBlock();
10124
- if (parentBlock.hash === remoteBlock.parentHash)
10125
- break;
10126
- if (unfinalizedBlocks.length === 0) {
10127
- const msg = `Encountered unrecoverable '${args.network.name}' reorg beyond finalized block ${hexToNumber7(finalizedBlock.number)}`;
10128
- args.common.logger.warn({ service: "realtime", msg });
10129
- throw new Error(msg);
10130
- } else {
10131
- remoteBlock = await _eth_getBlockByHash(args.requestQueue, {
10132
- hash: remoteBlock.parentHash
10133
- });
10134
- reorgedBlocks.push(unfinalizedBlocks.pop());
9793
+ for (const hash of Array.from(requiredTransactions)) {
9794
+ if (blockTransactionsHashes.has(hash) === false) {
9795
+ throw new Error(
9796
+ `Detected inconsistent RPC responses. 'transaction.hash' ${hash} not found in eth_getBlockReceipts response for block '${block.hash}'.`
9797
+ );
10135
9798
  }
10136
9799
  }
10137
- const commonAncestor = getLatestUnfinalizedBlock();
10138
- await args.onEvent({ type: "reorg", block: commonAncestor, reorgedBlocks });
10139
- args.common.logger.warn({
10140
- service: "realtime",
10141
- msg: `Reconciled ${reorgedBlocks.length}-block '${args.network.name}' reorg with common ancestor block ${hexToNumber7(commonAncestor.number)}`
10142
- });
10143
- unfinalizedChildAddresses.clear();
10144
- for (const filter of factories) {
10145
- unfinalizedChildAddresses.set(filter, /* @__PURE__ */ new Set());
10146
- for (const { hash } of unfinalizedBlocks) {
10147
- const factoryLogs = factoryLogsPerBlock.get(hash);
10148
- if (factoryLogs !== void 0) {
10149
- for (const log of factoryLogs) {
10150
- if (isLogFactoryMatched({ filter, log })) {
10151
- unfinalizedChildAddresses.get(filter).add(getChildAddress({ log, factory: filter }));
9800
+ const transactionReceipts = await syncTransactionReceipts(
9801
+ block.hash,
9802
+ requiredTransactionReceipts
9803
+ );
9804
+ return {
9805
+ block,
9806
+ logs,
9807
+ factoryLogs,
9808
+ traces,
9809
+ transactions,
9810
+ transactionReceipts
9811
+ };
9812
+ };
9813
+ const getLatestUnfinalizedBlock = () => {
9814
+ if (unfinalizedBlocks.length === 0) {
9815
+ return finalizedBlock;
9816
+ } else
9817
+ return unfinalizedBlocks[unfinalizedBlocks.length - 1];
9818
+ };
9819
+ return {
9820
+ start(startArgs) {
9821
+ finalizedBlock = startArgs.syncProgress.finalized;
9822
+ finalizedChildAddresses = startArgs.initialChildAddresses;
9823
+ const processBlock = mutex(
9824
+ async ({
9825
+ block,
9826
+ ...rest
9827
+ }) => {
9828
+ const latestBlock = getLatestUnfinalizedBlock();
9829
+ if (latestBlock.hash === block.hash) {
9830
+ args.common.logger.trace({
9831
+ service: "realtime",
9832
+ msg: `Skipped processing '${args.network.name}' block ${hexToNumber6(block.number)}, already synced`
9833
+ });
9834
+ return;
9835
+ }
9836
+ try {
9837
+ if (hexToNumber6(latestBlock.number) >= hexToNumber6(block.number)) {
9838
+ await handleReorg(block);
9839
+ processBlock.clear();
9840
+ return;
9841
+ }
9842
+ if (hexToNumber6(latestBlock.number) + 1 < hexToNumber6(block.number)) {
9843
+ const missingBlockRange = range(
9844
+ hexToNumber6(latestBlock.number) + 1,
9845
+ Math.min(
9846
+ hexToNumber6(block.number),
9847
+ hexToNumber6(latestBlock.number) + MAX_QUEUED_BLOCKS
9848
+ )
9849
+ );
9850
+ const pendingBlocks = await Promise.all(
9851
+ missingBlockRange.map(
9852
+ (blockNumber) => _eth_getBlockByNumber(args.requestQueue, {
9853
+ blockNumber
9854
+ }).then((block2) => fetchBlockEventData(block2))
9855
+ )
9856
+ );
9857
+ args.common.logger.debug({
9858
+ service: "realtime",
9859
+ msg: `Fetched ${missingBlockRange.length} missing '${args.network.name}' blocks [${hexToNumber6(latestBlock.number) + 1}, ${Math.min(
9860
+ hexToNumber6(block.number),
9861
+ hexToNumber6(latestBlock.number) + MAX_QUEUED_BLOCKS
9862
+ )}]`
9863
+ });
9864
+ processBlock.clear();
9865
+ for (const pendingBlock of pendingBlocks) {
9866
+ processBlock(pendingBlock);
9867
+ }
9868
+ processBlock({ block, ...rest });
9869
+ return;
9870
+ }
9871
+ if (block.parentHash !== latestBlock.hash) {
9872
+ await handleReorg(block);
9873
+ processBlock.clear();
9874
+ return;
9875
+ }
9876
+ await handleBlock({ block, ...rest });
9877
+ consecutiveErrors = 0;
9878
+ return;
9879
+ } catch (_error) {
9880
+ const error = _error;
9881
+ if (args.common.shutdown.isKilled) {
9882
+ throw new ShutdownError();
9883
+ }
9884
+ args.common.logger.warn({
9885
+ service: "realtime",
9886
+ msg: `Failed to process '${args.network.name}' block ${hexToNumber6(block.number)}`,
9887
+ error
9888
+ });
9889
+ const duration = ERROR_TIMEOUT[consecutiveErrors];
9890
+ args.common.logger.warn({
9891
+ service: "realtime",
9892
+ msg: `Retrying '${args.network.name}' sync after ${duration} ${duration === 1 ? "second" : "seconds"}.`
9893
+ });
9894
+ await wait(duration * 1e3);
9895
+ processBlock.clear();
9896
+ if (++consecutiveErrors === ERROR_TIMEOUT.length) {
9897
+ args.common.logger.error({
9898
+ service: "realtime",
9899
+ msg: `Fatal error: Unable to process '${args.network.name}' block ${hexToNumber6(block.number)} after ${ERROR_TIMEOUT.length} attempts.`,
9900
+ error
9901
+ });
9902
+ args.onFatalError(error);
10152
9903
  }
10153
9904
  }
10154
9905
  }
10155
- }
10156
- }
10157
- for (const { hash } of reorgedBlocks) {
10158
- factoryLogsPerBlock.delete(hash);
9906
+ );
9907
+ const enqueue = async () => {
9908
+ try {
9909
+ const block = await _eth_getBlockByNumber(args.requestQueue, {
9910
+ blockTag: "latest"
9911
+ });
9912
+ args.common.logger.debug({
9913
+ service: "realtime",
9914
+ msg: `Received latest '${args.network.name}' block ${hexToNumber6(block.number)}`
9915
+ });
9916
+ const latestBlock = getLatestUnfinalizedBlock();
9917
+ if (latestBlock.hash === block.hash) {
9918
+ args.common.logger.trace({
9919
+ service: "realtime",
9920
+ msg: `Skipped processing '${args.network.name}' block ${hexToNumber6(block.number)}, already synced`
9921
+ });
9922
+ return;
9923
+ }
9924
+ const endClock = startClock();
9925
+ const blockWithEventData = await fetchBlockEventData(block);
9926
+ consecutiveErrors = 0;
9927
+ return processBlock({ ...blockWithEventData, endClock });
9928
+ } catch (_error) {
9929
+ const error = _error;
9930
+ if (args.common.shutdown.isKilled) {
9931
+ throw new ShutdownError();
9932
+ }
9933
+ args.common.logger.warn({
9934
+ service: "realtime",
9935
+ msg: `Failed to fetch latest '${args.network.name}' block`,
9936
+ error
9937
+ });
9938
+ if (++consecutiveErrors === ERROR_TIMEOUT.length) {
9939
+ args.common.logger.error({
9940
+ service: "realtime",
9941
+ msg: `Fatal error: Unable to fetch latest '${args.network.name}' block after ${ERROR_TIMEOUT.length} attempts.`,
9942
+ error
9943
+ });
9944
+ args.onFatalError(error);
9945
+ }
9946
+ }
9947
+ };
9948
+ interval = setInterval(enqueue, args.network.pollingInterval);
9949
+ args.common.shutdown.add(() => {
9950
+ clearInterval(interval);
9951
+ });
9952
+ return enqueue().then(() => processBlock);
9953
+ },
9954
+ get unfinalizedBlocks() {
9955
+ return unfinalizedBlocks;
9956
+ },
9957
+ get finalizedChildAddresses() {
9958
+ return finalizedChildAddresses;
9959
+ },
9960
+ get unfinalizedChildAddresses() {
9961
+ return unfinalizedChildAddresses;
9962
+ },
9963
+ async kill() {
9964
+ clearInterval(interval);
10159
9965
  }
10160
9966
  };
10161
- const syncTransactionReceipts = async (blockHash, transactionHashes) => {
10162
- if (transactionHashes.size === 0) {
10163
- return [];
9967
+ };
9968
+
9969
+ // src/utils/estimate.ts
9970
+ var estimate = ({
9971
+ from,
9972
+ to,
9973
+ target,
9974
+ result,
9975
+ min: min2,
9976
+ max,
9977
+ prev,
9978
+ maxIncrease
9979
+ }) => {
9980
+ const density = (to - from) / (result || 1);
9981
+ return Math.min(
9982
+ Math.max(min2, Math.round(target * density)),
9983
+ Math.round(prev * maxIncrease),
9984
+ max
9985
+ );
9986
+ };
9987
+
9988
+ // src/utils/generators.ts
9989
+ async function* mergeAsyncGenerators(generators) {
9990
+ const results = [];
9991
+ let count = generators.length;
9992
+ let pwr = promiseWithResolvers();
9993
+ generators.map(async (generator) => {
9994
+ for await (const result of generator) {
9995
+ results.push(result);
9996
+ pwr.resolve();
9997
+ }
9998
+ count--;
9999
+ pwr.resolve();
10000
+ });
10001
+ while (count > 0 || results.length > 0) {
10002
+ if (results.length > 0) {
10003
+ yield results.shift();
10004
+ } else {
10005
+ await pwr.promise;
10006
+ pwr = promiseWithResolvers();
10164
10007
  }
10165
- if (isBlockReceipts === false) {
10166
- const transactionReceipts2 = await Promise.all(
10167
- Array.from(transactionHashes).map(
10168
- async (hash) => _eth_getTransactionReceipt(args.requestQueue, { hash })
10169
- )
10170
- );
10171
- return transactionReceipts2;
10008
+ }
10009
+ }
10010
+ async function* bufferAsyncGenerator(generator, size) {
10011
+ const buffer = [];
10012
+ let done = false;
10013
+ let pwr1 = promiseWithResolvers();
10014
+ let pwr2 = promiseWithResolvers();
10015
+ (async () => {
10016
+ for await (const result of generator) {
10017
+ buffer.push(result);
10018
+ pwr1.resolve();
10019
+ if (buffer.length > size)
10020
+ await pwr2.promise;
10021
+ pwr2 = promiseWithResolvers();
10172
10022
  }
10173
- let blockReceipts;
10174
- try {
10175
- blockReceipts = await _eth_getBlockReceipts(args.requestQueue, {
10176
- blockHash
10177
- });
10178
- } catch (_error) {
10179
- const error = _error;
10180
- args.common.logger.warn({
10181
- service: "realtime",
10182
- msg: `Caught eth_getBlockReceipts error on '${args.network.name}', switching to eth_getTransactionReceipt method.`,
10183
- error
10184
- });
10185
- isBlockReceipts = false;
10186
- return syncTransactionReceipts(blockHash, transactionHashes);
10023
+ done = true;
10024
+ pwr1.resolve();
10025
+ })();
10026
+ while (done === false || buffer.length > 0) {
10027
+ if (buffer.length > 0) {
10028
+ pwr2.resolve();
10029
+ yield buffer.shift();
10030
+ } else {
10031
+ await pwr1.promise;
10032
+ pwr1 = promiseWithResolvers();
10187
10033
  }
10188
- const blockReceiptsTransactionHashes = new Set(
10189
- blockReceipts.map((r) => r.transactionHash)
10190
- );
10191
- for (const hash of Array.from(transactionHashes)) {
10192
- if (blockReceiptsTransactionHashes.has(hash) === false) {
10193
- throw new Error(
10194
- `Detected inconsistent RPC responses. 'transaction.hash' ${hash} not found in eth_getBlockReceipts response for block '${blockHash}'`
10195
- );
10196
- }
10034
+ }
10035
+ }
10036
+
10037
+ // src/utils/partition.ts
10038
+ var partition = (array, predicate) => {
10039
+ let low = 0;
10040
+ let high = array.length;
10041
+ while (low < high) {
10042
+ const mid = Math.floor((low + high) / 2);
10043
+ if (predicate(array[mid])) {
10044
+ low = mid + 1;
10045
+ } else {
10046
+ high = mid;
10197
10047
  }
10198
- const transactionReceipts = blockReceipts.filter(
10199
- (receipt) => transactionHashes.has(receipt.transactionHash)
10048
+ }
10049
+ const left = array.slice(0, low);
10050
+ const right = array.slice(low);
10051
+ return [left, right];
10052
+ };
10053
+
10054
+ // src/utils/zipper.ts
10055
+ var zipper = (array1, array2, compare) => {
10056
+ const result = [];
10057
+ let i = 0;
10058
+ let j = 0;
10059
+ while (i < array1.length && j < array2.length) {
10060
+ if (compare ? compare(array1[i], array2[j]) < 0 : array1[i] < array2[j]) {
10061
+ result.push(array1[i]);
10062
+ i++;
10063
+ } else {
10064
+ result.push(array2[j]);
10065
+ j++;
10066
+ }
10067
+ }
10068
+ if (i < array1.length) {
10069
+ result.push(...array1.slice(i));
10070
+ }
10071
+ if (j < array2.length) {
10072
+ result.push(...array2.slice(j));
10073
+ }
10074
+ return result;
10075
+ };
10076
+ var zipperMany = (arrays, compare) => {
10077
+ if (arrays.length === 0)
10078
+ return [];
10079
+ if (arrays.length === 1)
10080
+ return arrays[0];
10081
+ let result = arrays[0];
10082
+ for (let i = 1; i < arrays.length; i++) {
10083
+ result = zipper(result, arrays[i], compare);
10084
+ }
10085
+ return result;
10086
+ };
10087
+
10088
+ // src/sync/index.ts
10089
+ import { hexToBigInt as hexToBigInt7, hexToNumber as hexToNumber8, toHex as toHex2 } from "viem";
10090
+
10091
+ // src/sync/events.ts
10092
+ import {
10093
+ DecodeLogDataMismatch,
10094
+ DecodeLogTopicsMismatch,
10095
+ checksumAddress as checksumAddress3,
10096
+ decodeAbiParameters,
10097
+ decodeFunctionData,
10098
+ decodeFunctionResult,
10099
+ hexToBigInt as hexToBigInt6,
10100
+ hexToNumber as hexToNumber7
10101
+ } from "viem";
10102
+ var buildEvents = ({
10103
+ sources,
10104
+ blockWithEventData: {
10105
+ block,
10106
+ logs,
10107
+ transactions,
10108
+ transactionReceipts,
10109
+ traces
10110
+ },
10111
+ finalizedChildAddresses,
10112
+ unfinalizedChildAddresses,
10113
+ chainId
10114
+ }) => {
10115
+ const events = [];
10116
+ const transactionCache = /* @__PURE__ */ new Map();
10117
+ const transactionReceiptCache = /* @__PURE__ */ new Map();
10118
+ for (const transaction of transactions) {
10119
+ transactionCache.set(transaction.hash, transaction);
10120
+ }
10121
+ for (const transactionReceipt of transactionReceipts) {
10122
+ transactionReceiptCache.set(
10123
+ transactionReceipt.transactionHash,
10124
+ transactionReceipt
10200
10125
  );
10201
- return transactionReceipts;
10202
- };
10203
- const fetchBlockEventData = async (block) => {
10204
- const shouldRequestLogs = block.logsBloom === zeroLogsBloom || logFilters.some((filter) => isFilterInBloom({ block, filter }));
10205
- let logs = [];
10206
- if (shouldRequestLogs) {
10207
- logs = await _eth_getLogs(args.requestQueue, { blockHash: block.hash });
10208
- if (block.logsBloom !== zeroLogsBloom && logs.length === 0) {
10209
- throw new Error(
10210
- "Detected invalid eth_getLogs response. `block.logsBloom` is not empty but zero logs were returned."
10211
- );
10212
- }
10213
- const logIds = /* @__PURE__ */ new Set();
10214
- for (const log of logs) {
10215
- if (log.blockHash !== block.hash) {
10216
- throw new Error(
10217
- `Detected invalid eth_getLogs response. 'log.blockHash' ${log.blockHash} does not match requested block hash ${block.hash}`
10218
- );
10219
- }
10220
- const id = `${log.blockHash}-${log.logIndex}`;
10221
- if (logIds.has(id)) {
10222
- args.common.logger.warn({
10223
- service: "sync",
10224
- msg: `Detected invalid eth_getLogs response. Duplicate log index ${log.logIndex} for block ${log.blockHash}.`
10225
- });
10226
- } else {
10227
- logIds.add(id);
10228
- }
10229
- if (block.transactions.find((t) => t.hash === log.transactionHash) === void 0) {
10230
- if (log.transactionHash === zeroHash2) {
10231
- args.common.logger.warn({
10232
- service: "sync",
10233
- msg: `Detected '${args.network.name}' log with empty transaction hash in block ${block.hash} at log index ${hexToNumber7(log.logIndex)}. This is expected for some networks like ZKsync.`
10234
- });
10235
- } else {
10236
- throw new Error(
10237
- `Detected inconsistent '${args.network.name}' RPC responses. 'log.transactionHash' ${log.transactionHash} not found in 'block.transactions' ${block.hash}`
10238
- );
10126
+ }
10127
+ for (let i = 0; i < sources.length; i++) {
10128
+ const source = sources[i];
10129
+ const filter = source.filter;
10130
+ if (chainId !== filter.chainId)
10131
+ continue;
10132
+ switch (source.type) {
10133
+ case "contract": {
10134
+ switch (filter.type) {
10135
+ case "log": {
10136
+ for (const log of logs) {
10137
+ if (isLogFilterMatched({ filter, block, log }) && (isAddressFactory(filter.address) ? finalizedChildAddresses.get(filter.address).has(log.address) || unfinalizedChildAddresses.get(filter.address).has(log.address) : true)) {
10138
+ events.push({
10139
+ chainId: filter.chainId,
10140
+ sourceIndex: i,
10141
+ checkpoint: encodeCheckpoint({
10142
+ blockTimestamp: hexToNumber7(block.timestamp),
10143
+ chainId: BigInt(filter.chainId),
10144
+ blockNumber: hexToBigInt6(log.blockNumber),
10145
+ transactionIndex: hexToBigInt6(log.transactionIndex),
10146
+ eventType: EVENT_TYPES.logs,
10147
+ eventIndex: hexToBigInt6(log.logIndex)
10148
+ }),
10149
+ log: convertLog(log),
10150
+ block: convertBlock(block),
10151
+ transaction: transactionCache.has(log.transactionHash) ? convertTransaction(
10152
+ transactionCache.get(log.transactionHash)
10153
+ ) : void 0,
10154
+ transactionReceipt: transactionReceiptCache.has(log.transactionHash) && shouldGetTransactionReceipt(filter) ? convertTransactionReceipt(
10155
+ transactionReceiptCache.get(log.transactionHash)
10156
+ ) : void 0,
10157
+ trace: void 0
10158
+ });
10159
+ }
10160
+ }
10161
+ break;
10162
+ }
10163
+ case "trace": {
10164
+ for (const trace of traces) {
10165
+ const fromChildAddresses = isAddressFactory(filter.fromAddress) ? [
10166
+ finalizedChildAddresses.get(filter.fromAddress),
10167
+ unfinalizedChildAddresses.get(filter.fromAddress)
10168
+ ] : void 0;
10169
+ const toChildAddresses = isAddressFactory(filter.toAddress) ? [
10170
+ finalizedChildAddresses.get(filter.toAddress),
10171
+ unfinalizedChildAddresses.get(filter.toAddress)
10172
+ ] : void 0;
10173
+ if (isTraceFilterMatched({
10174
+ filter,
10175
+ block,
10176
+ trace: trace.trace,
10177
+ fromChildAddresses,
10178
+ toChildAddresses
10179
+ }) && (filter.callType === void 0 ? true : filter.callType === trace.trace.type) && (filter.includeReverted ? true : trace.trace.error === void 0)) {
10180
+ const transaction = transactionCache.get(
10181
+ trace.transactionHash
10182
+ );
10183
+ const transactionReceipt = transactionReceiptCache.get(
10184
+ trace.transactionHash
10185
+ );
10186
+ events.push({
10187
+ chainId: filter.chainId,
10188
+ sourceIndex: i,
10189
+ checkpoint: encodeCheckpoint({
10190
+ blockTimestamp: hexToNumber7(block.timestamp),
10191
+ chainId: BigInt(filter.chainId),
10192
+ blockNumber: hexToBigInt6(block.number),
10193
+ transactionIndex: BigInt(transaction.transactionIndex),
10194
+ eventType: EVENT_TYPES.traces,
10195
+ eventIndex: BigInt(trace.trace.index)
10196
+ }),
10197
+ log: void 0,
10198
+ trace: convertTrace(trace),
10199
+ block: convertBlock(block),
10200
+ transaction: convertTransaction(transaction),
10201
+ transactionReceipt: shouldGetTransactionReceipt(filter) ? convertTransactionReceipt(transactionReceipt) : void 0
10202
+ });
10203
+ }
10204
+ }
10205
+ break;
10239
10206
  }
10240
10207
  }
10208
+ break;
10241
10209
  }
10242
- }
10243
- if (shouldRequestLogs === false && args.sources.some((s) => s.filter.type === "log")) {
10244
- args.common.logger.debug({
10245
- service: "realtime",
10246
- msg: `Skipped fetching '${args.network.name}' logs for block ${hexToNumber7(block.number)} due to bloom filter result`
10247
- });
10248
- }
10249
- const shouldRequestTraces = traceFilters.length > 0 || transferFilters.length > 0;
10250
- let traces = [];
10251
- if (shouldRequestTraces) {
10252
- traces = await _debug_traceBlockByHash(args.requestQueue, {
10253
- hash: block.hash
10254
- });
10255
- if (block.transactions.length !== 0 && traces.length === 0) {
10256
- throw new Error(
10257
- "Detected invalid debug_traceBlock response. `block.transactions` is not empty but zero traces were returned."
10258
- );
10259
- }
10260
- }
10261
- for (const trace of traces) {
10262
- if (block.transactions.find((t) => t.hash === trace.transactionHash) === void 0) {
10263
- throw new Error(
10264
- `Detected inconsistent RPC responses. 'trace.txHash' ${trace.transactionHash} not found in 'block' ${block.hash}`
10265
- );
10266
- }
10267
- }
10268
- const factoryLogs = logs.filter((log) => {
10269
- let isMatched = false;
10270
- for (const filter of factories) {
10271
- if (isLogFactoryMatched({ filter, log })) {
10272
- if (factoryLogsPerBlock.has(block.hash) === false) {
10273
- factoryLogsPerBlock.set(block.hash, []);
10210
+ case "account": {
10211
+ switch (filter.type) {
10212
+ case "transaction": {
10213
+ for (const transaction of transactions) {
10214
+ const fromChildAddresses = isAddressFactory(filter.fromAddress) ? [
10215
+ finalizedChildAddresses.get(filter.fromAddress),
10216
+ unfinalizedChildAddresses.get(filter.fromAddress)
10217
+ ] : void 0;
10218
+ const toChildAddresses = isAddressFactory(filter.toAddress) ? [
10219
+ finalizedChildAddresses.get(filter.toAddress),
10220
+ unfinalizedChildAddresses.get(filter.toAddress)
10221
+ ] : void 0;
10222
+ if (isTransactionFilterMatched({
10223
+ filter,
10224
+ block,
10225
+ transaction,
10226
+ fromChildAddresses,
10227
+ toChildAddresses
10228
+ }) && (filter.includeReverted ? true : transactionReceiptCache.get(transaction.hash).status === "0x1")) {
10229
+ events.push({
10230
+ chainId: filter.chainId,
10231
+ sourceIndex: i,
10232
+ checkpoint: encodeCheckpoint({
10233
+ blockTimestamp: hexToNumber7(block.timestamp),
10234
+ chainId: BigInt(filter.chainId),
10235
+ blockNumber: hexToBigInt6(block.number),
10236
+ transactionIndex: BigInt(transaction.transactionIndex),
10237
+ eventType: EVENT_TYPES.transactions,
10238
+ eventIndex: 0n
10239
+ }),
10240
+ log: void 0,
10241
+ trace: void 0,
10242
+ block: convertBlock(block),
10243
+ transaction: convertTransaction(transaction),
10244
+ transactionReceipt: convertTransactionReceipt(
10245
+ transactionReceiptCache.get(transaction.hash)
10246
+ )
10247
+ });
10248
+ }
10249
+ }
10250
+ break;
10274
10251
  }
10275
- factoryLogsPerBlock.get(block.hash).push(log);
10276
- isMatched = true;
10277
- }
10278
- }
10279
- return isMatched;
10280
- });
10281
- const requiredTransactions = /* @__PURE__ */ new Set();
10282
- const requiredTransactionReceipts = /* @__PURE__ */ new Set();
10283
- logs = logs.filter((log) => {
10284
- let isMatched = false;
10285
- for (const filter of logFilters) {
10286
- if (isLogFilterMatched({ filter, block, log })) {
10287
- isMatched = true;
10288
- if (log.transactionHash === zeroHash2) {
10289
- args.common.logger.warn({
10290
- service: "sync",
10291
- msg: `Detected '${args.network.name}' log with empty transaction hash in block ${block.hash} at log index ${hexToNumber7(log.logIndex)}. This is expected for some networks like ZKsync.`
10292
- });
10293
- } else {
10294
- requiredTransactions.add(log.transactionHash);
10295
- if (shouldGetTransactionReceipt(filter)) {
10296
- requiredTransactionReceipts.add(log.transactionHash);
10297
- break;
10252
+ case "transfer": {
10253
+ for (const trace of traces) {
10254
+ const fromChildAddresses = isAddressFactory(filter.fromAddress) ? [
10255
+ finalizedChildAddresses.get(filter.fromAddress),
10256
+ unfinalizedChildAddresses.get(filter.fromAddress)
10257
+ ] : void 0;
10258
+ const toChildAddresses = isAddressFactory(filter.toAddress) ? [
10259
+ finalizedChildAddresses.get(filter.toAddress),
10260
+ unfinalizedChildAddresses.get(filter.toAddress)
10261
+ ] : void 0;
10262
+ if (isTransferFilterMatched({
10263
+ filter,
10264
+ block,
10265
+ trace: trace.trace,
10266
+ fromChildAddresses,
10267
+ toChildAddresses
10268
+ }) && (filter.includeReverted ? true : trace.trace.error === void 0)) {
10269
+ const transaction = transactionCache.get(
10270
+ trace.transactionHash
10271
+ );
10272
+ const transactionReceipt = transactionReceiptCache.get(
10273
+ trace.transactionHash
10274
+ );
10275
+ events.push({
10276
+ chainId: filter.chainId,
10277
+ sourceIndex: i,
10278
+ checkpoint: encodeCheckpoint({
10279
+ blockTimestamp: hexToNumber7(block.timestamp),
10280
+ chainId: BigInt(filter.chainId),
10281
+ blockNumber: hexToBigInt6(block.number),
10282
+ transactionIndex: BigInt(transaction.transactionIndex),
10283
+ eventType: EVENT_TYPES.traces,
10284
+ eventIndex: BigInt(trace.trace.index)
10285
+ }),
10286
+ log: void 0,
10287
+ trace: convertTrace(trace),
10288
+ block: convertBlock(block),
10289
+ transaction: convertTransaction(transaction),
10290
+ transactionReceipt: shouldGetTransactionReceipt(filter) ? convertTransactionReceipt(transactionReceipt) : void 0
10291
+ });
10292
+ }
10298
10293
  }
10294
+ break;
10299
10295
  }
10300
10296
  }
10297
+ break;
10301
10298
  }
10302
- return isMatched;
10303
- });
10304
- traces = traces.filter((trace) => {
10305
- let isMatched = false;
10306
- for (const filter of transferFilters) {
10307
- if (isTransferFilterMatched({
10308
- filter,
10309
- block: { number: block.number },
10310
- trace: trace.trace
10311
- })) {
10312
- requiredTransactions.add(trace.transactionHash);
10313
- isMatched = true;
10314
- if (shouldGetTransactionReceipt(filter)) {
10315
- requiredTransactionReceipts.add(trace.transactionHash);
10316
- break;
10317
- }
10299
+ case "block": {
10300
+ if (isBlockFilterMatched({ filter, block })) {
10301
+ events.push({
10302
+ chainId: filter.chainId,
10303
+ sourceIndex: i,
10304
+ checkpoint: encodeCheckpoint({
10305
+ blockTimestamp: hexToNumber7(block.timestamp),
10306
+ chainId: BigInt(filter.chainId),
10307
+ blockNumber: hexToBigInt6(block.number),
10308
+ transactionIndex: MAX_CHECKPOINT.transactionIndex,
10309
+ eventType: EVENT_TYPES.blocks,
10310
+ eventIndex: ZERO_CHECKPOINT.eventIndex
10311
+ }),
10312
+ block: convertBlock(block),
10313
+ log: void 0,
10314
+ trace: void 0,
10315
+ transaction: void 0,
10316
+ transactionReceipt: void 0
10317
+ });
10318
10318
  }
10319
+ break;
10319
10320
  }
10320
- for (const filter of traceFilters) {
10321
- if (isTraceFilterMatched({
10322
- filter,
10323
- block: { number: block.number },
10324
- trace: trace.trace
10325
- })) {
10326
- requiredTransactions.add(trace.transactionHash);
10327
- isMatched = true;
10328
- if (shouldGetTransactionReceipt(filter)) {
10329
- requiredTransactionReceipts.add(trace.transactionHash);
10321
+ default:
10322
+ never(source);
10323
+ }
10324
+ }
10325
+ return events.sort((a, b) => a.checkpoint < b.checkpoint ? -1 : 1);
10326
+ };
10327
+ var decodeEvents = (common, sources, rawEvents) => {
10328
+ const events = [];
10329
+ const endClock = startClock();
10330
+ for (const event of rawEvents) {
10331
+ const source = sources[event.sourceIndex];
10332
+ switch (source.type) {
10333
+ case "contract": {
10334
+ switch (source.filter.type) {
10335
+ case "log": {
10336
+ try {
10337
+ if (event.log.topics[0] === void 0 || source.abiEvents.bySelector[event.log.topics[0]] === void 0) {
10338
+ throw new Error();
10339
+ }
10340
+ const { safeName, item } = source.abiEvents.bySelector[event.log.topics[0]];
10341
+ const args = decodeEventLog({
10342
+ abiItem: item,
10343
+ data: event.log.data,
10344
+ topics: event.log.topics
10345
+ });
10346
+ events.push({
10347
+ type: "log",
10348
+ chainId: event.chainId,
10349
+ checkpoint: event.checkpoint,
10350
+ name: `${source.name}:${safeName}`,
10351
+ event: {
10352
+ name: safeName,
10353
+ args: removeNullCharacters(args),
10354
+ log: event.log,
10355
+ block: event.block,
10356
+ transaction: event.transaction,
10357
+ transactionReceipt: event.transactionReceipt
10358
+ }
10359
+ });
10360
+ } catch (err) {
10361
+ if (source.filter.address === void 0) {
10362
+ common.logger.debug({
10363
+ service: "app",
10364
+ msg: `Unable to decode log, skipping it. id: ${event.log?.id}, data: ${event.log?.data}, topics: ${event.log?.topics}`
10365
+ });
10366
+ } else {
10367
+ common.logger.warn({
10368
+ service: "app",
10369
+ msg: `Unable to decode log, skipping it. id: ${event.log?.id}, data: ${event.log?.data}, topics: ${event.log?.topics}`
10370
+ });
10371
+ }
10372
+ }
10373
+ break;
10374
+ }
10375
+ case "trace": {
10376
+ try {
10377
+ const selector = event.trace.input.slice(0, 10).toLowerCase();
10378
+ if (source.abiFunctions.bySelector[selector] === void 0) {
10379
+ throw new Error();
10380
+ }
10381
+ const { item, safeName } = source.abiFunctions.bySelector[selector];
10382
+ const { args, functionName } = decodeFunctionData({
10383
+ abi: [item],
10384
+ data: event.trace.input
10385
+ });
10386
+ const result = decodeFunctionResult({
10387
+ abi: [item],
10388
+ data: event.trace.output,
10389
+ functionName
10390
+ });
10391
+ events.push({
10392
+ type: "trace",
10393
+ chainId: event.chainId,
10394
+ checkpoint: event.checkpoint,
10395
+ // NOTE: `safename` includes ()
10396
+ name: `${source.name}.${safeName}`,
10397
+ event: {
10398
+ args: removeNullCharacters(args),
10399
+ result: removeNullCharacters(result),
10400
+ trace: event.trace,
10401
+ block: event.block,
10402
+ transaction: event.transaction,
10403
+ transactionReceipt: event.transactionReceipt
10404
+ }
10405
+ });
10406
+ } catch (err) {
10407
+ if (source.filter.toAddress === void 0) {
10408
+ common.logger.debug({
10409
+ service: "app",
10410
+ msg: `Unable to decode trace, skipping it. id: ${event.trace?.id}, input: ${event.trace?.input}, output: ${event.trace?.output}`
10411
+ });
10412
+ } else {
10413
+ common.logger.warn({
10414
+ service: "app",
10415
+ msg: `Unable to decode trace, skipping it. id: ${event.trace?.id}, input: ${event.trace?.input}, output: ${event.trace?.output}`
10416
+ });
10417
+ }
10418
+ }
10330
10419
  break;
10331
10420
  }
10421
+ default:
10422
+ never(source.filter);
10332
10423
  }
10424
+ break;
10333
10425
  }
10334
- return isMatched;
10335
- });
10336
- const transactions = block.transactions.filter((transaction) => {
10337
- let isMatched = requiredTransactions.has(transaction.hash);
10338
- for (const filter of transactionFilters) {
10339
- if (isTransactionFilterMatched({ filter, block, transaction })) {
10340
- requiredTransactions.add(transaction.hash);
10341
- requiredTransactionReceipts.add(transaction.hash);
10342
- isMatched = true;
10343
- }
10344
- }
10345
- return isMatched;
10346
- });
10347
- const blockTransactionsHashes = new Set(
10348
- block.transactions.map((t) => t.hash)
10349
- );
10350
- for (const hash of Array.from(requiredTransactions)) {
10351
- if (blockTransactionsHashes.has(hash) === false) {
10352
- throw new Error(
10353
- `Detected inconsistent RPC responses. 'transaction.hash' ${hash} not found in eth_getBlockReceipts response for block '${block.hash}'.`
10354
- );
10355
- }
10356
- }
10357
- const transactionReceipts = await syncTransactionReceipts(
10358
- block.hash,
10359
- requiredTransactionReceipts
10360
- );
10361
- return {
10362
- block,
10363
- logs,
10364
- factoryLogs,
10365
- traces,
10366
- transactions,
10367
- transactionReceipts
10368
- };
10369
- };
10370
- const getLatestUnfinalizedBlock = () => {
10371
- if (unfinalizedBlocks.length === 0) {
10372
- return finalizedBlock;
10373
- } else
10374
- return unfinalizedBlocks[unfinalizedBlocks.length - 1];
10375
- };
10376
- return {
10377
- start(startArgs) {
10378
- finalizedBlock = startArgs.syncProgress.finalized;
10379
- finalizedChildAddresses = startArgs.initialChildAddresses;
10380
- const processBlock = mutex(
10381
- async ({
10382
- block,
10383
- ...rest
10384
- }) => {
10385
- const latestBlock = getLatestUnfinalizedBlock();
10386
- if (latestBlock.hash === block.hash) {
10387
- args.common.logger.trace({
10388
- service: "realtime",
10389
- msg: `Skipped processing '${args.network.name}' block ${hexToNumber7(block.number)}, already synced`
10426
+ case "account": {
10427
+ switch (source.filter.type) {
10428
+ case "transaction": {
10429
+ const isFrom = source.filter.toAddress === void 0;
10430
+ events.push({
10431
+ type: "transaction",
10432
+ chainId: event.chainId,
10433
+ checkpoint: event.checkpoint,
10434
+ name: `${source.name}:transaction:${isFrom ? "from" : "to"}`,
10435
+ event: {
10436
+ block: event.block,
10437
+ transaction: event.transaction,
10438
+ transactionReceipt: event.transactionReceipt
10439
+ }
10390
10440
  });
10391
- return;
10441
+ break;
10392
10442
  }
10393
- try {
10394
- if (hexToNumber7(latestBlock.number) >= hexToNumber7(block.number)) {
10395
- await handleReorg(block);
10396
- processBlock.clear();
10397
- return;
10398
- }
10399
- if (hexToNumber7(latestBlock.number) + 1 < hexToNumber7(block.number)) {
10400
- const missingBlockRange = range(
10401
- hexToNumber7(latestBlock.number) + 1,
10402
- Math.min(
10403
- hexToNumber7(block.number),
10404
- hexToNumber7(latestBlock.number) + MAX_QUEUED_BLOCKS
10405
- )
10406
- );
10407
- const pendingBlocks = await Promise.all(
10408
- missingBlockRange.map(
10409
- (blockNumber) => _eth_getBlockByNumber(args.requestQueue, {
10410
- blockNumber
10411
- }).then((block2) => fetchBlockEventData(block2))
10412
- )
10413
- );
10414
- args.common.logger.debug({
10415
- service: "realtime",
10416
- msg: `Fetched ${missingBlockRange.length} missing '${args.network.name}' blocks [${hexToNumber7(latestBlock.number) + 1}, ${Math.min(
10417
- hexToNumber7(block.number),
10418
- hexToNumber7(latestBlock.number) + MAX_QUEUED_BLOCKS
10419
- )}]`
10420
- });
10421
- processBlock.clear();
10422
- for (const pendingBlock of pendingBlocks) {
10423
- processBlock(pendingBlock);
10443
+ case "transfer": {
10444
+ const isFrom = source.filter.toAddress === void 0;
10445
+ events.push({
10446
+ type: "transfer",
10447
+ chainId: event.chainId,
10448
+ checkpoint: event.checkpoint,
10449
+ name: `${source.name}:transfer:${isFrom ? "from" : "to"}`,
10450
+ event: {
10451
+ transfer: {
10452
+ from: event.trace.from,
10453
+ to: event.trace.to,
10454
+ value: event.trace.value
10455
+ },
10456
+ block: event.block,
10457
+ transaction: event.transaction,
10458
+ transactionReceipt: event.transactionReceipt,
10459
+ trace: event.trace
10424
10460
  }
10425
- processBlock({ block, ...rest });
10426
- return;
10427
- }
10428
- if (block.parentHash !== latestBlock.hash) {
10429
- await handleReorg(block);
10430
- processBlock.clear();
10431
- return;
10432
- }
10433
- await handleBlock({ block, ...rest });
10434
- consecutiveErrors = 0;
10435
- return;
10436
- } catch (_error) {
10437
- const error = _error;
10438
- if (args.common.shutdown.isKilled) {
10439
- throw new ShutdownError();
10440
- }
10441
- args.common.logger.warn({
10442
- service: "realtime",
10443
- msg: `Failed to process '${args.network.name}' block ${hexToNumber7(block.number)}`,
10444
- error
10445
- });
10446
- const duration = ERROR_TIMEOUT[consecutiveErrors];
10447
- args.common.logger.warn({
10448
- service: "realtime",
10449
- msg: `Retrying '${args.network.name}' sync after ${duration} ${duration === 1 ? "second" : "seconds"}.`
10450
10461
  });
10451
- await wait(duration * 1e3);
10452
- processBlock.clear();
10453
- if (++consecutiveErrors === ERROR_TIMEOUT.length) {
10454
- args.common.logger.error({
10455
- service: "realtime",
10456
- msg: `Fatal error: Unable to process '${args.network.name}' block ${hexToNumber7(block.number)} after ${ERROR_TIMEOUT.length} attempts.`,
10457
- error
10458
- });
10459
- args.onFatalError(error);
10460
- }
10462
+ break;
10461
10463
  }
10462
10464
  }
10463
- );
10464
- const enqueue = async () => {
10465
- try {
10466
- const block = await _eth_getBlockByNumber(args.requestQueue, {
10467
- blockTag: "latest"
10468
- });
10469
- args.common.logger.debug({
10470
- service: "realtime",
10471
- msg: `Received latest '${args.network.name}' block ${hexToNumber7(block.number)}`
10472
- });
10473
- const latestBlock = getLatestUnfinalizedBlock();
10474
- if (latestBlock.hash === block.hash) {
10475
- args.common.logger.trace({
10476
- service: "realtime",
10477
- msg: `Skipped processing '${args.network.name}' block ${hexToNumber7(block.number)}, already synced`
10478
- });
10479
- return;
10480
- }
10481
- const endClock = startClock();
10482
- const blockWithEventData = await fetchBlockEventData(block);
10483
- consecutiveErrors = 0;
10484
- return processBlock({ ...blockWithEventData, endClock });
10485
- } catch (_error) {
10486
- const error = _error;
10487
- if (args.common.shutdown.isKilled) {
10488
- throw new ShutdownError();
10465
+ break;
10466
+ }
10467
+ case "block": {
10468
+ events.push({
10469
+ type: "block",
10470
+ chainId: event.chainId,
10471
+ checkpoint: event.checkpoint,
10472
+ name: `${source.name}:block`,
10473
+ event: {
10474
+ block: event.block
10489
10475
  }
10490
- args.common.logger.warn({
10491
- service: "realtime",
10492
- msg: `Failed to fetch latest '${args.network.name}' block`,
10493
- error
10494
- });
10495
- if (++consecutiveErrors === ERROR_TIMEOUT.length) {
10496
- args.common.logger.error({
10497
- service: "realtime",
10498
- msg: `Fatal error: Unable to fetch latest '${args.network.name}' block after ${ERROR_TIMEOUT.length} attempts.`,
10499
- error
10500
- });
10501
- args.onFatalError(error);
10476
+ });
10477
+ break;
10478
+ }
10479
+ default:
10480
+ never(source);
10481
+ }
10482
+ }
10483
+ common.metrics.ponder_indexing_abi_decoding_duration.observe(endClock());
10484
+ return events;
10485
+ };
10486
+ function decodeEventLog({
10487
+ abiItem,
10488
+ topics,
10489
+ data
10490
+ }) {
10491
+ const { inputs } = abiItem;
10492
+ const isUnnamed = inputs?.some((x) => !("name" in x && x.name));
10493
+ let args = isUnnamed ? [] : {};
10494
+ const [, ...argTopics] = topics;
10495
+ const indexedInputs = inputs.filter((x) => "indexed" in x && x.indexed);
10496
+ for (let i = 0; i < indexedInputs.length; i++) {
10497
+ const param = indexedInputs[i];
10498
+ const topic = argTopics[i];
10499
+ if (!topic)
10500
+ throw new DecodeLogTopicsMismatch({
10501
+ abiItem,
10502
+ param
10503
+ });
10504
+ args[isUnnamed ? i : param.name || i] = decodeTopic({
10505
+ param,
10506
+ value: topic
10507
+ });
10508
+ }
10509
+ const nonIndexedInputs = inputs.filter((x) => !("indexed" in x && x.indexed));
10510
+ if (nonIndexedInputs.length > 0) {
10511
+ if (data && data !== "0x") {
10512
+ const decodedData = decodeAbiParameters(nonIndexedInputs, data);
10513
+ if (decodedData) {
10514
+ if (isUnnamed)
10515
+ args = [...args, ...decodedData];
10516
+ else {
10517
+ for (let i = 0; i < nonIndexedInputs.length; i++) {
10518
+ args[nonIndexedInputs[i].name] = decodedData[i];
10502
10519
  }
10503
10520
  }
10504
- };
10505
- interval = setInterval(enqueue, args.network.pollingInterval);
10506
- args.common.shutdown.add(() => {
10507
- clearInterval(interval);
10508
- });
10509
- return enqueue().then(() => processBlock);
10510
- },
10511
- get unfinalizedBlocks() {
10512
- return unfinalizedBlocks;
10513
- },
10514
- get finalizedChildAddresses() {
10515
- return finalizedChildAddresses;
10516
- },
10517
- get unfinalizedChildAddresses() {
10518
- return unfinalizedChildAddresses;
10519
- },
10520
- async kill() {
10521
- clearInterval(interval);
10522
- }
10523
- };
10524
- };
10525
-
10526
- // src/utils/estimate.ts
10527
- var estimate = ({
10528
- from,
10529
- to,
10530
- target,
10531
- result,
10532
- min: min2,
10533
- max,
10534
- prev,
10535
- maxIncrease
10536
- }) => {
10537
- const density = (to - from) / (result || 1);
10538
- return Math.min(
10539
- Math.max(min2, Math.round(target * density)),
10540
- Math.round(prev * maxIncrease),
10541
- max
10542
- );
10543
- };
10544
-
10545
- // src/utils/generators.ts
10546
- async function* mergeAsyncGenerators(generators) {
10547
- const results = [];
10548
- let count = generators.length;
10549
- let pwr = promiseWithResolvers();
10550
- generators.map(async (generator) => {
10551
- for await (const result of generator) {
10552
- results.push(result);
10553
- pwr.resolve();
10554
- }
10555
- count--;
10556
- pwr.resolve();
10557
- });
10558
- while (count > 0 || results.length > 0) {
10559
- if (results.length > 0) {
10560
- yield results.shift();
10521
+ }
10561
10522
  } else {
10562
- await pwr.promise;
10563
- pwr = promiseWithResolvers();
10523
+ throw new DecodeLogDataMismatch({
10524
+ abiItem,
10525
+ data: "0x",
10526
+ params: nonIndexedInputs,
10527
+ size: 0
10528
+ });
10564
10529
  }
10565
10530
  }
10531
+ return Object.values(args).length > 0 ? args : void 0;
10566
10532
  }
10567
- async function* bufferAsyncGenerator(generator, size) {
10568
- const buffer = [];
10569
- let done = false;
10570
- let pwr1 = promiseWithResolvers();
10571
- let pwr2 = promiseWithResolvers();
10572
- (async () => {
10573
- for await (const result of generator) {
10574
- buffer.push(result);
10575
- pwr1.resolve();
10576
- if (buffer.length > size)
10577
- await pwr2.promise;
10578
- pwr2 = promiseWithResolvers();
10579
- }
10580
- done = true;
10581
- pwr1.resolve();
10582
- })();
10583
- while (done === false || buffer.length > 0) {
10584
- if (buffer.length > 0) {
10585
- pwr2.resolve();
10586
- yield buffer.shift();
10587
- } else {
10588
- await pwr1.promise;
10589
- pwr1 = promiseWithResolvers();
10590
- }
10591
- }
10533
+ function decodeTopic({ param, value }) {
10534
+ if (param.type === "string" || param.type === "bytes" || param.type === "tuple" || param.type.match(/^(.*)\[(\d+)?\]$/))
10535
+ return value;
10536
+ const decodedArg = decodeAbiParameters([param], value) || [];
10537
+ return decodedArg[0];
10592
10538
  }
10593
-
10594
- // src/utils/partition.ts
10595
- var partition = (array, predicate) => {
10596
- let low = 0;
10597
- let high = array.length;
10598
- while (low < high) {
10599
- const mid = Math.floor((low + high) / 2);
10600
- if (predicate(array[mid])) {
10601
- low = mid + 1;
10602
- } else {
10603
- high = mid;
10604
- }
10605
- }
10606
- const left = array.slice(0, low);
10607
- const right = array.slice(low);
10608
- return [left, right];
10609
- };
10610
-
10611
- // src/utils/zipper.ts
10612
- var zipper = (array1, array2, compare) => {
10613
- const result = [];
10614
- let i = 0;
10615
- let j = 0;
10616
- while (i < array1.length && j < array2.length) {
10617
- if (compare ? compare(array1[i], array2[j]) < 0 : array1[i] < array2[j]) {
10618
- result.push(array1[i]);
10619
- i++;
10620
- } else {
10621
- result.push(array2[j]);
10622
- j++;
10623
- }
10624
- }
10625
- if (i < array1.length) {
10626
- result.push(...array1.slice(i));
10539
+ function removeNullCharacters(obj) {
10540
+ if (typeof obj === "string") {
10541
+ return obj.replace(/\0/g, "");
10627
10542
  }
10628
- if (j < array2.length) {
10629
- result.push(...array2.slice(j));
10543
+ if (Array.isArray(obj)) {
10544
+ return obj.map(removeNullCharacters);
10630
10545
  }
10631
- return result;
10632
- };
10633
- var zipperMany = (arrays, compare) => {
10634
- if (arrays.length === 0)
10635
- return [];
10636
- if (arrays.length === 1)
10637
- return arrays[0];
10638
- let result = arrays[0];
10639
- for (let i = 1; i < arrays.length; i++) {
10640
- result = zipper(result, arrays[i], compare);
10546
+ if (obj && typeof obj === "object") {
10547
+ const newObj = {};
10548
+ for (const [key, val] of Object.entries(obj)) {
10549
+ newObj[key] = removeNullCharacters(val);
10550
+ }
10551
+ return newObj;
10641
10552
  }
10642
- return result;
10643
- };
10553
+ return obj;
10554
+ }
10555
+ var convertBlock = (block) => ({
10556
+ baseFeePerGas: block.baseFeePerGas ? hexToBigInt6(block.baseFeePerGas) : null,
10557
+ difficulty: hexToBigInt6(block.difficulty),
10558
+ extraData: block.extraData,
10559
+ gasLimit: hexToBigInt6(block.gasLimit),
10560
+ gasUsed: hexToBigInt6(block.gasUsed),
10561
+ hash: block.hash,
10562
+ logsBloom: block.logsBloom,
10563
+ miner: checksumAddress3(block.miner),
10564
+ mixHash: block.mixHash,
10565
+ nonce: block.nonce,
10566
+ number: hexToBigInt6(block.number),
10567
+ parentHash: block.parentHash,
10568
+ receiptsRoot: block.receiptsRoot,
10569
+ sha3Uncles: block.sha3Uncles,
10570
+ size: hexToBigInt6(block.size),
10571
+ stateRoot: block.stateRoot,
10572
+ timestamp: hexToBigInt6(block.timestamp),
10573
+ totalDifficulty: block.totalDifficulty ? hexToBigInt6(block.totalDifficulty) : null,
10574
+ transactionsRoot: block.transactionsRoot
10575
+ });
10576
+ var convertLog = (log) => ({
10577
+ id: `${log.blockHash}-${log.logIndex}`,
10578
+ address: checksumAddress3(log.address),
10579
+ data: log.data,
10580
+ logIndex: Number(log.logIndex),
10581
+ removed: false,
10582
+ topics: log.topics
10583
+ });
10584
+ var convertTransaction = (transaction) => ({
10585
+ from: checksumAddress3(transaction.from),
10586
+ gas: hexToBigInt6(transaction.gas),
10587
+ hash: transaction.hash,
10588
+ input: transaction.input,
10589
+ nonce: Number(transaction.nonce),
10590
+ r: transaction.r,
10591
+ s: transaction.s,
10592
+ to: transaction.to ? checksumAddress3(transaction.to) : transaction.to,
10593
+ transactionIndex: Number(transaction.transactionIndex),
10594
+ value: hexToBigInt6(transaction.value),
10595
+ v: transaction.v ? hexToBigInt6(transaction.v) : null,
10596
+ ...transaction.type === "0x0" ? {
10597
+ type: "legacy",
10598
+ gasPrice: hexToBigInt6(transaction.gasPrice)
10599
+ } : transaction.type === "0x1" ? {
10600
+ type: "eip2930",
10601
+ gasPrice: hexToBigInt6(transaction.gasPrice),
10602
+ accessList: transaction.accessList
10603
+ } : transaction.type === "0x2" ? {
10604
+ type: "eip1559",
10605
+ maxFeePerGas: hexToBigInt6(transaction.maxFeePerGas),
10606
+ maxPriorityFeePerGas: hexToBigInt6(transaction.maxPriorityFeePerGas)
10607
+ } : (
10608
+ // @ts-ignore
10609
+ transaction.type === "0x7e" ? {
10610
+ type: "deposit",
10611
+ // @ts-ignore
10612
+ maxFeePerGas: transaction.maxFeePerGas ? (
10613
+ // @ts-ignore
10614
+ hexToBigInt6(transaction.maxFeePerGas)
10615
+ ) : void 0,
10616
+ // @ts-ignore
10617
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas ? (
10618
+ // @ts-ignore
10619
+ hexToBigInt6(transaction.maxPriorityFeePerGas)
10620
+ ) : void 0
10621
+ } : {
10622
+ // @ts-ignore
10623
+ type: transaction.type
10624
+ }
10625
+ )
10626
+ });
10627
+ var convertTransactionReceipt = (transactionReceipt) => ({
10628
+ contractAddress: transactionReceipt.contractAddress ? checksumAddress3(transactionReceipt.contractAddress) : null,
10629
+ cumulativeGasUsed: hexToBigInt6(transactionReceipt.cumulativeGasUsed),
10630
+ effectiveGasPrice: hexToBigInt6(transactionReceipt.effectiveGasPrice),
10631
+ from: checksumAddress3(transactionReceipt.from),
10632
+ gasUsed: hexToBigInt6(transactionReceipt.gasUsed),
10633
+ logsBloom: transactionReceipt.logsBloom,
10634
+ status: transactionReceipt.status === "0x1" ? "success" : transactionReceipt.status === "0x0" ? "reverted" : transactionReceipt.status,
10635
+ to: transactionReceipt.to ? checksumAddress3(transactionReceipt.to) : null,
10636
+ type: transactionReceipt.type === "0x0" ? "legacy" : transactionReceipt.type === "0x1" ? "eip2930" : transactionReceipt.type === "0x2" ? "eip1559" : transactionReceipt.type === "0x7e" ? "deposit" : transactionReceipt.type
10637
+ });
10638
+ var convertTrace = (trace) => ({
10639
+ id: `${trace.transactionHash}-${trace.trace.index}`,
10640
+ type: trace.trace.type,
10641
+ from: checksumAddress3(trace.trace.from),
10642
+ to: trace.trace.to ? checksumAddress3(trace.trace.to) : null,
10643
+ input: trace.trace.input,
10644
+ output: trace.trace.output,
10645
+ gas: hexToBigInt6(trace.trace.gas),
10646
+ gasUsed: hexToBigInt6(trace.trace.gasUsed),
10647
+ value: trace.trace.value ? hexToBigInt6(trace.trace.value) : null,
10648
+ traceIndex: trace.trace.index,
10649
+ subcalls: trace.trace.subcalls
10650
+ });
10644
10651
 
10645
10652
  // src/sync/index.ts
10646
- import { hexToBigInt as hexToBigInt7, hexToNumber as hexToNumber8, toHex as toHex2 } from "viem";
10647
10653
  var syncBlockToLightBlock = ({
10648
10654
  hash,
10649
10655
  parentHash,
@@ -10682,17 +10688,17 @@ var splitEvents = (events) => {
10682
10688
  let hash;
10683
10689
  const result = [];
10684
10690
  for (const event of events) {
10685
- if (hash === void 0 || hash !== event.block.hash) {
10691
+ if (hash === void 0 || hash !== event.event.block.hash) {
10686
10692
  result.push({
10687
10693
  checkpoint: encodeCheckpoint({
10688
10694
  ...MAX_CHECKPOINT,
10689
- blockTimestamp: Number(event.block.timestamp),
10695
+ blockTimestamp: Number(event.event.block.timestamp),
10690
10696
  chainId: BigInt(event.chainId),
10691
- blockNumber: event.block.number
10697
+ blockNumber: event.event.block.number
10692
10698
  }),
10693
10699
  events: []
10694
10700
  });
10695
- hash = event.block.hash;
10701
+ hash = event.event.block.hash;
10696
10702
  }
10697
10703
  result[result.length - 1].events.push(event);
10698
10704
  }
@@ -10811,7 +10817,17 @@ var createSync = async (params) => {
10811
10817
  params.common.options.syncEventsQuerySize / (params.indexingBuild.networks.length * 2)
10812
10818
  )
10813
10819
  });
10814
- return bufferAsyncGenerator(localEventGenerator, 1);
10820
+ async function* decodeEventGenerator() {
10821
+ for await (const { events, checkpoint } of localEventGenerator) {
10822
+ const decodedEvents = decodeEvents(params.common, sources, events);
10823
+ params.common.logger.debug({
10824
+ service: "app",
10825
+ msg: `Decoded ${decodedEvents.length} '${network.name}' events`
10826
+ });
10827
+ yield { events: decodedEvents, checkpoint };
10828
+ }
10829
+ }
10830
+ return bufferAsyncGenerator(decodeEventGenerator(), 1);
10815
10831
  }
10816
10832
  );
10817
10833
  const mergeAsync = params.ordering === "multichain" ? mergeAsyncGenerators : mergeAsyncGeneratorsWithEventOrder;
@@ -10848,6 +10864,7 @@ var createSync = async (params) => {
10848
10864
  const latencyTimers = /* @__PURE__ */ new Map();
10849
10865
  const onRealtimeSyncEvent = (event, {
10850
10866
  network,
10867
+ sources,
10851
10868
  syncProgress,
10852
10869
  realtimeSync
10853
10870
  }) => {
@@ -10876,15 +10893,24 @@ var createSync = async (params) => {
10876
10893
  const readyEvents = events.concat(pendingEvents);
10877
10894
  pendingEvents = [];
10878
10895
  executedEvents = executedEvents.concat(readyEvents);
10896
+ const decodedEvents = decodeEvents(
10897
+ params.common,
10898
+ sources,
10899
+ readyEvents
10900
+ );
10879
10901
  params.common.logger.debug({
10880
10902
  service: "sync",
10881
- msg: `Sequenced ${readyEvents.length} '${network.name}' events for block ${hexToNumber8(event.block.number)}`
10903
+ msg: `Decoded ${decodedEvents.length} '${network.name}' events for block ${hexToNumber8(event.block.number)}`
10904
+ });
10905
+ params.common.logger.debug({
10906
+ service: "sync",
10907
+ msg: `Sequenced ${decodedEvents.length} '${network.name}' events for block ${hexToNumber8(event.block.number)}`
10882
10908
  });
10883
10909
  params.onRealtimeEvent({
10884
10910
  type: "block",
10885
10911
  checkpoint,
10886
10912
  status: structuredClone(status),
10887
- events: readyEvents.sort(
10913
+ events: decodedEvents.sort(
10888
10914
  (a, b) => a.checkpoint < b.checkpoint ? -1 : 1
10889
10915
  ),
10890
10916
  network
@@ -10915,15 +10941,24 @@ var createSync = async (params) => {
10915
10941
  const readyEvents = pendingEvents.concat(events).filter(({ checkpoint }) => checkpoint < to);
10916
10942
  pendingEvents = pendingEvents.concat(events).filter(({ checkpoint }) => checkpoint > to);
10917
10943
  executedEvents = executedEvents.concat(readyEvents);
10944
+ const decodedEvents = decodeEvents(
10945
+ params.common,
10946
+ sources,
10947
+ readyEvents
10948
+ );
10949
+ params.common.logger.debug({
10950
+ service: "sync",
10951
+ msg: `Decoded ${decodedEvents.length} '${network.name}' events for block ${hexToNumber8(event.block.number)}`
10952
+ });
10918
10953
  params.common.logger.debug({
10919
10954
  service: "sync",
10920
- msg: `Sequenced ${readyEvents.length} '${network.name}' events for timestamp range [${decodeCheckpoint(from).blockTimestamp}, ${decodeCheckpoint(to).blockTimestamp}]`
10955
+ msg: `Sequenced ${decodedEvents.length} '${network.name}' events for timestamp range [${decodeCheckpoint(from).blockTimestamp}, ${decodeCheckpoint(to).blockTimestamp}]`
10921
10956
  });
10922
10957
  params.onRealtimeEvent({
10923
10958
  type: "block",
10924
10959
  checkpoint: to,
10925
10960
  status: structuredClone(status),
10926
- events: readyEvents.sort(
10961
+ events: decodedEvents.sort(
10927
10962
  (a, b) => a.checkpoint < b.checkpoint ? -1 : 1
10928
10963
  ),
10929
10964
  network
@@ -11069,6 +11104,7 @@ var createSync = async (params) => {
11069
11104
  (event) => perChainOnRealtimeSyncEvent(event).then((event2) => {
11070
11105
  onRealtimeSyncEvent(event2, {
11071
11106
  network,
11107
+ sources,
11072
11108
  syncProgress,
11073
11109
  realtimeSync
11074
11110
  });
@@ -11433,6 +11469,9 @@ async function* getLocalEventGenerator(params) {
11433
11469
  cursor = queryCursor;
11434
11470
  yield { events, checkpoint: cursor };
11435
11471
  } catch (error) {
11472
+ if (params.common.shutdown.isKilled) {
11473
+ throw error;
11474
+ }
11436
11475
  params.common.logger.warn({
11437
11476
  service: "sync",
11438
11477
  msg: `Failed '${params.network.name}' extract query for timestamp range [${decodeCheckpoint(cursor).blockTimestamp}, ${decodeCheckpoint(to).blockTimestamp}]`,
@@ -11938,12 +11977,7 @@ async function run({
11938
11977
  let lastFlush = Date.now();
11939
11978
  for await (const events of sync.getEvents()) {
11940
11979
  if (events.length > 0) {
11941
- const decodedEvents = decodeEvents(common, indexingBuild.sources, events);
11942
- const eventChunks = chunk(decodedEvents, 93);
11943
- common.logger.debug({
11944
- service: "app",
11945
- msg: `Decoded ${decodedEvents.length} events`
11946
- });
11980
+ const eventChunks = chunk(events, 93);
11947
11981
  for (const eventChunk of eventChunks) {
11948
11982
  const result = await indexingService.processEvents({
11949
11983
  events: eventChunk
@@ -11991,12 +12025,12 @@ async function run({
11991
12025
  if (eta === void 0 || progress === void 0) {
11992
12026
  common.logger.info({
11993
12027
  service: "app",
11994
- msg: `Indexed ${decodedEvents.length} events`
12028
+ msg: `Indexed ${events.length} events`
11995
12029
  });
11996
12030
  } else {
11997
12031
  common.logger.info({
11998
12032
  service: "app",
11999
- msg: `Indexed ${decodedEvents.length} events with ${formatPercentage(progress)} complete and ${formatEta(eta * 1e3)} remaining`
12033
+ msg: `Indexed ${events.length} events with ${formatPercentage(progress)} complete and ${formatEta(eta * 1e3)} remaining`
12000
12034
  });
12001
12035
  }
12002
12036
  if (historicalIndexingStore.isCacheFull() && events.length > 0 || common.options.command === "dev" && lastFlush + 5e3 < Date.now() && events.length > 0) {
@@ -12065,21 +12099,16 @@ async function run({
12065
12099
  const network = indexingBuild.networks.find(
12066
12100
  (network2) => network2.chainId === Number(decodeCheckpoint(checkpoint).chainId)
12067
12101
  );
12068
- const decodedEvents = decodeEvents(
12069
- common,
12070
- indexingBuild.sources,
12071
- events
12072
- );
12073
12102
  common.logger.debug({
12074
12103
  service: "app",
12075
- msg: `Decoded ${decodedEvents.length} '${network.name}' events for block ${Number(decodeCheckpoint(checkpoint).blockNumber)}`
12104
+ msg: `Decoded ${events.length} '${network.name}' events for block ${Number(decodeCheckpoint(checkpoint).blockNumber)}`
12076
12105
  });
12077
12106
  const result = await indexingService.processEvents({
12078
- events: decodedEvents
12107
+ events
12079
12108
  });
12080
12109
  common.logger.info({
12081
12110
  service: "app",
12082
- msg: `Indexed ${decodedEvents.length} '${network.name}' events for block ${Number(decodeCheckpoint(checkpoint).blockNumber)}`
12111
+ msg: `Indexed ${events.length} '${network.name}' events for block ${Number(decodeCheckpoint(checkpoint).blockNumber)}`
12083
12112
  });
12084
12113
  if (result.status === "error")
12085
12114
  onReloadableError(result.error);