@xyo-network/xl1-cli 5.1.1 → 5.2.0
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/cli-min.mjs +1634 -642
- package/dist/cli-min.mjs.map +1 -1
- package/package.json +9 -9
package/dist/cli-min.mjs
CHANGED
|
@@ -66368,7 +66368,7 @@ config$1(en_default());
|
|
|
66368
66368
|
//#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js
|
|
66369
66369
|
var zod_default = external_exports;
|
|
66370
66370
|
//#endregion
|
|
66371
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.
|
|
66371
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4._8d90734bf06d8373d67780d6e09d467a/node_modules/@xyo-network/xl1-protocol/dist/neutral/protocol-model.mjs
|
|
66372
66372
|
var ExchangeOutcomeSchema$1 = asSchema$1("network.xyo.exchange.outcome", true);
|
|
66373
66373
|
var isExchangeOutcome$1 = isPayloadOfZodType$1(/* @__PURE__ */ object$5({
|
|
66374
66374
|
/** Hash of the ExchangeTerms payload this outcome settles */
|
|
@@ -67254,7 +67254,7 @@ var TransactionRejectionSchema$1 = asSchema$1("network.xyo.transaction.rejection
|
|
|
67254
67254
|
var isTransactionRejection$1 = isPayloadOfSchemaType$1(TransactionRejectionSchema$1);
|
|
67255
67255
|
AsObjectFactory.create(isTransactionRejection$1);
|
|
67256
67256
|
//#endregion
|
|
67257
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.
|
|
67257
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4._8d90734bf06d8373d67780d6e09d467a/node_modules/@xyo-network/xl1-protocol/dist/neutral/protocol-lib.mjs
|
|
67258
67258
|
function derivedReceiveAddress(address, scope) {
|
|
67259
67259
|
return toAddress(keccak256(new TextEncoder().encode(isDefined$1(scope) ? `${scope}|${address}` : address)).slice(-40), { prefix: false });
|
|
67260
67260
|
}
|
|
@@ -67290,6 +67290,20 @@ var NetworkStakeRewardsIndexPublishRunnerMoniker = "NetworkStakeRewardsIndexPubl
|
|
|
67290
67290
|
var SystemStatusRunnerMoniker = "SystemStatusRunner";
|
|
67291
67291
|
var SystemStatusViewerMoniker$1 = "SystemStatusViewer";
|
|
67292
67292
|
var SystemStatusPublisherMoniker = "SystemStatusPublisher";
|
|
67293
|
+
var FinalizedBlockStreamMoniker$1 = "FinalizedBlockStream";
|
|
67294
|
+
var FinalizedBlockStreamDesyncError$1 = class extends Error {
|
|
67295
|
+
/** The block whose `previous` did not match, when it could be fetched. */
|
|
67296
|
+
block;
|
|
67297
|
+
/** The hash the walk expected the next block's `previous` to be. */
|
|
67298
|
+
expectedPrevious;
|
|
67299
|
+
constructor(expectedPrevious, block) {
|
|
67300
|
+
const found = block ? `found ${block[0].previous} at block ${block[0].block}` : "no block found";
|
|
67301
|
+
super(`FinalizedBlockStream desynced: expected previous ${expectedPrevious}, ${found}`);
|
|
67302
|
+
this.name = "FinalizedBlockStreamDesyncError";
|
|
67303
|
+
this.expectedPrevious = expectedPrevious;
|
|
67304
|
+
this.block = block;
|
|
67305
|
+
}
|
|
67306
|
+
};
|
|
67293
67307
|
var BlocksStepSummarySchema$1 = asSchema$1("network.xyo.step.summary.blocks", true);
|
|
67294
67308
|
var isBlocksStepSummary$1 = isPayloadOfSchemaType$1(BlocksStepSummarySchema$1);
|
|
67295
67309
|
var asBlocksStepSummary$1 = AsObjectFactory.create(isBlocksStepSummary$1);
|
|
@@ -67498,7 +67512,7 @@ var TransactionValidationViewerMoniker$1 = "TransactionValidationViewer";
|
|
|
67498
67512
|
var WindowedBlockViewerMoniker$1 = "WindowedBlockViewer";
|
|
67499
67513
|
var XyoViewerMoniker$1 = "XyoViewer";
|
|
67500
67514
|
//#endregion
|
|
67501
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.
|
|
67515
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4._8d90734bf06d8373d67780d6e09d467a/node_modules/@xyo-network/xl1-protocol/dist/neutral/network-model.mjs
|
|
67502
67516
|
var local_default = "<svg id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\"><g style=\"opacity:.5;\"><path d=\"M154.71,97c.46,2.59,2.5,4.62,5.1,5.05l14.05,2.34,31.71-46.17c4.57-6.65-3.62-14.62-10.14-9.87l-43.68,31.83,2.97,16.82Z\" style=\"fill:#f47f00;\"/><path d=\"M173.86,151.62l-14.05,2.34c-2.6.43-4.64,2.45-5.1,5.05l-2.97,16.82,43.68,31.83c6.52,4.75,14.71-3.21,10.14-9.87l-31.71-46.17Z\" style=\"fill:#f47f00;\"/><path d=\"M82.14,104.38l14.05-2.34c2.6-.43,4.64-2.45,5.1-5.05l2.97-16.82-43.68-31.83c-6.52-4.75-14.71,3.21-10.14,9.87l31.71,46.17Z\" style=\"fill:#f47f00;\"/><path d=\"M101.29,159c-.46-2.59-2.5-4.62-5.1-5.05l-14.05-2.34-31.71,46.17c-4.57,6.65,3.62,14.62,10.14,9.87l43.68-31.83-2.97-16.82Z\" style=\"fill:#f47f00;\"/></g><path d=\"M107.33,104l15.94-90.32c.93-5.3,8.53-5.3,9.47,0l15.94,90.32c.35,2.01,1.94,3.57,3.95,3.91l92.24,15.35c5.36.89,5.36,8.59,0,9.49l-92.24,15.35c-2.01.33-3.59,1.9-3.95,3.91l-15.94,90.32c-.93,5.3-8.53,5.3-9.47,0l-15.94-90.32c-.35-2.01-1.94-3.57-3.95-3.91l-92.24-15.35c-5.36-.89-5.36-8.59,0-9.49l92.24-15.35c2.01-.33,3.59-1.9,3.95-3.91Z\" style=\"fill:#f47f00;\"/></svg>";
|
|
67503
67517
|
var mainnet_default = "<svg id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\"><path d=\"M154.71,97c.46,2.59,2.5,4.62,5.1,5.05l14.05,2.34,31.71-46.17c4.57-6.65-3.62-14.62-10.14-9.87l-43.68,31.83,2.97,16.82Z\" style=\"fill:#8d8fc6;\"/><path d=\"M173.86,151.62l-14.05,2.34c-2.6.43-4.64,2.45-5.1,5.05l-2.97,16.82,43.68,31.83c6.52,4.75,14.71-3.21,10.14-9.87l-31.71-46.17Z\" style=\"fill:#eb407a;\"/><path d=\"M82.14,104.38l14.05-2.34c2.6-.43,4.64-2.45,5.1-5.05l2.97-16.82-43.68-31.83c-6.52-4.75-14.71,3.21-10.14,9.87l31.71,46.17Z\" style=\"fill:#579fd6;\"/><path d=\"M101.29,159c-.46-2.59-2.5-4.62-5.1-5.05l-14.05-2.34-31.71,46.17c-4.57,6.65,3.62,14.62,10.14,9.87l43.68-31.83-2.97-16.82Z\" style=\"fill:#f27046;\"/><path d=\"M107.33,104l15.94-90.32c.93-5.3,8.53-5.3,9.47,0l15.94,90.32c.35,2.01,1.94,3.57,3.95,3.91l92.24,15.35c5.36.89,5.36,8.59,0,9.49l-92.24,15.35c-2.01.33-3.59,1.9-3.95,3.91l-15.94,90.32c-.93,5.3-8.53,5.3-9.47,0l-15.94-90.32c-.35-2.01-1.94-3.57-3.95-3.91l-92.24-15.35c-5.36-.89-5.36-8.59,0-9.49l92.24-15.35c2.01-.33,3.59-1.9,3.95-3.91Z\" style=\"fill:#572aff;\"/></svg>";
|
|
67504
67518
|
var testnet_default = "<svg id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\"><g style=\"opacity:.5;\"><path d=\"M154.71,97c.46,2.59,2.5,4.62,5.1,5.05l14.05,2.34,31.71-46.17c4.57-6.65-3.62-14.62-10.14-9.87l-43.68,31.83,2.97,16.82Z\" style=\"fill:#579fd6;\"/><path d=\"M173.86,151.62l-14.05,2.34c-2.6.43-4.64,2.45-5.1,5.05l-2.97,16.82,43.68,31.83c6.52,4.75,14.71-3.21,10.14-9.87l-31.71-46.17Z\" style=\"fill:#579fd6;\"/><path d=\"M82.14,104.38l14.05-2.34c2.6-.43,4.64-2.45,5.1-5.05l2.97-16.82-43.68-31.83c-6.52-4.75-14.71,3.21-10.14,9.87l31.71,46.17Z\" style=\"fill:#579fd6;\"/><path d=\"M101.29,159c-.46-2.59-2.5-4.62-5.1-5.05l-14.05-2.34-31.71,46.17c-4.57,6.65,3.62,14.62,10.14,9.87l43.68-31.83-2.97-16.82Z\" style=\"fill:#579fd6;\"/></g><path d=\"M107.33,104l15.94-90.32c.93-5.3,8.53-5.3,9.47,0l15.94,90.32c.35,2.01,1.94,3.57,3.95,3.91l92.24,15.35c5.36.89,5.36,8.59,0,9.49l-92.24,15.35c-2.01.33-3.59,1.9-3.95,3.91l-15.94,90.32c-.93,5.3-8.53,5.3-9.47,0l-15.94-90.32c-.35-2.01-1.94-3.57-3.95-3.91l-92.24-15.35c-5.36-.89-5.36-8.59,0-9.49l92.24-15.35c2.01-.33,3.59-1.9,3.95-3.91Z\" style=\"fill:#579fd6;\"/></svg>";
|
|
@@ -68148,7 +68162,7 @@ function admissionShadowHeadPath() {
|
|
|
68148
68162
|
return "admission/shadow/head.json";
|
|
68149
68163
|
}
|
|
68150
68164
|
//#endregion
|
|
68151
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.
|
|
68165
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4._8d90734bf06d8373d67780d6e09d467a/node_modules/@xyo-network/xl1-protocol/dist/neutral/schema.mjs
|
|
68152
68166
|
var asRequiredStrings = (required) => {
|
|
68153
68167
|
if (typeof required === "string") return [required];
|
|
68154
68168
|
if (!Array.isArray(required)) return [];
|
|
@@ -68384,7 +68398,7 @@ var TransferPayloadJsonSchema = {
|
|
|
68384
68398
|
};
|
|
68385
68399
|
var TransferPayloadJsonSchemaPayload = new PayloadBuilder$1({ schema: SchemaSchema$1 }).fields({ definition: TransferPayloadJsonSchema }).build();
|
|
68386
68400
|
//#endregion
|
|
68387
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.
|
|
68401
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4._8d90734bf06d8373d67780d6e09d467a/node_modules/@xyo-network/xl1-protocol/dist/neutral/validation.mjs
|
|
68388
68402
|
function maxTransactionFeeCost(tx) {
|
|
68389
68403
|
const { base, gasLimit, priority } = tx.fees;
|
|
68390
68404
|
return hexToBigInt(base) + hexToBigInt(priority) + hexToBigInt(gasLimit);
|
|
@@ -68630,7 +68644,7 @@ var validateTransaction = async (context, tx, additionalValidators) => {
|
|
|
68630
68644
|
}
|
|
68631
68645
|
};
|
|
68632
68646
|
//#endregion
|
|
68633
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
68647
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_3a01f3229f2daa942444e08696345b23/node_modules/@xyo-network/xl1-sdk/dist/neutral/driver-memory.mjs
|
|
68634
68648
|
var LruCacheMap$1 = class {
|
|
68635
68649
|
lruCache;
|
|
68636
68650
|
/** Creates an instance with the supplied configuration. */
|
|
@@ -71814,7 +71828,7 @@ var require_ExplorerSync = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
71814
71828
|
exports.ExplorerSync = ExplorerSync;
|
|
71815
71829
|
}));
|
|
71816
71830
|
//#endregion
|
|
71817
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
71831
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_3a01f3229f2daa942444e08696345b23/node_modules/@xyo-network/xl1-sdk/dist/node/protocol-sdk.mjs
|
|
71818
71832
|
var import_dist = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
71819
71833
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
71820
71834
|
exports.defaultLoadersSync = exports.defaultLoaders = exports.globalConfigSearchPlacesSync = exports.globalConfigSearchPlaces = exports.getDefaultSearchPlacesSync = exports.getDefaultSearchPlaces = exports.cosmiconfigSync = exports.cosmiconfig = void 0;
|
|
@@ -73065,21 +73079,47 @@ function blocksToChains$1(blocks) {
|
|
|
73065
73079
|
}
|
|
73066
73080
|
return chains;
|
|
73067
73081
|
}
|
|
73068
|
-
function toValidUncle$1(_context, finalizedWindowedChain, possibleUncle) {
|
|
73082
|
+
function toValidUncle$1(_context, finalizedWindowedChain, possibleUncle, onReject) {
|
|
73069
73083
|
const finalizedWindowStartBlockNumber = finalizedWindowedChain.at(0)?.[0].block ?? -1;
|
|
73070
73084
|
const finalizedHead = assertEx$1(finalizedWindowedChain.at(-1), () => "finalizedWindowedChain is empty");
|
|
73085
|
+
const tip = assertEx$1(possibleUncle.at(-1), () => "possibleUncle is empty");
|
|
73086
|
+
const reject = (reason, offendingTransactionHashes) => {
|
|
73087
|
+
onReject?.({
|
|
73088
|
+
blockHash: tip[0]._hash,
|
|
73089
|
+
blockNumber: tip[0].block,
|
|
73090
|
+
offendingTransactionHashes,
|
|
73091
|
+
reason
|
|
73092
|
+
});
|
|
73093
|
+
};
|
|
73071
73094
|
const prunedPossibleUncle = possibleUncle.filter((b) => b[0].block > finalizedHead[0].block);
|
|
73072
|
-
if (prunedPossibleUncle.length === 0)
|
|
73073
|
-
|
|
73074
|
-
|
|
73095
|
+
if (prunedPossibleUncle.length === 0) {
|
|
73096
|
+
reject("behind-finalized-head");
|
|
73097
|
+
return;
|
|
73098
|
+
}
|
|
73099
|
+
if (prunedPossibleUncle[0][0].block !== finalizedHead[0].block + 1) {
|
|
73100
|
+
reject("block-number-mismatch");
|
|
73101
|
+
return;
|
|
73102
|
+
}
|
|
73103
|
+
if (prunedPossibleUncle[0][0].previous !== finalizedHead[0]._hash) {
|
|
73104
|
+
reject("previous-hash-mismatch");
|
|
73105
|
+
return;
|
|
73106
|
+
}
|
|
73075
73107
|
const allUncleTransactions = prunedPossibleUncle.flatMap((b) => b[1]).filter(isTransactionBoundWitness$1);
|
|
73076
73108
|
const allFinalizedTransactions = finalizedWindowedChain.flatMap((b) => b[1]).filter(isTransactionBoundWitness$1);
|
|
73077
|
-
|
|
73078
|
-
if (
|
|
73109
|
+
const txsBeforeWindow = allUncleTransactions.filter((tx) => tx.nbf < finalizedWindowStartBlockNumber);
|
|
73110
|
+
if (txsBeforeWindow.length > 0) {
|
|
73111
|
+
reject("tx-before-window", txsBeforeWindow.map((tx) => tx._hash));
|
|
73112
|
+
return;
|
|
73113
|
+
}
|
|
73114
|
+
const txsInWindow = allUncleTransactions.filter((tx) => allFinalizedTransactions.some((finalTx) => finalTx._hash === tx._hash));
|
|
73115
|
+
if (txsInWindow.length > 0) {
|
|
73116
|
+
reject("tx-already-finalized", txsInWindow.map((tx) => tx._hash));
|
|
73117
|
+
return;
|
|
73118
|
+
}
|
|
73079
73119
|
return prunedPossibleUncle;
|
|
73080
73120
|
}
|
|
73081
|
-
function findUncles$1(context, finalizedWindowedChain, blocks) {
|
|
73082
|
-
return blocksToChains$1(blocks).map((chain) => toValidUncle$1(context, finalizedWindowedChain, chain)).filter(exists$1);
|
|
73121
|
+
function findUncles$1(context, finalizedWindowedChain, blocks, onReject) {
|
|
73122
|
+
return blocksToChains$1(blocks).map((chain) => toValidUncle$1(context, finalizedWindowedChain, chain, onReject)).filter(exists$1);
|
|
73083
73123
|
}
|
|
73084
73124
|
var ValidationConfigZod$1 = object$3({
|
|
73085
73125
|
signerAuthorizations: array$1(SignerAuthorizationZod$1).default([]).register(globalRegistry, {
|
|
@@ -73933,6 +73973,21 @@ async function buildUnsignedTransaction(chain, onChainPayloads, offChainPayloads
|
|
|
73933
73973
|
}
|
|
73934
73974
|
var DEFAULT_CONFIRMATION_ATTEMPTS = 20;
|
|
73935
73975
|
var DEFAULT_DELAY_BETWEEN_ATTEMPTS = 1e3;
|
|
73976
|
+
var TransactionConfirmationTimeoutError = class extends Error {
|
|
73977
|
+
/** Number of confirmation attempts made before giving up. */
|
|
73978
|
+
attempts;
|
|
73979
|
+
/** Marks the negative result as inconclusive: the transaction may still be pending or included later. */
|
|
73980
|
+
inconclusive = true;
|
|
73981
|
+
/** Hash of the transaction whose confirmation timed out. */
|
|
73982
|
+
txHash;
|
|
73983
|
+
/** Creates an instance for the given transaction and attempt count. */
|
|
73984
|
+
constructor(txHash, attempts) {
|
|
73985
|
+
super(`Transaction ${txHash} not confirmed after ${attempts} attempts \u2014 inconclusive: the transaction may still be pending or included later`);
|
|
73986
|
+
this.name = "TransactionConfirmationTimeoutError";
|
|
73987
|
+
this.attempts = attempts;
|
|
73988
|
+
this.txHash = txHash;
|
|
73989
|
+
}
|
|
73990
|
+
};
|
|
73936
73991
|
var assertNotExpired = async (viewer, txHash, exp, options) => {
|
|
73937
73992
|
const head = await viewer.currentBlockNumber();
|
|
73938
73993
|
if (head > exp) {
|
|
@@ -73953,8 +74008,8 @@ var confirmSubmittedTransaction = async (viewer, txHash, options) => {
|
|
|
73953
74008
|
if (isNumber(exp)) await assertNotExpired(viewer, txHash, exp, options);
|
|
73954
74009
|
attempts++;
|
|
73955
74010
|
if (attempts > maxAttempts) {
|
|
73956
|
-
options?.logger?.error(`\u26A0\uFE0F Transaction not confirmed after ${maxAttempts} attempts`);
|
|
73957
|
-
throw new
|
|
74011
|
+
options?.logger?.error(`\u26A0\uFE0F Transaction not confirmed after ${maxAttempts} attempts (inconclusive \u2014 it may still be pending)`);
|
|
74012
|
+
throw new TransactionConfirmationTimeoutError(txHash, maxAttempts);
|
|
73958
74013
|
}
|
|
73959
74014
|
options?.logger?.debug(`Transaction not confirmed yet, attempt ${attempts}. Retrying...`, txHash);
|
|
73960
74015
|
await delay$2(attemptDelay);
|
|
@@ -75206,6 +75261,7 @@ var SimpleBlockValidationViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
|
75206
75261
|
state: true,
|
|
75207
75262
|
head: void 0
|
|
75208
75263
|
};
|
|
75264
|
+
if (config !== void 0 && value !== true && state !== true) this.logger?.warn("validateBlocks called with a config that selects no validators (neither value nor state is true) — every block will report valid");
|
|
75209
75265
|
const blocksWithMeta = await Promise.all(blocks.map((b) => Promise.all([PayloadBuilder$1.addHashMeta(b[0]), PayloadBuilder$1.addHashMeta(b[1])])));
|
|
75210
75266
|
let head;
|
|
75211
75267
|
if (isChainQualifiedHeadConfig$1(config)) {
|
|
@@ -75254,18 +75310,30 @@ var SimpleBlockValidationViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
|
75254
75310
|
}
|
|
75255
75311
|
async doValidateState(blocks, chainIdAtBlockNumber) {
|
|
75256
75312
|
const windowedUncleChain = await this.updateWindowedChainCache();
|
|
75257
|
-
const
|
|
75313
|
+
const rejections = [];
|
|
75314
|
+
const uncles = findUncles$1(this.context, windowedUncleChain, blocks, (rejection) => rejections.push(rejection));
|
|
75258
75315
|
if (uncles.length !== 1) {
|
|
75259
|
-
|
|
75316
|
+
const rejectionSummary = rejections.map((r) => `${r.blockNumber} [${r.blockHash}]: ${r.reason}${(r.offendingTransactionHashes?.length ?? 0) > 0 ? ` (tx ${r.offendingTransactionHashes?.join(", ")})` : ""}`).join("; ");
|
|
75317
|
+
this.logger?.warn(`Unexpected uncle count during block validation [uncles=${uncles.length}, blocks=${blocks.length}]` + (rejectionSummary.length > 0 ? ` \u2014 rejected: ${rejectionSummary}` : ""));
|
|
75260
75318
|
this.logger?.debug(JSON.stringify({
|
|
75261
75319
|
uncles,
|
|
75262
75320
|
blocks: blocks.length
|
|
75263
75321
|
}, null, 2));
|
|
75264
75322
|
this.logger?.debug(JSON.stringify(windowedUncleChain, null, 2));
|
|
75265
|
-
return blocks.map((block) =>
|
|
75266
|
-
|
|
75267
|
-
|
|
75268
|
-
|
|
75323
|
+
return blocks.map((block) => {
|
|
75324
|
+
const rejection = rejections.find((r) => r.blockHash === block[0]._hash);
|
|
75325
|
+
const offendingTransactionHashes = rejection?.offendingTransactionHashes ?? [];
|
|
75326
|
+
if (rejection && offendingTransactionHashes.length > 0) return offendingTransactionHashes.map((txHash) => new HydratedBlockValidationError$1(txHash, block, `Uncle rejected during state validation: ${rejection.reason}`, {
|
|
75327
|
+
blockHash: rejection.blockHash,
|
|
75328
|
+
hash: txHash,
|
|
75329
|
+
reason: rejection.reason
|
|
75330
|
+
}));
|
|
75331
|
+
return [new HydratedBlockValidationError$1(block[0]._hash, block, `Unexpected uncle count during state validation${rejection ? `: ${rejection.reason}` : ""}`, {
|
|
75332
|
+
reason: rejection?.reason,
|
|
75333
|
+
uncles: uncles.length,
|
|
75334
|
+
blocks: blocks.length
|
|
75335
|
+
})];
|
|
75336
|
+
});
|
|
75269
75337
|
}
|
|
75270
75338
|
const validateState = assertEx$1(this.validators.blockStateValidator, () => "No block state validator registered");
|
|
75271
75339
|
return await Promise.all(uncles[0].map(async (block) => {
|
|
@@ -76102,6 +76170,303 @@ __publicField$25(SimpleFinalizationViewer$1, "monikers", [FinalizationViewerMoni
|
|
|
76102
76170
|
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
76103
76171
|
__publicField$25(SimpleFinalizationViewer$1, "surface", "node");
|
|
76104
76172
|
SimpleFinalizationViewer$1 = __decorateClass$26([creatableProvider$1()], SimpleFinalizationViewer$1);
|
|
76173
|
+
var MIN_POLL_INTERVAL_MS$1 = 5e3;
|
|
76174
|
+
var DEFAULT_POLL_INTERVAL_MS$1 = 1e4;
|
|
76175
|
+
var DEFAULT_FETCH_WINDOW$1 = StepSizes$1[2];
|
|
76176
|
+
var MAX_FETCH_WINDOW$1 = StepSizes$1[3];
|
|
76177
|
+
var SimpleFinalizedBlockStreamOptionsZod$1 = object$3({
|
|
76178
|
+
/**
|
|
76179
|
+
* Hot-surface resume checkpoint: emit blocks strictly after this hash, as a
|
|
76180
|
+
* verified splice (the first emission's `previous` must equal it — mismatch
|
|
76181
|
+
* emits `desynced` at startup rather than delivering a diverged chain).
|
|
76182
|
+
* Omitted, the stream starts at the current head, delivered as the first
|
|
76183
|
+
* `nextBlock`.
|
|
76184
|
+
*/
|
|
76185
|
+
after: optional$1(HashZod),
|
|
76186
|
+
/**
|
|
76187
|
+
* Upper bound on blocks fetched per `blocksByNumber` window during a walk.
|
|
76188
|
+
* The window adapts to the lag (never fetching past the head) and grows up to
|
|
76189
|
+
* this cap on deep replays, letting REST-backed viewers tile each window from
|
|
76190
|
+
* step rollup files. Capped at the largest served rollup (`StepSizes[3]`);
|
|
76191
|
+
* raise toward it for indexer-style deep replays, lower it to bound memory.
|
|
76192
|
+
*/
|
|
76193
|
+
fetchWindow: number$1().int().positive().max(MAX_FETCH_WINDOW$1).default(DEFAULT_FETCH_WINDOW$1),
|
|
76194
|
+
/**
|
|
76195
|
+
* Hot-surface catch-up bound: when the head is further ahead than this, a
|
|
76196
|
+
* `gap` is announced and delivery resumes `maxCatchUp` blocks behind head.
|
|
76197
|
+
* The cold `blocks()` surface ignores this — it never gaps.
|
|
76198
|
+
*/
|
|
76199
|
+
maxCatchUp: number$1().int().positive().default(StepSizes$1[1]),
|
|
76200
|
+
/** Head poll cadence shared by the hot surface and all `blocks()` iterations. */
|
|
76201
|
+
pollIntervalMs: number$1().min(MIN_POLL_INTERVAL_MS$1).default(DEFAULT_POLL_INTERVAL_MS$1)
|
|
76202
|
+
});
|
|
76203
|
+
function cursorFromBlock$1(block) {
|
|
76204
|
+
return {
|
|
76205
|
+
block: block[0].block,
|
|
76206
|
+
hash: block[0]._hash
|
|
76207
|
+
};
|
|
76208
|
+
}
|
|
76209
|
+
var SimpleFinalizedBlockStream$1 = class extends AbstractCreatableProvider$1 {
|
|
76210
|
+
/** Moniker implemented by this provider instance. */
|
|
76211
|
+
moniker = FinalizedBlockStreamMoniker$1;
|
|
76212
|
+
_blockViewer;
|
|
76213
|
+
_cursor;
|
|
76214
|
+
_finalizationViewer;
|
|
76215
|
+
_head;
|
|
76216
|
+
_headWaiters = [];
|
|
76217
|
+
_hotLoop;
|
|
76218
|
+
_isLive = false;
|
|
76219
|
+
_options;
|
|
76220
|
+
_pollInProgress = false;
|
|
76221
|
+
_pollTimer = null;
|
|
76222
|
+
_stopping = false;
|
|
76223
|
+
_terminal = false;
|
|
76224
|
+
/** Last position delivered on the hot surface, or `undefined` before the first. */
|
|
76225
|
+
get cursor() {
|
|
76226
|
+
return this._cursor;
|
|
76227
|
+
}
|
|
76228
|
+
/** True once the hot surface has caught up to the live head. */
|
|
76229
|
+
get isLive() {
|
|
76230
|
+
return this._isLive;
|
|
76231
|
+
}
|
|
76232
|
+
get options() {
|
|
76233
|
+
this._options ??= SimpleFinalizedBlockStreamOptionsZod$1.parse(this.config.options);
|
|
76234
|
+
return this._options;
|
|
76235
|
+
}
|
|
76236
|
+
/** Validates the provider options at create time. */
|
|
76237
|
+
static async paramsHandler(params = {}) {
|
|
76238
|
+
const handled = await super.paramsHandler(params);
|
|
76239
|
+
SimpleFinalizedBlockStreamOptionsZod$1.parse(handled.context.config.options);
|
|
76240
|
+
return handled;
|
|
76241
|
+
}
|
|
76242
|
+
/**
|
|
76243
|
+
* Cold, per-caller iteration: replay from `after`, then follow the head.
|
|
76244
|
+
* Gapless by construction — the caller paces the walk. Throws
|
|
76245
|
+
* `FinalizedBlockStreamDesyncError` on any continuity failure, including a
|
|
76246
|
+
* failed resume splice; other (transient) fetch errors also throw, and the
|
|
76247
|
+
* caller resumes from its own checkpoint.
|
|
76248
|
+
*/
|
|
76249
|
+
async *blocks(options) {
|
|
76250
|
+
let cursor;
|
|
76251
|
+
if (isDefined$1(options?.after)) cursor = await this.resolveCheckpoint(options.after);
|
|
76252
|
+
else {
|
|
76253
|
+
const head = await this.currentHead();
|
|
76254
|
+
yield {
|
|
76255
|
+
block: head,
|
|
76256
|
+
head: head[0].block
|
|
76257
|
+
};
|
|
76258
|
+
cursor = cursorFromBlock$1(head);
|
|
76259
|
+
}
|
|
76260
|
+
while (!this._stopping) {
|
|
76261
|
+
const headNumber = (await this.currentHead())[0].block;
|
|
76262
|
+
if (cursor.block >= headNumber) {
|
|
76263
|
+
await this.waitForHeadAdvance();
|
|
76264
|
+
continue;
|
|
76265
|
+
}
|
|
76266
|
+
for (const block of await this.nextBlocks(cursor, headNumber)) {
|
|
76267
|
+
cursor = this.advanceCursor(cursor, block);
|
|
76268
|
+
yield {
|
|
76269
|
+
block,
|
|
76270
|
+
head: headNumber
|
|
76271
|
+
};
|
|
76272
|
+
if (this._stopping) return;
|
|
76273
|
+
}
|
|
76274
|
+
}
|
|
76275
|
+
}
|
|
76276
|
+
/** Creates the provider instance after its dependencies and configuration have resolved. */
|
|
76277
|
+
async createHandler() {
|
|
76278
|
+
await super.createHandler();
|
|
76279
|
+
const injected = this.params.viewers;
|
|
76280
|
+
this._blockViewer = injected?.blocks ?? assertEx$1(await this.locator.getInstance("BlockViewer"), () => "BlockViewer instance is required");
|
|
76281
|
+
this._finalizationViewer = injected?.finalization ?? assertEx$1(await this.locator.getInstance("FinalizationViewer"), () => "FinalizationViewer instance is required");
|
|
76282
|
+
}
|
|
76283
|
+
/** Starts the head poll and the hot delivery loop. */
|
|
76284
|
+
async startHandler() {
|
|
76285
|
+
await super.startHandler();
|
|
76286
|
+
this._stopping = false;
|
|
76287
|
+
this._terminal = false;
|
|
76288
|
+
await this.pollHead();
|
|
76289
|
+
this._pollTimer = setInterval(() => {
|
|
76290
|
+
this.pollHead();
|
|
76291
|
+
}, this.options.pollIntervalMs);
|
|
76292
|
+
this._hotLoop = this.runHot();
|
|
76293
|
+
}
|
|
76294
|
+
/** Stops the poll, ends the hot loop, and emits the terminal `stopped` event. */
|
|
76295
|
+
async stopHandler() {
|
|
76296
|
+
this._stopping = true;
|
|
76297
|
+
if (this._pollTimer) {
|
|
76298
|
+
clearInterval(this._pollTimer);
|
|
76299
|
+
this._pollTimer = null;
|
|
76300
|
+
}
|
|
76301
|
+
this.releaseHeadWaiters();
|
|
76302
|
+
await this._hotLoop;
|
|
76303
|
+
this._hotLoop = void 0;
|
|
76304
|
+
if (!this._terminal) {
|
|
76305
|
+
this._terminal = true;
|
|
76306
|
+
await this.emitSerial("stopped", { cursor: this._cursor });
|
|
76307
|
+
}
|
|
76308
|
+
this._head = void 0;
|
|
76309
|
+
await super.stopHandler();
|
|
76310
|
+
}
|
|
76311
|
+
/**
|
|
76312
|
+
* Verifies continuity and advances a cursor to the delivered block. A
|
|
76313
|
+
* `previous` mismatch on the expected block number is a data-integrity
|
|
76314
|
+
* fault; a wrong/missing block number is a transient fetch problem.
|
|
76315
|
+
*/
|
|
76316
|
+
advanceCursor(cursor, block) {
|
|
76317
|
+
assertEx$1(block[0].block === cursor.block + 1, () => `FinalizedBlockStream: expected block ${cursor.block + 1}, fetched ${block[0].block}`);
|
|
76318
|
+
if (block[0].previous !== cursor.hash) throw new FinalizedBlockStreamDesyncError$1(cursor.hash, block);
|
|
76319
|
+
return cursorFromBlock$1(block);
|
|
76320
|
+
}
|
|
76321
|
+
/** One hot-loop step: bound the lag (announcing a `gap`), deliver the next window, mark live. */
|
|
76322
|
+
async advanceHot() {
|
|
76323
|
+
const head = await this.currentHead();
|
|
76324
|
+
const headNumber = head[0].block;
|
|
76325
|
+
const cursor = assertEx$1(this._cursor);
|
|
76326
|
+
if (cursor.block >= headNumber) {
|
|
76327
|
+
await this.markLive(head);
|
|
76328
|
+
await this.waitForHeadAdvance();
|
|
76329
|
+
return;
|
|
76330
|
+
}
|
|
76331
|
+
if (headNumber - cursor.block > this.options.maxCatchUp) {
|
|
76332
|
+
await this.announceGap(cursor, headNumber);
|
|
76333
|
+
return;
|
|
76334
|
+
}
|
|
76335
|
+
for (const block of await this.nextBlocks(cursor, headNumber)) {
|
|
76336
|
+
if (this._stopping) return;
|
|
76337
|
+
this._cursor = this.advanceCursor(assertEx$1(this._cursor), block);
|
|
76338
|
+
await this.emitSerial("nextBlock", {
|
|
76339
|
+
block,
|
|
76340
|
+
head: headNumber
|
|
76341
|
+
});
|
|
76342
|
+
}
|
|
76343
|
+
if (assertEx$1(this._cursor).block >= headNumber) await this.markLive(head);
|
|
76344
|
+
}
|
|
76345
|
+
/** Announces a hot-surface gap and splices the shared cursor to `maxCatchUp` behind head. */
|
|
76346
|
+
async announceGap(cursor, headNumber) {
|
|
76347
|
+
const resumeNumber = asXL1BlockNumber$1(headNumber - this.options.maxCatchUp + 1, true);
|
|
76348
|
+
const resumeBlock = assertEx$1(await this._blockViewer.blockByNumber(resumeNumber), () => `FinalizedBlockStream: gap resume block ${resumeNumber} unavailable`);
|
|
76349
|
+
const skipped = [asXL1BlockNumber$1(cursor.block + 1, true), asXL1BlockNumber$1(resumeNumber - 1, true)];
|
|
76350
|
+
this._isLive = false;
|
|
76351
|
+
await this.emitSerial("gap", {
|
|
76352
|
+
before: cursor,
|
|
76353
|
+
resumedAt: cursorFromBlock$1(resumeBlock),
|
|
76354
|
+
skipped
|
|
76355
|
+
});
|
|
76356
|
+
this._cursor = {
|
|
76357
|
+
block: asXL1BlockNumber$1(resumeNumber - 1, true),
|
|
76358
|
+
hash: assertEx$1(resumeBlock[0].previous, () => "FinalizedBlockStream: gap resume block has no previous")
|
|
76359
|
+
};
|
|
76360
|
+
}
|
|
76361
|
+
/** Returns the last polled head, fetching once when no poll has landed yet. */
|
|
76362
|
+
async currentHead() {
|
|
76363
|
+
if (this._head) return this._head;
|
|
76364
|
+
this._head ??= await this._finalizationViewer.head();
|
|
76365
|
+
return this._head;
|
|
76366
|
+
}
|
|
76367
|
+
/** Initializes the hot cursor: verified splice from `after`, or head-first delivery. */
|
|
76368
|
+
async initHotCursor() {
|
|
76369
|
+
const { after } = this.options;
|
|
76370
|
+
if (isDefined$1(after)) {
|
|
76371
|
+
this._cursor = await this.resolveCheckpoint(after);
|
|
76372
|
+
return;
|
|
76373
|
+
}
|
|
76374
|
+
const head = await this.currentHead();
|
|
76375
|
+
this._cursor = cursorFromBlock$1(head);
|
|
76376
|
+
await this.emitSerial("nextBlock", {
|
|
76377
|
+
block: head,
|
|
76378
|
+
head: head[0].block
|
|
76379
|
+
});
|
|
76380
|
+
await this.markLive(head);
|
|
76381
|
+
}
|
|
76382
|
+
/** Marks the hot surface live, emitting the transition once. */
|
|
76383
|
+
async markLive(head) {
|
|
76384
|
+
if (this._isLive) return;
|
|
76385
|
+
this._isLive = true;
|
|
76386
|
+
await this.emitSerial("live", { head: cursorFromBlock$1(head) });
|
|
76387
|
+
}
|
|
76388
|
+
/**
|
|
76389
|
+
* Fetches the ordered run of blocks after `cursor`, up to one window. Order
|
|
76390
|
+
* is normalized here; continuity is verified per block by `advanceCursor`.
|
|
76391
|
+
*/
|
|
76392
|
+
async nextBlocks(cursor, headNumber) {
|
|
76393
|
+
const hi = asXL1BlockNumber$1(Math.min(cursor.block + this.options.fetchWindow, headNumber), true);
|
|
76394
|
+
const run = (await this._blockViewer.blocksByNumber(hi, hi - cursor.block)).filter((block) => block[0].block > cursor.block).toSorted((a, b) => a[0].block - b[0].block);
|
|
76395
|
+
assertEx$1(run.length > 0, () => `FinalizedBlockStream: no blocks fetched in (${cursor.block}, ${hi}]`);
|
|
76396
|
+
return run;
|
|
76397
|
+
}
|
|
76398
|
+
/** Polls the finalized head, releasing all cursor walks blocked on head growth. */
|
|
76399
|
+
async pollHead() {
|
|
76400
|
+
if (this._pollInProgress) return;
|
|
76401
|
+
this._pollInProgress = true;
|
|
76402
|
+
try {
|
|
76403
|
+
const head = await this._finalizationViewer.head();
|
|
76404
|
+
if (head[0]._hash !== this._head?.[0]._hash) {
|
|
76405
|
+
this._head = head;
|
|
76406
|
+
this.releaseHeadWaiters();
|
|
76407
|
+
}
|
|
76408
|
+
} catch (ex) {
|
|
76409
|
+
this.logger?.error("FinalizedBlockStream: error polling head", ex);
|
|
76410
|
+
} finally {
|
|
76411
|
+
this._pollInProgress = false;
|
|
76412
|
+
}
|
|
76413
|
+
}
|
|
76414
|
+
releaseHeadWaiters() {
|
|
76415
|
+
const waiters = this._headWaiters.splice(0);
|
|
76416
|
+
for (const release of waiters) release();
|
|
76417
|
+
}
|
|
76418
|
+
/** Resolves a checkpoint hash to a cursor, or throws the desync error a missing checkpoint implies. */
|
|
76419
|
+
async resolveCheckpoint(after) {
|
|
76420
|
+
const checkpoint = await this._blockViewer.blockByHash(after);
|
|
76421
|
+
if (!checkpoint) throw new FinalizedBlockStreamDesyncError$1(after);
|
|
76422
|
+
return cursorFromBlock$1(checkpoint);
|
|
76423
|
+
}
|
|
76424
|
+
/**
|
|
76425
|
+
* The hot delivery loop. Transient errors are logged and retried on the next
|
|
76426
|
+
* head advance; a continuity failure emits the terminal `desynced` event.
|
|
76427
|
+
*/
|
|
76428
|
+
async runHot() {
|
|
76429
|
+
try {
|
|
76430
|
+
await this.initHotCursor();
|
|
76431
|
+
while (!this._stopping) try {
|
|
76432
|
+
await this.advanceHot();
|
|
76433
|
+
} catch (ex) {
|
|
76434
|
+
if (ex instanceof FinalizedBlockStreamDesyncError$1) throw ex;
|
|
76435
|
+
if (this._stopping) return;
|
|
76436
|
+
this.logger?.error("FinalizedBlockStream: hot loop error, retrying on next head", ex);
|
|
76437
|
+
await this.waitForHeadAdvance();
|
|
76438
|
+
}
|
|
76439
|
+
} catch (ex) {
|
|
76440
|
+
if (ex instanceof FinalizedBlockStreamDesyncError$1 && !this._terminal) {
|
|
76441
|
+
this._terminal = true;
|
|
76442
|
+
await this.emitSerial("desynced", {
|
|
76443
|
+
block: ex.block,
|
|
76444
|
+
expectedPrevious: ex.expectedPrevious
|
|
76445
|
+
});
|
|
76446
|
+
return;
|
|
76447
|
+
}
|
|
76448
|
+
this.logger?.error("FinalizedBlockStream: hot loop terminated", ex);
|
|
76449
|
+
}
|
|
76450
|
+
}
|
|
76451
|
+
/** Suspends until the polled head changes or the stream stops. */
|
|
76452
|
+
waitForHeadAdvance() {
|
|
76453
|
+
if (this._stopping) return Promise.resolve();
|
|
76454
|
+
return new Promise((resolve) => {
|
|
76455
|
+
this._headWaiters.push(resolve);
|
|
76456
|
+
});
|
|
76457
|
+
}
|
|
76458
|
+
};
|
|
76459
|
+
/** Connection kinds supported by this provider. */
|
|
76460
|
+
__publicField$25(SimpleFinalizedBlockStream$1, "connectionTypes", ["none"]);
|
|
76461
|
+
/** Primary moniker used to resolve this provider. */
|
|
76462
|
+
__publicField$25(SimpleFinalizedBlockStream$1, "defaultMoniker", FinalizedBlockStreamMoniker$1);
|
|
76463
|
+
/** Provider monikers that must resolve before this provider can be created. */
|
|
76464
|
+
__publicField$25(SimpleFinalizedBlockStream$1, "dependencies", [BlockViewerMoniker$1, FinalizationViewerMoniker$1]);
|
|
76465
|
+
/** Provider monikers implemented by this provider class. */
|
|
76466
|
+
__publicField$25(SimpleFinalizedBlockStream$1, "monikers", [FinalizedBlockStreamMoniker$1]);
|
|
76467
|
+
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
76468
|
+
__publicField$25(SimpleFinalizedBlockStream$1, "surface", "node");
|
|
76469
|
+
SimpleFinalizedBlockStream$1 = __decorateClass$26([creatableProvider$1()], SimpleFinalizedBlockStream$1);
|
|
76105
76470
|
var SimpleXyoGatewayRunner = class _SimpleXyoGatewayRunner extends AbstractCreatableProvider$1 {
|
|
76106
76471
|
/** Connection kinds supported by this provider. */
|
|
76107
76472
|
static connectionTypes = ["none"];
|
|
@@ -76345,6 +76710,83 @@ var nextPruneCursor$1 = (batch, pruneHashes, cursor) => {
|
|
|
76345
76710
|
const pruneSet = new Set(pruneHashes);
|
|
76346
76711
|
return batch.findLast((bundle3) => !pruneSet.has(bundle3._hash))?._sequence ?? cursor;
|
|
76347
76712
|
};
|
|
76713
|
+
async function simpleBlockValidationCheck$1(payloads, context) {
|
|
76714
|
+
return (await Promise.all(payloads.map(async (payload) => {
|
|
76715
|
+
return [isPayloadBundle$1(payload) ? await bundledPayloadToHydratedBlock$1(payload) : void 0, payload];
|
|
76716
|
+
}))).map(([block, bundle3]) => evaluateBlockCandidate$1(block, bundle3, context));
|
|
76717
|
+
}
|
|
76718
|
+
async function simpleTransactionValidationCheck$1(payloads, context) {
|
|
76719
|
+
const transactionBundles = await Promise.all(payloads.map(async (payload) => {
|
|
76720
|
+
return [isPayloadBundle$1(payload) ? await bundledPayloadToHydratedTransaction$1(payload) : void 0, payload];
|
|
76721
|
+
}));
|
|
76722
|
+
return Promise.all(transactionBundles.map(async ([transaction, bundle3]) => {
|
|
76723
|
+
return evaluateTransactionCandidate$1(transaction, bundle3, context);
|
|
76724
|
+
}));
|
|
76725
|
+
}
|
|
76726
|
+
function evaluateBlockCandidate$1(block, bundle3, { chainId, headNumber, logger }) {
|
|
76727
|
+
const typeCheckPassed = isSignedHydratedBlockWithHashMeta$1(block);
|
|
76728
|
+
const chainIdPassed = typeCheckPassed && block[0].chain === chainId;
|
|
76729
|
+
const blockNumberPassed = typeCheckPassed && block[0].block > headNumber;
|
|
76730
|
+
const validationPassed = typeCheckPassed && chainIdPassed && blockNumberPassed;
|
|
76731
|
+
if (!validationPassed) logFailedBlockCheck$1({
|
|
76732
|
+
block,
|
|
76733
|
+
blockNumberPassed,
|
|
76734
|
+
bundle: bundle3,
|
|
76735
|
+
chainIdPassed,
|
|
76736
|
+
headNumber,
|
|
76737
|
+
logger,
|
|
76738
|
+
typeCheckPassed
|
|
76739
|
+
});
|
|
76740
|
+
return [validationPassed ? block : void 0, bundle3];
|
|
76741
|
+
}
|
|
76742
|
+
async function evaluateTransactionCandidate$1(transaction, bundle3, { chainId, headNumber, logger, maxExpAhead }) {
|
|
76743
|
+
const typeCheckPassed = isSignedHydratedTransactionWithHashMeta$1(transaction);
|
|
76744
|
+
const chainIdPassed = typeCheckPassed && transaction[0].chain === chainId;
|
|
76745
|
+
const expPassed = typeCheckPassed && transaction[0].exp > headNumber && transaction[0].exp <= headNumber + maxExpAhead;
|
|
76746
|
+
const opcodeCheckPassed = await checkTransactionOpcodes$1(transaction, bundle3, logger);
|
|
76747
|
+
const validationPassed = typeCheckPassed && chainIdPassed && expPassed && opcodeCheckPassed;
|
|
76748
|
+
if (!validationPassed) logFailedTransactionCheck$1({
|
|
76749
|
+
bundle: bundle3,
|
|
76750
|
+
chainIdPassed,
|
|
76751
|
+
expPassed,
|
|
76752
|
+
headNumber,
|
|
76753
|
+
logger,
|
|
76754
|
+
opcodeCheckPassed,
|
|
76755
|
+
transaction,
|
|
76756
|
+
typeCheckPassed
|
|
76757
|
+
});
|
|
76758
|
+
return [validationPassed ? transaction : void 0, bundle3];
|
|
76759
|
+
}
|
|
76760
|
+
async function checkTransactionOpcodes$1(transaction, bundle3, logger) {
|
|
76761
|
+
try {
|
|
76762
|
+
await validateTransactionsOpcodes$1(transaction === void 0 ? [] : [transaction]);
|
|
76763
|
+
return true;
|
|
76764
|
+
} catch (error) {
|
|
76765
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
76766
|
+
logger?.debug(`Opcode validation failed for transaction ${bundle3._hash} during simpleValidationCheck`);
|
|
76767
|
+
logger?.debug(` - error: ${message}`);
|
|
76768
|
+
return false;
|
|
76769
|
+
}
|
|
76770
|
+
}
|
|
76771
|
+
function logFailedBlockCheck$1({ block, blockNumberPassed, bundle: bundle3, chainIdPassed, headNumber, logger, typeCheckPassed }) {
|
|
76772
|
+
if (chainIdPassed && typeCheckPassed && !blockNumberPassed) {
|
|
76773
|
+
logger?.debug(`Pruning stale block candidate bundle ${bundle3._hash} during simpleValidationCheck (candidate height ${block?.[0].block} <= finalized head ${headNumber} \u2014 routine GC of a finalized or superseded candidate)`);
|
|
76774
|
+
return;
|
|
76775
|
+
}
|
|
76776
|
+
logger?.debug(`Pruning block bundle ${bundle3._hash} during simpleValidationCheck`);
|
|
76777
|
+
logger?.debug(` - chainId match: ${chainIdPassed}`);
|
|
76778
|
+
logger?.debug(` - blockNumber check: ${blockNumberPassed} [head=${headNumber} candidate=${block?.[0].block}]`);
|
|
76779
|
+
logger?.debug(` - typeCheck: ${typeCheckPassed}`);
|
|
76780
|
+
logger?.debug(` - bundle hash: ${bundle3._hash}`);
|
|
76781
|
+
}
|
|
76782
|
+
function logFailedTransactionCheck$1({ bundle: bundle3, chainIdPassed, expPassed, headNumber, logger, opcodeCheckPassed, transaction, typeCheckPassed }) {
|
|
76783
|
+
logger?.debug(`Pruning transaction bundle ${bundle3._hash} during simpleValidationCheck`);
|
|
76784
|
+
logger?.debug(` - chainId match: ${chainIdPassed}`);
|
|
76785
|
+
logger?.debug(` - exp check: ${expPassed} [head=${headNumber} exp=${transaction?.[0].exp}]`);
|
|
76786
|
+
logger?.debug(` - opcode check: ${opcodeCheckPassed}`);
|
|
76787
|
+
logger?.debug(` - typeCheck: ${typeCheckPassed}`);
|
|
76788
|
+
logger?.debug(` - bundle hash: ${bundle3._hash}`);
|
|
76789
|
+
}
|
|
76348
76790
|
var DEFAULT_SYNC_INTERVAL$1 = 3e4;
|
|
76349
76791
|
var DEFAULT_SYNC_LIMIT$1 = 100;
|
|
76350
76792
|
var ENFORCE_CAP_BATCH_SIZE$1 = 1e3;
|
|
@@ -76477,7 +76919,11 @@ var SimpleMempoolRunner$1 = class extends AbstractCreatableProvider$1 {
|
|
|
76477
76919
|
}
|
|
76478
76920
|
while (batch.length > 0 && pruned < maxPrune && total < maxCheck) {
|
|
76479
76921
|
batches += 1;
|
|
76480
|
-
const blocksAndBundles = await
|
|
76922
|
+
const blocksAndBundles = await simpleBlockValidationCheck$1(batch, {
|
|
76923
|
+
chainId: await this.chainContractViewer.chainId(),
|
|
76924
|
+
headNumber: await this.finalizationViewer.headNumber(),
|
|
76925
|
+
logger: this.logger
|
|
76926
|
+
});
|
|
76481
76927
|
const blocks = blocksAndBundles.map(([b]) => b);
|
|
76482
76928
|
const bundles = blocksAndBundles.map(([_, p]) => p);
|
|
76483
76929
|
const valid = blocks.map((b) => !!b);
|
|
@@ -76491,9 +76937,10 @@ var SimpleMempoolRunner$1 = class extends AbstractCreatableProvider$1 {
|
|
|
76491
76937
|
state: true
|
|
76492
76938
|
}))),
|
|
76493
76939
|
isValidated: isSignedHydratedBlockWithHashMeta$1,
|
|
76494
|
-
onInvalid: ({ bundle: bundle3, result }) => {
|
|
76495
|
-
const errors = result;
|
|
76940
|
+
onInvalid: async ({ bundle: bundle3, item, result }) => {
|
|
76941
|
+
const errors = isSignedHydratedBlockWithHashMeta$1(result) ? [] : result;
|
|
76496
76942
|
this.logger?.info(`[SimpleMempoolRunner] prunePendingBlocks deleting block ${bundle3._hash} (validation: ${errors.at(0)?.message ?? "failed simple/full check"})`);
|
|
76943
|
+
await this.routeRejectedBlock(item, errors);
|
|
76497
76944
|
}
|
|
76498
76945
|
});
|
|
76499
76946
|
const pruneHashes = invalidBundleHashes$1(bundles, valid);
|
|
@@ -76529,7 +76976,12 @@ var SimpleMempoolRunner$1 = class extends AbstractCreatableProvider$1 {
|
|
|
76529
76976
|
}
|
|
76530
76977
|
while (batch.length > 0 && pruned < maxPrune && total < maxCheck) {
|
|
76531
76978
|
batches += 1;
|
|
76532
|
-
const transactionsAndBundles = await
|
|
76979
|
+
const transactionsAndBundles = await simpleTransactionValidationCheck$1(batch, {
|
|
76980
|
+
chainId: await this.chainContractViewer.chainId(),
|
|
76981
|
+
headNumber: await this.finalizationViewer.headNumber(),
|
|
76982
|
+
logger: this.logger,
|
|
76983
|
+
maxExpAhead: this.maxExpAhead
|
|
76984
|
+
});
|
|
76533
76985
|
const transactions = transactionsAndBundles.map(([t]) => t);
|
|
76534
76986
|
const bundles = transactionsAndBundles.map(([_, p]) => p);
|
|
76535
76987
|
const valid = transactions.map((t) => !!t);
|
|
@@ -76689,6 +77141,20 @@ var SimpleMempoolRunner$1 = class extends AbstractCreatableProvider$1 {
|
|
|
76689
77141
|
if (isDemotionAware$1(this._mempoolViewer)) return this._mempoolViewer.getEvictionPriorityOrder(bundleHashesOldestFirst);
|
|
76690
77142
|
return bundleHashesOldestFirst;
|
|
76691
77143
|
}
|
|
77144
|
+
async routeRejectedBlock(block, errors) {
|
|
77145
|
+
if (!this._deadLetterQueueRunner) return;
|
|
77146
|
+
const rejectionErrors = errors.map((e) => ({
|
|
77147
|
+
hash: e.hash ?? block[0]._hash,
|
|
77148
|
+
name: e.name ?? "BlockValidationError",
|
|
77149
|
+
message: String(e.message ?? e)
|
|
77150
|
+
}));
|
|
77151
|
+
await this._deadLetterQueueRunner.rejectBlock({
|
|
77152
|
+
schema: BlockRejectionSchema$1,
|
|
77153
|
+
block,
|
|
77154
|
+
errors: rejectionErrors,
|
|
77155
|
+
rejector: "mempool"
|
|
77156
|
+
});
|
|
77157
|
+
}
|
|
76692
77158
|
async routeRejectedTransaction(transaction, errors) {
|
|
76693
77159
|
if (!this._deadLetterQueueRunner) return;
|
|
76694
77160
|
const rejectionErrors = errors.map((e) => ({
|
|
@@ -76703,60 +77169,6 @@ var SimpleMempoolRunner$1 = class extends AbstractCreatableProvider$1 {
|
|
|
76703
77169
|
rejector: "mempool"
|
|
76704
77170
|
});
|
|
76705
77171
|
}
|
|
76706
|
-
async simpleBlockValidationCheck(payloads) {
|
|
76707
|
-
const headNumber = await this.finalizationViewer.headNumber();
|
|
76708
|
-
const chainId = await this.chainContractViewer.chainId();
|
|
76709
|
-
return (await Promise.all(payloads.map(async (p) => {
|
|
76710
|
-
return [isPayloadBundle$1(p) ? await bundledPayloadToHydratedBlock$1(p) : void 0, p];
|
|
76711
|
-
}))).map(([block, bundle3]) => {
|
|
76712
|
-
const blockCheckPassed = !!block;
|
|
76713
|
-
const chainIdPassed = blockCheckPassed ? block[0].chain === chainId : false;
|
|
76714
|
-
const blockNumberPassed = blockCheckPassed ? block[0].block > headNumber : false;
|
|
76715
|
-
const typeCheckPassed = blockCheckPassed ? isSignedHydratedBlockWithHashMeta$1(block) : false;
|
|
76716
|
-
const validationPassed = blockCheckPassed && chainIdPassed && blockNumberPassed && typeCheckPassed;
|
|
76717
|
-
const validatedBlock = validationPassed ? block : void 0;
|
|
76718
|
-
if (!validationPassed) {
|
|
76719
|
-
this.logger?.debug(`Pruning block bundle ${bundle3._hash} during simpleValidationCheck`);
|
|
76720
|
-
this.logger?.debug(` - chainId match: ${chainIdPassed}`);
|
|
76721
|
-
this.logger?.debug(` - blockNumber check: ${blockNumberPassed} [${headNumber}|${block?.[0].block}]`);
|
|
76722
|
-
this.logger?.debug(` - typeCheck: ${typeCheckPassed}`);
|
|
76723
|
-
this.logger?.debug(` - bundle hash: ${bundle3._hash}`);
|
|
76724
|
-
}
|
|
76725
|
-
return [validatedBlock, bundle3];
|
|
76726
|
-
});
|
|
76727
|
-
}
|
|
76728
|
-
async simpleTransactionValidationCheck(payloads) {
|
|
76729
|
-
const headNumber = await this.finalizationViewer.headNumber();
|
|
76730
|
-
const chainId = await this.chainContractViewer.chainId();
|
|
76731
|
-
const transactionBundles = await Promise.all(payloads.map(async (p) => {
|
|
76732
|
-
return [isPayloadBundle$1(p) ? await bundledPayloadToHydratedTransaction$1(p) : void 0, p];
|
|
76733
|
-
}));
|
|
76734
|
-
return await Promise.all(transactionBundles.map(async ([transaction, bundle3]) => {
|
|
76735
|
-
const transactionCheckPassed = !!transaction;
|
|
76736
|
-
const chainIdPassed = transactionCheckPassed ? transaction[0].chain === chainId : false;
|
|
76737
|
-
const expPassed = transactionCheckPassed ? transaction[0].exp > headNumber && transaction[0].exp <= headNumber + this.maxExpAhead : false;
|
|
76738
|
-
const typeCheckPassed = transactionCheckPassed ? isSignedHydratedTransactionWithHashMeta$1(transaction) : false;
|
|
76739
|
-
let opcodeCheckPassed = false;
|
|
76740
|
-
try {
|
|
76741
|
-
await validateTransactionsOpcodes$1(transaction ? [transaction] : []);
|
|
76742
|
-
opcodeCheckPassed = true;
|
|
76743
|
-
} catch (e) {
|
|
76744
|
-
this.logger?.debug(`Opcode validation failed for transaction ${bundle3._hash} during simpleValidationCheck`);
|
|
76745
|
-
this.logger?.debug(` - error: ${e.message}`);
|
|
76746
|
-
}
|
|
76747
|
-
const validationPassed = transactionCheckPassed && chainIdPassed && expPassed && typeCheckPassed && opcodeCheckPassed;
|
|
76748
|
-
const validatedTransaction = validationPassed ? transaction : void 0;
|
|
76749
|
-
if (!validationPassed) {
|
|
76750
|
-
this.logger?.debug(`Pruning block bundle ${bundle3._hash} during simpleValidationCheck`);
|
|
76751
|
-
this.logger?.debug(` - chainId match: ${chainIdPassed}`);
|
|
76752
|
-
this.logger?.debug(` - exp check: ${expPassed}`);
|
|
76753
|
-
this.logger?.debug(` - opcode check: ${opcodeCheckPassed}`);
|
|
76754
|
-
this.logger?.debug(` - typeCheck: ${typeCheckPassed}`);
|
|
76755
|
-
this.logger?.debug(` - bundle hash: ${bundle3._hash}`);
|
|
76756
|
-
}
|
|
76757
|
-
return [validatedTransaction, bundle3];
|
|
76758
|
-
}));
|
|
76759
|
-
}
|
|
76760
77172
|
async syncBlocksFrom(external) {
|
|
76761
77173
|
const externalBlocks = await external.pendingBlocks({ limit: this.syncLimit });
|
|
76762
77174
|
if (externalBlocks.length === 0) return;
|
|
@@ -76803,6 +77215,11 @@ __publicField$25(SimpleMempoolRunner$1, "monikers", [MempoolRunnerMoniker$1]);
|
|
|
76803
77215
|
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
76804
77216
|
__publicField$25(SimpleMempoolRunner$1, "surface", "node");
|
|
76805
77217
|
SimpleMempoolRunner$1 = __decorateClass$26([creatableProvider$1()], SimpleMempoolRunner$1);
|
|
77218
|
+
async function resolveHashCursor$1(archivist, providedCursor) {
|
|
77219
|
+
if (!isHash(providedCursor)) return void 0;
|
|
77220
|
+
const [payload] = await archivist.get([providedCursor]);
|
|
77221
|
+
return isDefined$1(payload) ? payload._sequence : void 0;
|
|
77222
|
+
}
|
|
76806
77223
|
var SimpleMempoolViewerOptionsZod$1 = object$3({
|
|
76807
77224
|
demotionThreshold: number$1().default(3),
|
|
76808
77225
|
handoutStatsTtlBlocks: number$1().default(1e3),
|
|
@@ -76870,11 +77287,7 @@ var SimpleMempoolViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
|
76870
77287
|
}
|
|
76871
77288
|
/** Returns the pending blocks result exposed by this provider. */
|
|
76872
77289
|
async pendingBlocks({ cursor: providedCursor } = {}) {
|
|
76873
|
-
|
|
76874
|
-
if (isHash(providedCursor)) {
|
|
76875
|
-
const [p] = await this.pendingBlocksArchivist.get([providedCursor]);
|
|
76876
|
-
if (isDefined$1(p)) cursor = p._sequence;
|
|
76877
|
-
}
|
|
77290
|
+
const cursor = await resolveHashCursor$1(this.pendingBlocksArchivist, providedCursor);
|
|
76878
77291
|
const filteredBundles = (await this.pendingBlocksArchivist.next({
|
|
76879
77292
|
order: "desc",
|
|
76880
77293
|
limit: 100,
|
|
@@ -76884,11 +77297,8 @@ var SimpleMempoolViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
|
76884
77297
|
}
|
|
76885
77298
|
/** Returns the pending transactions result exposed by this provider. */
|
|
76886
77299
|
async pendingTransactions({ cursor: providedCursor, limit = 100 } = {}) {
|
|
76887
|
-
|
|
76888
|
-
|
|
76889
|
-
const [p] = await this.pendingTransactionsArchivist.get([providedCursor]);
|
|
76890
|
-
if (isDefined$1(p)) cursor = p._sequence;
|
|
76891
|
-
}
|
|
77300
|
+
await this.windowedBlockViewer.sync?.();
|
|
77301
|
+
const cursor = await resolveHashCursor$1(this.pendingTransactionsArchivist, providedCursor);
|
|
76892
77302
|
this.logger?.debug(`Fetching pending transactions from cursor: ${cursor}`);
|
|
76893
77303
|
const bundles = await this.pendingTransactionsArchivist.next({
|
|
76894
77304
|
order: "asc",
|
|
@@ -78055,7 +78465,9 @@ var SimpleWindowedBlockViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
|
78055
78465
|
_blockNumberMap;
|
|
78056
78466
|
_blockViewer;
|
|
78057
78467
|
_chain = [];
|
|
78468
|
+
_inFlightSync = null;
|
|
78058
78469
|
_options;
|
|
78470
|
+
_queuedSync = null;
|
|
78059
78471
|
_syncMutex = new Mutex();
|
|
78060
78472
|
_timerId = null;
|
|
78061
78473
|
_transactionHashMap;
|
|
@@ -78163,6 +78575,32 @@ var SimpleWindowedBlockViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
|
78163
78575
|
await super.stopHandler();
|
|
78164
78576
|
this.stopPoll();
|
|
78165
78577
|
}
|
|
78578
|
+
/**
|
|
78579
|
+
* Synchronizes the in-memory window with the backing block viewer immediately, waiting for any
|
|
78580
|
+
* in-flight sync to complete first. Callers whose correctness depends on seeing the latest
|
|
78581
|
+
* finalized blocks (e.g. mempool inclusion checks) must call this rather than rely on the
|
|
78582
|
+
* background poll, whose interval is far coarser than block finalization.
|
|
78583
|
+
*
|
|
78584
|
+
* Concurrent callers are coalesced: a caller arriving while a sync runs joins one shared
|
|
78585
|
+
* follow-up pass (which starts after the running pass and therefore observes every block
|
|
78586
|
+
* finalized before the caller arrived) instead of enqueuing its own. Without this, N
|
|
78587
|
+
* concurrent callers — the handout path is reachable per producer tick and over RPC — would
|
|
78588
|
+
* execute N sequential backing reads behind the sync mutex.
|
|
78589
|
+
*/
|
|
78590
|
+
async sync() {
|
|
78591
|
+
if (this._inFlightSync === null) {
|
|
78592
|
+
const run = this.runSync().finally(() => {
|
|
78593
|
+
if (this._inFlightSync === run) this._inFlightSync = null;
|
|
78594
|
+
});
|
|
78595
|
+
this._inFlightSync = run;
|
|
78596
|
+
return await run;
|
|
78597
|
+
}
|
|
78598
|
+
this._queuedSync ??= this._inFlightSync.then(() => {
|
|
78599
|
+
this._queuedSync = null;
|
|
78600
|
+
return this.sync();
|
|
78601
|
+
});
|
|
78602
|
+
return await this._queuedSync;
|
|
78603
|
+
}
|
|
78166
78604
|
addBlock(block) {
|
|
78167
78605
|
this._chain.push(block);
|
|
78168
78606
|
this._blockHashMap.set(block[0]._hash, block);
|
|
@@ -78176,18 +78614,8 @@ var SimpleWindowedBlockViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
|
78176
78614
|
for (const tx of transactionsFromHydratedBlock$1(removedBlock)) this._transactionHashMap.delete(tx._hash);
|
|
78177
78615
|
}
|
|
78178
78616
|
}
|
|
78179
|
-
|
|
78180
|
-
this.
|
|
78181
|
-
this.sync();
|
|
78182
|
-
}, this.syncInterval);
|
|
78183
|
-
}
|
|
78184
|
-
stopPoll() {
|
|
78185
|
-
if (this._timerId) clearInterval(this._timerId);
|
|
78186
|
-
this._timerId = null;
|
|
78187
|
-
}
|
|
78188
|
-
async sync() {
|
|
78189
|
-
if (this._syncMutex.isLocked()) return;
|
|
78190
|
-
return await this._syncMutex.runExclusive(async () => {
|
|
78617
|
+
async runSync() {
|
|
78618
|
+
await this._syncMutex.runExclusive(async () => {
|
|
78191
78619
|
try {
|
|
78192
78620
|
let cursor = await this._blockViewer.currentBlock();
|
|
78193
78621
|
const previousHead = this._chain.length > 0 ? await this.currentBlockHash() : null;
|
|
@@ -78203,6 +78631,19 @@ var SimpleWindowedBlockViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
|
78203
78631
|
}
|
|
78204
78632
|
});
|
|
78205
78633
|
}
|
|
78634
|
+
startPoll() {
|
|
78635
|
+
this._timerId = setInterval(() => {
|
|
78636
|
+
this.syncIfIdle();
|
|
78637
|
+
}, this.syncInterval);
|
|
78638
|
+
}
|
|
78639
|
+
stopPoll() {
|
|
78640
|
+
if (this._timerId) clearInterval(this._timerId);
|
|
78641
|
+
this._timerId = null;
|
|
78642
|
+
}
|
|
78643
|
+
async syncIfIdle() {
|
|
78644
|
+
if (this._syncMutex.isLocked()) return;
|
|
78645
|
+
await this.sync();
|
|
78646
|
+
}
|
|
78206
78647
|
};
|
|
78207
78648
|
/** Connection kinds supported by this provider. */
|
|
78208
78649
|
__publicField$25(SimpleWindowedBlockViewer$1, "connectionTypes", [
|
|
@@ -81798,7 +82239,7 @@ function getOriginalId$1(rawRequest) {
|
|
|
81798
82239
|
return [void 0, false];
|
|
81799
82240
|
}
|
|
81800
82241
|
//#endregion
|
|
81801
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
82242
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_3a01f3229f2daa942444e08696345b23/node_modules/@xyo-network/xl1-sdk/dist/neutral/rpc.mjs
|
|
81802
82243
|
var __defProp$26 = Object.defineProperty;
|
|
81803
82244
|
var __getOwnPropDesc$25 = Object.getOwnPropertyDescriptor;
|
|
81804
82245
|
var __defNormalProp$24 = (obj, key, value) => key in obj ? __defProp$26(obj, key, {
|
|
@@ -84340,7 +84781,7 @@ var createRpcDispatchMiddleware = (schemas, handlers, options) => async ({ reque
|
|
|
84340
84781
|
}
|
|
84341
84782
|
};
|
|
84342
84783
|
//#endregion
|
|
84343
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
84784
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_3a01f3229f2daa942444e08696345b23/node_modules/@xyo-network/xl1-sdk/dist/neutral/rest-block-viewer.mjs
|
|
84344
84785
|
var __defProp$25 = Object.defineProperty;
|
|
84345
84786
|
var __getOwnPropDesc$24 = Object.getOwnPropertyDescriptor;
|
|
84346
84787
|
var __defNormalProp$23 = (obj, key, value) => key in obj ? __defProp$25(obj, key, {
|
|
@@ -105003,7 +105444,7 @@ var StakedXyoChainV2__factory = class extends ContractFactory {
|
|
|
105003
105444
|
}
|
|
105004
105445
|
};
|
|
105005
105446
|
//#endregion
|
|
105006
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
105447
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_3a01f3229f2daa942444e08696345b23/node_modules/@xyo-network/xl1-sdk/dist/neutral/providers.mjs
|
|
105007
105448
|
var __defProp$23 = Object.defineProperty;
|
|
105008
105449
|
var __getOwnPropDesc$23 = Object.getOwnPropertyDescriptor;
|
|
105009
105450
|
var __defNormalProp$22 = (obj, key, value) => key in obj ? __defProp$23(obj, key, {
|
|
@@ -105957,6 +106398,179 @@ __publicField$22(EvmStakeViewer$1, "monikers", [StakeViewerMoniker$1]);
|
|
|
105957
106398
|
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
105958
106399
|
__publicField$22(EvmStakeViewer$1, "surface", "node");
|
|
105959
106400
|
EvmStakeViewer$1 = __decorateClass$23([creatableProvider$1()], EvmStakeViewer$1);
|
|
106401
|
+
var DEFAULT_HEAD_POLL_INTERVAL_MS$2 = 5e3;
|
|
106402
|
+
var RestNetworkStakeStepRewardsByPositionViewerOptionsZod$1 = object$3({
|
|
106403
|
+
headPollIntervalMs: number$1().min(5e3).default(DEFAULT_HEAD_POLL_INTERVAL_MS$2),
|
|
106404
|
+
policyId: NetworkStakeRewardsPolicyIdZod.default(NETWORK_STAKE_REWARDS_UNMULTIPLIED_POLICY)
|
|
106405
|
+
});
|
|
106406
|
+
var RestNetworkStakeStepRewardsByPositionViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
106407
|
+
moniker = RestNetworkStakeStepRewardsByPositionViewer$1.defaultMoniker;
|
|
106408
|
+
currentHead;
|
|
106409
|
+
headPollIntervalMs = DEFAULT_HEAD_POLL_INTERVAL_MS$2;
|
|
106410
|
+
headPromise;
|
|
106411
|
+
lastSuccessfulHeadAt;
|
|
106412
|
+
manifestPromise;
|
|
106413
|
+
policyId = NETWORK_STAKE_REWARDS_UNMULTIPLIED_POLICY;
|
|
106414
|
+
snapshotPromises = /* @__PURE__ */ new Map();
|
|
106415
|
+
stepPromises = /* @__PURE__ */ new Map();
|
|
106416
|
+
get baseUrl() {
|
|
106417
|
+
const connection = RestNetworkStakeStepRewardsByPositionViewer$1.requireBoundConnection(this.config);
|
|
106418
|
+
const config = connection.config;
|
|
106419
|
+
if (config.type !== "rest") throw new Error(`Connection "${connection.name}" must be a rest connection`);
|
|
106420
|
+
return assertEx$1(config.baseUrl, () => `Connection "${connection.name}" requires a rest baseUrl`);
|
|
106421
|
+
}
|
|
106422
|
+
get fetchFn() {
|
|
106423
|
+
return this.context.fetchFn ?? fetch.bind(globalThis);
|
|
106424
|
+
}
|
|
106425
|
+
/** Returns the policy bonus. The unmultiplied-v1 index has no multipliers, so bonus is zero. */
|
|
106426
|
+
async bonus(options = {}) {
|
|
106427
|
+
const total = await this.total(options);
|
|
106428
|
+
return Object.fromEntries(Object.keys(total).map((key) => [Number(key), asAttoXL1$1(0n)]));
|
|
106429
|
+
}
|
|
106430
|
+
/** Claimed rewards are not part of the earned-reward index. */
|
|
106431
|
+
claimed(_options) {
|
|
106432
|
+
throw new Error("Method [claimed] not implemented.");
|
|
106433
|
+
}
|
|
106434
|
+
/** Creates the provider instance after validating its REST binding and options. */
|
|
106435
|
+
async createHandler() {
|
|
106436
|
+
await super.createHandler();
|
|
106437
|
+
RestNetworkStakeStepRewardsByPositionViewer$1.requireBoundConnection(this.config);
|
|
106438
|
+
const options = RestNetworkStakeStepRewardsByPositionViewerOptionsZod$1.parse(this.config.options);
|
|
106439
|
+
this.headPollIntervalMs = options.headPollIntervalMs;
|
|
106440
|
+
this.policyId = options.policyId;
|
|
106441
|
+
}
|
|
106442
|
+
/** Base-v1 total and earned rewards are identical. */
|
|
106443
|
+
async earned(options = {}) {
|
|
106444
|
+
return await this.total(options);
|
|
106445
|
+
}
|
|
106446
|
+
/** Returns rewards by requested position from the durable index. */
|
|
106447
|
+
async total({ range, positions } = {}) {
|
|
106448
|
+
if (!isArray(positions)) return {};
|
|
106449
|
+
const head = await this.getHead();
|
|
106450
|
+
const resolvedRange = asXL1BlockRange$1(range ?? [0, head.processedThroughBlock], { name: "RestNetworkStakeStepRewardsByPositionViewer" });
|
|
106451
|
+
const result = {};
|
|
106452
|
+
for (const position of positions) result[position] = (await this.totalForPosition(position, resolvedRange))[0];
|
|
106453
|
+
return result;
|
|
106454
|
+
}
|
|
106455
|
+
/** Returns one position's cumulative reward and the range's emitted reward pool. */
|
|
106456
|
+
async totalForPosition(position, range) {
|
|
106457
|
+
const head = await this.getHead();
|
|
106458
|
+
this.assertPublishedRange(range, head);
|
|
106459
|
+
if (head.positionCount === 0) return [asAttoXL1$1(0n), asAttoXL1$1(0n)];
|
|
106460
|
+
this.assertPosition(position, head);
|
|
106461
|
+
if (range[0] === 0 && range[1] >= head.processedThroughBlock) {
|
|
106462
|
+
const snapshot = await this.getSnapshot(head);
|
|
106463
|
+
return [asAttoXL1$1(BigInt(snapshot.positionRewards[String(position)] ?? "0")), asAttoXL1$1(BigInt(snapshot.totalReward))];
|
|
106464
|
+
}
|
|
106465
|
+
const steps = await this.stepsForRange(range, head);
|
|
106466
|
+
return [asAttoXL1$1(steps.reduce((sum, step) => sum + BigInt(step.positionRewards[String(position)] ?? "0"), 0n)), asAttoXL1$1(steps.reduce((sum, step) => sum + BigInt(step.totalReward), 0n))];
|
|
106467
|
+
}
|
|
106468
|
+
/** Returns the emitted reward pool for one indexed step. */
|
|
106469
|
+
async totalForStep(step) {
|
|
106470
|
+
const head = await this.getHead();
|
|
106471
|
+
this.assertPublishedStep(step, head);
|
|
106472
|
+
return asAttoXL1$1(BigInt((await this.getStep(step)).totalReward));
|
|
106473
|
+
}
|
|
106474
|
+
/** Returns one position's allocation and emitted pool for one indexed step. */
|
|
106475
|
+
async totalForStepForPosition(step, position) {
|
|
106476
|
+
const head = await this.getHead();
|
|
106477
|
+
this.assertPosition(position, head);
|
|
106478
|
+
this.assertPublishedStep(step, head);
|
|
106479
|
+
const record = await this.getStep(step);
|
|
106480
|
+
return [asAttoXL1$1(BigInt(record.positionRewards[String(position)] ?? "0")), asAttoXL1$1(BigInt(record.totalReward))];
|
|
106481
|
+
}
|
|
106482
|
+
/** Unclaimed rewards require redemption state and are not part of this index. */
|
|
106483
|
+
unclaimed(_options) {
|
|
106484
|
+
throw new Error("Method [unclaimed] not implemented.");
|
|
106485
|
+
}
|
|
106486
|
+
assertPosition(position, head) {
|
|
106487
|
+
assertEx$1(Number.isSafeInteger(position) && position >= 0 && position < head.positionCount, () => `Position ${position} is outside rewards index positionCount ${head.positionCount}`);
|
|
106488
|
+
}
|
|
106489
|
+
assertPublishedRange(range, head) {
|
|
106490
|
+
assertEx$1(range[1] <= head.processedThroughBlock, () => `Reward range ends at ${range[1]}, beyond index watermark ${head.processedThroughBlock}`);
|
|
106491
|
+
}
|
|
106492
|
+
assertPublishedStep(step, head) {
|
|
106493
|
+
assertEx$1(step.block <= head.processedThroughBlock, () => `Reward step ${step.block}|${step.step} is beyond index watermark ${head.processedThroughBlock}`);
|
|
106494
|
+
}
|
|
106495
|
+
async fetchJson(path) {
|
|
106496
|
+
const response = await this.fetchFn(`${this.baseUrl.replace(/\/$/, "")}/${path}`);
|
|
106497
|
+
if (!response.ok) throw new Error(`Network stake rewards index request failed [${response.status}] for ${path}`);
|
|
106498
|
+
return await response.json();
|
|
106499
|
+
}
|
|
106500
|
+
async getHead() {
|
|
106501
|
+
const now = Date.now();
|
|
106502
|
+
const elapsed = this.lastSuccessfulHeadAt === void 0 ? void 0 : now - this.lastSuccessfulHeadAt;
|
|
106503
|
+
if (this.currentHead !== void 0 && elapsed !== void 0 && elapsed >= 0 && elapsed < this.headPollIntervalMs) return this.currentHead;
|
|
106504
|
+
this.headPromise ??= this.syncHead().finally(() => {
|
|
106505
|
+
this.headPromise = void 0;
|
|
106506
|
+
});
|
|
106507
|
+
return await this.headPromise;
|
|
106508
|
+
}
|
|
106509
|
+
async getManifest() {
|
|
106510
|
+
this.manifestPromise ??= this.fetchJson(networkStakeRewardsIndexManifestPath(this.policyId)).then((value) => asNetworkStakeRewardsIndexManifest(value, true)).catch((error) => {
|
|
106511
|
+
this.manifestPromise = void 0;
|
|
106512
|
+
throw error;
|
|
106513
|
+
});
|
|
106514
|
+
return await this.manifestPromise;
|
|
106515
|
+
}
|
|
106516
|
+
async getSnapshot(head) {
|
|
106517
|
+
const { snapshotHash } = head;
|
|
106518
|
+
let promise = this.snapshotPromises.get(snapshotHash);
|
|
106519
|
+
if (promise === void 0) {
|
|
106520
|
+
const path = networkStakeRewardsIndexSnapshotPath(this.policyId, snapshotHash);
|
|
106521
|
+
promise = this.fetchJson(path).then(async (value) => {
|
|
106522
|
+
const snapshot = asNetworkStakeRewardsIndexSnapshot(value, true);
|
|
106523
|
+
assertEx$1(await PayloadBuilder$1.hash(snapshot) === snapshotHash, () => `Rewards snapshot hash mismatch: ${path}`);
|
|
106524
|
+
return snapshot;
|
|
106525
|
+
});
|
|
106526
|
+
this.snapshotPromises.set(snapshotHash, promise);
|
|
106527
|
+
}
|
|
106528
|
+
try {
|
|
106529
|
+
const snapshot = await promise;
|
|
106530
|
+
assertEx$1(snapshot.policyId === this.policyId, () => "Rewards snapshot policy mismatch");
|
|
106531
|
+
assertEx$1(snapshot.stepCount === head.stepCount, () => "Rewards snapshot step count mismatch");
|
|
106532
|
+
return snapshot;
|
|
106533
|
+
} catch (error) {
|
|
106534
|
+
this.snapshotPromises.delete(snapshotHash);
|
|
106535
|
+
throw error;
|
|
106536
|
+
}
|
|
106537
|
+
}
|
|
106538
|
+
async getStep(step) {
|
|
106539
|
+
const path = networkStakeRewardsIndexStepPath(this.policyId, step);
|
|
106540
|
+
let promise = this.stepPromises.get(path);
|
|
106541
|
+
if (promise === void 0) {
|
|
106542
|
+
promise = this.fetchJson(path).then((value) => asNetworkStakeRewardsIndexStep(value, true));
|
|
106543
|
+
this.stepPromises.set(path, promise);
|
|
106544
|
+
}
|
|
106545
|
+
try {
|
|
106546
|
+
const record = await promise;
|
|
106547
|
+
assertEx$1(record.policyId === this.policyId, () => "Rewards step policy mismatch");
|
|
106548
|
+
assertEx$1(record.step.block === step.block && record.step.step === step.step, () => "Rewards step identity mismatch");
|
|
106549
|
+
return record;
|
|
106550
|
+
} catch (error) {
|
|
106551
|
+
this.stepPromises.delete(path);
|
|
106552
|
+
throw error;
|
|
106553
|
+
}
|
|
106554
|
+
}
|
|
106555
|
+
async stepsForRange(range, head) {
|
|
106556
|
+
const steps = blockRangeSteps(range, (await this.getManifest()).stepLevels).filter((step) => step.block <= head.processedThroughBlock);
|
|
106557
|
+
return await Promise.all(steps.map(async (step) => await this.getStep(step)));
|
|
106558
|
+
}
|
|
106559
|
+
async syncHead() {
|
|
106560
|
+
assertEx$1((await this.getManifest()).policyId === this.policyId, () => "Rewards manifest policy mismatch");
|
|
106561
|
+
const head = asNetworkStakeRewardsIndexHead(await this.fetchJson(networkStakeRewardsIndexHeadPath(this.policyId)), true);
|
|
106562
|
+
assertEx$1(head.policyId === this.policyId, () => "Rewards head policy mismatch");
|
|
106563
|
+
this.currentHead = head;
|
|
106564
|
+
this.lastSuccessfulHeadAt = Date.now();
|
|
106565
|
+
return head;
|
|
106566
|
+
}
|
|
106567
|
+
};
|
|
106568
|
+
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "connectionTypes", ["rest"]);
|
|
106569
|
+
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "defaultMoniker", NetworkStakeStepRewardsByPositionViewerMoniker$1);
|
|
106570
|
+
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "dependencies", []);
|
|
106571
|
+
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "monikers", [NetworkStakeStepRewardsByPositionViewerMoniker$1]);
|
|
106572
|
+
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "surface", "node");
|
|
106573
|
+
RestNetworkStakeStepRewardsByPositionViewer$1 = __decorateClass$23([creatableProvider$1()], RestNetworkStakeStepRewardsByPositionViewer$1);
|
|
105960
106574
|
var SimpleDeadLetterQueueRunner$1 = class extends AbstractCreatableProvider$1 {
|
|
105961
106575
|
/** Moniker implemented by this provider instance. */
|
|
105962
106576
|
moniker = SimpleDeadLetterQueueRunner$1.defaultMoniker;
|
|
@@ -107353,181 +107967,8 @@ __publicField$22(RestChainParamsViewer$1, "monikers", [ChainParamsViewerMoniker]
|
|
|
107353
107967
|
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
107354
107968
|
__publicField$22(RestChainParamsViewer$1, "surface", "node");
|
|
107355
107969
|
RestChainParamsViewer$1 = __decorateClass$23([creatableProvider$1()], RestChainParamsViewer$1);
|
|
107356
|
-
var DEFAULT_HEAD_POLL_INTERVAL_MS2$1 = 5e3;
|
|
107357
|
-
var RestNetworkStakeStepRewardsByPositionViewerOptionsZod$1 = object$3({
|
|
107358
|
-
headPollIntervalMs: number$1().min(5e3).default(DEFAULT_HEAD_POLL_INTERVAL_MS2$1),
|
|
107359
|
-
policyId: NetworkStakeRewardsPolicyIdZod.default(NETWORK_STAKE_REWARDS_UNMULTIPLIED_POLICY)
|
|
107360
|
-
});
|
|
107361
|
-
var RestNetworkStakeStepRewardsByPositionViewer$1 = class extends AbstractCreatableProvider$1 {
|
|
107362
|
-
moniker = RestNetworkStakeStepRewardsByPositionViewer$1.defaultMoniker;
|
|
107363
|
-
currentHead;
|
|
107364
|
-
headPollIntervalMs = DEFAULT_HEAD_POLL_INTERVAL_MS2$1;
|
|
107365
|
-
headPromise;
|
|
107366
|
-
lastSuccessfulHeadAt;
|
|
107367
|
-
manifestPromise;
|
|
107368
|
-
policyId = NETWORK_STAKE_REWARDS_UNMULTIPLIED_POLICY;
|
|
107369
|
-
snapshotPromises = /* @__PURE__ */ new Map();
|
|
107370
|
-
stepPromises = /* @__PURE__ */ new Map();
|
|
107371
|
-
get baseUrl() {
|
|
107372
|
-
const connection = RestNetworkStakeStepRewardsByPositionViewer$1.requireBoundConnection(this.config);
|
|
107373
|
-
const config = connection.config;
|
|
107374
|
-
if (config.type !== "rest") throw new Error(`Connection "${connection.name}" must be a rest connection`);
|
|
107375
|
-
return assertEx$1(config.baseUrl, () => `Connection "${connection.name}" requires a rest baseUrl`);
|
|
107376
|
-
}
|
|
107377
|
-
get fetchFn() {
|
|
107378
|
-
return this.context.fetchFn ?? fetch.bind(globalThis);
|
|
107379
|
-
}
|
|
107380
|
-
/** Returns the policy bonus. The unmultiplied-v1 index has no multipliers, so bonus is zero. */
|
|
107381
|
-
async bonus(options = {}) {
|
|
107382
|
-
const total = await this.total(options);
|
|
107383
|
-
return Object.fromEntries(Object.keys(total).map((key) => [Number(key), asAttoXL1$1(0n)]));
|
|
107384
|
-
}
|
|
107385
|
-
/** Claimed rewards are not part of the earned-reward index. */
|
|
107386
|
-
claimed(_options) {
|
|
107387
|
-
throw new Error("Method [claimed] not implemented.");
|
|
107388
|
-
}
|
|
107389
|
-
/** Creates the provider instance after validating its REST binding and options. */
|
|
107390
|
-
async createHandler() {
|
|
107391
|
-
await super.createHandler();
|
|
107392
|
-
RestNetworkStakeStepRewardsByPositionViewer$1.requireBoundConnection(this.config);
|
|
107393
|
-
const options = RestNetworkStakeStepRewardsByPositionViewerOptionsZod$1.parse(this.config.options);
|
|
107394
|
-
this.headPollIntervalMs = options.headPollIntervalMs;
|
|
107395
|
-
this.policyId = options.policyId;
|
|
107396
|
-
}
|
|
107397
|
-
/** Base-v1 total and earned rewards are identical. */
|
|
107398
|
-
async earned(options = {}) {
|
|
107399
|
-
return await this.total(options);
|
|
107400
|
-
}
|
|
107401
|
-
/** Returns rewards by requested position from the durable index. */
|
|
107402
|
-
async total({ range, positions } = {}) {
|
|
107403
|
-
if (!isArray(positions)) return {};
|
|
107404
|
-
const head = await this.getHead();
|
|
107405
|
-
const resolvedRange = asXL1BlockRange$1(range ?? [0, head.processedThroughBlock], { name: "RestNetworkStakeStepRewardsByPositionViewer" });
|
|
107406
|
-
const result = {};
|
|
107407
|
-
for (const position of positions) result[position] = (await this.totalForPosition(position, resolvedRange))[0];
|
|
107408
|
-
return result;
|
|
107409
|
-
}
|
|
107410
|
-
/** Returns one position's cumulative reward and the range's emitted reward pool. */
|
|
107411
|
-
async totalForPosition(position, range) {
|
|
107412
|
-
const head = await this.getHead();
|
|
107413
|
-
this.assertPublishedRange(range, head);
|
|
107414
|
-
if (head.positionCount === 0) return [asAttoXL1$1(0n), asAttoXL1$1(0n)];
|
|
107415
|
-
this.assertPosition(position, head);
|
|
107416
|
-
if (range[0] === 0 && range[1] >= head.processedThroughBlock) {
|
|
107417
|
-
const snapshot = await this.getSnapshot(head);
|
|
107418
|
-
return [asAttoXL1$1(BigInt(snapshot.positionRewards[String(position)] ?? "0")), asAttoXL1$1(BigInt(snapshot.totalReward))];
|
|
107419
|
-
}
|
|
107420
|
-
const steps = await this.stepsForRange(range, head);
|
|
107421
|
-
return [asAttoXL1$1(steps.reduce((sum, step) => sum + BigInt(step.positionRewards[String(position)] ?? "0"), 0n)), asAttoXL1$1(steps.reduce((sum, step) => sum + BigInt(step.totalReward), 0n))];
|
|
107422
|
-
}
|
|
107423
|
-
/** Returns the emitted reward pool for one indexed step. */
|
|
107424
|
-
async totalForStep(step) {
|
|
107425
|
-
const head = await this.getHead();
|
|
107426
|
-
this.assertPublishedStep(step, head);
|
|
107427
|
-
return asAttoXL1$1(BigInt((await this.getStep(step)).totalReward));
|
|
107428
|
-
}
|
|
107429
|
-
/** Returns one position's allocation and emitted pool for one indexed step. */
|
|
107430
|
-
async totalForStepForPosition(step, position) {
|
|
107431
|
-
const head = await this.getHead();
|
|
107432
|
-
this.assertPosition(position, head);
|
|
107433
|
-
this.assertPublishedStep(step, head);
|
|
107434
|
-
const record = await this.getStep(step);
|
|
107435
|
-
return [asAttoXL1$1(BigInt(record.positionRewards[String(position)] ?? "0")), asAttoXL1$1(BigInt(record.totalReward))];
|
|
107436
|
-
}
|
|
107437
|
-
/** Unclaimed rewards require redemption state and are not part of this index. */
|
|
107438
|
-
unclaimed(_options) {
|
|
107439
|
-
throw new Error("Method [unclaimed] not implemented.");
|
|
107440
|
-
}
|
|
107441
|
-
assertPosition(position, head) {
|
|
107442
|
-
assertEx$1(Number.isSafeInteger(position) && position >= 0 && position < head.positionCount, () => `Position ${position} is outside rewards index positionCount ${head.positionCount}`);
|
|
107443
|
-
}
|
|
107444
|
-
assertPublishedRange(range, head) {
|
|
107445
|
-
assertEx$1(range[1] <= head.processedThroughBlock, () => `Reward range ends at ${range[1]}, beyond index watermark ${head.processedThroughBlock}`);
|
|
107446
|
-
}
|
|
107447
|
-
assertPublishedStep(step, head) {
|
|
107448
|
-
assertEx$1(step.block <= head.processedThroughBlock, () => `Reward step ${step.block}|${step.step} is beyond index watermark ${head.processedThroughBlock}`);
|
|
107449
|
-
}
|
|
107450
|
-
async fetchJson(path) {
|
|
107451
|
-
const response = await this.fetchFn(`${this.baseUrl.replace(/\/$/, "")}/${path}`);
|
|
107452
|
-
if (!response.ok) throw new Error(`Network stake rewards index request failed [${response.status}] for ${path}`);
|
|
107453
|
-
return await response.json();
|
|
107454
|
-
}
|
|
107455
|
-
async getHead() {
|
|
107456
|
-
const now = Date.now();
|
|
107457
|
-
const elapsed = this.lastSuccessfulHeadAt === void 0 ? void 0 : now - this.lastSuccessfulHeadAt;
|
|
107458
|
-
if (this.currentHead !== void 0 && elapsed !== void 0 && elapsed >= 0 && elapsed < this.headPollIntervalMs) return this.currentHead;
|
|
107459
|
-
this.headPromise ??= this.syncHead().finally(() => {
|
|
107460
|
-
this.headPromise = void 0;
|
|
107461
|
-
});
|
|
107462
|
-
return await this.headPromise;
|
|
107463
|
-
}
|
|
107464
|
-
async getManifest() {
|
|
107465
|
-
this.manifestPromise ??= this.fetchJson(networkStakeRewardsIndexManifestPath(this.policyId)).then((value) => asNetworkStakeRewardsIndexManifest(value, true)).catch((error) => {
|
|
107466
|
-
this.manifestPromise = void 0;
|
|
107467
|
-
throw error;
|
|
107468
|
-
});
|
|
107469
|
-
return await this.manifestPromise;
|
|
107470
|
-
}
|
|
107471
|
-
async getSnapshot(head) {
|
|
107472
|
-
const { snapshotHash } = head;
|
|
107473
|
-
let promise = this.snapshotPromises.get(snapshotHash);
|
|
107474
|
-
if (promise === void 0) {
|
|
107475
|
-
const path = networkStakeRewardsIndexSnapshotPath(this.policyId, snapshotHash);
|
|
107476
|
-
promise = this.fetchJson(path).then(async (value) => {
|
|
107477
|
-
const snapshot = asNetworkStakeRewardsIndexSnapshot(value, true);
|
|
107478
|
-
assertEx$1(await PayloadBuilder$1.hash(snapshot) === snapshotHash, () => `Rewards snapshot hash mismatch: ${path}`);
|
|
107479
|
-
return snapshot;
|
|
107480
|
-
});
|
|
107481
|
-
this.snapshotPromises.set(snapshotHash, promise);
|
|
107482
|
-
}
|
|
107483
|
-
try {
|
|
107484
|
-
const snapshot = await promise;
|
|
107485
|
-
assertEx$1(snapshot.policyId === this.policyId, () => "Rewards snapshot policy mismatch");
|
|
107486
|
-
assertEx$1(snapshot.stepCount === head.stepCount, () => "Rewards snapshot step count mismatch");
|
|
107487
|
-
return snapshot;
|
|
107488
|
-
} catch (error) {
|
|
107489
|
-
this.snapshotPromises.delete(snapshotHash);
|
|
107490
|
-
throw error;
|
|
107491
|
-
}
|
|
107492
|
-
}
|
|
107493
|
-
async getStep(step) {
|
|
107494
|
-
const path = networkStakeRewardsIndexStepPath(this.policyId, step);
|
|
107495
|
-
let promise = this.stepPromises.get(path);
|
|
107496
|
-
if (promise === void 0) {
|
|
107497
|
-
promise = this.fetchJson(path).then((value) => asNetworkStakeRewardsIndexStep(value, true));
|
|
107498
|
-
this.stepPromises.set(path, promise);
|
|
107499
|
-
}
|
|
107500
|
-
try {
|
|
107501
|
-
const record = await promise;
|
|
107502
|
-
assertEx$1(record.policyId === this.policyId, () => "Rewards step policy mismatch");
|
|
107503
|
-
assertEx$1(record.step.block === step.block && record.step.step === step.step, () => "Rewards step identity mismatch");
|
|
107504
|
-
return record;
|
|
107505
|
-
} catch (error) {
|
|
107506
|
-
this.stepPromises.delete(path);
|
|
107507
|
-
throw error;
|
|
107508
|
-
}
|
|
107509
|
-
}
|
|
107510
|
-
async stepsForRange(range, head) {
|
|
107511
|
-
const steps = blockRangeSteps(range, (await this.getManifest()).stepLevels).filter((step) => step.block <= head.processedThroughBlock);
|
|
107512
|
-
return await Promise.all(steps.map(async (step) => await this.getStep(step)));
|
|
107513
|
-
}
|
|
107514
|
-
async syncHead() {
|
|
107515
|
-
assertEx$1((await this.getManifest()).policyId === this.policyId, () => "Rewards manifest policy mismatch");
|
|
107516
|
-
const head = asNetworkStakeRewardsIndexHead(await this.fetchJson(networkStakeRewardsIndexHeadPath(this.policyId)), true);
|
|
107517
|
-
assertEx$1(head.policyId === this.policyId, () => "Rewards head policy mismatch");
|
|
107518
|
-
this.currentHead = head;
|
|
107519
|
-
this.lastSuccessfulHeadAt = Date.now();
|
|
107520
|
-
return head;
|
|
107521
|
-
}
|
|
107522
|
-
};
|
|
107523
|
-
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "connectionTypes", ["rest"]);
|
|
107524
|
-
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "defaultMoniker", NetworkStakeStepRewardsByPositionViewerMoniker$1);
|
|
107525
|
-
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "dependencies", []);
|
|
107526
|
-
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "monikers", [NetworkStakeStepRewardsByPositionViewerMoniker$1]);
|
|
107527
|
-
__publicField$22(RestNetworkStakeStepRewardsByPositionViewer$1, "surface", "node");
|
|
107528
|
-
RestNetworkStakeStepRewardsByPositionViewer$1 = __decorateClass$23([creatableProvider$1()], RestNetworkStakeStepRewardsByPositionViewer$1);
|
|
107529
107970
|
//#endregion
|
|
107530
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
107971
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_3a01f3229f2daa942444e08696345b23/node_modules/@xyo-network/xl1-sdk/dist/neutral/gateway.mjs
|
|
107531
107972
|
async function witnessPreviousStep(gateway, options) {
|
|
107532
107973
|
const { addToChain = false, step = 2, transactionOptions, witness: witnessOption } = options ?? {};
|
|
107533
107974
|
const size = stepSize$1(step);
|
|
@@ -107554,7 +107995,7 @@ async function witnessPreviousStep(gateway, options) {
|
|
|
107554
107995
|
return { witness };
|
|
107555
107996
|
}
|
|
107556
107997
|
//#endregion
|
|
107557
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
107998
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_3a01f3229f2daa942444e08696345b23/node_modules/@xyo-network/xl1-sdk/dist/neutral/wrappers.mjs
|
|
107558
107999
|
function parseHexOrBigInt(value) {
|
|
107559
108000
|
return AttoXL1$1(typeof value === "bigint" ? value : hexToBigInt(value));
|
|
107560
108001
|
}
|
|
@@ -109102,26 +109543,23 @@ function createInstalledActorRegistry() {
|
|
|
109102
109543
|
return createInstalledActorRegistry$1();
|
|
109103
109544
|
}
|
|
109104
109545
|
var DEFAULT_LMDB_CONNECTION$1 = "local-store";
|
|
109105
|
-
var DEFAULT_MONGO_CONNECTION
|
|
109106
|
-
|
|
109107
|
-
|
|
109108
|
-
return type === "lmdb" || type === "memory" || type === "mongo";
|
|
109546
|
+
var DEFAULT_MONGO_CONNECTION = "chain-mongo";
|
|
109547
|
+
function isStoreConnectionType(type) {
|
|
109548
|
+
return type === "lmdb" || type === "mongo";
|
|
109109
109549
|
}
|
|
109110
|
-
function
|
|
109111
|
-
|
|
109112
|
-
if (!Object.hasOwn(merged, DEFAULT_MEMORY_CONNECTION$1)) merged[DEFAULT_MEMORY_CONNECTION$1] = { type: "memory" };
|
|
109113
|
-
return merged;
|
|
109550
|
+
function isBindableStoreType(type) {
|
|
109551
|
+
return isStoreConnectionType(type) || type === "memory";
|
|
109114
109552
|
}
|
|
109115
|
-
function
|
|
109116
|
-
const localStore =
|
|
109117
|
-
if (localStore !== void 0 && isBindableStoreType
|
|
109118
|
-
if (
|
|
109119
|
-
for (const [name, connection] of Object.entries(
|
|
109553
|
+
function localChainStoreConnectionName(connections) {
|
|
109554
|
+
const localStore = connections[DEFAULT_LMDB_CONNECTION$1];
|
|
109555
|
+
if (localStore !== void 0 && isBindableStoreType(localStore.type)) return DEFAULT_LMDB_CONNECTION$1;
|
|
109556
|
+
if (connections["chain-mongo"]?.type === "mongo") return DEFAULT_MONGO_CONNECTION;
|
|
109557
|
+
for (const [name, connection] of Object.entries(connections)) if (connection !== void 0 && isStoreConnectionType(connection.type)) return name;
|
|
109120
109558
|
}
|
|
109121
109559
|
function resolveMongoConnection(config) {
|
|
109122
|
-
const
|
|
109123
|
-
const name =
|
|
109124
|
-
const connection = name === void 0 ? void 0 :
|
|
109560
|
+
const connections = config.connections ?? {};
|
|
109561
|
+
const name = localChainStoreConnectionName(connections);
|
|
109562
|
+
const connection = name === void 0 ? void 0 : connections[name];
|
|
109125
109563
|
if (connection?.type !== "mongo") return void 0;
|
|
109126
109564
|
return connection;
|
|
109127
109565
|
}
|
|
@@ -115918,7 +116356,7 @@ __publicField$19(MemoryArchivist, "labels", {
|
|
|
115918
116356
|
});
|
|
115919
116357
|
MemoryArchivist = __decorateClass$19([creatableModule()], MemoryArchivist);
|
|
115920
116358
|
//#endregion
|
|
115921
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.
|
|
116359
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-protocol@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4._8a6486617e91c015a37921faa069ed7b/node_modules/@xyo-network/xl1-protocol/dist/neutral/protocol-model.mjs
|
|
115922
116360
|
var ExchangeOutcomeSchema = asSchema("network.xyo.exchange.outcome", true);
|
|
115923
116361
|
var isExchangeOutcome = isPayloadOfZodType(/* @__PURE__ */ object$5({
|
|
115924
116362
|
/** Hash of the ExchangeTerms payload this outcome settles */
|
|
@@ -116743,6 +117181,20 @@ var FinalizationRunnerMoniker = "FinalizationRunner";
|
|
|
116743
117181
|
var MempoolRunnerMoniker = "MempoolRunner";
|
|
116744
117182
|
var DEFAULT_MAX_EXP_AHEAD = 1e3;
|
|
116745
117183
|
var SystemStatusViewerMoniker = "SystemStatusViewer";
|
|
117184
|
+
var FinalizedBlockStreamMoniker = "FinalizedBlockStream";
|
|
117185
|
+
var FinalizedBlockStreamDesyncError = class extends Error {
|
|
117186
|
+
/** The block whose `previous` did not match, when it could be fetched. */
|
|
117187
|
+
block;
|
|
117188
|
+
/** The hash the walk expected the next block's `previous` to be. */
|
|
117189
|
+
expectedPrevious;
|
|
117190
|
+
constructor(expectedPrevious, block) {
|
|
117191
|
+
const found = block ? `found ${block[0].previous} at block ${block[0].block}` : "no block found";
|
|
117192
|
+
super(`FinalizedBlockStream desynced: expected previous ${expectedPrevious}, ${found}`);
|
|
117193
|
+
this.name = "FinalizedBlockStreamDesyncError";
|
|
117194
|
+
this.expectedPrevious = expectedPrevious;
|
|
117195
|
+
this.block = block;
|
|
117196
|
+
}
|
|
117197
|
+
};
|
|
116746
117198
|
var BlocksStepSummarySchema = asSchema("network.xyo.step.summary.blocks", true);
|
|
116747
117199
|
var isBlocksStepSummary = isPayloadOfSchemaType(BlocksStepSummarySchema);
|
|
116748
117200
|
var asBlocksStepSummary = AsObjectFactory.create(isBlocksStepSummary);
|
|
@@ -116904,7 +117356,7 @@ new import_ajv.Ajv({
|
|
|
116904
117356
|
strict: true
|
|
116905
117357
|
});
|
|
116906
117358
|
//#endregion
|
|
116907
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
117359
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_a771cefd6e9eb69efc5a95a989caf2a3/node_modules/@xyo-network/xl1-sdk/dist/neutral/driver-memory.mjs
|
|
116908
117360
|
var LruCacheMap = class {
|
|
116909
117361
|
lruCache;
|
|
116910
117362
|
/** Creates an instance with the supplied configuration. */
|
|
@@ -116986,7 +117438,7 @@ var MemoryMap = class {
|
|
|
116986
117438
|
}
|
|
116987
117439
|
};
|
|
116988
117440
|
//#endregion
|
|
116989
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
117441
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_a771cefd6e9eb69efc5a95a989caf2a3/node_modules/@xyo-network/xl1-sdk/dist/node/protocol-sdk.mjs
|
|
116990
117442
|
var __defProp$18 = Object.defineProperty;
|
|
116991
117443
|
var __getOwnPropDesc$18 = Object.getOwnPropertyDescriptor;
|
|
116992
117444
|
var __defNormalProp$18 = (obj, key, value) => key in obj ? __defProp$18(obj, key, {
|
|
@@ -117854,21 +118306,47 @@ function blocksToChains(blocks) {
|
|
|
117854
118306
|
}
|
|
117855
118307
|
return chains;
|
|
117856
118308
|
}
|
|
117857
|
-
function toValidUncle(_context, finalizedWindowedChain, possibleUncle) {
|
|
118309
|
+
function toValidUncle(_context, finalizedWindowedChain, possibleUncle, onReject) {
|
|
117858
118310
|
const finalizedWindowStartBlockNumber = finalizedWindowedChain.at(0)?.[0].block ?? -1;
|
|
117859
118311
|
const finalizedHead = assertEx$1(finalizedWindowedChain.at(-1), () => "finalizedWindowedChain is empty");
|
|
118312
|
+
const tip = assertEx$1(possibleUncle.at(-1), () => "possibleUncle is empty");
|
|
118313
|
+
const reject = (reason, offendingTransactionHashes) => {
|
|
118314
|
+
onReject?.({
|
|
118315
|
+
blockHash: tip[0]._hash,
|
|
118316
|
+
blockNumber: tip[0].block,
|
|
118317
|
+
offendingTransactionHashes,
|
|
118318
|
+
reason
|
|
118319
|
+
});
|
|
118320
|
+
};
|
|
117860
118321
|
const prunedPossibleUncle = possibleUncle.filter((b) => b[0].block > finalizedHead[0].block);
|
|
117861
|
-
if (prunedPossibleUncle.length === 0)
|
|
117862
|
-
|
|
117863
|
-
|
|
118322
|
+
if (prunedPossibleUncle.length === 0) {
|
|
118323
|
+
reject("behind-finalized-head");
|
|
118324
|
+
return;
|
|
118325
|
+
}
|
|
118326
|
+
if (prunedPossibleUncle[0][0].block !== finalizedHead[0].block + 1) {
|
|
118327
|
+
reject("block-number-mismatch");
|
|
118328
|
+
return;
|
|
118329
|
+
}
|
|
118330
|
+
if (prunedPossibleUncle[0][0].previous !== finalizedHead[0]._hash) {
|
|
118331
|
+
reject("previous-hash-mismatch");
|
|
118332
|
+
return;
|
|
118333
|
+
}
|
|
117864
118334
|
const allUncleTransactions = prunedPossibleUncle.flatMap((b) => b[1]).filter(isTransactionBoundWitness);
|
|
117865
118335
|
const allFinalizedTransactions = finalizedWindowedChain.flatMap((b) => b[1]).filter(isTransactionBoundWitness);
|
|
117866
|
-
|
|
117867
|
-
if (
|
|
118336
|
+
const txsBeforeWindow = allUncleTransactions.filter((tx) => tx.nbf < finalizedWindowStartBlockNumber);
|
|
118337
|
+
if (txsBeforeWindow.length > 0) {
|
|
118338
|
+
reject("tx-before-window", txsBeforeWindow.map((tx) => tx._hash));
|
|
118339
|
+
return;
|
|
118340
|
+
}
|
|
118341
|
+
const txsInWindow = allUncleTransactions.filter((tx) => allFinalizedTransactions.some((finalTx) => finalTx._hash === tx._hash));
|
|
118342
|
+
if (txsInWindow.length > 0) {
|
|
118343
|
+
reject("tx-already-finalized", txsInWindow.map((tx) => tx._hash));
|
|
118344
|
+
return;
|
|
118345
|
+
}
|
|
117868
118346
|
return prunedPossibleUncle;
|
|
117869
118347
|
}
|
|
117870
|
-
function findUncles(context, finalizedWindowedChain, blocks) {
|
|
117871
|
-
return blocksToChains(blocks).map((chain) => toValidUncle(context, finalizedWindowedChain, chain)).filter(exists$1);
|
|
118348
|
+
function findUncles(context, finalizedWindowedChain, blocks, onReject) {
|
|
118349
|
+
return blocksToChains(blocks).map((chain) => toValidUncle(context, finalizedWindowedChain, chain, onReject)).filter(exists$1);
|
|
117872
118350
|
}
|
|
117873
118351
|
var ValidationConfigZod = object$3({
|
|
117874
118352
|
signerAuthorizations: array$1(SignerAuthorizationZod).default([]).register(globalRegistry, {
|
|
@@ -119366,6 +119844,7 @@ var SimpleBlockValidationViewer = class extends AbstractCreatableProvider {
|
|
|
119366
119844
|
state: true,
|
|
119367
119845
|
head: void 0
|
|
119368
119846
|
};
|
|
119847
|
+
if (config !== void 0 && value !== true && state !== true) this.logger?.warn("validateBlocks called with a config that selects no validators (neither value nor state is true) — every block will report valid");
|
|
119369
119848
|
const blocksWithMeta = await Promise.all(blocks.map((b) => Promise.all([PayloadBuilder.addHashMeta(b[0]), PayloadBuilder.addHashMeta(b[1])])));
|
|
119370
119849
|
let head;
|
|
119371
119850
|
if (isChainQualifiedHeadConfig(config)) {
|
|
@@ -119414,18 +119893,30 @@ var SimpleBlockValidationViewer = class extends AbstractCreatableProvider {
|
|
|
119414
119893
|
}
|
|
119415
119894
|
async doValidateState(blocks, chainIdAtBlockNumber) {
|
|
119416
119895
|
const windowedUncleChain = await this.updateWindowedChainCache();
|
|
119417
|
-
const
|
|
119896
|
+
const rejections = [];
|
|
119897
|
+
const uncles = findUncles(this.context, windowedUncleChain, blocks, (rejection) => rejections.push(rejection));
|
|
119418
119898
|
if (uncles.length !== 1) {
|
|
119419
|
-
|
|
119899
|
+
const rejectionSummary = rejections.map((r) => `${r.blockNumber} [${r.blockHash}]: ${r.reason}${(r.offendingTransactionHashes?.length ?? 0) > 0 ? ` (tx ${r.offendingTransactionHashes?.join(", ")})` : ""}`).join("; ");
|
|
119900
|
+
this.logger?.warn(`Unexpected uncle count during block validation [uncles=${uncles.length}, blocks=${blocks.length}]` + (rejectionSummary.length > 0 ? ` \u2014 rejected: ${rejectionSummary}` : ""));
|
|
119420
119901
|
this.logger?.debug(JSON.stringify({
|
|
119421
119902
|
uncles,
|
|
119422
119903
|
blocks: blocks.length
|
|
119423
119904
|
}, null, 2));
|
|
119424
119905
|
this.logger?.debug(JSON.stringify(windowedUncleChain, null, 2));
|
|
119425
|
-
return blocks.map((block) =>
|
|
119426
|
-
|
|
119427
|
-
|
|
119428
|
-
|
|
119906
|
+
return blocks.map((block) => {
|
|
119907
|
+
const rejection = rejections.find((r) => r.blockHash === block[0]._hash);
|
|
119908
|
+
const offendingTransactionHashes = rejection?.offendingTransactionHashes ?? [];
|
|
119909
|
+
if (rejection && offendingTransactionHashes.length > 0) return offendingTransactionHashes.map((txHash) => new HydratedBlockValidationError(txHash, block, `Uncle rejected during state validation: ${rejection.reason}`, {
|
|
119910
|
+
blockHash: rejection.blockHash,
|
|
119911
|
+
hash: txHash,
|
|
119912
|
+
reason: rejection.reason
|
|
119913
|
+
}));
|
|
119914
|
+
return [new HydratedBlockValidationError(block[0]._hash, block, `Unexpected uncle count during state validation${rejection ? `: ${rejection.reason}` : ""}`, {
|
|
119915
|
+
reason: rejection?.reason,
|
|
119916
|
+
uncles: uncles.length,
|
|
119917
|
+
blocks: blocks.length
|
|
119918
|
+
})];
|
|
119919
|
+
});
|
|
119429
119920
|
}
|
|
119430
119921
|
const validateState = assertEx$1(this.validators.blockStateValidator, () => "No block state validator registered");
|
|
119431
119922
|
return await Promise.all(uncles[0].map(async (block) => {
|
|
@@ -120262,6 +120753,303 @@ __publicField$18(SimpleFinalizationViewer, "monikers", [FinalizationViewerMonike
|
|
|
120262
120753
|
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
120263
120754
|
__publicField$18(SimpleFinalizationViewer, "surface", "node");
|
|
120264
120755
|
SimpleFinalizationViewer = __decorateClass$18([creatableProvider()], SimpleFinalizationViewer);
|
|
120756
|
+
var MIN_POLL_INTERVAL_MS = 5e3;
|
|
120757
|
+
var DEFAULT_POLL_INTERVAL_MS = 1e4;
|
|
120758
|
+
var DEFAULT_FETCH_WINDOW = StepSizes[2];
|
|
120759
|
+
var MAX_FETCH_WINDOW = StepSizes[3];
|
|
120760
|
+
var SimpleFinalizedBlockStreamOptionsZod = object$3({
|
|
120761
|
+
/**
|
|
120762
|
+
* Hot-surface resume checkpoint: emit blocks strictly after this hash, as a
|
|
120763
|
+
* verified splice (the first emission's `previous` must equal it — mismatch
|
|
120764
|
+
* emits `desynced` at startup rather than delivering a diverged chain).
|
|
120765
|
+
* Omitted, the stream starts at the current head, delivered as the first
|
|
120766
|
+
* `nextBlock`.
|
|
120767
|
+
*/
|
|
120768
|
+
after: optional$1(HashZod),
|
|
120769
|
+
/**
|
|
120770
|
+
* Upper bound on blocks fetched per `blocksByNumber` window during a walk.
|
|
120771
|
+
* The window adapts to the lag (never fetching past the head) and grows up to
|
|
120772
|
+
* this cap on deep replays, letting REST-backed viewers tile each window from
|
|
120773
|
+
* step rollup files. Capped at the largest served rollup (`StepSizes[3]`);
|
|
120774
|
+
* raise toward it for indexer-style deep replays, lower it to bound memory.
|
|
120775
|
+
*/
|
|
120776
|
+
fetchWindow: number$1().int().positive().max(MAX_FETCH_WINDOW).default(DEFAULT_FETCH_WINDOW),
|
|
120777
|
+
/**
|
|
120778
|
+
* Hot-surface catch-up bound: when the head is further ahead than this, a
|
|
120779
|
+
* `gap` is announced and delivery resumes `maxCatchUp` blocks behind head.
|
|
120780
|
+
* The cold `blocks()` surface ignores this — it never gaps.
|
|
120781
|
+
*/
|
|
120782
|
+
maxCatchUp: number$1().int().positive().default(StepSizes[1]),
|
|
120783
|
+
/** Head poll cadence shared by the hot surface and all `blocks()` iterations. */
|
|
120784
|
+
pollIntervalMs: number$1().min(MIN_POLL_INTERVAL_MS).default(DEFAULT_POLL_INTERVAL_MS)
|
|
120785
|
+
});
|
|
120786
|
+
function cursorFromBlock(block) {
|
|
120787
|
+
return {
|
|
120788
|
+
block: block[0].block,
|
|
120789
|
+
hash: block[0]._hash
|
|
120790
|
+
};
|
|
120791
|
+
}
|
|
120792
|
+
var SimpleFinalizedBlockStream = class extends AbstractCreatableProvider {
|
|
120793
|
+
/** Moniker implemented by this provider instance. */
|
|
120794
|
+
moniker = FinalizedBlockStreamMoniker;
|
|
120795
|
+
_blockViewer;
|
|
120796
|
+
_cursor;
|
|
120797
|
+
_finalizationViewer;
|
|
120798
|
+
_head;
|
|
120799
|
+
_headWaiters = [];
|
|
120800
|
+
_hotLoop;
|
|
120801
|
+
_isLive = false;
|
|
120802
|
+
_options;
|
|
120803
|
+
_pollInProgress = false;
|
|
120804
|
+
_pollTimer = null;
|
|
120805
|
+
_stopping = false;
|
|
120806
|
+
_terminal = false;
|
|
120807
|
+
/** Last position delivered on the hot surface, or `undefined` before the first. */
|
|
120808
|
+
get cursor() {
|
|
120809
|
+
return this._cursor;
|
|
120810
|
+
}
|
|
120811
|
+
/** True once the hot surface has caught up to the live head. */
|
|
120812
|
+
get isLive() {
|
|
120813
|
+
return this._isLive;
|
|
120814
|
+
}
|
|
120815
|
+
get options() {
|
|
120816
|
+
this._options ??= SimpleFinalizedBlockStreamOptionsZod.parse(this.config.options);
|
|
120817
|
+
return this._options;
|
|
120818
|
+
}
|
|
120819
|
+
/** Validates the provider options at create time. */
|
|
120820
|
+
static async paramsHandler(params = {}) {
|
|
120821
|
+
const handled = await super.paramsHandler(params);
|
|
120822
|
+
SimpleFinalizedBlockStreamOptionsZod.parse(handled.context.config.options);
|
|
120823
|
+
return handled;
|
|
120824
|
+
}
|
|
120825
|
+
/**
|
|
120826
|
+
* Cold, per-caller iteration: replay from `after`, then follow the head.
|
|
120827
|
+
* Gapless by construction — the caller paces the walk. Throws
|
|
120828
|
+
* `FinalizedBlockStreamDesyncError` on any continuity failure, including a
|
|
120829
|
+
* failed resume splice; other (transient) fetch errors also throw, and the
|
|
120830
|
+
* caller resumes from its own checkpoint.
|
|
120831
|
+
*/
|
|
120832
|
+
async *blocks(options) {
|
|
120833
|
+
let cursor;
|
|
120834
|
+
if (isDefined$1(options?.after)) cursor = await this.resolveCheckpoint(options.after);
|
|
120835
|
+
else {
|
|
120836
|
+
const head = await this.currentHead();
|
|
120837
|
+
yield {
|
|
120838
|
+
block: head,
|
|
120839
|
+
head: head[0].block
|
|
120840
|
+
};
|
|
120841
|
+
cursor = cursorFromBlock(head);
|
|
120842
|
+
}
|
|
120843
|
+
while (!this._stopping) {
|
|
120844
|
+
const headNumber = (await this.currentHead())[0].block;
|
|
120845
|
+
if (cursor.block >= headNumber) {
|
|
120846
|
+
await this.waitForHeadAdvance();
|
|
120847
|
+
continue;
|
|
120848
|
+
}
|
|
120849
|
+
for (const block of await this.nextBlocks(cursor, headNumber)) {
|
|
120850
|
+
cursor = this.advanceCursor(cursor, block);
|
|
120851
|
+
yield {
|
|
120852
|
+
block,
|
|
120853
|
+
head: headNumber
|
|
120854
|
+
};
|
|
120855
|
+
if (this._stopping) return;
|
|
120856
|
+
}
|
|
120857
|
+
}
|
|
120858
|
+
}
|
|
120859
|
+
/** Creates the provider instance after its dependencies and configuration have resolved. */
|
|
120860
|
+
async createHandler() {
|
|
120861
|
+
await super.createHandler();
|
|
120862
|
+
const injected = this.params.viewers;
|
|
120863
|
+
this._blockViewer = injected?.blocks ?? assertEx$1(await this.locator.getInstance("BlockViewer"), () => "BlockViewer instance is required");
|
|
120864
|
+
this._finalizationViewer = injected?.finalization ?? assertEx$1(await this.locator.getInstance("FinalizationViewer"), () => "FinalizationViewer instance is required");
|
|
120865
|
+
}
|
|
120866
|
+
/** Starts the head poll and the hot delivery loop. */
|
|
120867
|
+
async startHandler() {
|
|
120868
|
+
await super.startHandler();
|
|
120869
|
+
this._stopping = false;
|
|
120870
|
+
this._terminal = false;
|
|
120871
|
+
await this.pollHead();
|
|
120872
|
+
this._pollTimer = setInterval(() => {
|
|
120873
|
+
this.pollHead();
|
|
120874
|
+
}, this.options.pollIntervalMs);
|
|
120875
|
+
this._hotLoop = this.runHot();
|
|
120876
|
+
}
|
|
120877
|
+
/** Stops the poll, ends the hot loop, and emits the terminal `stopped` event. */
|
|
120878
|
+
async stopHandler() {
|
|
120879
|
+
this._stopping = true;
|
|
120880
|
+
if (this._pollTimer) {
|
|
120881
|
+
clearInterval(this._pollTimer);
|
|
120882
|
+
this._pollTimer = null;
|
|
120883
|
+
}
|
|
120884
|
+
this.releaseHeadWaiters();
|
|
120885
|
+
await this._hotLoop;
|
|
120886
|
+
this._hotLoop = void 0;
|
|
120887
|
+
if (!this._terminal) {
|
|
120888
|
+
this._terminal = true;
|
|
120889
|
+
await this.emitSerial("stopped", { cursor: this._cursor });
|
|
120890
|
+
}
|
|
120891
|
+
this._head = void 0;
|
|
120892
|
+
await super.stopHandler();
|
|
120893
|
+
}
|
|
120894
|
+
/**
|
|
120895
|
+
* Verifies continuity and advances a cursor to the delivered block. A
|
|
120896
|
+
* `previous` mismatch on the expected block number is a data-integrity
|
|
120897
|
+
* fault; a wrong/missing block number is a transient fetch problem.
|
|
120898
|
+
*/
|
|
120899
|
+
advanceCursor(cursor, block) {
|
|
120900
|
+
assertEx$1(block[0].block === cursor.block + 1, () => `FinalizedBlockStream: expected block ${cursor.block + 1}, fetched ${block[0].block}`);
|
|
120901
|
+
if (block[0].previous !== cursor.hash) throw new FinalizedBlockStreamDesyncError(cursor.hash, block);
|
|
120902
|
+
return cursorFromBlock(block);
|
|
120903
|
+
}
|
|
120904
|
+
/** One hot-loop step: bound the lag (announcing a `gap`), deliver the next window, mark live. */
|
|
120905
|
+
async advanceHot() {
|
|
120906
|
+
const head = await this.currentHead();
|
|
120907
|
+
const headNumber = head[0].block;
|
|
120908
|
+
const cursor = assertEx$1(this._cursor);
|
|
120909
|
+
if (cursor.block >= headNumber) {
|
|
120910
|
+
await this.markLive(head);
|
|
120911
|
+
await this.waitForHeadAdvance();
|
|
120912
|
+
return;
|
|
120913
|
+
}
|
|
120914
|
+
if (headNumber - cursor.block > this.options.maxCatchUp) {
|
|
120915
|
+
await this.announceGap(cursor, headNumber);
|
|
120916
|
+
return;
|
|
120917
|
+
}
|
|
120918
|
+
for (const block of await this.nextBlocks(cursor, headNumber)) {
|
|
120919
|
+
if (this._stopping) return;
|
|
120920
|
+
this._cursor = this.advanceCursor(assertEx$1(this._cursor), block);
|
|
120921
|
+
await this.emitSerial("nextBlock", {
|
|
120922
|
+
block,
|
|
120923
|
+
head: headNumber
|
|
120924
|
+
});
|
|
120925
|
+
}
|
|
120926
|
+
if (assertEx$1(this._cursor).block >= headNumber) await this.markLive(head);
|
|
120927
|
+
}
|
|
120928
|
+
/** Announces a hot-surface gap and splices the shared cursor to `maxCatchUp` behind head. */
|
|
120929
|
+
async announceGap(cursor, headNumber) {
|
|
120930
|
+
const resumeNumber = asXL1BlockNumber(headNumber - this.options.maxCatchUp + 1, true);
|
|
120931
|
+
const resumeBlock = assertEx$1(await this._blockViewer.blockByNumber(resumeNumber), () => `FinalizedBlockStream: gap resume block ${resumeNumber} unavailable`);
|
|
120932
|
+
const skipped = [asXL1BlockNumber(cursor.block + 1, true), asXL1BlockNumber(resumeNumber - 1, true)];
|
|
120933
|
+
this._isLive = false;
|
|
120934
|
+
await this.emitSerial("gap", {
|
|
120935
|
+
before: cursor,
|
|
120936
|
+
resumedAt: cursorFromBlock(resumeBlock),
|
|
120937
|
+
skipped
|
|
120938
|
+
});
|
|
120939
|
+
this._cursor = {
|
|
120940
|
+
block: asXL1BlockNumber(resumeNumber - 1, true),
|
|
120941
|
+
hash: assertEx$1(resumeBlock[0].previous, () => "FinalizedBlockStream: gap resume block has no previous")
|
|
120942
|
+
};
|
|
120943
|
+
}
|
|
120944
|
+
/** Returns the last polled head, fetching once when no poll has landed yet. */
|
|
120945
|
+
async currentHead() {
|
|
120946
|
+
if (this._head) return this._head;
|
|
120947
|
+
this._head ??= await this._finalizationViewer.head();
|
|
120948
|
+
return this._head;
|
|
120949
|
+
}
|
|
120950
|
+
/** Initializes the hot cursor: verified splice from `after`, or head-first delivery. */
|
|
120951
|
+
async initHotCursor() {
|
|
120952
|
+
const { after } = this.options;
|
|
120953
|
+
if (isDefined$1(after)) {
|
|
120954
|
+
this._cursor = await this.resolveCheckpoint(after);
|
|
120955
|
+
return;
|
|
120956
|
+
}
|
|
120957
|
+
const head = await this.currentHead();
|
|
120958
|
+
this._cursor = cursorFromBlock(head);
|
|
120959
|
+
await this.emitSerial("nextBlock", {
|
|
120960
|
+
block: head,
|
|
120961
|
+
head: head[0].block
|
|
120962
|
+
});
|
|
120963
|
+
await this.markLive(head);
|
|
120964
|
+
}
|
|
120965
|
+
/** Marks the hot surface live, emitting the transition once. */
|
|
120966
|
+
async markLive(head) {
|
|
120967
|
+
if (this._isLive) return;
|
|
120968
|
+
this._isLive = true;
|
|
120969
|
+
await this.emitSerial("live", { head: cursorFromBlock(head) });
|
|
120970
|
+
}
|
|
120971
|
+
/**
|
|
120972
|
+
* Fetches the ordered run of blocks after `cursor`, up to one window. Order
|
|
120973
|
+
* is normalized here; continuity is verified per block by `advanceCursor`.
|
|
120974
|
+
*/
|
|
120975
|
+
async nextBlocks(cursor, headNumber) {
|
|
120976
|
+
const hi = asXL1BlockNumber(Math.min(cursor.block + this.options.fetchWindow, headNumber), true);
|
|
120977
|
+
const run = (await this._blockViewer.blocksByNumber(hi, hi - cursor.block)).filter((block) => block[0].block > cursor.block).toSorted((a, b) => a[0].block - b[0].block);
|
|
120978
|
+
assertEx$1(run.length > 0, () => `FinalizedBlockStream: no blocks fetched in (${cursor.block}, ${hi}]`);
|
|
120979
|
+
return run;
|
|
120980
|
+
}
|
|
120981
|
+
/** Polls the finalized head, releasing all cursor walks blocked on head growth. */
|
|
120982
|
+
async pollHead() {
|
|
120983
|
+
if (this._pollInProgress) return;
|
|
120984
|
+
this._pollInProgress = true;
|
|
120985
|
+
try {
|
|
120986
|
+
const head = await this._finalizationViewer.head();
|
|
120987
|
+
if (head[0]._hash !== this._head?.[0]._hash) {
|
|
120988
|
+
this._head = head;
|
|
120989
|
+
this.releaseHeadWaiters();
|
|
120990
|
+
}
|
|
120991
|
+
} catch (ex) {
|
|
120992
|
+
this.logger?.error("FinalizedBlockStream: error polling head", ex);
|
|
120993
|
+
} finally {
|
|
120994
|
+
this._pollInProgress = false;
|
|
120995
|
+
}
|
|
120996
|
+
}
|
|
120997
|
+
releaseHeadWaiters() {
|
|
120998
|
+
const waiters = this._headWaiters.splice(0);
|
|
120999
|
+
for (const release of waiters) release();
|
|
121000
|
+
}
|
|
121001
|
+
/** Resolves a checkpoint hash to a cursor, or throws the desync error a missing checkpoint implies. */
|
|
121002
|
+
async resolveCheckpoint(after) {
|
|
121003
|
+
const checkpoint = await this._blockViewer.blockByHash(after);
|
|
121004
|
+
if (!checkpoint) throw new FinalizedBlockStreamDesyncError(after);
|
|
121005
|
+
return cursorFromBlock(checkpoint);
|
|
121006
|
+
}
|
|
121007
|
+
/**
|
|
121008
|
+
* The hot delivery loop. Transient errors are logged and retried on the next
|
|
121009
|
+
* head advance; a continuity failure emits the terminal `desynced` event.
|
|
121010
|
+
*/
|
|
121011
|
+
async runHot() {
|
|
121012
|
+
try {
|
|
121013
|
+
await this.initHotCursor();
|
|
121014
|
+
while (!this._stopping) try {
|
|
121015
|
+
await this.advanceHot();
|
|
121016
|
+
} catch (ex) {
|
|
121017
|
+
if (ex instanceof FinalizedBlockStreamDesyncError) throw ex;
|
|
121018
|
+
if (this._stopping) return;
|
|
121019
|
+
this.logger?.error("FinalizedBlockStream: hot loop error, retrying on next head", ex);
|
|
121020
|
+
await this.waitForHeadAdvance();
|
|
121021
|
+
}
|
|
121022
|
+
} catch (ex) {
|
|
121023
|
+
if (ex instanceof FinalizedBlockStreamDesyncError && !this._terminal) {
|
|
121024
|
+
this._terminal = true;
|
|
121025
|
+
await this.emitSerial("desynced", {
|
|
121026
|
+
block: ex.block,
|
|
121027
|
+
expectedPrevious: ex.expectedPrevious
|
|
121028
|
+
});
|
|
121029
|
+
return;
|
|
121030
|
+
}
|
|
121031
|
+
this.logger?.error("FinalizedBlockStream: hot loop terminated", ex);
|
|
121032
|
+
}
|
|
121033
|
+
}
|
|
121034
|
+
/** Suspends until the polled head changes or the stream stops. */
|
|
121035
|
+
waitForHeadAdvance() {
|
|
121036
|
+
if (this._stopping) return Promise.resolve();
|
|
121037
|
+
return new Promise((resolve) => {
|
|
121038
|
+
this._headWaiters.push(resolve);
|
|
121039
|
+
});
|
|
121040
|
+
}
|
|
121041
|
+
};
|
|
121042
|
+
/** Connection kinds supported by this provider. */
|
|
121043
|
+
__publicField$18(SimpleFinalizedBlockStream, "connectionTypes", ["none"]);
|
|
121044
|
+
/** Primary moniker used to resolve this provider. */
|
|
121045
|
+
__publicField$18(SimpleFinalizedBlockStream, "defaultMoniker", FinalizedBlockStreamMoniker);
|
|
121046
|
+
/** Provider monikers that must resolve before this provider can be created. */
|
|
121047
|
+
__publicField$18(SimpleFinalizedBlockStream, "dependencies", [BlockViewerMoniker, FinalizationViewerMoniker]);
|
|
121048
|
+
/** Provider monikers implemented by this provider class. */
|
|
121049
|
+
__publicField$18(SimpleFinalizedBlockStream, "monikers", [FinalizedBlockStreamMoniker]);
|
|
121050
|
+
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
121051
|
+
__publicField$18(SimpleFinalizedBlockStream, "surface", "node");
|
|
121052
|
+
SimpleFinalizedBlockStream = __decorateClass$18([creatableProvider()], SimpleFinalizedBlockStream);
|
|
120265
121053
|
var SimpleIndexViewer = class extends AbstractCreatableProvider {
|
|
120266
121054
|
/** Moniker implemented by this provider instance. */
|
|
120267
121055
|
moniker = SimpleIndexViewer.defaultMoniker;
|
|
@@ -120435,6 +121223,83 @@ var nextPruneCursor = (batch, pruneHashes, cursor) => {
|
|
|
120435
121223
|
const pruneSet = new Set(pruneHashes);
|
|
120436
121224
|
return batch.findLast((bundle3) => !pruneSet.has(bundle3._hash))?._sequence ?? cursor;
|
|
120437
121225
|
};
|
|
121226
|
+
async function simpleBlockValidationCheck(payloads, context) {
|
|
121227
|
+
return (await Promise.all(payloads.map(async (payload) => {
|
|
121228
|
+
return [isPayloadBundle(payload) ? await bundledPayloadToHydratedBlock(payload) : void 0, payload];
|
|
121229
|
+
}))).map(([block, bundle3]) => evaluateBlockCandidate(block, bundle3, context));
|
|
121230
|
+
}
|
|
121231
|
+
async function simpleTransactionValidationCheck(payloads, context) {
|
|
121232
|
+
const transactionBundles = await Promise.all(payloads.map(async (payload) => {
|
|
121233
|
+
return [isPayloadBundle(payload) ? await bundledPayloadToHydratedTransaction(payload) : void 0, payload];
|
|
121234
|
+
}));
|
|
121235
|
+
return Promise.all(transactionBundles.map(async ([transaction, bundle3]) => {
|
|
121236
|
+
return evaluateTransactionCandidate(transaction, bundle3, context);
|
|
121237
|
+
}));
|
|
121238
|
+
}
|
|
121239
|
+
function evaluateBlockCandidate(block, bundle3, { chainId, headNumber, logger }) {
|
|
121240
|
+
const typeCheckPassed = isSignedHydratedBlockWithHashMeta(block);
|
|
121241
|
+
const chainIdPassed = typeCheckPassed && block[0].chain === chainId;
|
|
121242
|
+
const blockNumberPassed = typeCheckPassed && block[0].block > headNumber;
|
|
121243
|
+
const validationPassed = typeCheckPassed && chainIdPassed && blockNumberPassed;
|
|
121244
|
+
if (!validationPassed) logFailedBlockCheck({
|
|
121245
|
+
block,
|
|
121246
|
+
blockNumberPassed,
|
|
121247
|
+
bundle: bundle3,
|
|
121248
|
+
chainIdPassed,
|
|
121249
|
+
headNumber,
|
|
121250
|
+
logger,
|
|
121251
|
+
typeCheckPassed
|
|
121252
|
+
});
|
|
121253
|
+
return [validationPassed ? block : void 0, bundle3];
|
|
121254
|
+
}
|
|
121255
|
+
async function evaluateTransactionCandidate(transaction, bundle3, { chainId, headNumber, logger, maxExpAhead }) {
|
|
121256
|
+
const typeCheckPassed = isSignedHydratedTransactionWithHashMeta(transaction);
|
|
121257
|
+
const chainIdPassed = typeCheckPassed && transaction[0].chain === chainId;
|
|
121258
|
+
const expPassed = typeCheckPassed && transaction[0].exp > headNumber && transaction[0].exp <= headNumber + maxExpAhead;
|
|
121259
|
+
const opcodeCheckPassed = await checkTransactionOpcodes(transaction, bundle3, logger);
|
|
121260
|
+
const validationPassed = typeCheckPassed && chainIdPassed && expPassed && opcodeCheckPassed;
|
|
121261
|
+
if (!validationPassed) logFailedTransactionCheck({
|
|
121262
|
+
bundle: bundle3,
|
|
121263
|
+
chainIdPassed,
|
|
121264
|
+
expPassed,
|
|
121265
|
+
headNumber,
|
|
121266
|
+
logger,
|
|
121267
|
+
opcodeCheckPassed,
|
|
121268
|
+
transaction,
|
|
121269
|
+
typeCheckPassed
|
|
121270
|
+
});
|
|
121271
|
+
return [validationPassed ? transaction : void 0, bundle3];
|
|
121272
|
+
}
|
|
121273
|
+
async function checkTransactionOpcodes(transaction, bundle3, logger) {
|
|
121274
|
+
try {
|
|
121275
|
+
await validateTransactionsOpcodes(transaction === void 0 ? [] : [transaction]);
|
|
121276
|
+
return true;
|
|
121277
|
+
} catch (error) {
|
|
121278
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
121279
|
+
logger?.debug(`Opcode validation failed for transaction ${bundle3._hash} during simpleValidationCheck`);
|
|
121280
|
+
logger?.debug(` - error: ${message}`);
|
|
121281
|
+
return false;
|
|
121282
|
+
}
|
|
121283
|
+
}
|
|
121284
|
+
function logFailedBlockCheck({ block, blockNumberPassed, bundle: bundle3, chainIdPassed, headNumber, logger, typeCheckPassed }) {
|
|
121285
|
+
if (chainIdPassed && typeCheckPassed && !blockNumberPassed) {
|
|
121286
|
+
logger?.debug(`Pruning stale block candidate bundle ${bundle3._hash} during simpleValidationCheck (candidate height ${block?.[0].block} <= finalized head ${headNumber} \u2014 routine GC of a finalized or superseded candidate)`);
|
|
121287
|
+
return;
|
|
121288
|
+
}
|
|
121289
|
+
logger?.debug(`Pruning block bundle ${bundle3._hash} during simpleValidationCheck`);
|
|
121290
|
+
logger?.debug(` - chainId match: ${chainIdPassed}`);
|
|
121291
|
+
logger?.debug(` - blockNumber check: ${blockNumberPassed} [head=${headNumber} candidate=${block?.[0].block}]`);
|
|
121292
|
+
logger?.debug(` - typeCheck: ${typeCheckPassed}`);
|
|
121293
|
+
logger?.debug(` - bundle hash: ${bundle3._hash}`);
|
|
121294
|
+
}
|
|
121295
|
+
function logFailedTransactionCheck({ bundle: bundle3, chainIdPassed, expPassed, headNumber, logger, opcodeCheckPassed, transaction, typeCheckPassed }) {
|
|
121296
|
+
logger?.debug(`Pruning transaction bundle ${bundle3._hash} during simpleValidationCheck`);
|
|
121297
|
+
logger?.debug(` - chainId match: ${chainIdPassed}`);
|
|
121298
|
+
logger?.debug(` - exp check: ${expPassed} [head=${headNumber} exp=${transaction?.[0].exp}]`);
|
|
121299
|
+
logger?.debug(` - opcode check: ${opcodeCheckPassed}`);
|
|
121300
|
+
logger?.debug(` - typeCheck: ${typeCheckPassed}`);
|
|
121301
|
+
logger?.debug(` - bundle hash: ${bundle3._hash}`);
|
|
121302
|
+
}
|
|
120438
121303
|
var DEFAULT_SYNC_INTERVAL = 3e4;
|
|
120439
121304
|
var DEFAULT_SYNC_LIMIT = 100;
|
|
120440
121305
|
var ENFORCE_CAP_BATCH_SIZE = 1e3;
|
|
@@ -120567,7 +121432,11 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
120567
121432
|
}
|
|
120568
121433
|
while (batch.length > 0 && pruned < maxPrune && total < maxCheck) {
|
|
120569
121434
|
batches += 1;
|
|
120570
|
-
const blocksAndBundles = await
|
|
121435
|
+
const blocksAndBundles = await simpleBlockValidationCheck(batch, {
|
|
121436
|
+
chainId: await this.chainContractViewer.chainId(),
|
|
121437
|
+
headNumber: await this.finalizationViewer.headNumber(),
|
|
121438
|
+
logger: this.logger
|
|
121439
|
+
});
|
|
120571
121440
|
const blocks = blocksAndBundles.map(([b]) => b);
|
|
120572
121441
|
const bundles = blocksAndBundles.map(([_, p]) => p);
|
|
120573
121442
|
const valid = blocks.map((b) => !!b);
|
|
@@ -120581,9 +121450,10 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
120581
121450
|
state: true
|
|
120582
121451
|
}))),
|
|
120583
121452
|
isValidated: isSignedHydratedBlockWithHashMeta,
|
|
120584
|
-
onInvalid: ({ bundle: bundle3, result }) => {
|
|
120585
|
-
const errors = result;
|
|
121453
|
+
onInvalid: async ({ bundle: bundle3, item, result }) => {
|
|
121454
|
+
const errors = isSignedHydratedBlockWithHashMeta(result) ? [] : result;
|
|
120586
121455
|
this.logger?.info(`[SimpleMempoolRunner] prunePendingBlocks deleting block ${bundle3._hash} (validation: ${errors.at(0)?.message ?? "failed simple/full check"})`);
|
|
121456
|
+
await this.routeRejectedBlock(item, errors);
|
|
120587
121457
|
}
|
|
120588
121458
|
});
|
|
120589
121459
|
const pruneHashes = invalidBundleHashes(bundles, valid);
|
|
@@ -120619,7 +121489,12 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
120619
121489
|
}
|
|
120620
121490
|
while (batch.length > 0 && pruned < maxPrune && total < maxCheck) {
|
|
120621
121491
|
batches += 1;
|
|
120622
|
-
const transactionsAndBundles = await
|
|
121492
|
+
const transactionsAndBundles = await simpleTransactionValidationCheck(batch, {
|
|
121493
|
+
chainId: await this.chainContractViewer.chainId(),
|
|
121494
|
+
headNumber: await this.finalizationViewer.headNumber(),
|
|
121495
|
+
logger: this.logger,
|
|
121496
|
+
maxExpAhead: this.maxExpAhead
|
|
121497
|
+
});
|
|
120623
121498
|
const transactions = transactionsAndBundles.map(([t]) => t);
|
|
120624
121499
|
const bundles = transactionsAndBundles.map(([_, p]) => p);
|
|
120625
121500
|
const valid = transactions.map((t) => !!t);
|
|
@@ -120779,6 +121654,20 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
120779
121654
|
if (isDemotionAware(this._mempoolViewer)) return this._mempoolViewer.getEvictionPriorityOrder(bundleHashesOldestFirst);
|
|
120780
121655
|
return bundleHashesOldestFirst;
|
|
120781
121656
|
}
|
|
121657
|
+
async routeRejectedBlock(block, errors) {
|
|
121658
|
+
if (!this._deadLetterQueueRunner) return;
|
|
121659
|
+
const rejectionErrors = errors.map((e) => ({
|
|
121660
|
+
hash: e.hash ?? block[0]._hash,
|
|
121661
|
+
name: e.name ?? "BlockValidationError",
|
|
121662
|
+
message: String(e.message ?? e)
|
|
121663
|
+
}));
|
|
121664
|
+
await this._deadLetterQueueRunner.rejectBlock({
|
|
121665
|
+
schema: BlockRejectionSchema,
|
|
121666
|
+
block,
|
|
121667
|
+
errors: rejectionErrors,
|
|
121668
|
+
rejector: "mempool"
|
|
121669
|
+
});
|
|
121670
|
+
}
|
|
120782
121671
|
async routeRejectedTransaction(transaction, errors) {
|
|
120783
121672
|
if (!this._deadLetterQueueRunner) return;
|
|
120784
121673
|
const rejectionErrors = errors.map((e) => ({
|
|
@@ -120793,60 +121682,6 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
120793
121682
|
rejector: "mempool"
|
|
120794
121683
|
});
|
|
120795
121684
|
}
|
|
120796
|
-
async simpleBlockValidationCheck(payloads) {
|
|
120797
|
-
const headNumber = await this.finalizationViewer.headNumber();
|
|
120798
|
-
const chainId = await this.chainContractViewer.chainId();
|
|
120799
|
-
return (await Promise.all(payloads.map(async (p) => {
|
|
120800
|
-
return [isPayloadBundle(p) ? await bundledPayloadToHydratedBlock(p) : void 0, p];
|
|
120801
|
-
}))).map(([block, bundle3]) => {
|
|
120802
|
-
const blockCheckPassed = !!block;
|
|
120803
|
-
const chainIdPassed = blockCheckPassed ? block[0].chain === chainId : false;
|
|
120804
|
-
const blockNumberPassed = blockCheckPassed ? block[0].block > headNumber : false;
|
|
120805
|
-
const typeCheckPassed = blockCheckPassed ? isSignedHydratedBlockWithHashMeta(block) : false;
|
|
120806
|
-
const validationPassed = blockCheckPassed && chainIdPassed && blockNumberPassed && typeCheckPassed;
|
|
120807
|
-
const validatedBlock = validationPassed ? block : void 0;
|
|
120808
|
-
if (!validationPassed) {
|
|
120809
|
-
this.logger?.debug(`Pruning block bundle ${bundle3._hash} during simpleValidationCheck`);
|
|
120810
|
-
this.logger?.debug(` - chainId match: ${chainIdPassed}`);
|
|
120811
|
-
this.logger?.debug(` - blockNumber check: ${blockNumberPassed} [${headNumber}|${block?.[0].block}]`);
|
|
120812
|
-
this.logger?.debug(` - typeCheck: ${typeCheckPassed}`);
|
|
120813
|
-
this.logger?.debug(` - bundle hash: ${bundle3._hash}`);
|
|
120814
|
-
}
|
|
120815
|
-
return [validatedBlock, bundle3];
|
|
120816
|
-
});
|
|
120817
|
-
}
|
|
120818
|
-
async simpleTransactionValidationCheck(payloads) {
|
|
120819
|
-
const headNumber = await this.finalizationViewer.headNumber();
|
|
120820
|
-
const chainId = await this.chainContractViewer.chainId();
|
|
120821
|
-
const transactionBundles = await Promise.all(payloads.map(async (p) => {
|
|
120822
|
-
return [isPayloadBundle(p) ? await bundledPayloadToHydratedTransaction(p) : void 0, p];
|
|
120823
|
-
}));
|
|
120824
|
-
return await Promise.all(transactionBundles.map(async ([transaction, bundle3]) => {
|
|
120825
|
-
const transactionCheckPassed = !!transaction;
|
|
120826
|
-
const chainIdPassed = transactionCheckPassed ? transaction[0].chain === chainId : false;
|
|
120827
|
-
const expPassed = transactionCheckPassed ? transaction[0].exp > headNumber && transaction[0].exp <= headNumber + this.maxExpAhead : false;
|
|
120828
|
-
const typeCheckPassed = transactionCheckPassed ? isSignedHydratedTransactionWithHashMeta(transaction) : false;
|
|
120829
|
-
let opcodeCheckPassed = false;
|
|
120830
|
-
try {
|
|
120831
|
-
await validateTransactionsOpcodes(transaction ? [transaction] : []);
|
|
120832
|
-
opcodeCheckPassed = true;
|
|
120833
|
-
} catch (e) {
|
|
120834
|
-
this.logger?.debug(`Opcode validation failed for transaction ${bundle3._hash} during simpleValidationCheck`);
|
|
120835
|
-
this.logger?.debug(` - error: ${e.message}`);
|
|
120836
|
-
}
|
|
120837
|
-
const validationPassed = transactionCheckPassed && chainIdPassed && expPassed && typeCheckPassed && opcodeCheckPassed;
|
|
120838
|
-
const validatedTransaction = validationPassed ? transaction : void 0;
|
|
120839
|
-
if (!validationPassed) {
|
|
120840
|
-
this.logger?.debug(`Pruning block bundle ${bundle3._hash} during simpleValidationCheck`);
|
|
120841
|
-
this.logger?.debug(` - chainId match: ${chainIdPassed}`);
|
|
120842
|
-
this.logger?.debug(` - exp check: ${expPassed}`);
|
|
120843
|
-
this.logger?.debug(` - opcode check: ${opcodeCheckPassed}`);
|
|
120844
|
-
this.logger?.debug(` - typeCheck: ${typeCheckPassed}`);
|
|
120845
|
-
this.logger?.debug(` - bundle hash: ${bundle3._hash}`);
|
|
120846
|
-
}
|
|
120847
|
-
return [validatedTransaction, bundle3];
|
|
120848
|
-
}));
|
|
120849
|
-
}
|
|
120850
121685
|
async syncBlocksFrom(external) {
|
|
120851
121686
|
const externalBlocks = await external.pendingBlocks({ limit: this.syncLimit });
|
|
120852
121687
|
if (externalBlocks.length === 0) return;
|
|
@@ -120893,6 +121728,11 @@ __publicField$18(SimpleMempoolRunner, "monikers", [MempoolRunnerMoniker]);
|
|
|
120893
121728
|
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
120894
121729
|
__publicField$18(SimpleMempoolRunner, "surface", "node");
|
|
120895
121730
|
SimpleMempoolRunner = __decorateClass$18([creatableProvider()], SimpleMempoolRunner);
|
|
121731
|
+
async function resolveHashCursor(archivist, providedCursor) {
|
|
121732
|
+
if (!isHash(providedCursor)) return void 0;
|
|
121733
|
+
const [payload] = await archivist.get([providedCursor]);
|
|
121734
|
+
return isDefined$1(payload) ? payload._sequence : void 0;
|
|
121735
|
+
}
|
|
120896
121736
|
var SimpleMempoolViewerOptionsZod = object$3({
|
|
120897
121737
|
demotionThreshold: number$1().default(3),
|
|
120898
121738
|
handoutStatsTtlBlocks: number$1().default(1e3),
|
|
@@ -120960,11 +121800,7 @@ var SimpleMempoolViewer = class extends AbstractCreatableProvider {
|
|
|
120960
121800
|
}
|
|
120961
121801
|
/** Returns the pending blocks result exposed by this provider. */
|
|
120962
121802
|
async pendingBlocks({ cursor: providedCursor } = {}) {
|
|
120963
|
-
|
|
120964
|
-
if (isHash(providedCursor)) {
|
|
120965
|
-
const [p] = await this.pendingBlocksArchivist.get([providedCursor]);
|
|
120966
|
-
if (isDefined$1(p)) cursor = p._sequence;
|
|
120967
|
-
}
|
|
121803
|
+
const cursor = await resolveHashCursor(this.pendingBlocksArchivist, providedCursor);
|
|
120968
121804
|
const filteredBundles = (await this.pendingBlocksArchivist.next({
|
|
120969
121805
|
order: "desc",
|
|
120970
121806
|
limit: 100,
|
|
@@ -120974,11 +121810,8 @@ var SimpleMempoolViewer = class extends AbstractCreatableProvider {
|
|
|
120974
121810
|
}
|
|
120975
121811
|
/** Returns the pending transactions result exposed by this provider. */
|
|
120976
121812
|
async pendingTransactions({ cursor: providedCursor, limit = 100 } = {}) {
|
|
120977
|
-
|
|
120978
|
-
|
|
120979
|
-
const [p] = await this.pendingTransactionsArchivist.get([providedCursor]);
|
|
120980
|
-
if (isDefined$1(p)) cursor = p._sequence;
|
|
120981
|
-
}
|
|
121813
|
+
await this.windowedBlockViewer.sync?.();
|
|
121814
|
+
const cursor = await resolveHashCursor(this.pendingTransactionsArchivist, providedCursor);
|
|
120982
121815
|
this.logger?.debug(`Fetching pending transactions from cursor: ${cursor}`);
|
|
120983
121816
|
const bundles = await this.pendingTransactionsArchivist.next({
|
|
120984
121817
|
order: "asc",
|
|
@@ -122104,7 +122937,9 @@ var SimpleWindowedBlockViewer = class extends AbstractCreatableProvider {
|
|
|
122104
122937
|
_blockNumberMap;
|
|
122105
122938
|
_blockViewer;
|
|
122106
122939
|
_chain = [];
|
|
122940
|
+
_inFlightSync = null;
|
|
122107
122941
|
_options;
|
|
122942
|
+
_queuedSync = null;
|
|
122108
122943
|
_syncMutex = new Mutex();
|
|
122109
122944
|
_timerId = null;
|
|
122110
122945
|
_transactionHashMap;
|
|
@@ -122212,6 +123047,32 @@ var SimpleWindowedBlockViewer = class extends AbstractCreatableProvider {
|
|
|
122212
123047
|
await super.stopHandler();
|
|
122213
123048
|
this.stopPoll();
|
|
122214
123049
|
}
|
|
123050
|
+
/**
|
|
123051
|
+
* Synchronizes the in-memory window with the backing block viewer immediately, waiting for any
|
|
123052
|
+
* in-flight sync to complete first. Callers whose correctness depends on seeing the latest
|
|
123053
|
+
* finalized blocks (e.g. mempool inclusion checks) must call this rather than rely on the
|
|
123054
|
+
* background poll, whose interval is far coarser than block finalization.
|
|
123055
|
+
*
|
|
123056
|
+
* Concurrent callers are coalesced: a caller arriving while a sync runs joins one shared
|
|
123057
|
+
* follow-up pass (which starts after the running pass and therefore observes every block
|
|
123058
|
+
* finalized before the caller arrived) instead of enqueuing its own. Without this, N
|
|
123059
|
+
* concurrent callers — the handout path is reachable per producer tick and over RPC — would
|
|
123060
|
+
* execute N sequential backing reads behind the sync mutex.
|
|
123061
|
+
*/
|
|
123062
|
+
async sync() {
|
|
123063
|
+
if (this._inFlightSync === null) {
|
|
123064
|
+
const run = this.runSync().finally(() => {
|
|
123065
|
+
if (this._inFlightSync === run) this._inFlightSync = null;
|
|
123066
|
+
});
|
|
123067
|
+
this._inFlightSync = run;
|
|
123068
|
+
return await run;
|
|
123069
|
+
}
|
|
123070
|
+
this._queuedSync ??= this._inFlightSync.then(() => {
|
|
123071
|
+
this._queuedSync = null;
|
|
123072
|
+
return this.sync();
|
|
123073
|
+
});
|
|
123074
|
+
return await this._queuedSync;
|
|
123075
|
+
}
|
|
122215
123076
|
addBlock(block) {
|
|
122216
123077
|
this._chain.push(block);
|
|
122217
123078
|
this._blockHashMap.set(block[0]._hash, block);
|
|
@@ -122225,18 +123086,8 @@ var SimpleWindowedBlockViewer = class extends AbstractCreatableProvider {
|
|
|
122225
123086
|
for (const tx of transactionsFromHydratedBlock(removedBlock)) this._transactionHashMap.delete(tx._hash);
|
|
122226
123087
|
}
|
|
122227
123088
|
}
|
|
122228
|
-
|
|
122229
|
-
this.
|
|
122230
|
-
this.sync();
|
|
122231
|
-
}, this.syncInterval);
|
|
122232
|
-
}
|
|
122233
|
-
stopPoll() {
|
|
122234
|
-
if (this._timerId) clearInterval(this._timerId);
|
|
122235
|
-
this._timerId = null;
|
|
122236
|
-
}
|
|
122237
|
-
async sync() {
|
|
122238
|
-
if (this._syncMutex.isLocked()) return;
|
|
122239
|
-
return await this._syncMutex.runExclusive(async () => {
|
|
123089
|
+
async runSync() {
|
|
123090
|
+
await this._syncMutex.runExclusive(async () => {
|
|
122240
123091
|
try {
|
|
122241
123092
|
let cursor = await this._blockViewer.currentBlock();
|
|
122242
123093
|
const previousHead = this._chain.length > 0 ? await this.currentBlockHash() : null;
|
|
@@ -122252,6 +123103,19 @@ var SimpleWindowedBlockViewer = class extends AbstractCreatableProvider {
|
|
|
122252
123103
|
}
|
|
122253
123104
|
});
|
|
122254
123105
|
}
|
|
123106
|
+
startPoll() {
|
|
123107
|
+
this._timerId = setInterval(() => {
|
|
123108
|
+
this.syncIfIdle();
|
|
123109
|
+
}, this.syncInterval);
|
|
123110
|
+
}
|
|
123111
|
+
stopPoll() {
|
|
123112
|
+
if (this._timerId) clearInterval(this._timerId);
|
|
123113
|
+
this._timerId = null;
|
|
123114
|
+
}
|
|
123115
|
+
async syncIfIdle() {
|
|
123116
|
+
if (this._syncMutex.isLocked()) return;
|
|
123117
|
+
await this.sync();
|
|
123118
|
+
}
|
|
122255
123119
|
};
|
|
122256
123120
|
/** Connection kinds supported by this provider. */
|
|
122257
123121
|
__publicField$18(SimpleWindowedBlockViewer, "connectionTypes", [
|
|
@@ -123269,7 +124133,7 @@ function getOriginalId(rawRequest) {
|
|
|
123269
124133
|
return [void 0, false];
|
|
123270
124134
|
}
|
|
123271
124135
|
//#endregion
|
|
123272
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
124136
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_a771cefd6e9eb69efc5a95a989caf2a3/node_modules/@xyo-network/xl1-sdk/dist/neutral/rpc.mjs
|
|
123273
124137
|
var __defProp$17 = Object.defineProperty;
|
|
123274
124138
|
var __getOwnPropDesc$17 = Object.getOwnPropertyDescriptor;
|
|
123275
124139
|
var __defNormalProp$17 = (obj, key, value) => key in obj ? __defProp$17(obj, key, {
|
|
@@ -224588,7 +225452,7 @@ var BaseMongoSdk = class {
|
|
|
224588
225452
|
}
|
|
224589
225453
|
};
|
|
224590
225454
|
//#endregion
|
|
224591
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-driver-mongodb@5.
|
|
225455
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-driver-mongodb@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zo_c6dcb1b9a06ee930febaf04848b7a277/node_modules/@xyo-network/xl1-driver-mongodb/dist/neutral/index.mjs
|
|
224592
225456
|
var __defProp$15 = Object.defineProperty;
|
|
224593
225457
|
var __getOwnPropDesc$15 = Object.getOwnPropertyDescriptor;
|
|
224594
225458
|
var __defNormalProp$15 = (obj, key, value) => key in obj ? __defProp$15(obj, key, {
|
|
@@ -227822,7 +228686,12 @@ var ChainFinalizer = class extends Base {
|
|
|
227822
228686
|
this.windowedFinalizedChain = [...this.windowedFinalizedChain, ...chain].slice(-this.maxWindowSize);
|
|
227823
228687
|
}
|
|
227824
228688
|
};
|
|
227825
|
-
var ChainHeadSelector = class extends ChainFinalizer {
|
|
228689
|
+
var ChainHeadSelector = class _ChainHeadSelector extends ChainFinalizer {
|
|
228690
|
+
/**
|
|
228691
|
+
* How long uncle selection may go without a single qualifying candidate (while candidates are
|
|
228692
|
+
* present) before a warning is emitted; also the minimum interval between repeat warnings.
|
|
228693
|
+
*/
|
|
228694
|
+
static SilentUncleRejectionWarnAfterMs = 5e3;
|
|
227826
228695
|
admission;
|
|
227827
228696
|
allowedProducers;
|
|
227828
228697
|
backoffMs;
|
|
@@ -227848,6 +228717,7 @@ var ChainHeadSelector = class extends ChainFinalizer {
|
|
|
227848
228717
|
const proposedBlocks = await this.admit(allProposedBlocks, allowed);
|
|
227849
228718
|
this.windowedFinalizedChain = await getWindowedChain$1(this.context, this.blockViewer, this.maxWindowSize, this.windowedFinalizedChain);
|
|
227850
228719
|
const uncles = findUncles$1(this.context, this.windowedFinalizedChain, proposedBlocks);
|
|
228720
|
+
this.reportSilentUncleRejections(proposedBlocks, uncles.length);
|
|
227851
228721
|
return findBestUncle(this.windowedFinalizedChain, uncles, {
|
|
227852
228722
|
backoffMs: this.backoffMs,
|
|
227853
228723
|
minCandidates: this.minCandidates
|
|
@@ -227918,6 +228788,32 @@ var ChainHeadSelector = class extends ChainFinalizer {
|
|
|
227918
228788
|
});
|
|
227919
228789
|
} catch {}
|
|
227920
228790
|
}
|
|
228791
|
+
/**
|
|
228792
|
+
* Surfaces the otherwise-silent case where candidates are continuously present but none
|
|
228793
|
+
* qualifies as an uncle — without this, the only signal of a stalled selector is an endless
|
|
228794
|
+
* "No new blocks found N to N" while rejected candidates cycle through the pool. Zero-qualify
|
|
228795
|
+
* moments are routine in healthy operation (a just-finalized candidate lingers until the pool
|
|
228796
|
+
* GC), so this warns only after candidates have been failing continuously for
|
|
228797
|
+
* SilentUncleRejectionWarnAfterMs — an idle (candidate-free) tick resets the clock — then
|
|
228798
|
+
* rate-limits to one warn per that interval. State lives in context.singletons because a
|
|
228799
|
+
* fresh ChainHeadSelector is constructed on every finalization tick.
|
|
228800
|
+
*/
|
|
228801
|
+
reportSilentUncleRejections(proposedBlocks, uncleCount) {
|
|
228802
|
+
const singletons = this.context.singletons;
|
|
228803
|
+
const stateKey = "ChainHeadSelector:uncleSelectionHealth";
|
|
228804
|
+
const now = Date.now();
|
|
228805
|
+
const state = singletons[stateKey] ?? { lastWarnedAt: 0 };
|
|
228806
|
+
singletons[stateKey] = state;
|
|
228807
|
+
if (uncleCount > 0 || proposedBlocks.length === 0) {
|
|
228808
|
+
state.unqualifiedSince = void 0;
|
|
228809
|
+
return;
|
|
228810
|
+
}
|
|
228811
|
+
state.unqualifiedSince ??= now;
|
|
228812
|
+
if (now - state.unqualifiedSince < _ChainHeadSelector.SilentUncleRejectionWarnAfterMs) return;
|
|
228813
|
+
if (now - state.lastWarnedAt < _ChainHeadSelector.SilentUncleRejectionWarnAfterMs) return;
|
|
228814
|
+
state.lastWarnedAt = now;
|
|
228815
|
+
this.context.logger?.warn(`findBestHead: candidates have failed uncle qualification continuously for ${now - state.unqualifiedSince}ms \u2014 ${proposedBlocks.length} pending candidate(s): ` + proposedBlocks.map((b) => `${b[0].block} [${b[0]._hash}]`).join(", "));
|
|
228816
|
+
}
|
|
227921
228817
|
};
|
|
227922
228818
|
asSchema$1("network.xyo.chain.summary.producers", true);
|
|
227923
228819
|
asSchema$1("network.xyo.chain.summary.staked.intent", true);
|
|
@@ -228072,7 +228968,7 @@ var STAKE_EVENT_NAMES$1 = /* @__PURE__ */ new Set([
|
|
|
228072
228968
|
"StakeRemoved",
|
|
228073
228969
|
"StakeWithdrawn"
|
|
228074
228970
|
]);
|
|
228075
|
-
var DEFAULT_HEAD_POLL_INTERVAL_MS = 5e3;
|
|
228971
|
+
var DEFAULT_HEAD_POLL_INTERVAL_MS$1 = 5e3;
|
|
228076
228972
|
var MIN_HEAD_POLL_INTERVAL_MS = 5e3;
|
|
228077
228973
|
var RestStakeEventsViewerOptionsZod = object$3({ headPollIntervalMs: number$1().optional() });
|
|
228078
228974
|
var RestStakeEventsViewer = class extends AbstractCreatableProvider$1 {
|
|
@@ -228080,7 +228976,7 @@ var RestStakeEventsViewer = class extends AbstractCreatableProvider$1 {
|
|
|
228080
228976
|
completeFrames = /* @__PURE__ */ new Map();
|
|
228081
228977
|
contractInterface = new Interface(IAddressStakingEvents__factory2.abi);
|
|
228082
228978
|
currentHead;
|
|
228083
|
-
headPollIntervalMs = DEFAULT_HEAD_POLL_INTERVAL_MS;
|
|
228979
|
+
headPollIntervalMs = DEFAULT_HEAD_POLL_INTERVAL_MS$1;
|
|
228084
228980
|
lastSuccessfulSyncAt;
|
|
228085
228981
|
manifestPromise;
|
|
228086
228982
|
positionCountCheckpoints = [];
|
|
@@ -228104,7 +229000,7 @@ var RestStakeEventsViewer = class extends AbstractCreatableProvider$1 {
|
|
|
228104
229000
|
RestStakeEventsViewer.requireBoundConnection(this.config);
|
|
228105
229001
|
const { headPollIntervalMs } = RestStakeEventsViewerOptionsZod.parse(this.config.options);
|
|
228106
229002
|
if (headPollIntervalMs !== void 0) assertEx$1(headPollIntervalMs >= MIN_HEAD_POLL_INTERVAL_MS, () => `headPollIntervalMs must be at least ${MIN_HEAD_POLL_INTERVAL_MS}ms`);
|
|
228107
|
-
this.headPollIntervalMs = headPollIntervalMs ?? DEFAULT_HEAD_POLL_INTERVAL_MS;
|
|
229003
|
+
this.headPollIntervalMs = headPollIntervalMs ?? DEFAULT_HEAD_POLL_INTERVAL_MS$1;
|
|
228108
229004
|
}
|
|
228109
229005
|
async positionCount(range) {
|
|
228110
229006
|
await this.sync();
|
|
@@ -230079,7 +230975,7 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230079
230975
|
moniker = SimpleBlockRunner.defaultMoniker;
|
|
230080
230976
|
_blockRewardDiviner;
|
|
230081
230977
|
_deadLetterQueueRunner;
|
|
230082
|
-
_excludedTransactionHashes = /* @__PURE__ */ new
|
|
230978
|
+
_excludedTransactionHashes = /* @__PURE__ */ new Map();
|
|
230083
230979
|
_lastRedeclarationBlock;
|
|
230084
230980
|
_rejectedTransactionsArchivist;
|
|
230085
230981
|
_account;
|
|
@@ -230089,6 +230985,7 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230089
230985
|
_blockValidationViewer;
|
|
230090
230986
|
_chainParamsViewer;
|
|
230091
230987
|
_finalizationViewer;
|
|
230988
|
+
_lastRejectedBuildAt = 0;
|
|
230092
230989
|
/** Cache of the last candidate this runner signed; the mempool is the source of truth. */
|
|
230093
230990
|
_lastSignedCandidate;
|
|
230094
230991
|
_mempoolViewer;
|
|
@@ -230203,10 +231100,13 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230203
231100
|
const shouldValidateBalances = validateBalances ?? this.params.validateBalances ?? true;
|
|
230204
231101
|
return await this.spanAsync("proposeNextValidBlock", async () => {
|
|
230205
231102
|
try {
|
|
231103
|
+
if (this.isWithinRejectedBuildBackoff(force)) return;
|
|
230206
231104
|
const { block: previousBlock } = assertEx$1(asBlockBoundWitness$1(head), () => "Invalid head block");
|
|
230207
231105
|
const nextBlock = previousBlock + 1;
|
|
230208
231106
|
const chainId = await this.finalizationViewer.chainId();
|
|
230209
|
-
const
|
|
231107
|
+
const pendingTransactionsRaw = await this.mempoolViewer.pendingTransactions({ limit: SimpleBlockRunner.DefaultBlockSize });
|
|
231108
|
+
this.evictStaleExclusions(previousBlock);
|
|
231109
|
+
const pendingTransactions = pendingTransactionsRaw.filter((tx) => !this._excludedTransactionHashes.has(tx[0]._hash));
|
|
230210
231110
|
const nextBlockTransactions = await this.rejectWrongChainTransactions(pendingTransactions, chainId);
|
|
230211
231111
|
this.logger?.log(`Pending Tx Count ${nextBlockTransactions.length}`);
|
|
230212
231112
|
const nonTxPayloads = [];
|
|
@@ -230216,10 +231116,7 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230216
231116
|
const rewardTransferPayloads = await this.getBlockRewardTransfers(nextBlock);
|
|
230217
231117
|
nonTxPayloads.push(...rewardTransferPayloads);
|
|
230218
231118
|
const transactionTransfers = await generateTransactionFeeTransfers(this.address, nextBlockTransactions);
|
|
230219
|
-
const timeStart = Date.now();
|
|
230220
231119
|
const timePayload = await this.generateTimePayload();
|
|
230221
|
-
const timeDuration = Date.now() - timeStart;
|
|
230222
|
-
if (timeDuration > 100) this.logger?.warn(`[Slow] Generated time payload in ${timeDuration}ms`);
|
|
230223
231120
|
const [initialFundedTransactions, initialFundedTransfers] = await this.filterByFunded(head, nextBlockTransactions, transactionTransfers, shouldValidateBalances);
|
|
230224
231121
|
const stepRewardPoolBalance = (await this.accountBalanceViewer.accountBalances([XYO_STEP_REWARD_ADDRESS]))[String(XYO_STEP_REWARD_ADDRESS)];
|
|
230225
231122
|
const { block: proposedBlock, errors: proposedErrors } = await this.runBuildValidateRetryLoop({
|
|
@@ -230231,14 +231128,31 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230231
231128
|
initialFundedTransactions,
|
|
230232
231129
|
initialFundedTransfers
|
|
230233
231130
|
});
|
|
230234
|
-
|
|
230235
|
-
if (proposedBlock !== void 0) await this.rejectExhaustedBlock(proposedBlock, proposedErrors);
|
|
231131
|
+
return await this.commitProposedBlock(proposedBlock, proposedErrors);
|
|
230236
231132
|
} catch (error) {
|
|
230237
231133
|
this.logger?.error(`Error proposing next valid block: ${error.message}`);
|
|
230238
231134
|
throw error;
|
|
230239
231135
|
}
|
|
230240
231136
|
}, this.context);
|
|
230241
231137
|
}
|
|
231138
|
+
addTransferOutflow(outflow, payload) {
|
|
231139
|
+
let result = outflow;
|
|
231140
|
+
for (const [to, amount] of Object.entries(payload.transfers)) {
|
|
231141
|
+
if (to === payload.from) continue;
|
|
231142
|
+
result += hexToBigInt(amount ?? "00");
|
|
231143
|
+
}
|
|
231144
|
+
return result;
|
|
231145
|
+
}
|
|
231146
|
+
async commitProposedBlock(proposedBlock, proposedErrors) {
|
|
231147
|
+
if (proposedErrors.length === 0 && isSignedHydratedBlockWithHashMeta$1(proposedBlock)) {
|
|
231148
|
+
this._lastRejectedBuildAt = 0;
|
|
231149
|
+
return proposedBlock;
|
|
231150
|
+
}
|
|
231151
|
+
if (proposedBlock !== void 0) {
|
|
231152
|
+
this._lastRejectedBuildAt = Date.now();
|
|
231153
|
+
await this.rejectExhaustedBlock(proposedBlock, proposedErrors);
|
|
231154
|
+
}
|
|
231155
|
+
}
|
|
230242
231156
|
/**
|
|
230243
231157
|
* Compute the cumulative outflow a single tx would charge to its `from`
|
|
230244
231158
|
* address, using the same rule as `BlockCumulativeBalanceValidator`:
|
|
@@ -230248,14 +231162,6 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230248
231162
|
* reject, which would otherwise wedge the chain because the producer's
|
|
230249
231163
|
* `_lastProducedBlock` cache mutes retries.
|
|
230250
231164
|
*/
|
|
230251
|
-
addTransferOutflow(outflow, payload) {
|
|
230252
|
-
let result = outflow;
|
|
230253
|
-
for (const [to, amount] of Object.entries(payload.transfers)) {
|
|
230254
|
-
if (to === payload.from) continue;
|
|
230255
|
-
result += hexToBigInt(amount ?? "00");
|
|
230256
|
-
}
|
|
230257
|
-
return result;
|
|
230258
|
-
}
|
|
230259
231165
|
computeTransactionOutflow(tx) {
|
|
230260
231166
|
const [bw, payloads] = tx;
|
|
230261
231167
|
const { base, gasLimit, priority } = bw.fees;
|
|
@@ -230269,6 +231175,14 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230269
231175
|
}
|
|
230270
231176
|
return outflow;
|
|
230271
231177
|
}
|
|
231178
|
+
/**
|
|
231179
|
+
* Drops head-relative ('block-balance') exclusions once the head has advanced past the height
|
|
231180
|
+
* they were recorded at — the sender's funding is re-evaluated by filterByFunded at the new
|
|
231181
|
+
* head. Deterministic ('tx-invalid') exclusions are kept for the process lifetime.
|
|
231182
|
+
*/
|
|
231183
|
+
evictStaleExclusions(headBlock) {
|
|
231184
|
+
for (const [hash, entry] of this._excludedTransactionHashes) if (entry.reason === "block-balance" && headBlock > entry.excludedAtBlock) this._excludedTransactionHashes.delete(hash);
|
|
231185
|
+
}
|
|
230272
231186
|
async filterByFunded(head, txs, transfers, validateBalances = false) {
|
|
230273
231187
|
const fundedTransfers = [];
|
|
230274
231188
|
const fundedTransactions = [];
|
|
@@ -230298,7 +231212,11 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230298
231212
|
return [fundedTransactions, fundedTransfers];
|
|
230299
231213
|
}
|
|
230300
231214
|
async generateTimePayload() {
|
|
230301
|
-
|
|
231215
|
+
const timeStart = Date.now();
|
|
231216
|
+
const timePayload = await this.timeSyncViewer.currentTimePayload();
|
|
231217
|
+
const timeDuration = Date.now() - timeStart;
|
|
231218
|
+
if (timeDuration > 100) this.logger?.warn(`[Slow] Generated time payload in ${timeDuration}ms`);
|
|
231219
|
+
return timePayload;
|
|
230302
231220
|
}
|
|
230303
231221
|
/**
|
|
230304
231222
|
* Check if a heartbeat block is required based on network activity.
|
|
@@ -230310,6 +231228,11 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230310
231228
|
if (isDefined$1(epoch) && Date.now() - epoch > this.heartbeatInterval) return true;
|
|
230311
231229
|
return false;
|
|
230312
231230
|
}
|
|
231231
|
+
isWithinRejectedBuildBackoff(force) {
|
|
231232
|
+
if (force || Date.now() - this._lastRejectedBuildAt >= SimpleBlockRunner.RejectedBuildBackoffMs) return false;
|
|
231233
|
+
this.logger?.debug("Skipping block production during rejected-build backoff");
|
|
231234
|
+
return true;
|
|
231235
|
+
}
|
|
230313
231236
|
/**
|
|
230314
231237
|
* The hash of this producer's own earlier candidate at the same height and parent, if any.
|
|
230315
231238
|
*
|
|
@@ -230404,7 +231327,11 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230404
231327
|
];
|
|
230405
231328
|
this.logger?.info(`Building block ${head.block + 1}${attempt > 0 ? ` (retry ${attempt})` : ""}`);
|
|
230406
231329
|
lastBlock = await buildNextBlock(head, candidateTransactions, blockPayloads, [this.account], XYO_STEP_REWARD_ADDRESS, stepRewardPoolBalance, void 0, chainId, supersedes);
|
|
230407
|
-
const validated = await this.blockValidationViewer.validateBlock(lastBlock, {
|
|
231330
|
+
const validated = await this.blockValidationViewer.validateBlock(lastBlock, {
|
|
231331
|
+
value: true,
|
|
231332
|
+
state: true,
|
|
231333
|
+
head: head._hash
|
|
231334
|
+
});
|
|
230408
231335
|
if (isSignedHydratedBlockWithHashMeta$1(validated)) {
|
|
230409
231336
|
this._lastSignedCandidate = {
|
|
230410
231337
|
block: validated[0].block,
|
|
@@ -230423,7 +231350,10 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230423
231350
|
errors: validated
|
|
230424
231351
|
});
|
|
230425
231352
|
if (offendingHashes.length === 0 || reason === "unknown") break;
|
|
230426
|
-
for (const offendingHash of offendingHashes) this._excludedTransactionHashes.
|
|
231353
|
+
for (const offendingHash of offendingHashes) this._excludedTransactionHashes.set(offendingHash, {
|
|
231354
|
+
excludedAtBlock: head.block,
|
|
231355
|
+
reason
|
|
231356
|
+
});
|
|
230427
231357
|
const offendingSet = new Set(offendingHashes);
|
|
230428
231358
|
candidateTransactions = candidateTransactions.filter((tx) => !offendingSet.has(tx[0]._hash));
|
|
230429
231359
|
const remainingFromAddresses = new Set(candidateTransactions.map((tx) => tx[0].from));
|
|
@@ -230436,6 +231366,12 @@ var SimpleBlockRunner = class extends AbstractCreatableProvider$1 {
|
|
|
230436
231366
|
};
|
|
230437
231367
|
}
|
|
230438
231368
|
};
|
|
231369
|
+
/**
|
|
231370
|
+
* Minimum time between build attempts after a fully-rejected build (validation exhausted with
|
|
231371
|
+
* no attributable transaction to exclude). Such a build fails identically until external state
|
|
231372
|
+
* changes, so retrying at the production tick rate only churns build → validate → DLQ.
|
|
231373
|
+
*/
|
|
231374
|
+
__publicField$11(SimpleBlockRunner, "RejectedBuildBackoffMs", 1e3);
|
|
230439
231375
|
__publicField$11(SimpleBlockRunner, "connectionTypes", [
|
|
230440
231376
|
"lmdb",
|
|
230441
231377
|
"mongo",
|
|
@@ -232388,6 +233324,8 @@ var ProducerActor = class extends ChainActor {
|
|
|
232388
233324
|
_blockViewer;
|
|
232389
233325
|
_chainContractViewer;
|
|
232390
233326
|
_chainId;
|
|
233327
|
+
_fastCandidateRecoveriesForHead = 0;
|
|
233328
|
+
_lastCandidateGoneCheckTime = 0;
|
|
232391
233329
|
_lastHeadChangeTime;
|
|
232392
233330
|
_lastHeadHash;
|
|
232393
233331
|
_mempoolRunner;
|
|
@@ -232453,6 +233391,8 @@ var ProducerActor = class extends ChainActor {
|
|
|
232453
233391
|
this._lastProducedBlock = void 0;
|
|
232454
233392
|
this._lastHeadHash = void 0;
|
|
232455
233393
|
this._lastHeadChangeTime = void 0;
|
|
233394
|
+
this._fastCandidateRecoveriesForHead = 0;
|
|
233395
|
+
this._lastCandidateGoneCheckTime = 0;
|
|
232456
233396
|
this.registerTimer("BlockProductionTimer", async () => {
|
|
232457
233397
|
await this.produceBlock();
|
|
232458
233398
|
}, 2e3, this.blockProductionCheckInterval);
|
|
@@ -232463,6 +233403,25 @@ var ProducerActor = class extends ChainActor {
|
|
|
232463
233403
|
calculateBlocksUntilProducerDeclarationExpiration(currentBlock) {
|
|
232464
233404
|
return (this._lastRedeclarationIntent?.exp ?? currentBlock) - currentBlock;
|
|
232465
233405
|
}
|
|
233406
|
+
/**
|
|
233407
|
+
* Whether the last produced candidate has vanished from the pending-block pool while the head
|
|
233408
|
+
* has not advanced — i.e. the mempool pruned it after downstream validation rejected it. The
|
|
233409
|
+
* probe runs at most once per CandidateGoneCheckIntervalMs while a candidate stands on an
|
|
233410
|
+
* unchanged head (one pendingBlocks read per probe); only POSITIVE recoveries — probes that
|
|
233411
|
+
* find the candidate gone — are capped at MaxFastCandidateRecoveriesPerHead per head, so a
|
|
233412
|
+
* persistently-rejected producer backs off to the stale-head resubmission threshold instead of
|
|
233413
|
+
* churning rebuilds forever.
|
|
233414
|
+
*/
|
|
233415
|
+
async lastCandidateDropped(now) {
|
|
233416
|
+
const lastProduced = this._lastProducedBlock;
|
|
233417
|
+
if (isUndefined$1(lastProduced)) return false;
|
|
233418
|
+
if (this._fastCandidateRecoveriesForHead >= ProducerActor.MaxFastCandidateRecoveriesPerHead) return false;
|
|
233419
|
+
if (now - this._lastCandidateGoneCheckTime < ProducerActor.CandidateGoneCheckIntervalMs) return false;
|
|
233420
|
+
this._lastCandidateGoneCheckTime = now;
|
|
233421
|
+
const pendingBlocks = await this.mempoolViewer.pendingBlocks();
|
|
233422
|
+
if (pendingBlocks.some((candidate) => candidate[0]._hash === lastProduced[0]._hash)) return false;
|
|
233423
|
+
return pendingBlocks.length < ProducerActor.CandidateGoneScanLimit;
|
|
233424
|
+
}
|
|
232466
233425
|
async produceBlock() {
|
|
232467
233426
|
this._producerActorBlockProductionChecks.add(1, this._metricAttributes);
|
|
232468
233427
|
await this.spanAsync("produceBlock", async () => {
|
|
@@ -232470,40 +233429,7 @@ var ProducerActor = class extends ChainActor {
|
|
|
232470
233429
|
this.logger?.debug("Skipping block production, previous production still in progress");
|
|
232471
233430
|
return;
|
|
232472
233431
|
}
|
|
232473
|
-
await this._produceBlockMutex.runExclusive(
|
|
232474
|
-
const [head] = await this.blockViewer.currentBlock();
|
|
232475
|
-
const headHash = head._hash;
|
|
232476
|
-
const currentTime = Date.now();
|
|
232477
|
-
if (this._lastHeadHash !== headHash) {
|
|
232478
|
-
const lastHeadHashHex = isDefined$1(this._lastHeadHash) ? `0x${this._lastHeadHash}` : "undefined";
|
|
232479
|
-
const currentHeadHashHex = `0x${headHash}`;
|
|
232480
|
-
this.logger?.log(`Found updated head ${lastHeadHashHex} -> ${currentHeadHashHex}`);
|
|
232481
|
-
this._lastHeadHash = headHash;
|
|
232482
|
-
this._lastHeadChangeTime = currentTime;
|
|
232483
|
-
}
|
|
232484
|
-
const timeSinceHeadChange = isDefined$1(this._lastHeadChangeTime) ? currentTime - this._lastHeadChangeTime : 0;
|
|
232485
|
-
const shouldSubmit = this._lastProducedBlock?.[0].previous !== headHash;
|
|
232486
|
-
const shouldResubmit = timeSinceHeadChange > this.headResubmissionThreshold;
|
|
232487
|
-
if (!(shouldSubmit || shouldResubmit)) {
|
|
232488
|
-
this.logger?.debug("No block submission required at this time.");
|
|
232489
|
-
return;
|
|
232490
|
-
}
|
|
232491
|
-
if (shouldResubmit) {
|
|
232492
|
-
this.logger?.log(`Resubmitting block due to stale head. Head ${toFormattedBlockReference(head)} unchanged for ${timeSinceHeadChange}ms`);
|
|
232493
|
-
this._lastHeadChangeTime = currentTime;
|
|
232494
|
-
}
|
|
232495
|
-
this._producerActorBlockProductionAttempts.add(1, this._metricAttributes);
|
|
232496
|
-
const nextBlock = await this.blockRunner.produceNextBlock(head);
|
|
232497
|
-
if (nextBlock) {
|
|
232498
|
-
const displayBlockNumber = toFormattedBlockReference(nextBlock[0]);
|
|
232499
|
-
this.logger?.log("Produced block:", displayBlockNumber);
|
|
232500
|
-
this._producerActorBlocksProduced.add(1, this._metricAttributes);
|
|
232501
|
-
if ((await this.mempoolRunner.submitBlocks([nextBlock])).length === 0) this.logger?.error(`Submit dropped block ${displayBlockNumber} silently \u2014 archivist accepted 0 of 1 (hash ${nextBlock[0]._hash})`);
|
|
232502
|
-
else this.logger?.log("Published block:", displayBlockNumber);
|
|
232503
|
-
this._producerActorBlocksPublished.add(1, this._metricAttributes);
|
|
232504
|
-
this._lastProducedBlock = nextBlock;
|
|
232505
|
-
} else this.logger?.log("No block produced for submission.");
|
|
232506
|
-
});
|
|
233432
|
+
await this._produceBlockMutex.runExclusive(() => this.produceBlockExclusive());
|
|
232507
233433
|
}, {
|
|
232508
233434
|
...this.context,
|
|
232509
233435
|
timeBudgetLimit: 1e3
|
|
@@ -232568,8 +233494,73 @@ var ProducerActor = class extends ChainActor {
|
|
|
232568
233494
|
}
|
|
232569
233495
|
return true;
|
|
232570
233496
|
}
|
|
233497
|
+
async produceBlockExclusive() {
|
|
233498
|
+
const [head] = await this.blockViewer.currentBlock();
|
|
233499
|
+
const headHash = head._hash;
|
|
233500
|
+
const currentTime = Date.now();
|
|
233501
|
+
this.recordHeadChange(headHash, currentTime);
|
|
233502
|
+
const timeSinceHeadChange = isDefined$1(this._lastHeadChangeTime) ? currentTime - this._lastHeadChangeTime : 0;
|
|
233503
|
+
const shouldSubmit = this._lastProducedBlock?.[0].previous !== headHash;
|
|
233504
|
+
const shouldResubmit = timeSinceHeadChange > this.headResubmissionThreshold;
|
|
233505
|
+
const shouldRecoverDroppedCandidate = !shouldSubmit && !shouldResubmit && await this.lastCandidateDropped(currentTime);
|
|
233506
|
+
if (!(shouldSubmit || shouldResubmit || shouldRecoverDroppedCandidate)) {
|
|
233507
|
+
this.logger?.debug("No block submission required at this time.");
|
|
233508
|
+
return;
|
|
233509
|
+
}
|
|
233510
|
+
if (shouldResubmit) {
|
|
233511
|
+
this.logger?.log(`Resubmitting block due to stale head. Head ${toFormattedBlockReference(head)} unchanged for ${timeSinceHeadChange}ms`);
|
|
233512
|
+
this._lastHeadChangeTime = currentTime;
|
|
233513
|
+
}
|
|
233514
|
+
if (shouldRecoverDroppedCandidate) this.recoverDroppedCandidate();
|
|
233515
|
+
await this.publishNextBlock(head, currentTime);
|
|
233516
|
+
}
|
|
233517
|
+
async publishNextBlock(head, currentTime) {
|
|
233518
|
+
this._producerActorBlockProductionAttempts.add(1, this._metricAttributes);
|
|
233519
|
+
const nextBlock = await this.blockRunner.produceNextBlock(head);
|
|
233520
|
+
if (!nextBlock) {
|
|
233521
|
+
this.logger?.log("No block produced for submission.");
|
|
233522
|
+
return;
|
|
233523
|
+
}
|
|
233524
|
+
const displayBlockNumber = toFormattedBlockReference(nextBlock[0]);
|
|
233525
|
+
this.logger?.log("Produced block:", displayBlockNumber);
|
|
233526
|
+
this._producerActorBlocksProduced.add(1, this._metricAttributes);
|
|
233527
|
+
if ((await this.mempoolRunner.submitBlocks([nextBlock])).length === 0) {
|
|
233528
|
+
this.logger?.error(`Submit dropped block ${displayBlockNumber} silently \u2014 archivist accepted 0 of 1 (hash ${nextBlock[0]._hash})`);
|
|
233529
|
+
return;
|
|
233530
|
+
}
|
|
233531
|
+
this.logger?.log("Published block:", displayBlockNumber);
|
|
233532
|
+
this._producerActorBlocksPublished.add(1, this._metricAttributes);
|
|
233533
|
+
this._lastProducedBlock = nextBlock;
|
|
233534
|
+
this._lastCandidateGoneCheckTime = currentTime;
|
|
233535
|
+
}
|
|
233536
|
+
recordHeadChange(headHash, currentTime) {
|
|
233537
|
+
if (this._lastHeadHash === headHash) return;
|
|
233538
|
+
const lastHeadHashHex = isDefined$1(this._lastHeadHash) ? `0x${this._lastHeadHash}` : "undefined";
|
|
233539
|
+
this.logger?.log(`Found updated head ${lastHeadHashHex} -> 0x${headHash}`);
|
|
233540
|
+
this._lastHeadHash = headHash;
|
|
233541
|
+
this._lastHeadChangeTime = currentTime;
|
|
233542
|
+
this._fastCandidateRecoveriesForHead = 0;
|
|
233543
|
+
}
|
|
233544
|
+
recoverDroppedCandidate() {
|
|
233545
|
+
const lastProduced = this._lastProducedBlock;
|
|
233546
|
+
if (isUndefined$1(lastProduced)) return;
|
|
233547
|
+
this._fastCandidateRecoveriesForHead += 1;
|
|
233548
|
+
this.logger?.warn(`Last produced candidate ${toFormattedBlockReference(lastProduced[0])} is no longer pending (pruned or rejected); resuming production (recovery ${this._fastCandidateRecoveriesForHead}/${ProducerActor.MaxFastCandidateRecoveriesPerHead} for this head)`);
|
|
233549
|
+
this._lastProducedBlock = void 0;
|
|
233550
|
+
}
|
|
232571
233551
|
};
|
|
232572
233552
|
/**
|
|
233553
|
+
* Minimum time in milliseconds between checks of whether the last produced
|
|
233554
|
+
* candidate is still in the pending-block pool. Bounds the cost of the
|
|
233555
|
+
* dropped-candidate recovery probe (a pendingBlocks read per check).
|
|
233556
|
+
*/
|
|
233557
|
+
__publicField$7(ProducerActor, "CandidateGoneCheckIntervalMs", 1e3);
|
|
233558
|
+
/**
|
|
233559
|
+
* The mempool viewer's fixed pendingBlocks page size. A probe that sees a full page cannot
|
|
233560
|
+
* prove the candidate is gone and must treat it as still pending.
|
|
233561
|
+
*/
|
|
233562
|
+
__publicField$7(ProducerActor, "CandidateGoneScanLimit", 100);
|
|
233563
|
+
/**
|
|
232573
233564
|
* The default interval time (in MS) between block production attempts.
|
|
232574
233565
|
*/
|
|
232575
233566
|
__publicField$7(ProducerActor, "DefaultBlockProductionCheckInterval", DEFAULT_BLOCK_PRODUCTION_CHECK_INTERVAL);
|
|
@@ -232589,6 +233580,13 @@ __publicField$7(ProducerActor, "DefaultBlockProductionCheckInterval", DEFAULT_BL
|
|
|
232589
233580
|
*/
|
|
232590
233581
|
__publicField$7(ProducerActor, "HeadResubmissionThresholdMs", 3e4);
|
|
232591
233582
|
/**
|
|
233583
|
+
* Maximum number of dropped-candidate recoveries per head before deferring to
|
|
233584
|
+
* the stale-head resubmission threshold. A producer whose candidates are
|
|
233585
|
+
* persistently rejected (e.g. not on the allow-list) must back off rather
|
|
233586
|
+
* than churn rebuild/reject cycles at the recovery cadence forever.
|
|
233587
|
+
*/
|
|
233588
|
+
__publicField$7(ProducerActor, "MaxFastCandidateRecoveriesPerHead", 3);
|
|
233589
|
+
/**
|
|
232592
233590
|
* The window (in blocks) before expiration to attempt redeclaration of producer intent.
|
|
232593
233591
|
*/
|
|
232594
233592
|
__publicField$7(ProducerActor, "RedeclarationWindow", 1e3);
|
|
@@ -240910,7 +241908,7 @@ function withDeprecationWarning$1(module, host, options = {}) {
|
|
|
240910
241908
|
return module;
|
|
240911
241909
|
}
|
|
240912
241910
|
//#endregion
|
|
240913
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.
|
|
241911
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-sdk@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@4.4.3__@o_3a01f3229f2daa942444e08696345b23/node_modules/@xyo-network/xl1-sdk/dist/node/providers.mjs
|
|
240914
241912
|
var __defProp$3 = Object.defineProperty;
|
|
240915
241913
|
var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
|
|
240916
241914
|
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, {
|
|
@@ -241864,6 +242862,179 @@ __publicField$3(EvmStakeViewer, "monikers", [StakeViewerMoniker$1]);
|
|
|
241864
242862
|
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
241865
242863
|
__publicField$3(EvmStakeViewer, "surface", "node");
|
|
241866
242864
|
EvmStakeViewer = __decorateClass$3([creatableProvider$1()], EvmStakeViewer);
|
|
242865
|
+
var DEFAULT_HEAD_POLL_INTERVAL_MS = 5e3;
|
|
242866
|
+
var RestNetworkStakeStepRewardsByPositionViewerOptionsZod = object$3({
|
|
242867
|
+
headPollIntervalMs: number$1().min(5e3).default(DEFAULT_HEAD_POLL_INTERVAL_MS),
|
|
242868
|
+
policyId: NetworkStakeRewardsPolicyIdZod.default(NETWORK_STAKE_REWARDS_UNMULTIPLIED_POLICY)
|
|
242869
|
+
});
|
|
242870
|
+
var RestNetworkStakeStepRewardsByPositionViewer = class extends AbstractCreatableProvider$1 {
|
|
242871
|
+
moniker = RestNetworkStakeStepRewardsByPositionViewer.defaultMoniker;
|
|
242872
|
+
currentHead;
|
|
242873
|
+
headPollIntervalMs = DEFAULT_HEAD_POLL_INTERVAL_MS;
|
|
242874
|
+
headPromise;
|
|
242875
|
+
lastSuccessfulHeadAt;
|
|
242876
|
+
manifestPromise;
|
|
242877
|
+
policyId = NETWORK_STAKE_REWARDS_UNMULTIPLIED_POLICY;
|
|
242878
|
+
snapshotPromises = /* @__PURE__ */ new Map();
|
|
242879
|
+
stepPromises = /* @__PURE__ */ new Map();
|
|
242880
|
+
get baseUrl() {
|
|
242881
|
+
const connection = RestNetworkStakeStepRewardsByPositionViewer.requireBoundConnection(this.config);
|
|
242882
|
+
const config = connection.config;
|
|
242883
|
+
if (config.type !== "rest") throw new Error(`Connection "${connection.name}" must be a rest connection`);
|
|
242884
|
+
return assertEx$1(config.baseUrl, () => `Connection "${connection.name}" requires a rest baseUrl`);
|
|
242885
|
+
}
|
|
242886
|
+
get fetchFn() {
|
|
242887
|
+
return this.context.fetchFn ?? fetch.bind(globalThis);
|
|
242888
|
+
}
|
|
242889
|
+
/** Returns the policy bonus. The unmultiplied-v1 index has no multipliers, so bonus is zero. */
|
|
242890
|
+
async bonus(options = {}) {
|
|
242891
|
+
const total = await this.total(options);
|
|
242892
|
+
return Object.fromEntries(Object.keys(total).map((key) => [Number(key), asAttoXL1$1(0n)]));
|
|
242893
|
+
}
|
|
242894
|
+
/** Claimed rewards are not part of the earned-reward index. */
|
|
242895
|
+
claimed(_options) {
|
|
242896
|
+
throw new Error("Method [claimed] not implemented.");
|
|
242897
|
+
}
|
|
242898
|
+
/** Creates the provider instance after validating its REST binding and options. */
|
|
242899
|
+
async createHandler() {
|
|
242900
|
+
await super.createHandler();
|
|
242901
|
+
RestNetworkStakeStepRewardsByPositionViewer.requireBoundConnection(this.config);
|
|
242902
|
+
const options = RestNetworkStakeStepRewardsByPositionViewerOptionsZod.parse(this.config.options);
|
|
242903
|
+
this.headPollIntervalMs = options.headPollIntervalMs;
|
|
242904
|
+
this.policyId = options.policyId;
|
|
242905
|
+
}
|
|
242906
|
+
/** Base-v1 total and earned rewards are identical. */
|
|
242907
|
+
async earned(options = {}) {
|
|
242908
|
+
return await this.total(options);
|
|
242909
|
+
}
|
|
242910
|
+
/** Returns rewards by requested position from the durable index. */
|
|
242911
|
+
async total({ range, positions } = {}) {
|
|
242912
|
+
if (!isArray(positions)) return {};
|
|
242913
|
+
const head = await this.getHead();
|
|
242914
|
+
const resolvedRange = asXL1BlockRange$1(range ?? [0, head.processedThroughBlock], { name: "RestNetworkStakeStepRewardsByPositionViewer" });
|
|
242915
|
+
const result = {};
|
|
242916
|
+
for (const position of positions) result[position] = (await this.totalForPosition(position, resolvedRange))[0];
|
|
242917
|
+
return result;
|
|
242918
|
+
}
|
|
242919
|
+
/** Returns one position's cumulative reward and the range's emitted reward pool. */
|
|
242920
|
+
async totalForPosition(position, range) {
|
|
242921
|
+
const head = await this.getHead();
|
|
242922
|
+
this.assertPublishedRange(range, head);
|
|
242923
|
+
if (head.positionCount === 0) return [asAttoXL1$1(0n), asAttoXL1$1(0n)];
|
|
242924
|
+
this.assertPosition(position, head);
|
|
242925
|
+
if (range[0] === 0 && range[1] >= head.processedThroughBlock) {
|
|
242926
|
+
const snapshot = await this.getSnapshot(head);
|
|
242927
|
+
return [asAttoXL1$1(BigInt(snapshot.positionRewards[String(position)] ?? "0")), asAttoXL1$1(BigInt(snapshot.totalReward))];
|
|
242928
|
+
}
|
|
242929
|
+
const steps = await this.stepsForRange(range, head);
|
|
242930
|
+
return [asAttoXL1$1(steps.reduce((sum, step) => sum + BigInt(step.positionRewards[String(position)] ?? "0"), 0n)), asAttoXL1$1(steps.reduce((sum, step) => sum + BigInt(step.totalReward), 0n))];
|
|
242931
|
+
}
|
|
242932
|
+
/** Returns the emitted reward pool for one indexed step. */
|
|
242933
|
+
async totalForStep(step) {
|
|
242934
|
+
const head = await this.getHead();
|
|
242935
|
+
this.assertPublishedStep(step, head);
|
|
242936
|
+
return asAttoXL1$1(BigInt((await this.getStep(step)).totalReward));
|
|
242937
|
+
}
|
|
242938
|
+
/** Returns one position's allocation and emitted pool for one indexed step. */
|
|
242939
|
+
async totalForStepForPosition(step, position) {
|
|
242940
|
+
const head = await this.getHead();
|
|
242941
|
+
this.assertPosition(position, head);
|
|
242942
|
+
this.assertPublishedStep(step, head);
|
|
242943
|
+
const record = await this.getStep(step);
|
|
242944
|
+
return [asAttoXL1$1(BigInt(record.positionRewards[String(position)] ?? "0")), asAttoXL1$1(BigInt(record.totalReward))];
|
|
242945
|
+
}
|
|
242946
|
+
/** Unclaimed rewards require redemption state and are not part of this index. */
|
|
242947
|
+
unclaimed(_options) {
|
|
242948
|
+
throw new Error("Method [unclaimed] not implemented.");
|
|
242949
|
+
}
|
|
242950
|
+
assertPosition(position, head) {
|
|
242951
|
+
assertEx$1(Number.isSafeInteger(position) && position >= 0 && position < head.positionCount, () => `Position ${position} is outside rewards index positionCount ${head.positionCount}`);
|
|
242952
|
+
}
|
|
242953
|
+
assertPublishedRange(range, head) {
|
|
242954
|
+
assertEx$1(range[1] <= head.processedThroughBlock, () => `Reward range ends at ${range[1]}, beyond index watermark ${head.processedThroughBlock}`);
|
|
242955
|
+
}
|
|
242956
|
+
assertPublishedStep(step, head) {
|
|
242957
|
+
assertEx$1(step.block <= head.processedThroughBlock, () => `Reward step ${step.block}|${step.step} is beyond index watermark ${head.processedThroughBlock}`);
|
|
242958
|
+
}
|
|
242959
|
+
async fetchJson(path) {
|
|
242960
|
+
const response = await this.fetchFn(`${this.baseUrl.replace(/\/$/, "")}/${path}`);
|
|
242961
|
+
if (!response.ok) throw new Error(`Network stake rewards index request failed [${response.status}] for ${path}`);
|
|
242962
|
+
return await response.json();
|
|
242963
|
+
}
|
|
242964
|
+
async getHead() {
|
|
242965
|
+
const now = Date.now();
|
|
242966
|
+
const elapsed = this.lastSuccessfulHeadAt === void 0 ? void 0 : now - this.lastSuccessfulHeadAt;
|
|
242967
|
+
if (this.currentHead !== void 0 && elapsed !== void 0 && elapsed >= 0 && elapsed < this.headPollIntervalMs) return this.currentHead;
|
|
242968
|
+
this.headPromise ??= this.syncHead().finally(() => {
|
|
242969
|
+
this.headPromise = void 0;
|
|
242970
|
+
});
|
|
242971
|
+
return await this.headPromise;
|
|
242972
|
+
}
|
|
242973
|
+
async getManifest() {
|
|
242974
|
+
this.manifestPromise ??= this.fetchJson(networkStakeRewardsIndexManifestPath(this.policyId)).then((value) => asNetworkStakeRewardsIndexManifest(value, true)).catch((error) => {
|
|
242975
|
+
this.manifestPromise = void 0;
|
|
242976
|
+
throw error;
|
|
242977
|
+
});
|
|
242978
|
+
return await this.manifestPromise;
|
|
242979
|
+
}
|
|
242980
|
+
async getSnapshot(head) {
|
|
242981
|
+
const { snapshotHash } = head;
|
|
242982
|
+
let promise = this.snapshotPromises.get(snapshotHash);
|
|
242983
|
+
if (promise === void 0) {
|
|
242984
|
+
const path = networkStakeRewardsIndexSnapshotPath(this.policyId, snapshotHash);
|
|
242985
|
+
promise = this.fetchJson(path).then(async (value) => {
|
|
242986
|
+
const snapshot = asNetworkStakeRewardsIndexSnapshot(value, true);
|
|
242987
|
+
assertEx$1(await PayloadBuilder$1.hash(snapshot) === snapshotHash, () => `Rewards snapshot hash mismatch: ${path}`);
|
|
242988
|
+
return snapshot;
|
|
242989
|
+
});
|
|
242990
|
+
this.snapshotPromises.set(snapshotHash, promise);
|
|
242991
|
+
}
|
|
242992
|
+
try {
|
|
242993
|
+
const snapshot = await promise;
|
|
242994
|
+
assertEx$1(snapshot.policyId === this.policyId, () => "Rewards snapshot policy mismatch");
|
|
242995
|
+
assertEx$1(snapshot.stepCount === head.stepCount, () => "Rewards snapshot step count mismatch");
|
|
242996
|
+
return snapshot;
|
|
242997
|
+
} catch (error) {
|
|
242998
|
+
this.snapshotPromises.delete(snapshotHash);
|
|
242999
|
+
throw error;
|
|
243000
|
+
}
|
|
243001
|
+
}
|
|
243002
|
+
async getStep(step) {
|
|
243003
|
+
const path = networkStakeRewardsIndexStepPath(this.policyId, step);
|
|
243004
|
+
let promise = this.stepPromises.get(path);
|
|
243005
|
+
if (promise === void 0) {
|
|
243006
|
+
promise = this.fetchJson(path).then((value) => asNetworkStakeRewardsIndexStep(value, true));
|
|
243007
|
+
this.stepPromises.set(path, promise);
|
|
243008
|
+
}
|
|
243009
|
+
try {
|
|
243010
|
+
const record = await promise;
|
|
243011
|
+
assertEx$1(record.policyId === this.policyId, () => "Rewards step policy mismatch");
|
|
243012
|
+
assertEx$1(record.step.block === step.block && record.step.step === step.step, () => "Rewards step identity mismatch");
|
|
243013
|
+
return record;
|
|
243014
|
+
} catch (error) {
|
|
243015
|
+
this.stepPromises.delete(path);
|
|
243016
|
+
throw error;
|
|
243017
|
+
}
|
|
243018
|
+
}
|
|
243019
|
+
async stepsForRange(range, head) {
|
|
243020
|
+
const steps = blockRangeSteps(range, (await this.getManifest()).stepLevels).filter((step) => step.block <= head.processedThroughBlock);
|
|
243021
|
+
return await Promise.all(steps.map(async (step) => await this.getStep(step)));
|
|
243022
|
+
}
|
|
243023
|
+
async syncHead() {
|
|
243024
|
+
assertEx$1((await this.getManifest()).policyId === this.policyId, () => "Rewards manifest policy mismatch");
|
|
243025
|
+
const head = asNetworkStakeRewardsIndexHead(await this.fetchJson(networkStakeRewardsIndexHeadPath(this.policyId)), true);
|
|
243026
|
+
assertEx$1(head.policyId === this.policyId, () => "Rewards head policy mismatch");
|
|
243027
|
+
this.currentHead = head;
|
|
243028
|
+
this.lastSuccessfulHeadAt = Date.now();
|
|
243029
|
+
return head;
|
|
243030
|
+
}
|
|
243031
|
+
};
|
|
243032
|
+
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "connectionTypes", ["rest"]);
|
|
243033
|
+
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "defaultMoniker", NetworkStakeStepRewardsByPositionViewerMoniker$1);
|
|
243034
|
+
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "dependencies", []);
|
|
243035
|
+
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "monikers", [NetworkStakeStepRewardsByPositionViewerMoniker$1]);
|
|
243036
|
+
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "surface", "node");
|
|
243037
|
+
RestNetworkStakeStepRewardsByPositionViewer = __decorateClass$3([creatableProvider$1()], RestNetworkStakeStepRewardsByPositionViewer);
|
|
241867
243038
|
var SimpleDeadLetterQueueRunner = class extends AbstractCreatableProvider$1 {
|
|
241868
243039
|
/** Moniker implemented by this provider instance. */
|
|
241869
243040
|
moniker = SimpleDeadLetterQueueRunner.defaultMoniker;
|
|
@@ -243260,181 +244431,8 @@ __publicField$3(RestChainParamsViewer, "monikers", [ChainParamsViewerMoniker]);
|
|
|
243260
244431
|
/** Read, write, or mixed capability surface exposed by the provider. */
|
|
243261
244432
|
__publicField$3(RestChainParamsViewer, "surface", "node");
|
|
243262
244433
|
RestChainParamsViewer = __decorateClass$3([creatableProvider$1()], RestChainParamsViewer);
|
|
243263
|
-
var DEFAULT_HEAD_POLL_INTERVAL_MS2 = 5e3;
|
|
243264
|
-
var RestNetworkStakeStepRewardsByPositionViewerOptionsZod = object$3({
|
|
243265
|
-
headPollIntervalMs: number$1().min(5e3).default(DEFAULT_HEAD_POLL_INTERVAL_MS2),
|
|
243266
|
-
policyId: NetworkStakeRewardsPolicyIdZod.default(NETWORK_STAKE_REWARDS_UNMULTIPLIED_POLICY)
|
|
243267
|
-
});
|
|
243268
|
-
var RestNetworkStakeStepRewardsByPositionViewer = class extends AbstractCreatableProvider$1 {
|
|
243269
|
-
moniker = RestNetworkStakeStepRewardsByPositionViewer.defaultMoniker;
|
|
243270
|
-
currentHead;
|
|
243271
|
-
headPollIntervalMs = DEFAULT_HEAD_POLL_INTERVAL_MS2;
|
|
243272
|
-
headPromise;
|
|
243273
|
-
lastSuccessfulHeadAt;
|
|
243274
|
-
manifestPromise;
|
|
243275
|
-
policyId = NETWORK_STAKE_REWARDS_UNMULTIPLIED_POLICY;
|
|
243276
|
-
snapshotPromises = /* @__PURE__ */ new Map();
|
|
243277
|
-
stepPromises = /* @__PURE__ */ new Map();
|
|
243278
|
-
get baseUrl() {
|
|
243279
|
-
const connection = RestNetworkStakeStepRewardsByPositionViewer.requireBoundConnection(this.config);
|
|
243280
|
-
const config = connection.config;
|
|
243281
|
-
if (config.type !== "rest") throw new Error(`Connection "${connection.name}" must be a rest connection`);
|
|
243282
|
-
return assertEx$1(config.baseUrl, () => `Connection "${connection.name}" requires a rest baseUrl`);
|
|
243283
|
-
}
|
|
243284
|
-
get fetchFn() {
|
|
243285
|
-
return this.context.fetchFn ?? fetch.bind(globalThis);
|
|
243286
|
-
}
|
|
243287
|
-
/** Returns the policy bonus. The unmultiplied-v1 index has no multipliers, so bonus is zero. */
|
|
243288
|
-
async bonus(options = {}) {
|
|
243289
|
-
const total = await this.total(options);
|
|
243290
|
-
return Object.fromEntries(Object.keys(total).map((key) => [Number(key), asAttoXL1$1(0n)]));
|
|
243291
|
-
}
|
|
243292
|
-
/** Claimed rewards are not part of the earned-reward index. */
|
|
243293
|
-
claimed(_options) {
|
|
243294
|
-
throw new Error("Method [claimed] not implemented.");
|
|
243295
|
-
}
|
|
243296
|
-
/** Creates the provider instance after validating its REST binding and options. */
|
|
243297
|
-
async createHandler() {
|
|
243298
|
-
await super.createHandler();
|
|
243299
|
-
RestNetworkStakeStepRewardsByPositionViewer.requireBoundConnection(this.config);
|
|
243300
|
-
const options = RestNetworkStakeStepRewardsByPositionViewerOptionsZod.parse(this.config.options);
|
|
243301
|
-
this.headPollIntervalMs = options.headPollIntervalMs;
|
|
243302
|
-
this.policyId = options.policyId;
|
|
243303
|
-
}
|
|
243304
|
-
/** Base-v1 total and earned rewards are identical. */
|
|
243305
|
-
async earned(options = {}) {
|
|
243306
|
-
return await this.total(options);
|
|
243307
|
-
}
|
|
243308
|
-
/** Returns rewards by requested position from the durable index. */
|
|
243309
|
-
async total({ range, positions } = {}) {
|
|
243310
|
-
if (!isArray(positions)) return {};
|
|
243311
|
-
const head = await this.getHead();
|
|
243312
|
-
const resolvedRange = asXL1BlockRange$1(range ?? [0, head.processedThroughBlock], { name: "RestNetworkStakeStepRewardsByPositionViewer" });
|
|
243313
|
-
const result = {};
|
|
243314
|
-
for (const position of positions) result[position] = (await this.totalForPosition(position, resolvedRange))[0];
|
|
243315
|
-
return result;
|
|
243316
|
-
}
|
|
243317
|
-
/** Returns one position's cumulative reward and the range's emitted reward pool. */
|
|
243318
|
-
async totalForPosition(position, range) {
|
|
243319
|
-
const head = await this.getHead();
|
|
243320
|
-
this.assertPublishedRange(range, head);
|
|
243321
|
-
if (head.positionCount === 0) return [asAttoXL1$1(0n), asAttoXL1$1(0n)];
|
|
243322
|
-
this.assertPosition(position, head);
|
|
243323
|
-
if (range[0] === 0 && range[1] >= head.processedThroughBlock) {
|
|
243324
|
-
const snapshot = await this.getSnapshot(head);
|
|
243325
|
-
return [asAttoXL1$1(BigInt(snapshot.positionRewards[String(position)] ?? "0")), asAttoXL1$1(BigInt(snapshot.totalReward))];
|
|
243326
|
-
}
|
|
243327
|
-
const steps = await this.stepsForRange(range, head);
|
|
243328
|
-
return [asAttoXL1$1(steps.reduce((sum, step) => sum + BigInt(step.positionRewards[String(position)] ?? "0"), 0n)), asAttoXL1$1(steps.reduce((sum, step) => sum + BigInt(step.totalReward), 0n))];
|
|
243329
|
-
}
|
|
243330
|
-
/** Returns the emitted reward pool for one indexed step. */
|
|
243331
|
-
async totalForStep(step) {
|
|
243332
|
-
const head = await this.getHead();
|
|
243333
|
-
this.assertPublishedStep(step, head);
|
|
243334
|
-
return asAttoXL1$1(BigInt((await this.getStep(step)).totalReward));
|
|
243335
|
-
}
|
|
243336
|
-
/** Returns one position's allocation and emitted pool for one indexed step. */
|
|
243337
|
-
async totalForStepForPosition(step, position) {
|
|
243338
|
-
const head = await this.getHead();
|
|
243339
|
-
this.assertPosition(position, head);
|
|
243340
|
-
this.assertPublishedStep(step, head);
|
|
243341
|
-
const record = await this.getStep(step);
|
|
243342
|
-
return [asAttoXL1$1(BigInt(record.positionRewards[String(position)] ?? "0")), asAttoXL1$1(BigInt(record.totalReward))];
|
|
243343
|
-
}
|
|
243344
|
-
/** Unclaimed rewards require redemption state and are not part of this index. */
|
|
243345
|
-
unclaimed(_options) {
|
|
243346
|
-
throw new Error("Method [unclaimed] not implemented.");
|
|
243347
|
-
}
|
|
243348
|
-
assertPosition(position, head) {
|
|
243349
|
-
assertEx$1(Number.isSafeInteger(position) && position >= 0 && position < head.positionCount, () => `Position ${position} is outside rewards index positionCount ${head.positionCount}`);
|
|
243350
|
-
}
|
|
243351
|
-
assertPublishedRange(range, head) {
|
|
243352
|
-
assertEx$1(range[1] <= head.processedThroughBlock, () => `Reward range ends at ${range[1]}, beyond index watermark ${head.processedThroughBlock}`);
|
|
243353
|
-
}
|
|
243354
|
-
assertPublishedStep(step, head) {
|
|
243355
|
-
assertEx$1(step.block <= head.processedThroughBlock, () => `Reward step ${step.block}|${step.step} is beyond index watermark ${head.processedThroughBlock}`);
|
|
243356
|
-
}
|
|
243357
|
-
async fetchJson(path) {
|
|
243358
|
-
const response = await this.fetchFn(`${this.baseUrl.replace(/\/$/, "")}/${path}`);
|
|
243359
|
-
if (!response.ok) throw new Error(`Network stake rewards index request failed [${response.status}] for ${path}`);
|
|
243360
|
-
return await response.json();
|
|
243361
|
-
}
|
|
243362
|
-
async getHead() {
|
|
243363
|
-
const now = Date.now();
|
|
243364
|
-
const elapsed = this.lastSuccessfulHeadAt === void 0 ? void 0 : now - this.lastSuccessfulHeadAt;
|
|
243365
|
-
if (this.currentHead !== void 0 && elapsed !== void 0 && elapsed >= 0 && elapsed < this.headPollIntervalMs) return this.currentHead;
|
|
243366
|
-
this.headPromise ??= this.syncHead().finally(() => {
|
|
243367
|
-
this.headPromise = void 0;
|
|
243368
|
-
});
|
|
243369
|
-
return await this.headPromise;
|
|
243370
|
-
}
|
|
243371
|
-
async getManifest() {
|
|
243372
|
-
this.manifestPromise ??= this.fetchJson(networkStakeRewardsIndexManifestPath(this.policyId)).then((value) => asNetworkStakeRewardsIndexManifest(value, true)).catch((error) => {
|
|
243373
|
-
this.manifestPromise = void 0;
|
|
243374
|
-
throw error;
|
|
243375
|
-
});
|
|
243376
|
-
return await this.manifestPromise;
|
|
243377
|
-
}
|
|
243378
|
-
async getSnapshot(head) {
|
|
243379
|
-
const { snapshotHash } = head;
|
|
243380
|
-
let promise = this.snapshotPromises.get(snapshotHash);
|
|
243381
|
-
if (promise === void 0) {
|
|
243382
|
-
const path = networkStakeRewardsIndexSnapshotPath(this.policyId, snapshotHash);
|
|
243383
|
-
promise = this.fetchJson(path).then(async (value) => {
|
|
243384
|
-
const snapshot = asNetworkStakeRewardsIndexSnapshot(value, true);
|
|
243385
|
-
assertEx$1(await PayloadBuilder$1.hash(snapshot) === snapshotHash, () => `Rewards snapshot hash mismatch: ${path}`);
|
|
243386
|
-
return snapshot;
|
|
243387
|
-
});
|
|
243388
|
-
this.snapshotPromises.set(snapshotHash, promise);
|
|
243389
|
-
}
|
|
243390
|
-
try {
|
|
243391
|
-
const snapshot = await promise;
|
|
243392
|
-
assertEx$1(snapshot.policyId === this.policyId, () => "Rewards snapshot policy mismatch");
|
|
243393
|
-
assertEx$1(snapshot.stepCount === head.stepCount, () => "Rewards snapshot step count mismatch");
|
|
243394
|
-
return snapshot;
|
|
243395
|
-
} catch (error) {
|
|
243396
|
-
this.snapshotPromises.delete(snapshotHash);
|
|
243397
|
-
throw error;
|
|
243398
|
-
}
|
|
243399
|
-
}
|
|
243400
|
-
async getStep(step) {
|
|
243401
|
-
const path = networkStakeRewardsIndexStepPath(this.policyId, step);
|
|
243402
|
-
let promise = this.stepPromises.get(path);
|
|
243403
|
-
if (promise === void 0) {
|
|
243404
|
-
promise = this.fetchJson(path).then((value) => asNetworkStakeRewardsIndexStep(value, true));
|
|
243405
|
-
this.stepPromises.set(path, promise);
|
|
243406
|
-
}
|
|
243407
|
-
try {
|
|
243408
|
-
const record = await promise;
|
|
243409
|
-
assertEx$1(record.policyId === this.policyId, () => "Rewards step policy mismatch");
|
|
243410
|
-
assertEx$1(record.step.block === step.block && record.step.step === step.step, () => "Rewards step identity mismatch");
|
|
243411
|
-
return record;
|
|
243412
|
-
} catch (error) {
|
|
243413
|
-
this.stepPromises.delete(path);
|
|
243414
|
-
throw error;
|
|
243415
|
-
}
|
|
243416
|
-
}
|
|
243417
|
-
async stepsForRange(range, head) {
|
|
243418
|
-
const steps = blockRangeSteps(range, (await this.getManifest()).stepLevels).filter((step) => step.block <= head.processedThroughBlock);
|
|
243419
|
-
return await Promise.all(steps.map(async (step) => await this.getStep(step)));
|
|
243420
|
-
}
|
|
243421
|
-
async syncHead() {
|
|
243422
|
-
assertEx$1((await this.getManifest()).policyId === this.policyId, () => "Rewards manifest policy mismatch");
|
|
243423
|
-
const head = asNetworkStakeRewardsIndexHead(await this.fetchJson(networkStakeRewardsIndexHeadPath(this.policyId)), true);
|
|
243424
|
-
assertEx$1(head.policyId === this.policyId, () => "Rewards head policy mismatch");
|
|
243425
|
-
this.currentHead = head;
|
|
243426
|
-
this.lastSuccessfulHeadAt = Date.now();
|
|
243427
|
-
return head;
|
|
243428
|
-
}
|
|
243429
|
-
};
|
|
243430
|
-
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "connectionTypes", ["rest"]);
|
|
243431
|
-
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "defaultMoniker", NetworkStakeStepRewardsByPositionViewerMoniker$1);
|
|
243432
|
-
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "dependencies", []);
|
|
243433
|
-
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "monikers", [NetworkStakeStepRewardsByPositionViewerMoniker$1]);
|
|
243434
|
-
__publicField$3(RestNetworkStakeStepRewardsByPositionViewer, "surface", "node");
|
|
243435
|
-
RestNetworkStakeStepRewardsByPositionViewer = __decorateClass$3([creatableProvider$1()], RestNetworkStakeStepRewardsByPositionViewer);
|
|
243436
244434
|
//#endregion
|
|
243437
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-s3-providers@5.
|
|
244435
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-s3-providers@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod@_ce56e55bbf1d84b2b77d13465e8b0d29/node_modules/@xyo-network/xl1-s3-providers/dist/node/index.mjs
|
|
243438
244436
|
var __defProp$2 = Object.defineProperty;
|
|
243439
244437
|
var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
|
|
243440
244438
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, {
|
|
@@ -246045,6 +247043,7 @@ async function initFinalizationArchivistIfNeeded(archivist, config, account, opt
|
|
|
246045
247043
|
const genesisAccount = await Account$1.random();
|
|
246046
247044
|
const chainId2 = possibleChainId ?? toAddress(genesisAccount.address);
|
|
246047
247045
|
possibleChainId = chainId2;
|
|
247046
|
+
options.logger?.info(`No head found in chain store \u2014 creating genesis block for chain [${chainId2}]`);
|
|
246048
247047
|
if (!config.chain.genesisRewardAddress) {
|
|
246049
247048
|
const accounts = await buildInsecureGenesisRewardAccounts();
|
|
246050
247049
|
options.logger?.warn(formatInsecureGenesisRewardWarning(accounts));
|
|
@@ -246061,23 +247060,16 @@ function ownStoreArchivist(runtimeResourceOwner, lease) {
|
|
|
246061
247060
|
runtimeResourceOwner.add(async () => await lease.release());
|
|
246062
247061
|
return lease.archivist;
|
|
246063
247062
|
}
|
|
246064
|
-
var DEFAULT_LMDB_CONNECTION2 = "local-store";
|
|
246065
|
-
var DEFAULT_MONGO_CONNECTION = "chain-mongo";
|
|
246066
|
-
function isStoreConnectionType(type) {
|
|
246067
|
-
return type === "lmdb" || type === "mongo";
|
|
246068
|
-
}
|
|
246069
|
-
function isBindableStoreType(type) {
|
|
246070
|
-
return isStoreConnectionType(type) || type === "memory";
|
|
246071
|
-
}
|
|
246072
247063
|
function storeConnectionName(connections) {
|
|
246073
247064
|
const profiles = connections;
|
|
246074
|
-
const localStore = profiles[
|
|
246075
|
-
if (localStore !== void 0 && isBindableStoreType(localStore.type)) return
|
|
246076
|
-
if (profiles[
|
|
247065
|
+
const localStore = profiles[DEFAULT_LMDB_CONNECTION$1];
|
|
247066
|
+
if (localStore !== void 0 && isBindableStoreType(localStore.type)) return DEFAULT_LMDB_CONNECTION$1;
|
|
247067
|
+
if (profiles["chain-mongo"]?.type === "mongo") return DEFAULT_MONGO_CONNECTION;
|
|
247068
|
+
for (const [name, connection] of Object.entries(profiles)) if (isStoreConnectionType(connection.type)) return name;
|
|
246077
247069
|
for (const [name, connection] of Object.entries(profiles)) if (isBindableStoreType(connection.type)) return name;
|
|
246078
247070
|
}
|
|
246079
247071
|
function shouldSkipLocalNodeBoot(config) {
|
|
246080
|
-
return
|
|
247072
|
+
return localChainStoreConnectionName(config.connections ?? {}) === void 0;
|
|
246081
247073
|
}
|
|
246082
247074
|
function resolveStoreConnection(config) {
|
|
246083
247075
|
const profiles = connectionProfiles(config);
|
|
@@ -246676,7 +247668,7 @@ async function tryParseConfig(options) {
|
|
|
246676
247668
|
return finalize ? finalizeConfig(section) : section;
|
|
246677
247669
|
}
|
|
246678
247670
|
//#endregion
|
|
246679
|
-
//#region ../../node_modules/.pnpm/@xyo-network+xl1-system-status@5.
|
|
247671
|
+
//#region ../../node_modules/.pnpm/@xyo-network+xl1-system-status@5.3.1_@ariestools+sdk@8.1.9_@opentelemetry+api@1.9.1_zod_53421f1300494c9cc1ceb6d1caea9317/node_modules/@xyo-network/xl1-system-status/dist/node/index.mjs
|
|
246680
247672
|
function resolveStatusProbe(status, url) {
|
|
246681
247673
|
switch (url) {
|
|
246682
247674
|
case "/healthz": {
|
|
@@ -247860,8 +248852,8 @@ $0 <command> [options]`).parserConfiguration({
|
|
|
247860
248852
|
}
|
|
247861
248853
|
}).help().alias("help", "h").version(fullVersion2);
|
|
247862
248854
|
}
|
|
247863
|
-
var version = isDefined$1("5.
|
|
247864
|
-
var gitHash = isDefined$1("
|
|
248855
|
+
var version = isDefined$1("5.2.0") ? "5.2.0" : "unknown";
|
|
248856
|
+
var gitHash = isDefined$1("eb511295a") ? "eb511295a" : "";
|
|
247865
248857
|
var fullVersion = gitHash.length > 0 ? `${version} (${gitHash})` : version;
|
|
247866
248858
|
var mapXl1CliFailure = createSysExitFailureMapper();
|
|
247867
248859
|
var defaultDependencies2 = {
|