ponder 0.8.13 → 0.8.15
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 +150 -24
- package/dist/bin/ponder.js.map +1 -1
- package/package.json +1 -1
- package/src/bin/utils/run.ts +2 -2
- package/src/sync/index.ts +14 -4
- package/src/sync-historical/index.ts +133 -18
- package/src/sync-realtime/index.ts +57 -7
- package/src/utils/rpc.ts +14 -0
package/dist/bin/ponder.js
CHANGED
|
@@ -8233,6 +8233,10 @@ var _eth_getTransactionReceipt = (requestQueue, { hash }) => requestQueue.reques
|
|
|
8233
8233
|
});
|
|
8234
8234
|
return receipt;
|
|
8235
8235
|
});
|
|
8236
|
+
var _eth_getBlockReceipts = (requestQueue, { blockHash }) => requestQueue.request({
|
|
8237
|
+
method: "eth_getBlockReceipts",
|
|
8238
|
+
params: [blockHash]
|
|
8239
|
+
}).then((receipts) => receipts);
|
|
8236
8240
|
var _debug_traceBlockByNumber = (requestQueue, {
|
|
8237
8241
|
blockNumber
|
|
8238
8242
|
}) => requestQueue.request({
|
|
@@ -8320,9 +8324,12 @@ import {
|
|
|
8320
8324
|
} from "viem";
|
|
8321
8325
|
var createHistoricalSync = async (args) => {
|
|
8322
8326
|
let isKilled = false;
|
|
8327
|
+
let isBlockReceipts = true;
|
|
8323
8328
|
const blockCache = /* @__PURE__ */ new Map();
|
|
8324
8329
|
const traceCache = /* @__PURE__ */ new Map();
|
|
8325
8330
|
const transactionsCache = /* @__PURE__ */ new Set();
|
|
8331
|
+
const blockReceiptsCache = /* @__PURE__ */ new Map();
|
|
8332
|
+
const transactionReceiptsCache = /* @__PURE__ */ new Map();
|
|
8326
8333
|
const getLogsRequestMetadata = /* @__PURE__ */ new Map();
|
|
8327
8334
|
let intervalsCache;
|
|
8328
8335
|
if (args.network.disableCache) {
|
|
@@ -8459,6 +8466,65 @@ var createHistoricalSync = async (args) => {
|
|
|
8459
8466
|
return await traces;
|
|
8460
8467
|
}
|
|
8461
8468
|
};
|
|
8469
|
+
const syncTransactionReceipts = async (block, transactionHashes) => {
|
|
8470
|
+
if (isBlockReceipts === false) {
|
|
8471
|
+
const transactionReceipts2 = await Promise.all(
|
|
8472
|
+
Array.from(transactionHashes).map(
|
|
8473
|
+
(hash) => syncTransactionReceipt(hash)
|
|
8474
|
+
)
|
|
8475
|
+
);
|
|
8476
|
+
return transactionReceipts2;
|
|
8477
|
+
}
|
|
8478
|
+
let blockReceipts;
|
|
8479
|
+
try {
|
|
8480
|
+
blockReceipts = await syncBlockReceipts(block);
|
|
8481
|
+
} catch (_error) {
|
|
8482
|
+
const error = _error;
|
|
8483
|
+
args.common.logger.warn({
|
|
8484
|
+
service: "sync",
|
|
8485
|
+
msg: `Caught eth_getBlockReceipts error on '${args.network.name}', switching to eth_getTransactionReceipt method.`,
|
|
8486
|
+
error
|
|
8487
|
+
});
|
|
8488
|
+
isBlockReceipts = false;
|
|
8489
|
+
return syncTransactionReceipts(block, transactionHashes);
|
|
8490
|
+
}
|
|
8491
|
+
const blockReceiptsTransactionHashes = new Set(
|
|
8492
|
+
blockReceipts.map((r) => r.transactionHash)
|
|
8493
|
+
);
|
|
8494
|
+
for (const hash of Array.from(transactionHashes)) {
|
|
8495
|
+
if (blockReceiptsTransactionHashes.has(hash) === false) {
|
|
8496
|
+
throw new Error(
|
|
8497
|
+
`Detected inconsistent RPC responses. 'transaction.hash' ${hash} not found in eth_getBlockReceipts response for block '${block}'`
|
|
8498
|
+
);
|
|
8499
|
+
}
|
|
8500
|
+
}
|
|
8501
|
+
const transactionReceipts = blockReceipts.filter(
|
|
8502
|
+
(receipt) => transactionHashes.has(receipt.transactionHash)
|
|
8503
|
+
);
|
|
8504
|
+
return transactionReceipts;
|
|
8505
|
+
};
|
|
8506
|
+
const syncTransactionReceipt = async (transaction) => {
|
|
8507
|
+
if (transactionReceiptsCache.has(transaction)) {
|
|
8508
|
+
return await transactionReceiptsCache.get(transaction);
|
|
8509
|
+
} else {
|
|
8510
|
+
const receipt = _eth_getTransactionReceipt(args.requestQueue, {
|
|
8511
|
+
hash: transaction
|
|
8512
|
+
});
|
|
8513
|
+
transactionReceiptsCache.set(transaction, receipt);
|
|
8514
|
+
return await receipt;
|
|
8515
|
+
}
|
|
8516
|
+
};
|
|
8517
|
+
const syncBlockReceipts = async (block) => {
|
|
8518
|
+
if (blockReceiptsCache.has(block)) {
|
|
8519
|
+
return await blockReceiptsCache.get(block);
|
|
8520
|
+
} else {
|
|
8521
|
+
const blockReceipts = _eth_getBlockReceipts(args.requestQueue, {
|
|
8522
|
+
blockHash: block
|
|
8523
|
+
});
|
|
8524
|
+
blockReceiptsCache.set(block, blockReceipts);
|
|
8525
|
+
return await blockReceipts;
|
|
8526
|
+
}
|
|
8527
|
+
};
|
|
8462
8528
|
const syncLogFactory = async (filter, interval) => {
|
|
8463
8529
|
const logs = await syncLogsDynamic({
|
|
8464
8530
|
filter,
|
|
@@ -8494,6 +8560,7 @@ var createHistoricalSync = async (args) => {
|
|
|
8494
8560
|
const blocks = await Promise.all(
|
|
8495
8561
|
logs.map((log) => syncBlock(hexToNumber4(log.blockNumber)))
|
|
8496
8562
|
);
|
|
8563
|
+
const requiredBlocks = new Set(blocks.map((b) => b.hash));
|
|
8497
8564
|
for (let i = 0; i < logs.length; i++) {
|
|
8498
8565
|
const log = logs[i];
|
|
8499
8566
|
const block = blocks[i];
|
|
@@ -8523,10 +8590,13 @@ var createHistoricalSync = async (args) => {
|
|
|
8523
8590
|
return;
|
|
8524
8591
|
if (shouldGetTransactionReceipt(filter)) {
|
|
8525
8592
|
const transactionReceipts = await Promise.all(
|
|
8526
|
-
Array.from(
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
|
|
8593
|
+
Array.from(requiredBlocks).map((blockHash) => {
|
|
8594
|
+
const blockTransactionHashes = new Set(
|
|
8595
|
+
logs.filter((l) => l.blockHash === blockHash).map((l) => l.transactionHash)
|
|
8596
|
+
);
|
|
8597
|
+
return syncTransactionReceipts(blockHash, blockTransactionHashes);
|
|
8598
|
+
})
|
|
8599
|
+
).then((receipts) => receipts.flat());
|
|
8530
8600
|
if (isKilled)
|
|
8531
8601
|
return;
|
|
8532
8602
|
await args.syncStore.insertTransactionReceipts({
|
|
@@ -8559,6 +8629,7 @@ var createHistoricalSync = async (args) => {
|
|
|
8559
8629
|
if (isKilled)
|
|
8560
8630
|
return;
|
|
8561
8631
|
const transactionHashes = /* @__PURE__ */ new Set();
|
|
8632
|
+
const requiredBlocks = /* @__PURE__ */ new Set();
|
|
8562
8633
|
for (const block of blocks) {
|
|
8563
8634
|
block.transactions.map((transaction) => {
|
|
8564
8635
|
if (isTransactionFilterMatched({
|
|
@@ -8569,6 +8640,7 @@ var createHistoricalSync = async (args) => {
|
|
|
8569
8640
|
toChildAddresses
|
|
8570
8641
|
})) {
|
|
8571
8642
|
transactionHashes.add(transaction.hash);
|
|
8643
|
+
requiredBlocks.add(block);
|
|
8572
8644
|
}
|
|
8573
8645
|
});
|
|
8574
8646
|
}
|
|
@@ -8578,10 +8650,13 @@ var createHistoricalSync = async (args) => {
|
|
|
8578
8650
|
if (isKilled)
|
|
8579
8651
|
return;
|
|
8580
8652
|
const transactionReceipts = await Promise.all(
|
|
8581
|
-
Array.from(
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8653
|
+
Array.from(requiredBlocks).map((block) => {
|
|
8654
|
+
const blockTransactionHashes = new Set(
|
|
8655
|
+
block.transactions.filter((t) => transactionHashes.has(t.hash)).map((t) => t.hash)
|
|
8656
|
+
);
|
|
8657
|
+
return syncTransactionReceipts(block.hash, blockTransactionHashes);
|
|
8658
|
+
})
|
|
8659
|
+
).then((receipts) => receipts.flat());
|
|
8585
8660
|
if (isKilled)
|
|
8586
8661
|
return;
|
|
8587
8662
|
await args.syncStore.insertTransactionReceipts({
|
|
@@ -8592,6 +8667,7 @@ var createHistoricalSync = async (args) => {
|
|
|
8592
8667
|
const syncTraceOrTransferFilter = async (filter, interval) => {
|
|
8593
8668
|
const fromChildAddresses = isAddressFactory(filter.fromAddress) ? await syncAddressFactory(filter.fromAddress, interval) : void 0;
|
|
8594
8669
|
const toChildAddresses = isAddressFactory(filter.toAddress) ? await syncAddressFactory(filter.toAddress, interval) : void 0;
|
|
8670
|
+
const requiredBlocks = /* @__PURE__ */ new Set();
|
|
8595
8671
|
const traces = await Promise.all(
|
|
8596
8672
|
intervalRange(interval).map(async (number) => {
|
|
8597
8673
|
let traces2 = await syncTrace(number);
|
|
@@ -8613,6 +8689,7 @@ var createHistoricalSync = async (args) => {
|
|
|
8613
8689
|
if (traces2.length === 0)
|
|
8614
8690
|
return [];
|
|
8615
8691
|
const block = await syncBlock(number);
|
|
8692
|
+
requiredBlocks.add(block.hash);
|
|
8616
8693
|
return traces2.map((trace) => {
|
|
8617
8694
|
const transaction = block.transactions.find(
|
|
8618
8695
|
(t) => t.hash === trace.transactionHash
|
|
@@ -8629,9 +8706,6 @@ var createHistoricalSync = async (args) => {
|
|
|
8629
8706
|
).then((traces2) => traces2.flat());
|
|
8630
8707
|
if (isKilled)
|
|
8631
8708
|
return;
|
|
8632
|
-
const transactionHashes = new Set(
|
|
8633
|
-
traces.map(({ transaction }) => transaction.hash)
|
|
8634
|
-
);
|
|
8635
8709
|
await args.syncStore.insertTraces({
|
|
8636
8710
|
traces,
|
|
8637
8711
|
chainId: args.network.chainId
|
|
@@ -8640,10 +8714,13 @@ var createHistoricalSync = async (args) => {
|
|
|
8640
8714
|
return;
|
|
8641
8715
|
if (shouldGetTransactionReceipt(filter)) {
|
|
8642
8716
|
const transactionReceipts = await Promise.all(
|
|
8643
|
-
Array.from(
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8717
|
+
Array.from(requiredBlocks).map((blockHash) => {
|
|
8718
|
+
const blockTransactionHashes = new Set(
|
|
8719
|
+
traces.filter((t) => t.block.hash === blockHash).map((t) => t.transaction.hash)
|
|
8720
|
+
);
|
|
8721
|
+
return syncTransactionReceipts(blockHash, blockTransactionHashes);
|
|
8722
|
+
})
|
|
8723
|
+
).then((receipts) => receipts.flat());
|
|
8647
8724
|
if (isKilled)
|
|
8648
8725
|
return;
|
|
8649
8726
|
await args.syncStore.insertTransactionReceipts({
|
|
@@ -8738,6 +8815,8 @@ var createHistoricalSync = async (args) => {
|
|
|
8738
8815
|
blockCache.clear();
|
|
8739
8816
|
traceCache.clear();
|
|
8740
8817
|
transactionsCache.clear();
|
|
8818
|
+
blockReceiptsCache.clear();
|
|
8819
|
+
transactionReceiptsCache.clear();
|
|
8741
8820
|
return latestBlock;
|
|
8742
8821
|
},
|
|
8743
8822
|
kill() {
|
|
@@ -8828,6 +8907,7 @@ var ERROR_TIMEOUT = [
|
|
|
8828
8907
|
var MAX_QUEUED_BLOCKS = 25;
|
|
8829
8908
|
var createRealtimeSync = (args) => {
|
|
8830
8909
|
let isKilled = false;
|
|
8910
|
+
let isBlockReceipts = true;
|
|
8831
8911
|
let finalizedBlock;
|
|
8832
8912
|
let finalizedChildAddresses;
|
|
8833
8913
|
const unfinalizedChildAddresses = /* @__PURE__ */ new Map();
|
|
@@ -9151,6 +9231,45 @@ var createRealtimeSync = (args) => {
|
|
|
9151
9231
|
factoryLogsPerBlock.delete(hash);
|
|
9152
9232
|
}
|
|
9153
9233
|
};
|
|
9234
|
+
const syncTransactionReceipts = async (blockHash, transactionHashes) => {
|
|
9235
|
+
if (isBlockReceipts === false) {
|
|
9236
|
+
const transactionReceipts2 = await Promise.all(
|
|
9237
|
+
Array.from(transactionHashes).map(
|
|
9238
|
+
async (hash) => _eth_getTransactionReceipt(args.requestQueue, { hash })
|
|
9239
|
+
)
|
|
9240
|
+
);
|
|
9241
|
+
return transactionReceipts2;
|
|
9242
|
+
}
|
|
9243
|
+
let blockReceipts;
|
|
9244
|
+
try {
|
|
9245
|
+
blockReceipts = await _eth_getBlockReceipts(args.requestQueue, {
|
|
9246
|
+
blockHash
|
|
9247
|
+
});
|
|
9248
|
+
} catch (_error) {
|
|
9249
|
+
const error = _error;
|
|
9250
|
+
args.common.logger.warn({
|
|
9251
|
+
service: "realtime",
|
|
9252
|
+
msg: `Caught eth_getBlockReceipts error on '${args.network.name}', switching to eth_getTransactionReceipt method.`,
|
|
9253
|
+
error
|
|
9254
|
+
});
|
|
9255
|
+
isBlockReceipts = false;
|
|
9256
|
+
return syncTransactionReceipts(blockHash, transactionHashes);
|
|
9257
|
+
}
|
|
9258
|
+
const blockReceiptsTransactionHashes = new Set(
|
|
9259
|
+
blockReceipts.map((r) => r.transactionHash)
|
|
9260
|
+
);
|
|
9261
|
+
for (const hash of Array.from(transactionHashes)) {
|
|
9262
|
+
if (blockReceiptsTransactionHashes.has(hash) === false) {
|
|
9263
|
+
throw new Error(
|
|
9264
|
+
`Detected inconsistent RPC responses. Transaction receipt with transactionHash ${hash} is missing in \`blockReceipts\`.`
|
|
9265
|
+
);
|
|
9266
|
+
}
|
|
9267
|
+
}
|
|
9268
|
+
const transactionReceipts = blockReceipts.filter(
|
|
9269
|
+
(receipt) => transactionHashes.has(receipt.transactionHash)
|
|
9270
|
+
);
|
|
9271
|
+
return transactionReceipts;
|
|
9272
|
+
};
|
|
9154
9273
|
const fetchBlockEventData = async (block) => {
|
|
9155
9274
|
const shouldRequestLogs = block.logsBloom === zeroLogsBloom || logFilters.some((filter) => isFilterInBloom({ block, filter }));
|
|
9156
9275
|
let logs = [];
|
|
@@ -9272,14 +9391,13 @@ var createRealtimeSync = (args) => {
|
|
|
9272
9391
|
for (const hash of Array.from(requiredTransactions)) {
|
|
9273
9392
|
if (blockTransactionsHashes.has(hash) === false) {
|
|
9274
9393
|
throw new Error(
|
|
9275
|
-
`Detected inconsistent RPC responses.
|
|
9394
|
+
`Detected inconsistent RPC responses. 'transaction.hash' ${hash} not found in eth_getBlockReceipts response for block '${block.hash}'.`
|
|
9276
9395
|
);
|
|
9277
9396
|
}
|
|
9278
9397
|
}
|
|
9279
|
-
const transactionReceipts = await
|
|
9280
|
-
block.
|
|
9281
|
-
|
|
9282
|
-
)
|
|
9398
|
+
const transactionReceipts = await syncTransactionReceipts(
|
|
9399
|
+
block.hash,
|
|
9400
|
+
requiredTransactionReceipts
|
|
9283
9401
|
);
|
|
9284
9402
|
return {
|
|
9285
9403
|
block,
|
|
@@ -9775,10 +9893,18 @@ var splitEvents = (events) => {
|
|
|
9775
9893
|
const result = [];
|
|
9776
9894
|
for (const event of events) {
|
|
9777
9895
|
if (prevHash === void 0 || prevHash !== event.block.hash) {
|
|
9778
|
-
result.push(
|
|
9896
|
+
result.push({
|
|
9897
|
+
checkpoint: encodeCheckpoint({
|
|
9898
|
+
...maxCheckpoint,
|
|
9899
|
+
blockTimestamp: Number(event.block.timestamp),
|
|
9900
|
+
chainId: BigInt(event.chainId),
|
|
9901
|
+
blockNumber: event.block.number
|
|
9902
|
+
}),
|
|
9903
|
+
events: []
|
|
9904
|
+
});
|
|
9779
9905
|
prevHash = event.block.hash;
|
|
9780
9906
|
}
|
|
9781
|
-
result[result.length - 1].push(event);
|
|
9907
|
+
result[result.length - 1].events.push(event);
|
|
9782
9908
|
}
|
|
9783
9909
|
return result;
|
|
9784
9910
|
};
|
|
@@ -10535,14 +10661,14 @@ async function run({
|
|
|
10535
10661
|
worker: async (event) => {
|
|
10536
10662
|
switch (event.type) {
|
|
10537
10663
|
case "block": {
|
|
10538
|
-
for (const events of splitEvents(event.events)) {
|
|
10664
|
+
for (const { checkpoint, events } of splitEvents(event.events)) {
|
|
10539
10665
|
const result = await handleEvents(
|
|
10540
10666
|
decodeEvents(common, indexingBuild.sources, events),
|
|
10541
10667
|
event.checkpoint
|
|
10542
10668
|
);
|
|
10543
10669
|
if (result.status === "error")
|
|
10544
10670
|
onReloadableError(result.error);
|
|
10545
|
-
await database.complete({ checkpoint
|
|
10671
|
+
await database.complete({ checkpoint });
|
|
10546
10672
|
}
|
|
10547
10673
|
await metadataStore.setStatus(event.status);
|
|
10548
10674
|
break;
|