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.
- package/dist/bin/ponder.js +1139 -1110
- package/dist/bin/ponder.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/bin/utils/run.ts +7 -18
- package/src/graphql/index.ts +1 -1
- package/src/sync/index.ts +60 -20
- package/src/sync-historical/index.ts +26 -26
package/dist/bin/ponder.js
CHANGED
|
@@ -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
|
|
9216
|
-
hexToNumber as
|
|
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
|
-
|
|
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
|
|
9246
|
-
const intervals = metadata ? getChunks({
|
|
8686
|
+
const intervals = getChunks({
|
|
9247
8687
|
interval,
|
|
9248
|
-
maxChunkSize:
|
|
9249
|
-
})
|
|
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 =
|
|
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
|
-
|
|
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 (
|
|
9330
|
-
|
|
9331
|
-
|
|
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 (
|
|
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(
|
|
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 ${
|
|
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 ${
|
|
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
|
|
9203
|
+
import { hexToNumber as hexToNumber6, zeroHash as zeroHash2 } from "viem";
|
|
9761
9204
|
|
|
9762
9205
|
// src/sync-realtime/bloom.ts
|
|
9763
|
-
import { hexToBytes, hexToNumber as
|
|
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 (
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 =
|
|
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) =>
|
|
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 ${
|
|
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) =>
|
|
9515
|
+
(lb) => hexToNumber6(lb.number) <= hexToNumber6(pendingFinalizedBlock.number)
|
|
10073
9516
|
);
|
|
10074
9517
|
unfinalizedBlocks = unfinalizedBlocks.filter(
|
|
10075
|
-
(lb) =>
|
|
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
|
-
|
|
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
|
|
10116
|
-
(
|
|
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
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
|
|
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
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
|
|
10147
|
-
|
|
10148
|
-
|
|
10149
|
-
|
|
10150
|
-
|
|
10151
|
-
|
|
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
|
-
|
|
10158
|
-
|
|
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
|
-
|
|
10162
|
-
|
|
10163
|
-
|
|
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
|
-
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10169
|
-
|
|
10170
|
-
|
|
10171
|
-
|
|
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
|
-
|
|
10174
|
-
|
|
10175
|
-
|
|
10176
|
-
|
|
10177
|
-
|
|
10178
|
-
|
|
10179
|
-
|
|
10180
|
-
|
|
10181
|
-
|
|
10182
|
-
|
|
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
|
-
|
|
10189
|
-
|
|
10190
|
-
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
|
|
10194
|
-
|
|
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
|
-
|
|
10199
|
-
|
|
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
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
const
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
|
|
10210
|
-
"
|
|
10211
|
-
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
|
|
10215
|
-
|
|
10216
|
-
|
|
10217
|
-
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
|
|
10223
|
-
|
|
10224
|
-
|
|
10225
|
-
|
|
10226
|
-
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
|
|
10234
|
-
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
|
|
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
|
-
|
|
10244
|
-
|
|
10245
|
-
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
10261
|
-
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10270
|
-
|
|
10271
|
-
|
|
10272
|
-
|
|
10273
|
-
|
|
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
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
|
|
10287
|
-
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
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
|
-
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
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
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
|
|
10329
|
-
|
|
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
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
|
|
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
|
-
|
|
10441
|
+
break;
|
|
10392
10442
|
}
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
|
|
10403
|
-
|
|
10404
|
-
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
|
|
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
|
-
|
|
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
|
-
|
|
10465
|
-
|
|
10466
|
-
|
|
10467
|
-
|
|
10468
|
-
|
|
10469
|
-
|
|
10470
|
-
|
|
10471
|
-
|
|
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
|
-
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
|
|
10494
|
-
|
|
10495
|
-
|
|
10496
|
-
|
|
10497
|
-
|
|
10498
|
-
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
|
|
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
|
-
|
|
10563
|
-
|
|
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
|
-
|
|
10568
|
-
|
|
10569
|
-
|
|
10570
|
-
|
|
10571
|
-
|
|
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
|
-
|
|
10595
|
-
|
|
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 (
|
|
10629
|
-
|
|
10543
|
+
if (Array.isArray(obj)) {
|
|
10544
|
+
return obj.map(removeNullCharacters);
|
|
10630
10545
|
}
|
|
10631
|
-
|
|
10632
|
-
};
|
|
10633
|
-
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
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
|
|
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
|
-
|
|
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: `
|
|
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:
|
|
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 ${
|
|
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:
|
|
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
|
|
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 ${
|
|
12028
|
+
msg: `Indexed ${events.length} events`
|
|
11995
12029
|
});
|
|
11996
12030
|
} else {
|
|
11997
12031
|
common.logger.info({
|
|
11998
12032
|
service: "app",
|
|
11999
|
-
msg: `Indexed ${
|
|
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 ${
|
|
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
|
|
12107
|
+
events
|
|
12079
12108
|
});
|
|
12080
12109
|
common.logger.info({
|
|
12081
12110
|
service: "app",
|
|
12082
|
-
msg: `Indexed ${
|
|
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);
|