@xyo-network/xl1-cli 1.22.0 → 1.23.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/README.md +251 -0
- package/dist/cli-min.mjs +904 -160
- package/dist/cli-min.mjs.map +1 -1
- package/package.json +31 -36
- package/README.body.md +0 -109
- package/README.reference.md +0 -0
package/dist/cli-min.mjs
CHANGED
|
@@ -53500,7 +53500,7 @@ function isTransferDescriptor(thing) {
|
|
|
53500
53500
|
// src/master/invocation-proxy.ts
|
|
53501
53501
|
var debugMessages = debug$3("threads:master:messages");
|
|
53502
53502
|
var nextJobUID = 1;
|
|
53503
|
-
var dedupe = (array) => [...new Set(array)];
|
|
53503
|
+
var dedupe$1 = (array) => [...new Set(array)];
|
|
53504
53504
|
var isJobErrorMessage = (data) => data?.type === "error" /* error */;
|
|
53505
53505
|
var isJobResultMessage = (data) => data?.type === "result" /* result */;
|
|
53506
53506
|
var isJobStartMessage = (data) => data?.type === "running" /* running */;
|
|
@@ -53570,7 +53570,7 @@ function prepareArguments(rawArgs) {
|
|
|
53570
53570
|
}
|
|
53571
53571
|
return {
|
|
53572
53572
|
args,
|
|
53573
|
-
transferables: transferables.length === 0 ? transferables : dedupe(transferables)
|
|
53573
|
+
transferables: transferables.length === 0 ? transferables : dedupe$1(transferables)
|
|
53574
53574
|
};
|
|
53575
53575
|
}
|
|
53576
53576
|
function createProxyFunction(worker, method) {
|
|
@@ -73059,6 +73059,7 @@ UnsignedTransactionBoundWitnessZod.safeExtend(StorageMetaZod.shape);
|
|
|
73059
73059
|
var SignedTransactionBoundWitnessZod = SignedBoundWitnessZod.safeExtend(TransactionBoundWitnessFieldsZod.shape);
|
|
73060
73060
|
var asSignedTransactionBoundWitness = zodAsFactory(SignedTransactionBoundWitnessZod, "asSignedTransactionBoundWitness");
|
|
73061
73061
|
var SignedTransactionBoundWitnessWithHashMetaZod = WithHashMetaZod(SignedTransactionBoundWitnessZod);
|
|
73062
|
+
var isSignedTransactionBoundWitnessWithHashMeta = zodIsFactory(SignedTransactionBoundWitnessWithHashMetaZod);
|
|
73062
73063
|
var asSignedTransactionBoundWitnessWithHashMeta = zodAsFactory(
|
|
73063
73064
|
SignedTransactionBoundWitnessWithHashMetaZod,
|
|
73064
73065
|
"asSignedTransactionBoundWitnessWithHashMeta"
|
|
@@ -73353,7 +73354,7 @@ var defaultRewardRatio = 0.05;
|
|
|
73353
73354
|
var minTransactionFees = {
|
|
73354
73355
|
base: AttoXL1(1000n * AttoXL1ConvertFactor.nano),
|
|
73355
73356
|
gasPrice: AttoXL1(10n * AttoXL1ConvertFactor.nano),
|
|
73356
|
-
gasLimit: AttoXL1(
|
|
73357
|
+
gasLimit: AttoXL1(10n * AttoXL1ConvertFactor.nano),
|
|
73357
73358
|
priority: AttoXL1(0n * AttoXL1ConvertFactor.nano)
|
|
73358
73359
|
};
|
|
73359
73360
|
|
|
@@ -73361,7 +73362,7 @@ var minTransactionFees = {
|
|
|
73361
73362
|
var defaultTransactionFees = {
|
|
73362
73363
|
base: minTransactionFees.base,
|
|
73363
73364
|
gasPrice: AttoXL1(10n * AttoXL1ConvertFactor.nano),
|
|
73364
|
-
gasLimit: AttoXL1(
|
|
73365
|
+
gasLimit: AttoXL1(1000n * AttoXL1ConvertFactor.nano),
|
|
73365
73366
|
priority: minTransactionFees.priority
|
|
73366
73367
|
};
|
|
73367
73368
|
var HydratedTransactionZod = tuple([
|
|
@@ -73404,7 +73405,7 @@ tuple([
|
|
|
73404
73405
|
WithStorageMetaZod(SignedTransactionBoundWitnessZod),
|
|
73405
73406
|
array$1(WithStorageMetaZod(PayloadZod).loose())
|
|
73406
73407
|
]);
|
|
73407
|
-
var CaveatTypesZod = _enum$1(["chain", "expiration", "filteredResponse", "rateLimit", "restrictReturnedAccounts"]);
|
|
73408
|
+
var CaveatTypesZod = _enum$1(["chain", "dataLakeAccess", "expiration", "filteredResponse", "rateLimit", "restrictReturnedAccounts"]);
|
|
73408
73409
|
var CaveatsZod = object$4({
|
|
73409
73410
|
type: CaveatTypesZod,
|
|
73410
73411
|
value: json$3()
|
|
@@ -73607,13 +73608,16 @@ var HydratedBlockValidationError = class extends ValidationError {
|
|
|
73607
73608
|
};
|
|
73608
73609
|
ValidationErrorZod.extend({
|
|
73609
73610
|
chainId: HexZod,
|
|
73610
|
-
name: literal$2("HydratedBlockStateValidationError")
|
|
73611
|
+
name: literal$2("HydratedBlockStateValidationError"),
|
|
73612
|
+
offendingTransactionHashes: array$1(HashZod).optional()
|
|
73611
73613
|
}).loose();
|
|
73612
73614
|
var HydratedBlockStateValidationError = class extends ValidationError {
|
|
73613
73615
|
chainId;
|
|
73614
|
-
|
|
73616
|
+
offendingTransactionHashes;
|
|
73617
|
+
constructor(hash, chainId, value, message, cause, offendingTransactionHashes) {
|
|
73615
73618
|
super(hash, value, message, cause);
|
|
73616
73619
|
this.chainId = chainId;
|
|
73620
|
+
this.offendingTransactionHashes = offendingTransactionHashes;
|
|
73617
73621
|
}
|
|
73618
73622
|
};
|
|
73619
73623
|
|
|
@@ -74434,7 +74438,7 @@ var RpcRemoteConfigZod = union$1([HttpRpcRemoteConfigZod, PostMessageRpcRemoteCo
|
|
|
74434
74438
|
var RemoteConfigZod = object$4({ rpc: RpcRemoteConfigZod.optional() }).describe("Configuration for remote connections, including RPC");
|
|
74435
74439
|
var hasMongoConfig = (config) => {
|
|
74436
74440
|
if (isUndefined(config)) return false;
|
|
74437
|
-
return isDefined(config.connectionString) && isDefined(config.database) && isDefined(config.domain)
|
|
74441
|
+
return isDefined(config.connectionString) && isDefined(config.database) && isDefined(config.domain);
|
|
74438
74442
|
};
|
|
74439
74443
|
var MongoConfigZod = object$4({
|
|
74440
74444
|
// TODO: Create from other arguments
|
|
@@ -74833,26 +74837,6 @@ async function externalBlockRangeFromStep(context, blockViewer, stepIdentity) {
|
|
|
74833
74837
|
return await externalBlockRangeFromXL1BlockRange(context, blockViewer, xl1BlockRange);
|
|
74834
74838
|
});
|
|
74835
74839
|
}
|
|
74836
|
-
async function addDataLakePayloadsToPayloads(hashes, payloads, dataLakeViewer) {
|
|
74837
|
-
if (isUndefined(dataLakeViewer)) return [payloads, []];
|
|
74838
|
-
const missingPayloadHashes = hashes.filter((hash) => !payloads.some((p) => p._hash === hash));
|
|
74839
|
-
const payloadsFromDataLake = await PayloadBuilder.addHashMeta(
|
|
74840
|
-
await PayloadBuilder.addHashMeta((await dataLakeViewer.get(missingPayloadHashes)).filter(isAnyPayload))
|
|
74841
|
-
);
|
|
74842
|
-
return [[...payloads, ...payloadsFromDataLake], payloadsFromDataLake.map((p) => p._hash)];
|
|
74843
|
-
}
|
|
74844
|
-
|
|
74845
|
-
// src/primitives/datalake/addDataLakePayloads.ts
|
|
74846
|
-
async function addDataLakePayloads([boundWitness, payloads], dataLakeViewer) {
|
|
74847
|
-
const [updatedPayloads, foundHashes] = await addDataLakePayloadsToPayloads(boundWitness.payload_hashes, payloads, dataLakeViewer);
|
|
74848
|
-
return [
|
|
74849
|
-
[
|
|
74850
|
-
boundWitness,
|
|
74851
|
-
updatedPayloads
|
|
74852
|
-
],
|
|
74853
|
-
foundHashes
|
|
74854
|
-
];
|
|
74855
|
-
}
|
|
74856
74840
|
function mapToMapType(map) {
|
|
74857
74841
|
return {
|
|
74858
74842
|
get: (key) => map.get(key),
|
|
@@ -75634,6 +75618,7 @@ var registerCreatableProviderFactory = (registry, factory, labels, primary = fal
|
|
|
75634
75618
|
const factoryClone = buildProviderFactory(factory, factory.defaultParams, labels);
|
|
75635
75619
|
registry[factoryClone.defaultMoniker] = [factoryClone, ...registry[factoryClone.defaultMoniker] ?? []];
|
|
75636
75620
|
for (const moniker of factoryClone.monikers) {
|
|
75621
|
+
if (moniker === factoryClone.defaultMoniker) continue;
|
|
75637
75622
|
registry[moniker] = isPrimaryForMoniker(moniker) ? [factoryClone, ...registry[moniker] ?? []] : [...registry[moniker] ?? [], factoryClone];
|
|
75638
75623
|
}
|
|
75639
75624
|
};
|
|
@@ -76249,10 +76234,9 @@ var MIN_HEAD_POLL_INTERVAL_MS$1 = 5e3;
|
|
|
76249
76234
|
var SimpleBlockViewer = class extends AbstractCreatableProvider {
|
|
76250
76235
|
moniker = SimpleBlockViewer.defaultMoniker;
|
|
76251
76236
|
_store;
|
|
76252
|
-
dataLakeViewer;
|
|
76253
76237
|
finalizationViewer;
|
|
76254
76238
|
payloadCache = new LruCacheMap({ max: 1e4 });
|
|
76255
|
-
|
|
76239
|
+
signedHydratedBlockWithHashMetaCache = new LruCacheMap({ max: 2e3, ttl: 1e3 * 60 * 60 });
|
|
76256
76240
|
_headPollHash;
|
|
76257
76241
|
_headPollInProgress = false;
|
|
76258
76242
|
_headPollTimer = null;
|
|
@@ -76288,17 +76272,16 @@ var SimpleBlockViewer = class extends AbstractCreatableProvider {
|
|
|
76288
76272
|
}
|
|
76289
76273
|
async blockByHash(hash) {
|
|
76290
76274
|
return await this.spanAsync("blockByHash", async () => {
|
|
76291
|
-
const cachedBlock = this.
|
|
76275
|
+
const cachedBlock = this.signedHydratedBlockWithHashMetaCache.get(hash);
|
|
76292
76276
|
if (cachedBlock) {
|
|
76293
76277
|
return cachedBlock;
|
|
76294
76278
|
}
|
|
76295
76279
|
const cache = this.hydratedBlockCache;
|
|
76296
76280
|
const block = await cache.get(hash);
|
|
76297
|
-
|
|
76298
|
-
|
|
76299
|
-
this.signedHydratedBlockWithDataLakePayloadsCache.set(hash, result);
|
|
76281
|
+
if (block) {
|
|
76282
|
+
this.signedHydratedBlockWithHashMetaCache.set(hash, block);
|
|
76300
76283
|
}
|
|
76301
|
-
return
|
|
76284
|
+
return block ?? null;
|
|
76302
76285
|
}, { ...this.context, timeBudgetLimit: 100 });
|
|
76303
76286
|
}
|
|
76304
76287
|
async blockByNumber(blockNumber) {
|
|
@@ -76351,13 +76334,11 @@ var SimpleBlockViewer = class extends AbstractCreatableProvider {
|
|
|
76351
76334
|
}
|
|
76352
76335
|
async createHandler() {
|
|
76353
76336
|
await super.createHandler();
|
|
76354
|
-
this.dataLakeViewer = await this.locator.tryGetInstance(DataLakeViewerMoniker);
|
|
76355
76337
|
this.finalizationViewer = await this.locator.getInstance(FinalizationViewerMoniker);
|
|
76356
76338
|
this._store = { chainMap: this.params.finalizedArchivist };
|
|
76357
76339
|
}
|
|
76358
76340
|
async currentBlock() {
|
|
76359
|
-
|
|
76360
|
-
return result;
|
|
76341
|
+
return await this.finalizationViewer.head();
|
|
76361
76342
|
}
|
|
76362
76343
|
async currentBlockHash() {
|
|
76363
76344
|
return await this.finalizationViewer.headHash();
|
|
@@ -76375,7 +76356,7 @@ var SimpleBlockViewer = class extends AbstractCreatableProvider {
|
|
|
76375
76356
|
const cachedHashes = new Set(cachedPayloads.map((p) => p._hash));
|
|
76376
76357
|
remainingHashes = remainingHashes.filter((h) => !cachedHashes.has(h));
|
|
76377
76358
|
const finalizedPayloads = remainingHashes.length > 0 ? await this.finalizedArchivist.get(remainingHashes) : [];
|
|
76378
|
-
const
|
|
76359
|
+
const resultPayloads = [...cachedPayloads, ...finalizedPayloads.filter(exists$2)];
|
|
76379
76360
|
resultPayloads.map((payload) => {
|
|
76380
76361
|
this.payloadCache.set(payload._hash, payload);
|
|
76381
76362
|
});
|
|
@@ -76414,9 +76395,7 @@ var SimpleBlockViewer = class extends AbstractCreatableProvider {
|
|
|
76414
76395
|
await super.stopHandler();
|
|
76415
76396
|
}
|
|
76416
76397
|
async blockByNumberWithContext(chainContext, blockNumber) {
|
|
76417
|
-
|
|
76418
|
-
const [result] = block ? await addDataLakePayloads(block, this.dataLakeViewer) : [null, []];
|
|
76419
|
-
return result;
|
|
76398
|
+
return asSignedHydratedBlockWithHashMeta(await hydratedBlockByNumber(chainContext, blockNumber)) ?? null;
|
|
76420
76399
|
}
|
|
76421
76400
|
async pollHead(emitOnChange) {
|
|
76422
76401
|
if (this._headPollInProgress) return;
|
|
@@ -76998,15 +76977,25 @@ var SimpleXyoGatewayRunner = class _SimpleXyoGatewayRunner extends AbstractCreat
|
|
|
76998
76977
|
const [hash] = await this.addPayloadsToChain([transfer], [], options);
|
|
76999
76978
|
return hash;
|
|
77000
76979
|
}
|
|
76980
|
+
transactionRequiredGas(hydratedTransaction) {
|
|
76981
|
+
return transactionRequiredGas(hydratedTransaction);
|
|
76982
|
+
}
|
|
77001
76983
|
};
|
|
77002
76984
|
var DEFAULT_SYNC_INTERVAL = 3e4;
|
|
77003
76985
|
var DEFAULT_SYNC_LIMIT = 100;
|
|
76986
|
+
var ENFORCE_CAP_BATCH_SIZE = 1e3;
|
|
76987
|
+
function isDemotionAware(viewer) {
|
|
76988
|
+
if (!viewer) return false;
|
|
76989
|
+
const candidate = viewer;
|
|
76990
|
+
return typeof candidate.forget === "function" && typeof candidate.getEvictionPriorityOrder === "function";
|
|
76991
|
+
}
|
|
77004
76992
|
var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
77005
76993
|
moniker = SimpleMempoolRunner.defaultMoniker;
|
|
77006
76994
|
_blockValidationViewer;
|
|
77007
76995
|
_chainContractViewer;
|
|
77008
76996
|
_deadLetterQueueRunner;
|
|
77009
76997
|
_finalizationViewer;
|
|
76998
|
+
_mempoolViewer;
|
|
77010
76999
|
_transactionValidationViewer;
|
|
77011
77000
|
_syncMutex = new Mutex$1();
|
|
77012
77001
|
_syncTimerId = null;
|
|
@@ -77025,6 +77014,9 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
77025
77014
|
get maxExpAhead() {
|
|
77026
77015
|
return this.params.maxExpAhead ?? DEFAULT_MAX_EXP_AHEAD;
|
|
77027
77016
|
}
|
|
77017
|
+
get maxPendingTransactions() {
|
|
77018
|
+
return this.params.maxPendingTransactions ?? 0;
|
|
77019
|
+
}
|
|
77028
77020
|
get pendingBlocksArchivist() {
|
|
77029
77021
|
return this.params.pendingBlocksArchivist;
|
|
77030
77022
|
}
|
|
@@ -77040,6 +77032,9 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
77040
77032
|
get transactionValidationViewer() {
|
|
77041
77033
|
return this._transactionValidationViewer;
|
|
77042
77034
|
}
|
|
77035
|
+
get validateOnSubmit() {
|
|
77036
|
+
return this.params.validateOnSubmit ?? true;
|
|
77037
|
+
}
|
|
77043
77038
|
static async paramsHandler(params) {
|
|
77044
77039
|
return {
|
|
77045
77040
|
...await super.paramsHandler(params),
|
|
@@ -77054,6 +77049,7 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
77054
77049
|
this._finalizationViewer = await this.locator.getInstance(FinalizationViewerMoniker);
|
|
77055
77050
|
this._transactionValidationViewer = await this.locator.getInstance(TransactionValidationViewerMoniker);
|
|
77056
77051
|
this._deadLetterQueueRunner = await this.locator.tryGetInstance(DeadLetterQueueRunnerMoniker);
|
|
77052
|
+
this._mempoolViewer = await this.locator.tryGetInstance(MempoolViewerMoniker);
|
|
77057
77053
|
}
|
|
77058
77054
|
async prunePendingBlocks({
|
|
77059
77055
|
batchSize = 10,
|
|
@@ -77168,6 +77164,7 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
77168
77164
|
pruned += pruneHashes.length;
|
|
77169
77165
|
total += batch.length;
|
|
77170
77166
|
await this.pendingTransactionsArchivist.delete(pruneHashes);
|
|
77167
|
+
this.forgetBundleHashes(pruneHashes);
|
|
77171
77168
|
const pruneSet = new Set(pruneHashes);
|
|
77172
77169
|
const lastSurvivor = batch.findLast((p) => !pruneSet.has(p._hash));
|
|
77173
77170
|
cursor = lastSurvivor?._sequence ?? cursor;
|
|
@@ -77177,8 +77174,7 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
77177
77174
|
order: "desc"
|
|
77178
77175
|
});
|
|
77179
77176
|
}
|
|
77180
|
-
this.
|
|
77181
|
-
return [pruned, total];
|
|
77177
|
+
return this.finalizePruneTransactionsResult(pruned, total);
|
|
77182
77178
|
}
|
|
77183
77179
|
async submitBlocks(blocks) {
|
|
77184
77180
|
const bundles = await Promise.all(blocks.map(async ([bw, payloads]) => {
|
|
@@ -77193,20 +77189,38 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
77193
77189
|
async submitTransactions(transactions) {
|
|
77194
77190
|
const headNumber = await this.finalizationViewer.headNumber();
|
|
77195
77191
|
const maxExp = headNumber + this.maxExpAhead;
|
|
77196
|
-
const
|
|
77192
|
+
const expValid = transactions.filter(([tx]) => {
|
|
77197
77193
|
if (tx.exp > maxExp) {
|
|
77198
77194
|
this.logger?.debug(`Rejecting transaction with exp ${tx.exp} exceeding max allowed ${maxExp}`);
|
|
77199
77195
|
return false;
|
|
77200
77196
|
}
|
|
77201
77197
|
return true;
|
|
77202
77198
|
});
|
|
77203
|
-
const
|
|
77204
|
-
|
|
77199
|
+
const hashedTransactions = await Promise.all(
|
|
77200
|
+
expValid.map(async ([tx, payloads]) => [
|
|
77205
77201
|
await PayloadBuilder.addHashMeta(tx),
|
|
77206
77202
|
await PayloadBuilder.addHashMeta(payloads)
|
|
77207
|
-
])
|
|
77208
|
-
|
|
77203
|
+
])
|
|
77204
|
+
);
|
|
77205
|
+
if (this.validateOnSubmit) {
|
|
77206
|
+
const validationResults = await Promise.all(
|
|
77207
|
+
hashedTransactions.map(async (tx) => this.transactionValidationViewer.validateTransaction(tx, { value: true, state: true }))
|
|
77208
|
+
);
|
|
77209
|
+
const failures = [];
|
|
77210
|
+
for (const [i, result] of validationResults.entries()) {
|
|
77211
|
+
if (!isSignedHydratedTransactionWithHashMeta(result)) {
|
|
77212
|
+
failures.push({ tx: hashedTransactions[i], errors: result });
|
|
77213
|
+
}
|
|
77214
|
+
}
|
|
77215
|
+
if (failures.length > 0) {
|
|
77216
|
+
await Promise.all(failures.map((f) => this.routeRejectedTransaction(f.tx, f.errors)));
|
|
77217
|
+
const detail = failures.map((f) => `${f.tx[0]._hash}: ${f.errors.map((e) => e.message).join("; ")}`).join(" | ");
|
|
77218
|
+
throw new Error(`SimpleMempoolRunner: rejected ${failures.length} transaction(s) at admission: ${detail}`);
|
|
77219
|
+
}
|
|
77220
|
+
}
|
|
77221
|
+
const bundles = hashedTransactions.map((tx) => hydratedTransactionToPayloadBundle(tx));
|
|
77209
77222
|
const inserted = await this.pendingTransactionsArchivist.insert(bundles);
|
|
77223
|
+
await this.enforceCap();
|
|
77210
77224
|
return inserted.map((p) => p._hash);
|
|
77211
77225
|
}
|
|
77212
77226
|
async startHandler() {
|
|
@@ -77225,6 +77239,50 @@ var SimpleMempoolRunner = class extends AbstractCreatableProvider {
|
|
|
77225
77239
|
this._syncTimerId = null;
|
|
77226
77240
|
}
|
|
77227
77241
|
}
|
|
77242
|
+
async collectAllPendingTransactionBundles() {
|
|
77243
|
+
const all = [];
|
|
77244
|
+
let cursor;
|
|
77245
|
+
while (true) {
|
|
77246
|
+
const batch = await this.pendingTransactionsArchivist.next({
|
|
77247
|
+
limit: ENFORCE_CAP_BATCH_SIZE,
|
|
77248
|
+
cursor,
|
|
77249
|
+
order: "asc"
|
|
77250
|
+
});
|
|
77251
|
+
if (batch.length === 0) break;
|
|
77252
|
+
all.push(...batch);
|
|
77253
|
+
cursor = batch.at(-1)?._sequence;
|
|
77254
|
+
if (batch.length < ENFORCE_CAP_BATCH_SIZE) break;
|
|
77255
|
+
}
|
|
77256
|
+
return all;
|
|
77257
|
+
}
|
|
77258
|
+
async enforceCap() {
|
|
77259
|
+
const cap = this.maxPendingTransactions;
|
|
77260
|
+
if (cap <= 0) return;
|
|
77261
|
+
const all = await this.collectAllPendingTransactionBundles();
|
|
77262
|
+
if (all.length <= cap) return;
|
|
77263
|
+
const excess = all.length - cap;
|
|
77264
|
+
const bundleHashesOldestFirst = all.map((p) => p._hash);
|
|
77265
|
+
const orderedForEviction = this.orderForEviction(bundleHashesOldestFirst);
|
|
77266
|
+
const toEvict = orderedForEviction.slice(0, excess);
|
|
77267
|
+
await this.pendingTransactionsArchivist.delete(toEvict);
|
|
77268
|
+
this.forgetBundleHashes(toEvict);
|
|
77269
|
+
this.logger?.debug(`enforceCap evicted ${toEvict.length} bundles (pool=${all.length}, cap=${cap})`);
|
|
77270
|
+
}
|
|
77271
|
+
async finalizePruneTransactionsResult(pruned, total) {
|
|
77272
|
+
this.logger?.debug(`prunePendingTransactions completed: pruned=${pruned}, totalChecked=${total}`);
|
|
77273
|
+
await this.enforceCap();
|
|
77274
|
+
return [pruned, total];
|
|
77275
|
+
}
|
|
77276
|
+
forgetBundleHashes(bundleHashes) {
|
|
77277
|
+
if (bundleHashes.length === 0) return;
|
|
77278
|
+
if (isDemotionAware(this._mempoolViewer)) this._mempoolViewer.forget(bundleHashes);
|
|
77279
|
+
}
|
|
77280
|
+
orderForEviction(bundleHashesOldestFirst) {
|
|
77281
|
+
if (isDemotionAware(this._mempoolViewer)) {
|
|
77282
|
+
return this._mempoolViewer.getEvictionPriorityOrder(bundleHashesOldestFirst);
|
|
77283
|
+
}
|
|
77284
|
+
return bundleHashesOldestFirst;
|
|
77285
|
+
}
|
|
77228
77286
|
async routeRejectedTransaction(transaction, errors) {
|
|
77229
77287
|
if (!this._deadLetterQueueRunner) return;
|
|
77230
77288
|
const rejectionErrors = errors.map((e) => ({
|
|
@@ -77329,9 +77387,18 @@ SimpleMempoolRunner = __decorateClass$4([
|
|
|
77329
77387
|
creatableProvider()
|
|
77330
77388
|
], SimpleMempoolRunner);
|
|
77331
77389
|
var DEFAULT_MEMPOOL_SELECTION_RATIO = 0.66;
|
|
77390
|
+
var DEFAULT_DEMOTION_THRESHOLD = 3;
|
|
77391
|
+
var DEFAULT_HANDOUT_STATS_TTL_BLOCKS = 1e3;
|
|
77332
77392
|
var SimpleMempoolViewer = class extends AbstractCreatableProvider {
|
|
77333
77393
|
moniker = SimpleMempoolViewer.defaultMoniker;
|
|
77394
|
+
_handoutStats = /* @__PURE__ */ new Map();
|
|
77334
77395
|
_windowedBlockViewer;
|
|
77396
|
+
get demotionThreshold() {
|
|
77397
|
+
return this.params.demotionThreshold ?? DEFAULT_DEMOTION_THRESHOLD;
|
|
77398
|
+
}
|
|
77399
|
+
get handoutStatsTtlBlocks() {
|
|
77400
|
+
return this.params.handoutStatsTtlBlocks ?? DEFAULT_HANDOUT_STATS_TTL_BLOCKS;
|
|
77401
|
+
}
|
|
77335
77402
|
get pendingBlocksArchivist() {
|
|
77336
77403
|
return this.params.pendingBlocksArchivist;
|
|
77337
77404
|
}
|
|
@@ -77345,6 +77412,32 @@ var SimpleMempoolViewer = class extends AbstractCreatableProvider {
|
|
|
77345
77412
|
await super.createHandler();
|
|
77346
77413
|
this._windowedBlockViewer = await this.locator.getInstance(WindowedBlockViewerMoniker);
|
|
77347
77414
|
}
|
|
77415
|
+
/** Drop handout stats for the given bundle hashes. Called when a bundle has been evicted or otherwise removed from the pool. */
|
|
77416
|
+
forget(bundleHashes) {
|
|
77417
|
+
for (const hash of bundleHashes) this._handoutStats.delete(hash);
|
|
77418
|
+
}
|
|
77419
|
+
/** Return the subset of the given bundle hashes that are currently considered demoted. */
|
|
77420
|
+
getDemotedBundleHashes(bundleHashes) {
|
|
77421
|
+
return bundleHashes.filter((hash) => this.isDemoted(hash));
|
|
77422
|
+
}
|
|
77423
|
+
/**
|
|
77424
|
+
* Return the bundle hashes in the order they should be evicted under size pressure.
|
|
77425
|
+
* Demoted entries come first, sorted by handouts descending; the remainder is left as-is
|
|
77426
|
+
* so the caller can append by FIFO sequence order.
|
|
77427
|
+
*/
|
|
77428
|
+
getEvictionPriorityOrder(bundleHashes) {
|
|
77429
|
+
const demoted = [];
|
|
77430
|
+
const nonDemoted = [];
|
|
77431
|
+
for (const hash of bundleHashes) {
|
|
77432
|
+
if (this.isDemoted(hash)) demoted.push(hash);
|
|
77433
|
+
else nonDemoted.push(hash);
|
|
77434
|
+
}
|
|
77435
|
+
demoted.sort((a, b) => (this._handoutStats.get(b)?.handouts ?? 0) - (this._handoutStats.get(a)?.handouts ?? 0));
|
|
77436
|
+
return [...demoted, ...nonDemoted];
|
|
77437
|
+
}
|
|
77438
|
+
getHandoutStats(bundleHash) {
|
|
77439
|
+
return this._handoutStats.get(bundleHash);
|
|
77440
|
+
}
|
|
77348
77441
|
async pendingBlocks({ cursor: providedCursor } = {}) {
|
|
77349
77442
|
let cursor = void 0;
|
|
77350
77443
|
if (isHash(providedCursor)) {
|
|
@@ -77387,6 +77480,7 @@ var SimpleMempoolViewer = class extends AbstractCreatableProvider {
|
|
|
77387
77480
|
})
|
|
77388
77481
|
)).filter(exists$2);
|
|
77389
77482
|
const currentBlock = await this.windowedBlockViewer.currentBlock();
|
|
77483
|
+
const currentBlockNumber = currentBlock[0].block;
|
|
77390
77484
|
const evaluated = await Promise.all(
|
|
77391
77485
|
hydratedWithBundle.map(async ({ bundle: bundle3, tx }) => ({
|
|
77392
77486
|
bundle: bundle3,
|
|
@@ -77400,25 +77494,43 @@ var SimpleMempoolViewer = class extends AbstractCreatableProvider {
|
|
|
77400
77494
|
await Promise.all(
|
|
77401
77495
|
deletionCandidates.map(async ({ bundle: bundle3, tx }) => {
|
|
77402
77496
|
await this.deleteBundledTransaction(bundle3);
|
|
77497
|
+
this._handoutStats.delete(bundle3._hash);
|
|
77403
77498
|
this.logger?.debug(`Purged completed/expired bundled transaction: ${bundle3._hash}/${tx[0]._hash}`);
|
|
77404
77499
|
})
|
|
77405
77500
|
);
|
|
77406
|
-
|
|
77407
|
-
|
|
77501
|
+
this.gcHandoutStats(currentBlockNumber);
|
|
77502
|
+
const inclusionCandidates = (await Promise.all(validTransactions.map(async ({ bundle: bundle3, tx }) => {
|
|
77503
|
+
if (await this.isInclusionCandidate(tx, currentBlock, false)) return { bundle: bundle3, tx };
|
|
77408
77504
|
}))).filter(exists$2);
|
|
77409
77505
|
const selectionRatio = this.params.mempoolSelectionRatio ?? DEFAULT_MEMPOOL_SELECTION_RATIO;
|
|
77410
|
-
const
|
|
77411
|
-
const
|
|
77412
|
-
const
|
|
77413
|
-
|
|
77414
|
-
|
|
77415
|
-
|
|
77416
|
-
|
|
77417
|
-
|
|
77506
|
+
const nonDemoted = inclusionCandidates.filter(({ bundle: bundle3 }) => !this.isDemoted(bundle3._hash));
|
|
77507
|
+
const demoted = inclusionCandidates.filter(({ bundle: bundle3 }) => this.isDemoted(bundle3._hash));
|
|
77508
|
+
const primary = this.selectWithRatio(nonDemoted, limit, selectionRatio);
|
|
77509
|
+
const topupNeeded = limit - primary.length;
|
|
77510
|
+
const topup = topupNeeded > 0 ? this.selectWithRatio(demoted, topupNeeded, selectionRatio) : [];
|
|
77511
|
+
let combined = [...primary, ...topup];
|
|
77512
|
+
if (combined.length === 0 && inclusionCandidates.length > 0) {
|
|
77513
|
+
combined = deduplicateWithBundleBySigner(inclusionCandidates).slice(0, 1);
|
|
77514
|
+
}
|
|
77515
|
+
for (const { bundle: bundle3 } of combined) {
|
|
77516
|
+
this.recordHandout(bundle3._hash, currentBlockNumber);
|
|
77517
|
+
}
|
|
77518
|
+
this.logger?.debug(`Inclusion candidates: ${inclusionCandidates.length} (nonDemoted=${nonDemoted.length}, demoted=${demoted.length}); returning ${combined.length}`);
|
|
77519
|
+
return combined.map(({ tx }) => tx);
|
|
77520
|
+
}
|
|
77521
|
+
isDemoted(bundleHash) {
|
|
77522
|
+
const stats = this._handoutStats.get(bundleHash);
|
|
77523
|
+
return stats !== void 0 && stats.handouts >= this.demotionThreshold;
|
|
77418
77524
|
}
|
|
77419
77525
|
async deleteBundledTransaction(bundle3) {
|
|
77420
77526
|
await this.pendingTransactionsArchivist.delete([bundle3._hash]);
|
|
77421
77527
|
}
|
|
77528
|
+
gcHandoutStats(currentBlockNumber) {
|
|
77529
|
+
const ttl = this.handoutStatsTtlBlocks;
|
|
77530
|
+
for (const [hash, stats] of this._handoutStats) {
|
|
77531
|
+
if (currentBlockNumber - stats.firstHandoutAt > ttl) this._handoutStats.delete(hash);
|
|
77532
|
+
}
|
|
77533
|
+
}
|
|
77422
77534
|
/**
|
|
77423
77535
|
* Evaluates a transaction to determine if it should be purged from the mempool.
|
|
77424
77536
|
* @param tx The transaction to evaluate
|
|
@@ -77451,6 +77563,21 @@ var SimpleMempoolViewer = class extends AbstractCreatableProvider {
|
|
|
77451
77563
|
if (checkForDeletable && await this.isDeletable(tx, currentBlock)) return false;
|
|
77452
77564
|
return true;
|
|
77453
77565
|
}
|
|
77566
|
+
recordHandout(bundleHash, currentBlockNumber) {
|
|
77567
|
+
const existing = this._handoutStats.get(bundleHash);
|
|
77568
|
+
if (existing) {
|
|
77569
|
+
existing.handouts += 1;
|
|
77570
|
+
} else {
|
|
77571
|
+
this._handoutStats.set(bundleHash, { handouts: 1, firstHandoutAt: currentBlockNumber });
|
|
77572
|
+
}
|
|
77573
|
+
}
|
|
77574
|
+
selectWithRatio(group, take, selectionRatio) {
|
|
77575
|
+
if (take <= 0 || group.length === 0) return [];
|
|
77576
|
+
const maxByRatio = Math.ceil(group.length * selectionRatio);
|
|
77577
|
+
const effectiveLimit = Math.min(take, maxByRatio);
|
|
77578
|
+
const randomSelected = group.filter(() => Math.random() < selectionRatio);
|
|
77579
|
+
return deduplicateWithBundleBySigner(randomSelected).slice(0, effectiveLimit);
|
|
77580
|
+
}
|
|
77454
77581
|
};
|
|
77455
77582
|
__publicField$4(SimpleMempoolViewer, "defaultMoniker", MempoolViewerMoniker);
|
|
77456
77583
|
__publicField$4(SimpleMempoolViewer, "dependencies", [WindowedBlockViewerMoniker]);
|
|
@@ -77458,9 +77585,9 @@ __publicField$4(SimpleMempoolViewer, "monikers", [MempoolViewerMoniker]);
|
|
|
77458
77585
|
SimpleMempoolViewer = __decorateClass$4([
|
|
77459
77586
|
creatableProvider()
|
|
77460
77587
|
], SimpleMempoolViewer);
|
|
77461
|
-
function
|
|
77588
|
+
function deduplicateWithBundleBySigner(items) {
|
|
77462
77589
|
const seen = /* @__PURE__ */ new Set();
|
|
77463
|
-
return
|
|
77590
|
+
return items.filter(({ tx }) => {
|
|
77464
77591
|
const key = tx[0].addresses.toSorted().join(",");
|
|
77465
77592
|
if (seen.has(key)) return false;
|
|
77466
77593
|
seen.add(key);
|
|
@@ -79567,7 +79694,7 @@ function requireRe () {
|
|
|
79567
79694
|
createToken('GTLT', '((?:<|>)?=?)');
|
|
79568
79695
|
|
|
79569
79696
|
// Something like "2.*" or "1.2.x".
|
|
79570
|
-
// Note that "x.x" is a valid xRange
|
|
79697
|
+
// Note that "x.x" is a valid xRange identifier, meaning "any version"
|
|
79571
79698
|
// Only the first item is strictly required.
|
|
79572
79699
|
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
|
|
79573
79700
|
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);
|
|
@@ -80563,6 +80690,62 @@ function requireCoerce () {
|
|
|
80563
80690
|
return coerce_1;
|
|
80564
80691
|
}
|
|
80565
80692
|
|
|
80693
|
+
var truncate_1;
|
|
80694
|
+
var hasRequiredTruncate;
|
|
80695
|
+
|
|
80696
|
+
function requireTruncate () {
|
|
80697
|
+
if (hasRequiredTruncate) return truncate_1;
|
|
80698
|
+
hasRequiredTruncate = 1;
|
|
80699
|
+
|
|
80700
|
+
const parse = requireParse$1();
|
|
80701
|
+
const constants = requireConstants();
|
|
80702
|
+
const SemVer = requireSemver$1();
|
|
80703
|
+
|
|
80704
|
+
const truncate = (version, truncation, options) => {
|
|
80705
|
+
if (!constants.RELEASE_TYPES.includes(truncation)) {
|
|
80706
|
+
return null
|
|
80707
|
+
}
|
|
80708
|
+
|
|
80709
|
+
const clonedVersion = cloneInputVersion(version, options);
|
|
80710
|
+
return clonedVersion && doTruncation(clonedVersion, truncation)
|
|
80711
|
+
};
|
|
80712
|
+
|
|
80713
|
+
const cloneInputVersion = (version, options) => {
|
|
80714
|
+
const versionStringToParse = (
|
|
80715
|
+
version instanceof SemVer ? version.version : version
|
|
80716
|
+
);
|
|
80717
|
+
|
|
80718
|
+
return parse(versionStringToParse, options)
|
|
80719
|
+
};
|
|
80720
|
+
|
|
80721
|
+
const doTruncation = (version, truncation) => {
|
|
80722
|
+
if (isPrerelease(truncation)) {
|
|
80723
|
+
return version.version
|
|
80724
|
+
}
|
|
80725
|
+
|
|
80726
|
+
version.prerelease = [];
|
|
80727
|
+
|
|
80728
|
+
switch (truncation) {
|
|
80729
|
+
case 'major':
|
|
80730
|
+
version.minor = 0;
|
|
80731
|
+
version.patch = 0;
|
|
80732
|
+
break
|
|
80733
|
+
case 'minor':
|
|
80734
|
+
version.patch = 0;
|
|
80735
|
+
break
|
|
80736
|
+
}
|
|
80737
|
+
|
|
80738
|
+
return version.format()
|
|
80739
|
+
};
|
|
80740
|
+
|
|
80741
|
+
const isPrerelease = (type) => {
|
|
80742
|
+
return type.startsWith('pre')
|
|
80743
|
+
};
|
|
80744
|
+
|
|
80745
|
+
truncate_1 = truncate;
|
|
80746
|
+
return truncate_1;
|
|
80747
|
+
}
|
|
80748
|
+
|
|
80566
80749
|
var lrucache;
|
|
80567
80750
|
var hasRequiredLrucache;
|
|
80568
80751
|
|
|
@@ -82012,6 +82195,7 @@ function requireSemver () {
|
|
|
82012
82195
|
const lte = requireLte();
|
|
82013
82196
|
const cmp = requireCmp();
|
|
82014
82197
|
const coerce = requireCoerce();
|
|
82198
|
+
const truncate = requireTruncate();
|
|
82015
82199
|
const Comparator = requireComparator();
|
|
82016
82200
|
const Range = requireRange$1();
|
|
82017
82201
|
const satisfies = requireSatisfies();
|
|
@@ -82050,6 +82234,7 @@ function requireSemver () {
|
|
|
82050
82234
|
lte,
|
|
82051
82235
|
cmp,
|
|
82052
82236
|
coerce,
|
|
82237
|
+
truncate,
|
|
82053
82238
|
Comparator,
|
|
82054
82239
|
Range,
|
|
82055
82240
|
satisfies,
|
|
@@ -85149,38 +85334,29 @@ JsonRpcAccountBalanceViewer = __decorateClass$3([
|
|
|
85149
85334
|
], JsonRpcAccountBalanceViewer);
|
|
85150
85335
|
var JsonRpcBlockViewerMethods = class extends AbstractJsonRpcViewer {
|
|
85151
85336
|
moniker = BlockViewerMoniker;
|
|
85152
|
-
dataLakeViewer;
|
|
85153
85337
|
async blocksByHash(hash, limit) {
|
|
85154
|
-
|
|
85338
|
+
return await this.transport.sendRequest(
|
|
85155
85339
|
"blockViewer_blocksByHash",
|
|
85156
85340
|
isDefined(limit) ? [hash, limit] : [hash]
|
|
85157
85341
|
);
|
|
85158
|
-
return await Promise.all(result.map(async (block) => (await addDataLakePayloads(block, this.dataLakeViewer))[0]));
|
|
85159
85342
|
}
|
|
85160
85343
|
async blocksByNumber(block, limit) {
|
|
85161
|
-
|
|
85344
|
+
return await this.transport.sendRequest(
|
|
85162
85345
|
"blockViewer_blocksByNumber",
|
|
85163
85346
|
isDefined(limit) ? [block, limit] : [block]
|
|
85164
85347
|
);
|
|
85165
|
-
return await Promise.all(result.map(async (block2) => (await addDataLakePayloads(block2, this.dataLakeViewer))[0]));
|
|
85166
|
-
}
|
|
85167
|
-
async createHandler() {
|
|
85168
|
-
await super.createHandler();
|
|
85169
|
-
this.dataLakeViewer = await this.locator.tryGetInstance(DataLakeViewerMoniker);
|
|
85170
85348
|
}
|
|
85171
85349
|
async currentBlock() {
|
|
85172
|
-
|
|
85350
|
+
return await this.transport.sendRequest(
|
|
85173
85351
|
"blockViewer_currentBlock",
|
|
85174
85352
|
[]
|
|
85175
85353
|
);
|
|
85176
|
-
return (await addDataLakePayloads(result, this.dataLakeViewer))[0];
|
|
85177
85354
|
}
|
|
85178
85355
|
async payloadsByHash(hashes) {
|
|
85179
|
-
|
|
85356
|
+
return await this.transport.sendRequest(
|
|
85180
85357
|
"blockViewer_payloadsByHash",
|
|
85181
85358
|
[hashes]
|
|
85182
85359
|
);
|
|
85183
|
-
return (await addDataLakePayloadsToPayloads(hashes, result, this.dataLakeViewer))[0];
|
|
85184
85360
|
}
|
|
85185
85361
|
schemas() {
|
|
85186
85362
|
return BlockViewerRpcSchemas;
|
|
@@ -85530,7 +85706,6 @@ JsonRpcTimeSyncViewer = __decorateClass$3([
|
|
|
85530
85706
|
], JsonRpcTimeSyncViewer);
|
|
85531
85707
|
var JsonRpcTransactionViewer = class extends AbstractJsonRpcViewer {
|
|
85532
85708
|
moniker = JsonRpcTransactionViewer.defaultMoniker;
|
|
85533
|
-
dataLakeViewer;
|
|
85534
85709
|
_blockViewer;
|
|
85535
85710
|
get blockViewer() {
|
|
85536
85711
|
return this._blockViewer;
|
|
@@ -85566,24 +85741,23 @@ var JsonRpcTransactionViewer = class extends AbstractJsonRpcViewer {
|
|
|
85566
85741
|
}
|
|
85567
85742
|
async byHash(transactionHash) {
|
|
85568
85743
|
const result = await this.transport.sendRequest("transactionViewer_byHash", [transactionHash]);
|
|
85569
|
-
return result
|
|
85744
|
+
return result ?? null;
|
|
85570
85745
|
}
|
|
85571
85746
|
async createHandler() {
|
|
85572
85747
|
await super.createHandler();
|
|
85573
85748
|
this._blockViewer = await this.locator.getInstance(BlockViewerMoniker);
|
|
85574
|
-
this.dataLakeViewer = await this.locator.tryGetInstance(DataLakeViewerMoniker);
|
|
85575
85749
|
}
|
|
85576
85750
|
async transactionByBlockHashAndIndex(blockHash, transactionIndex) {
|
|
85577
85751
|
const result = await this.transport.sendRequest("transactionViewer_transactionByBlockHashAndIndex", [blockHash, transactionIndex]);
|
|
85578
|
-
return result
|
|
85752
|
+
return result ?? null;
|
|
85579
85753
|
}
|
|
85580
85754
|
async transactionByBlockNumberAndIndex(blockNumber, transactionIndex) {
|
|
85581
85755
|
const result = await this.transport.sendRequest("transactionViewer_transactionByBlockNumberAndIndex", [blockNumber, transactionIndex]);
|
|
85582
|
-
return result
|
|
85756
|
+
return result ?? null;
|
|
85583
85757
|
}
|
|
85584
85758
|
async transactionByHash(transactionHash) {
|
|
85585
85759
|
const result = await this.transport.sendRequest("transactionViewer_transactionByHash", [transactionHash]);
|
|
85586
|
-
return result
|
|
85760
|
+
return result ?? null;
|
|
85587
85761
|
}
|
|
85588
85762
|
schemas() {
|
|
85589
85763
|
return TransactionViewerRpcSchemas;
|
|
@@ -111901,6 +112075,16 @@ var validateHydratedBlock = /* @__PURE__ */ __name$g(async (context, hydratedBlo
|
|
|
111901
112075
|
}
|
|
111902
112076
|
return errors;
|
|
111903
112077
|
}, "validateHydratedBlock");
|
|
112078
|
+
function offendingTransactionHashesForAddress(block, address) {
|
|
112079
|
+
const hashes = [];
|
|
112080
|
+
for (const payload of block[1]) {
|
|
112081
|
+
if (isSignedTransactionBoundWitnessWithHashMeta(payload) && payload.from === address) {
|
|
112082
|
+
hashes.push(payload._hash);
|
|
112083
|
+
}
|
|
112084
|
+
}
|
|
112085
|
+
return hashes;
|
|
112086
|
+
}
|
|
112087
|
+
__name$g(offendingTransactionHashesForAddress, "offendingTransactionHashesForAddress");
|
|
111904
112088
|
var RequiredBalanceBlockStateValidator = /* @__PURE__ */ __name$g(async (context, block) => {
|
|
111905
112089
|
return await spanRootAsync("RequiredBalanceBlockStateValidator", async () => {
|
|
111906
112090
|
const errors = [];
|
|
@@ -111930,7 +112114,8 @@ var RequiredBalanceBlockStateValidator = /* @__PURE__ */ __name$g(async (context
|
|
|
111930
112114
|
});
|
|
111931
112115
|
const balance = result[address] ?? AttoXL1(0n);
|
|
111932
112116
|
if (address !== XYO_ZERO_ADDRESS && reqBalance > balance) {
|
|
111933
|
-
|
|
112117
|
+
const offendingTransactionHashes = offendingTransactionHashesForAddress(block, address);
|
|
112118
|
+
errors.push(new HydratedBlockStateValidationError(block?.[0]?._hash ?? ZERO_HASH, chainId, block, `insufficient balance for ${address} ${balance} < ${requiredBalances[address]}`, void 0, offendingTransactionHashes.length > 0 ? offendingTransactionHashes : void 0));
|
|
111934
112119
|
}
|
|
111935
112120
|
}
|
|
111936
112121
|
}, context);
|
|
@@ -111963,6 +112148,24 @@ var validateHydratedBlockState = /* @__PURE__ */ __name$g(async (context, hydrat
|
|
|
111963
112148
|
return errors;
|
|
111964
112149
|
}, context);
|
|
111965
112150
|
}, "validateHydratedBlockState");
|
|
112151
|
+
async function balanceShortfallErrors(context, tx, requiredBalances) {
|
|
112152
|
+
const errors = [];
|
|
112153
|
+
const requiredAddresses = Object.keys(requiredBalances);
|
|
112154
|
+
if (requiredAddresses.length === 0) return errors;
|
|
112155
|
+
const headBlock = (await context.blockViewer.currentBlock())[0];
|
|
112156
|
+
const balances = await context.accountBalanceViewer.accountBalances(requiredAddresses, {
|
|
112157
|
+
head: headBlock._hash
|
|
112158
|
+
});
|
|
112159
|
+
for (const address of requiredAddresses) {
|
|
112160
|
+
const reqBalance = requiredBalances[address];
|
|
112161
|
+
const balance = balances[address] ?? AttoXL1(0n);
|
|
112162
|
+
if (address !== XYO_ZERO_ADDRESS && reqBalance > balance) {
|
|
112163
|
+
errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, `insufficient balance for ${address} ${balance} < ${reqBalance}`));
|
|
112164
|
+
}
|
|
112165
|
+
}
|
|
112166
|
+
return errors;
|
|
112167
|
+
}
|
|
112168
|
+
__name$g(balanceShortfallErrors, "balanceShortfallErrors");
|
|
111966
112169
|
var RequiredBalanceTransactionStateValidator = /* @__PURE__ */ __name$g(async (context, tx) => {
|
|
111967
112170
|
return await spanRootAsync("RequiredBalanceTransactionStateValidator", async () => {
|
|
111968
112171
|
const errors = [];
|
|
@@ -111972,26 +112175,18 @@ var RequiredBalanceTransactionStateValidator = /* @__PURE__ */ __name$g(async (c
|
|
|
111972
112175
|
}, tx[1]);
|
|
111973
112176
|
const wrapper = await HydratedTransactionWrapper.parse(tx);
|
|
111974
112177
|
const from = wrapper.boundWitness.from;
|
|
111975
|
-
const
|
|
112178
|
+
const gasRequired = transactionRequiredGas(tx);
|
|
112179
|
+
if (wrapper.fees.gasLimit < gasRequired) {
|
|
112180
|
+
errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, `fees.gasLimit ${wrapper.fees.gasLimit} < required gas ${gasRequired}`));
|
|
112181
|
+
}
|
|
112182
|
+
const gasCost = gasRequired * wrapper.fees.gasPrice;
|
|
111976
112183
|
const baseCost = wrapper.fees.base;
|
|
111977
112184
|
netBalances[from] = (netBalances[from] ?? 0n) - gasCost - baseCost;
|
|
111978
112185
|
const requiredBalances = {};
|
|
111979
112186
|
for (const [address, net] of Object.entries(netBalances)) {
|
|
111980
112187
|
if (net < 0n) requiredBalances[address] = -net;
|
|
111981
112188
|
}
|
|
111982
|
-
|
|
111983
|
-
if (requiredAddresses.length === 0) return errors;
|
|
111984
|
-
const headBlock = (await context.blockViewer.currentBlock())[0];
|
|
111985
|
-
const balances = await context.accountBalanceViewer.accountBalances(requiredAddresses, {
|
|
111986
|
-
head: headBlock._hash
|
|
111987
|
-
});
|
|
111988
|
-
for (const address of requiredAddresses) {
|
|
111989
|
-
const reqBalance = requiredBalances[address];
|
|
111990
|
-
const balance = balances[address] ?? AttoXL1(0n);
|
|
111991
|
-
if (address !== XYO_ZERO_ADDRESS && reqBalance > balance) {
|
|
111992
|
-
errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, `insufficient balance for ${address} ${balance} < ${reqBalance}`));
|
|
111993
|
-
}
|
|
111994
|
-
}
|
|
112189
|
+
errors.push(...await balanceShortfallErrors(context, tx, requiredBalances));
|
|
111995
112190
|
} catch (ex) {
|
|
111996
112191
|
errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, `Failed RequiredBalanceTransactionStateValidator: ${ex}`, ex));
|
|
111997
112192
|
}
|
|
@@ -113615,6 +113810,70 @@ async function generateTransactionFeeTransfers(address, transactions) {
|
|
|
113615
113810
|
return payloads;
|
|
113616
113811
|
}
|
|
113617
113812
|
__name$d(generateTransactionFeeTransfers, "generateTransactionFeeTransfers");
|
|
113813
|
+
async function scoreTransaction(tx) {
|
|
113814
|
+
const wrapper = await HydratedTransactionWrapper.parse(tx);
|
|
113815
|
+
const from = wrapper.boundWitness.from;
|
|
113816
|
+
const gasPrice = wrapper.fees.gasPrice;
|
|
113817
|
+
const gasCost = transactionRequiredGas(tx) * gasPrice;
|
|
113818
|
+
const baseCost = wrapper.fees.base;
|
|
113819
|
+
const netBalances = netBalancesForPayloads({
|
|
113820
|
+
}, tx[1]);
|
|
113821
|
+
const fromNet = netBalances[from] ?? 0n;
|
|
113822
|
+
const transferOut = fromNet < 0n ? -fromNet : 0n;
|
|
113823
|
+
return {
|
|
113824
|
+
cost: gasCost + baseCost + transferOut,
|
|
113825
|
+
gasPrice
|
|
113826
|
+
};
|
|
113827
|
+
}
|
|
113828
|
+
__name$d(scoreTransaction, "scoreTransaction");
|
|
113829
|
+
async function identifyOffendingTransactions(args) {
|
|
113830
|
+
const { errors, candidateTransactions } = args;
|
|
113831
|
+
const candidateHashes = new Set(candidateTransactions.map((tx) => tx[0]._hash));
|
|
113832
|
+
const txInvalidHashes = /* @__PURE__ */ new Set();
|
|
113833
|
+
for (const error of errors) {
|
|
113834
|
+
if (candidateHashes.has(error.hash)) txInvalidHashes.add(error.hash);
|
|
113835
|
+
const cause = error.cause;
|
|
113836
|
+
if (cause?.hash && candidateHashes.has(cause.hash)) txInvalidHashes.add(cause.hash);
|
|
113837
|
+
}
|
|
113838
|
+
if (txInvalidHashes.size > 0) {
|
|
113839
|
+
return {
|
|
113840
|
+
offendingHashes: [
|
|
113841
|
+
...txInvalidHashes
|
|
113842
|
+
],
|
|
113843
|
+
reason: "tx-invalid"
|
|
113844
|
+
};
|
|
113845
|
+
}
|
|
113846
|
+
const balanceOffenderHashes = /* @__PURE__ */ new Set();
|
|
113847
|
+
for (const error of errors) {
|
|
113848
|
+
const offendingHashes = error.offendingTransactionHashes ?? [];
|
|
113849
|
+
for (const hash of offendingHashes) {
|
|
113850
|
+
if (candidateHashes.has(hash)) balanceOffenderHashes.add(hash);
|
|
113851
|
+
}
|
|
113852
|
+
}
|
|
113853
|
+
if (balanceOffenderHashes.size === 0) {
|
|
113854
|
+
return {
|
|
113855
|
+
offendingHashes: [],
|
|
113856
|
+
reason: "unknown"
|
|
113857
|
+
};
|
|
113858
|
+
}
|
|
113859
|
+
const offenders = candidateTransactions.filter((tx) => balanceOffenderHashes.has(tx[0]._hash));
|
|
113860
|
+
const scored = await Promise.all(offenders.map(async (tx) => ({
|
|
113861
|
+
tx,
|
|
113862
|
+
...await scoreTransaction(tx)
|
|
113863
|
+
})));
|
|
113864
|
+
scored.sort((a, b) => {
|
|
113865
|
+
if (a.cost !== b.cost) return a.cost < b.cost ? 1 : -1;
|
|
113866
|
+
if (a.gasPrice !== b.gasPrice) return a.gasPrice < b.gasPrice ? -1 : 1;
|
|
113867
|
+
return a.tx[0]._hash < b.tx[0]._hash ? -1 : 1;
|
|
113868
|
+
});
|
|
113869
|
+
return {
|
|
113870
|
+
offendingHashes: [
|
|
113871
|
+
scored[0].tx[0]._hash
|
|
113872
|
+
],
|
|
113873
|
+
reason: "block-balance"
|
|
113874
|
+
};
|
|
113875
|
+
}
|
|
113876
|
+
__name$d(identifyOffendingTransactions, "identifyOffendingTransactions");
|
|
113618
113877
|
|
|
113619
113878
|
// src/simple/block/runner/SimpleBlockRunner.ts
|
|
113620
113879
|
function _ts_decorate4(decorators, target, key, desc) {
|
|
@@ -113647,6 +113906,9 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
113647
113906
|
moniker = _SimpleBlockRunner.defaultMoniker;
|
|
113648
113907
|
_blockRewardDiviner;
|
|
113649
113908
|
_deadLetterQueueRunner;
|
|
113909
|
+
// TODO(producer-exclusion-set): uncapped for v1. If memory grows in long-running producers,
|
|
113910
|
+
// add FIFO eviction or a TTL keyed off block number.
|
|
113911
|
+
_excludedTransactionHashes = /* @__PURE__ */ new Set();
|
|
113650
113912
|
_lastRedeclarationBlock;
|
|
113651
113913
|
_rejectedTransactionsArchivist;
|
|
113652
113914
|
_account;
|
|
@@ -113788,17 +114050,18 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
113788
114050
|
const { block: previousBlock } = assertEx(asBlockBoundWitness(head), () => "Invalid head block");
|
|
113789
114051
|
const nextBlock = previousBlock + 1;
|
|
113790
114052
|
const chainId = await this.finalizationViewer.chainId();
|
|
113791
|
-
const
|
|
114053
|
+
const pendingTransactionsRaw = await this.mempoolViewer.pendingTransactions({
|
|
113792
114054
|
limit: _SimpleBlockRunner.DefaultBlockSize
|
|
113793
114055
|
});
|
|
114056
|
+
const pendingTransactions = pendingTransactionsRaw.filter((tx) => !this._excludedTransactionHashes.has(tx[0]._hash));
|
|
113794
114057
|
const nextBlockTransactions = await this.rejectWrongChainTransactions(pendingTransactions, chainId);
|
|
113795
114058
|
this.logger?.log(`Pending Tx Count ${nextBlockTransactions.length}`);
|
|
113796
|
-
const
|
|
114059
|
+
const nonTxPayloads = [];
|
|
113797
114060
|
const producerRedeclarationPayload = await this.getProducerRedeclaration(head);
|
|
113798
|
-
if (producerRedeclarationPayload)
|
|
114061
|
+
if (producerRedeclarationPayload) nonTxPayloads.push(producerRedeclarationPayload);
|
|
113799
114062
|
if (nextBlockTransactions.length === 0 && !this.heartbeatRequired(head) && !force) return;
|
|
113800
114063
|
const rewardTransferPayloads = await this.getBlockRewardTransfers(nextBlock);
|
|
113801
|
-
|
|
114064
|
+
nonTxPayloads.push(...rewardTransferPayloads);
|
|
113802
114065
|
const transactionTransfers = await generateTransactionFeeTransfers(this.address, nextBlockTransactions);
|
|
113803
114066
|
const timeStart = Date.now();
|
|
113804
114067
|
const timePayload = await this.generateTimePayload();
|
|
@@ -113806,48 +114069,26 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
113806
114069
|
if (timeDuration > 100) {
|
|
113807
114070
|
this.logger?.warn(`[Slow] Generated time payload in ${timeDuration}ms`);
|
|
113808
114071
|
}
|
|
113809
|
-
const [
|
|
113810
|
-
blockPayloads.push(...fundedTransfers, timePayload);
|
|
113811
|
-
this.logger?.info(`Building block ${head.block + 1}`);
|
|
113812
|
-
const startBuild = Date.now();
|
|
114072
|
+
const [initialFundedTransactions, initialFundedTransfers] = await this.filterByFunded(head, nextBlockTransactions, transactionTransfers, validateBalances);
|
|
113813
114073
|
const stepRewardPoolBalance = (await this.accountBalanceViewer.accountBalances([
|
|
113814
114074
|
XYO_STEP_REWARD_ADDRESS
|
|
113815
114075
|
]))[XYO_STEP_REWARD_ADDRESS];
|
|
113816
|
-
const
|
|
113817
|
-
|
|
113818
|
-
|
|
113819
|
-
|
|
113820
|
-
|
|
113821
|
-
|
|
113822
|
-
|
|
113823
|
-
|
|
114076
|
+
const result = await this.runBuildValidateRetryLoop({
|
|
114077
|
+
head,
|
|
114078
|
+
chainId,
|
|
114079
|
+
stepRewardPoolBalance,
|
|
114080
|
+
nonTxPayloads,
|
|
114081
|
+
timePayload,
|
|
114082
|
+
initialFundedTransactions,
|
|
114083
|
+
initialFundedTransfers
|
|
113824
114084
|
});
|
|
113825
|
-
|
|
113826
|
-
if (isSignedHydratedBlockWithHashMeta(validatedBlock)) {
|
|
114085
|
+
if (isSignedHydratedBlockWithHashMeta(result.block)) {
|
|
113827
114086
|
await this.mempoolRunner.submitBlocks([
|
|
113828
|
-
|
|
114087
|
+
result.block
|
|
113829
114088
|
]);
|
|
113830
|
-
return
|
|
113831
|
-
} else {
|
|
113832
|
-
const errors = validatedBlock;
|
|
113833
|
-
this.logger?.warn(`Validation of produced block failed: ${errors.at(0)?.message}`);
|
|
113834
|
-
if (this._deadLetterQueueRunner) {
|
|
113835
|
-
const rejectionErrors = errors.map((e) => ({
|
|
113836
|
-
hash: block[0]._hash,
|
|
113837
|
-
name: "BlockValidationError",
|
|
113838
|
-
message: String(e.message ?? e)
|
|
113839
|
-
}));
|
|
113840
|
-
await this._deadLetterQueueRunner.rejectBlock({
|
|
113841
|
-
schema: BlockRejectionSchema,
|
|
113842
|
-
block,
|
|
113843
|
-
errors: rejectionErrors,
|
|
113844
|
-
rejector: "producer"
|
|
113845
|
-
});
|
|
113846
|
-
} else {
|
|
113847
|
-
const rejectedTransactions = block[1];
|
|
113848
|
-
await this.rejectedTransactionsArchivist.insert(rejectedTransactions);
|
|
113849
|
-
}
|
|
114089
|
+
return result.block;
|
|
113850
114090
|
}
|
|
114091
|
+
if (result.block) await this.rejectExhaustedBlock(result.block, result.errors);
|
|
113851
114092
|
} catch (error) {
|
|
113852
114093
|
this.logger?.error(`Error proposing next valid block: ${error.message}`);
|
|
113853
114094
|
throw error;
|
|
@@ -113894,6 +114135,24 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
113894
114135
|
}
|
|
113895
114136
|
return false;
|
|
113896
114137
|
}
|
|
114138
|
+
async rejectExhaustedBlock(block, errors) {
|
|
114139
|
+
this.logger?.warn(`Validation of produced block failed: ${errors.at(0)?.message}`);
|
|
114140
|
+
if (this._deadLetterQueueRunner) {
|
|
114141
|
+
const rejectionErrors = errors.map((e) => ({
|
|
114142
|
+
hash: block[0]._hash,
|
|
114143
|
+
name: "BlockValidationError",
|
|
114144
|
+
message: String(e.message ?? e)
|
|
114145
|
+
}));
|
|
114146
|
+
await this._deadLetterQueueRunner.rejectBlock({
|
|
114147
|
+
schema: BlockRejectionSchema,
|
|
114148
|
+
block,
|
|
114149
|
+
errors: rejectionErrors,
|
|
114150
|
+
rejector: "producer"
|
|
114151
|
+
});
|
|
114152
|
+
} else {
|
|
114153
|
+
await this.rejectedTransactionsArchivist.insert(block[1]);
|
|
114154
|
+
}
|
|
114155
|
+
}
|
|
113897
114156
|
// Partition pending transactions by chain-ID match; route mismatches to the transaction DLQ.
|
|
113898
114157
|
async rejectWrongChainTransactions(transactions, chainId) {
|
|
113899
114158
|
const localChain = chainId.toLowerCase();
|
|
@@ -113924,6 +114183,51 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
113924
114183
|
}
|
|
113925
114184
|
return matched;
|
|
113926
114185
|
}
|
|
114186
|
+
async runBuildValidateRetryLoop(args) {
|
|
114187
|
+
const { chainId, head, initialFundedTransactions, initialFundedTransfers, nonTxPayloads, stepRewardPoolBalance, timePayload } = args;
|
|
114188
|
+
const maxAttempts = Math.max(1, initialFundedTransactions.length);
|
|
114189
|
+
let candidateTransactions = initialFundedTransactions;
|
|
114190
|
+
let candidateTransfers = initialFundedTransfers;
|
|
114191
|
+
let lastBlock;
|
|
114192
|
+
let lastErrors = [];
|
|
114193
|
+
for (let attempt = 0; attempt <= maxAttempts; attempt++) {
|
|
114194
|
+
const blockPayloads = [
|
|
114195
|
+
...nonTxPayloads,
|
|
114196
|
+
...candidateTransfers,
|
|
114197
|
+
timePayload
|
|
114198
|
+
];
|
|
114199
|
+
this.logger?.info(`Building block ${head.block + 1}${attempt > 0 ? ` (retry ${attempt})` : ""}`);
|
|
114200
|
+
lastBlock = await buildNextBlock(head, candidateTransactions, blockPayloads, [
|
|
114201
|
+
this.account
|
|
114202
|
+
], XYO_STEP_REWARD_ADDRESS, stepRewardPoolBalance, void 0, chainId);
|
|
114203
|
+
const validated = await this.blockValidationViewer.validateBlock(lastBlock, {
|
|
114204
|
+
head: head._hash
|
|
114205
|
+
});
|
|
114206
|
+
if (isSignedHydratedBlockWithHashMeta(validated)) {
|
|
114207
|
+
return {
|
|
114208
|
+
block: validated,
|
|
114209
|
+
errors: []
|
|
114210
|
+
};
|
|
114211
|
+
}
|
|
114212
|
+
lastErrors = validated;
|
|
114213
|
+
if (attempt === maxAttempts) break;
|
|
114214
|
+
const { offendingHashes, reason } = await identifyOffendingTransactions({
|
|
114215
|
+
candidateTransactions,
|
|
114216
|
+
errors: validated
|
|
114217
|
+
});
|
|
114218
|
+
if (offendingHashes.length === 0 || reason === "unknown") break;
|
|
114219
|
+
for (const offendingHash of offendingHashes) this._excludedTransactionHashes.add(offendingHash);
|
|
114220
|
+
const offendingSet = new Set(offendingHashes);
|
|
114221
|
+
candidateTransactions = candidateTransactions.filter((tx) => !offendingSet.has(tx[0]._hash));
|
|
114222
|
+
const remainingFromAddresses = new Set(candidateTransactions.map((tx) => tx[0].from));
|
|
114223
|
+
candidateTransfers = (await generateTransactionFeeTransfers(this.address, candidateTransactions)).filter((t) => remainingFromAddresses.has(t.from));
|
|
114224
|
+
this.logger?.warn(`Block validation failed (attempt ${attempt + 1}); excluded ${offendingHashes.length} tx(s), retrying`);
|
|
114225
|
+
}
|
|
114226
|
+
return {
|
|
114227
|
+
block: lastBlock,
|
|
114228
|
+
errors: lastErrors
|
|
114229
|
+
};
|
|
114230
|
+
}
|
|
113927
114231
|
};
|
|
113928
114232
|
SimpleBlockRunner = _ts_decorate4([
|
|
113929
114233
|
creatableProvider()
|
|
@@ -185742,6 +186046,8 @@ BaseConfigContextZod.extend({
|
|
|
185742
186046
|
});
|
|
185743
186047
|
var DEFAULT_MEMPOOL_BLOCK_PRUNE_INTERVAL = 1e3;
|
|
185744
186048
|
var DEFAULT_MEMPOOL_TRANSACTION_PRUNE_INTERVAL = 1e3;
|
|
186049
|
+
var DEFAULT_MEMPOOL_DEMOTION_THRESHOLD = 3;
|
|
186050
|
+
var DEFAULT_MEMPOOL_MAX_PENDING_TRANSACTIONS = 0;
|
|
185745
186051
|
var MempoolConfigZod = HostActorConfigZod.extend({
|
|
185746
186052
|
enabled: union$1([
|
|
185747
186053
|
string$2(),
|
|
@@ -185778,6 +186084,16 @@ var MempoolConfigZod = HostActorConfigZod.extend({
|
|
|
185778
186084
|
title: "mempool.blockPruneInterval",
|
|
185779
186085
|
type: "number"
|
|
185780
186086
|
}),
|
|
186087
|
+
demotionThreshold: number$2().int().positive().default(DEFAULT_MEMPOOL_DEMOTION_THRESHOLD).register(globalRegistry, {
|
|
186088
|
+
description: "Number of times a transaction may be handed out to producers without being included in a block before it is considered demoted",
|
|
186089
|
+
title: "mempool.demotionThreshold",
|
|
186090
|
+
type: "number"
|
|
186091
|
+
}),
|
|
186092
|
+
maxPendingTransactions: number$2().int().nonnegative().default(DEFAULT_MEMPOOL_MAX_PENDING_TRANSACTIONS).register(globalRegistry, {
|
|
186093
|
+
description: "Maximum number of pending transactions in the pool. When exceeded, demoted transactions are evicted first, then oldest by sequence. 0 disables the cap.",
|
|
186094
|
+
title: "mempool.maxPendingTransactions",
|
|
186095
|
+
type: "number"
|
|
186096
|
+
}),
|
|
185781
186097
|
transactionPruneInterval: number$2().default(DEFAULT_MEMPOOL_TRANSACTION_PRUNE_INTERVAL).register(globalRegistry, {
|
|
185782
186098
|
description: "The interval time (in milliseconds) between pending transaction prune attempts",
|
|
185783
186099
|
title: "mempool.transactionPruneInterval",
|
|
@@ -186543,6 +186859,14 @@ function createDefaultCapabilityRegistry() {
|
|
|
186543
186859
|
return registry;
|
|
186544
186860
|
}
|
|
186545
186861
|
__name$8(createDefaultCapabilityRegistry, "createDefaultCapabilityRegistry");
|
|
186862
|
+
function readMempoolTuning(ctx) {
|
|
186863
|
+
const cfg = ctx.actorContext.config;
|
|
186864
|
+
return {
|
|
186865
|
+
demotionThreshold: cfg?.mempool?.demotionThreshold,
|
|
186866
|
+
maxPendingTransactions: cfg?.mempool?.maxPendingTransactions
|
|
186867
|
+
};
|
|
186868
|
+
}
|
|
186869
|
+
__name$8(readMempoolTuning, "readMempoolTuning");
|
|
186546
186870
|
var passes = /* @__PURE__ */ __name$8(() => true, "passes");
|
|
186547
186871
|
var localTier1Descriptors = [
|
|
186548
186872
|
{
|
|
@@ -186559,10 +186883,14 @@ var localTier1Descriptors = [
|
|
|
186559
186883
|
],
|
|
186560
186884
|
surface: "node",
|
|
186561
186885
|
preconditions: passes,
|
|
186562
|
-
build: /* @__PURE__ */ __name$8((ctx) =>
|
|
186563
|
-
|
|
186564
|
-
|
|
186565
|
-
|
|
186886
|
+
build: /* @__PURE__ */ __name$8((ctx) => {
|
|
186887
|
+
const { demotionThreshold } = readMempoolTuning(ctx);
|
|
186888
|
+
return SimpleMempoolViewer.factory(SimpleMempoolViewer.dependencies, {
|
|
186889
|
+
pendingTransactionsArchivist: ctx.process.pendingTransactionsArchivist,
|
|
186890
|
+
pendingBlocksArchivist: ctx.process.pendingBlocksArchivist,
|
|
186891
|
+
demotionThreshold
|
|
186892
|
+
});
|
|
186893
|
+
}, "build")
|
|
186566
186894
|
},
|
|
186567
186895
|
{
|
|
186568
186896
|
id: "SimpleMempoolRunner",
|
|
@@ -186578,10 +186906,14 @@ var localTier1Descriptors = [
|
|
|
186578
186906
|
],
|
|
186579
186907
|
surface: "node",
|
|
186580
186908
|
preconditions: passes,
|
|
186581
|
-
build: /* @__PURE__ */ __name$8((ctx) =>
|
|
186582
|
-
|
|
186583
|
-
|
|
186584
|
-
|
|
186909
|
+
build: /* @__PURE__ */ __name$8((ctx) => {
|
|
186910
|
+
const { maxPendingTransactions } = readMempoolTuning(ctx);
|
|
186911
|
+
return SimpleMempoolRunner.factory(SimpleMempoolRunner.dependencies, {
|
|
186912
|
+
pendingTransactionsArchivist: ctx.process.pendingTransactionsArchivist,
|
|
186913
|
+
pendingBlocksArchivist: ctx.process.pendingBlocksArchivist,
|
|
186914
|
+
maxPendingTransactions
|
|
186915
|
+
});
|
|
186916
|
+
}, "build")
|
|
186585
186917
|
},
|
|
186586
186918
|
{
|
|
186587
186919
|
id: "SimpleAccountBalanceViewer",
|
|
@@ -187731,6 +188063,167 @@ async function rootLocatorFromConfig(context, validateDepsOnRegister = false, on
|
|
|
187731
188063
|
return locator;
|
|
187732
188064
|
}
|
|
187733
188065
|
__name$8(rootLocatorFromConfig, "rootLocatorFromConfig");
|
|
188066
|
+
var apiNeeds = {
|
|
188067
|
+
required: [
|
|
188068
|
+
AccountBalanceViewerMoniker,
|
|
188069
|
+
BlockViewerMoniker,
|
|
188070
|
+
FinalizationViewerMoniker,
|
|
188071
|
+
MempoolViewerMoniker,
|
|
188072
|
+
TransactionViewerMoniker,
|
|
188073
|
+
XyoConnectionMoniker$1,
|
|
188074
|
+
XyoGatewayMoniker,
|
|
188075
|
+
XyoRunnerMoniker,
|
|
188076
|
+
XyoViewerMoniker
|
|
188077
|
+
]
|
|
188078
|
+
};
|
|
188079
|
+
var mempoolNeeds = {
|
|
188080
|
+
required: [
|
|
188081
|
+
MempoolRunnerMoniker,
|
|
188082
|
+
// SimpleMempoolRunner.dependencies includes TransactionValidationViewer
|
|
188083
|
+
// — not resolved by the actor directly but pulled in at construction.
|
|
188084
|
+
TransactionValidationViewerMoniker,
|
|
188085
|
+
// SimpleMempoolViewer.dependencies includes WindowedBlockViewer — the
|
|
188086
|
+
// mempool viewer is built when api/finalizer resolve MempoolViewer.
|
|
188087
|
+
WindowedBlockViewerMoniker
|
|
188088
|
+
]
|
|
188089
|
+
};
|
|
188090
|
+
var finalizerNeeds = {
|
|
188091
|
+
required: [
|
|
188092
|
+
BlockValidationViewerMoniker,
|
|
188093
|
+
BlockViewerMoniker,
|
|
188094
|
+
FinalizationRunnerMoniker,
|
|
188095
|
+
MempoolViewerMoniker
|
|
188096
|
+
],
|
|
188097
|
+
optional: [
|
|
188098
|
+
DeadLetterQueueRunnerMoniker
|
|
188099
|
+
]
|
|
188100
|
+
};
|
|
188101
|
+
var ACTOR_MIRRORS = {
|
|
188102
|
+
api: apiNeeds,
|
|
188103
|
+
mempool: mempoolNeeds,
|
|
188104
|
+
finalizer: finalizerNeeds
|
|
188105
|
+
};
|
|
188106
|
+
var apiExtraDescriptors = [
|
|
188107
|
+
{
|
|
188108
|
+
id: "SimpleXyoRunner",
|
|
188109
|
+
satisfies: [
|
|
188110
|
+
XyoRunnerMoniker
|
|
188111
|
+
],
|
|
188112
|
+
tier: 1,
|
|
188113
|
+
backings: [],
|
|
188114
|
+
surface: "node",
|
|
188115
|
+
preconditions: /* @__PURE__ */ __name$8(() => true, "preconditions"),
|
|
188116
|
+
build: /* @__PURE__ */ __name$8(() => SimpleXyoRunner.factory(SimpleXyoRunner.dependencies, {}), "build")
|
|
188117
|
+
},
|
|
188118
|
+
{
|
|
188119
|
+
id: "SimpleXyoConnectionRunner",
|
|
188120
|
+
satisfies: [
|
|
188121
|
+
XyoConnectionMoniker$1
|
|
188122
|
+
],
|
|
188123
|
+
// Same tier as `SimpleXyoConnectionViewer`; higher priority wins the
|
|
188124
|
+
// `XyoConnection` moniker in any actor mix that includes the API.
|
|
188125
|
+
tier: 1,
|
|
188126
|
+
priority: 100,
|
|
188127
|
+
backings: [],
|
|
188128
|
+
surface: "node",
|
|
188129
|
+
preconditions: /* @__PURE__ */ __name$8(() => true, "preconditions"),
|
|
188130
|
+
build: /* @__PURE__ */ __name$8(() => SimpleXyoConnectionRunner.factory(SimpleXyoConnectionRunner.dependencies, {}), "build")
|
|
188131
|
+
},
|
|
188132
|
+
{
|
|
188133
|
+
id: "SimpleXyoGateway",
|
|
188134
|
+
satisfies: [
|
|
188135
|
+
XyoGatewayMoniker
|
|
188136
|
+
],
|
|
188137
|
+
tier: 1,
|
|
188138
|
+
backings: [],
|
|
188139
|
+
surface: "node",
|
|
188140
|
+
preconditions: /* @__PURE__ */ __name$8(() => true, "preconditions"),
|
|
188141
|
+
build: /* @__PURE__ */ __name$8(() => SimpleXyoGateway.factory(SimpleXyoGateway.dependencies, {}), "build")
|
|
188142
|
+
}
|
|
188143
|
+
];
|
|
188144
|
+
var ACTOR_EXTRA_DESCRIPTORS = {
|
|
188145
|
+
api: apiExtraDescriptors
|
|
188146
|
+
};
|
|
188147
|
+
var ACTOR_CONFIG_PARSERS = {
|
|
188148
|
+
api: ApiConfigZod,
|
|
188149
|
+
mempool: MempoolConfigZod,
|
|
188150
|
+
finalizer: FinalizerConfigZod
|
|
188151
|
+
};
|
|
188152
|
+
var SHARED_LOCATOR_SUPPORTED_ACTORS = [
|
|
188153
|
+
"api",
|
|
188154
|
+
"mempool",
|
|
188155
|
+
"finalizer"
|
|
188156
|
+
];
|
|
188157
|
+
function canUseSharedLocator(actors, config) {
|
|
188158
|
+
if (actors.length === 0) return false;
|
|
188159
|
+
if (config.remote?.rpc) return false;
|
|
188160
|
+
const names = new Set(actors.map((a) => a.name));
|
|
188161
|
+
const fullCanary = SHARED_LOCATOR_SUPPORTED_ACTORS.every((name) => names.has(name));
|
|
188162
|
+
if (!fullCanary) return false;
|
|
188163
|
+
return actors.every((actor) => {
|
|
188164
|
+
if (!SHARED_LOCATOR_SUPPORTED_ACTORS.includes(actor.name)) return false;
|
|
188165
|
+
if (actor.name === "api") {
|
|
188166
|
+
const merged = ApiConfigZod.parse(deepMerge$1(config, actor));
|
|
188167
|
+
if (merged.stateless === true) return false;
|
|
188168
|
+
}
|
|
188169
|
+
return true;
|
|
188170
|
+
});
|
|
188171
|
+
}
|
|
188172
|
+
__name$8(canUseSharedLocator, "canUseSharedLocator");
|
|
188173
|
+
async function sharedLocatorFromConfig(context, actors, config, options = {}) {
|
|
188174
|
+
const unionNeeds2 = {
|
|
188175
|
+
required: dedupe(actors.flatMap((a) => ACTOR_MIRRORS[a.name]?.required ?? [])),
|
|
188176
|
+
optional: dedupe(actors.flatMap((a) => ACTOR_MIRRORS[a.name]?.optional ?? []))
|
|
188177
|
+
};
|
|
188178
|
+
const extraDescriptors = actors.flatMap((a) => ACTOR_EXTRA_DESCRIPTORS[a.name] ?? []);
|
|
188179
|
+
const commonContext = {
|
|
188180
|
+
...context,
|
|
188181
|
+
config: {
|
|
188182
|
+
...config,
|
|
188183
|
+
name: "_shared_common"
|
|
188184
|
+
}
|
|
188185
|
+
};
|
|
188186
|
+
const commonLocator = await commonLocatorFromConfig(commonContext);
|
|
188187
|
+
const sharedContext = {
|
|
188188
|
+
...commonLocator.context,
|
|
188189
|
+
config: {
|
|
188190
|
+
...config,
|
|
188191
|
+
name: "_shared"
|
|
188192
|
+
}
|
|
188193
|
+
};
|
|
188194
|
+
const result = await locatorFromActorNeeds(sharedContext, [
|
|
188195
|
+
unionNeeds2
|
|
188196
|
+
], {
|
|
188197
|
+
extraDescriptors,
|
|
188198
|
+
onInsecureGenesisConfirm: options.onInsecureGenesisConfirm,
|
|
188199
|
+
validateDepsOnRegister: false
|
|
188200
|
+
});
|
|
188201
|
+
const sharedWithEvm = await initEvmProvidersIfAvailable(result.locator);
|
|
188202
|
+
sharedWithEvm.freeze();
|
|
188203
|
+
const perActor = {};
|
|
188204
|
+
for (const actor of actors) {
|
|
188205
|
+
const parser = ACTOR_CONFIG_PARSERS[actor.name];
|
|
188206
|
+
const actorConfig = parser ? parser.parse(deepMerge$1(config, actor)) : actor;
|
|
188207
|
+
const actorContext = {
|
|
188208
|
+
...sharedWithEvm.context,
|
|
188209
|
+
config: actorConfig
|
|
188210
|
+
};
|
|
188211
|
+
const view = new ProviderFactoryLocator(actorContext, sharedWithEvm.registry);
|
|
188212
|
+
view.freeze();
|
|
188213
|
+
perActor[actor.name] = view;
|
|
188214
|
+
}
|
|
188215
|
+
return {
|
|
188216
|
+
shared: sharedWithEvm,
|
|
188217
|
+
perActor
|
|
188218
|
+
};
|
|
188219
|
+
}
|
|
188220
|
+
__name$8(sharedLocatorFromConfig, "sharedLocatorFromConfig");
|
|
188221
|
+
function dedupe(items) {
|
|
188222
|
+
return [
|
|
188223
|
+
...new Set(items)
|
|
188224
|
+
];
|
|
188225
|
+
}
|
|
188226
|
+
__name$8(dedupe, "dedupe");
|
|
187734
188227
|
|
|
187735
188228
|
// src/node/config/locators/locatorsFromConfig.ts
|
|
187736
188229
|
function allActorsAreSelfSufficient(actors, config) {
|
|
@@ -187744,6 +188237,12 @@ function allActorsAreSelfSufficient(actors, config) {
|
|
|
187744
188237
|
__name$8(allActorsAreSelfSufficient, "allActorsAreSelfSufficient");
|
|
187745
188238
|
async function locatorsFromConfig(context, { actors, ...config }, onInsecureGenesisConfirm) {
|
|
187746
188239
|
const result = {};
|
|
188240
|
+
if (canUseSharedLocator(actors, config)) {
|
|
188241
|
+
const { perActor } = await sharedLocatorFromConfig(context, actors, config, {
|
|
188242
|
+
onInsecureGenesisConfirm
|
|
188243
|
+
});
|
|
188244
|
+
return perActor;
|
|
188245
|
+
}
|
|
187747
188246
|
const skipRoot = allActorsAreSelfSufficient(actors, config);
|
|
187748
188247
|
if (!skipRoot) {
|
|
187749
188248
|
const rootContext = {
|
|
@@ -213763,7 +214262,7 @@ if (!nativeAccelerationDisabled) {
|
|
|
213763
214262
|
}
|
|
213764
214263
|
}
|
|
213765
214264
|
|
|
213766
|
-
const version$1 = '5.76.
|
|
214265
|
+
const version$1 = '5.76.8';
|
|
213767
214266
|
|
|
213768
214267
|
/**
|
|
213769
214268
|
* Includes all the scripts needed by the queue and jobs.
|
|
@@ -217230,6 +217729,18 @@ local function getJobSchedulerEveryNextMillis(prevMillis, every, now, offset, st
|
|
|
217230
217729
|
nextMillis = nextMillis > now and nextMillis or now
|
|
217231
217730
|
else
|
|
217232
217731
|
nextMillis = now
|
|
217732
|
+
-- For the first iteration with no startDate and an explicit
|
|
217733
|
+
-- offset, align nextMillis to the next offset slot strictly
|
|
217734
|
+
-- after now. Without this the user-supplied offset is
|
|
217735
|
+
-- recorded but ignored, and the first job fires at now
|
|
217736
|
+
-- instead of the next aligned timestamp (issue #3705).
|
|
217737
|
+
if offset and offset > 0 then
|
|
217738
|
+
local aligned = math.floor(nextMillis / every) * every + offset
|
|
217739
|
+
if aligned <= nextMillis then
|
|
217740
|
+
aligned = aligned + every
|
|
217741
|
+
end
|
|
217742
|
+
nextMillis = aligned
|
|
217743
|
+
end
|
|
217233
217744
|
end
|
|
217234
217745
|
else
|
|
217235
217746
|
nextMillis = prevMillis + every
|
|
@@ -217872,7 +218383,7 @@ const addParentJob = {
|
|
|
217872
218383
|
};
|
|
217873
218384
|
|
|
217874
218385
|
const content$K = `--[[
|
|
217875
|
-
Adds a
|
|
218386
|
+
Adds a prioritized job to the queue by doing the following:
|
|
217876
218387
|
- Increases the job counter if needed.
|
|
217877
218388
|
- Creates a new job key with the job data.
|
|
217878
218389
|
- Adds the job to the "added" list so that workers gets notified.
|
|
@@ -220076,7 +220587,7 @@ const content$D = `--[[
|
|
|
220076
220587
|
ARGV[2] lock duration in milliseconds
|
|
220077
220588
|
ARGV[3] jobid
|
|
220078
220589
|
Output:
|
|
220079
|
-
"1" if lock
|
|
220590
|
+
"1" if lock extended successfully.
|
|
220080
220591
|
]]
|
|
220081
220592
|
local rcall = redis.call
|
|
220082
220593
|
if rcall("GET", KEYS[1]) == ARGV[1] then
|
|
@@ -221007,7 +221518,7 @@ if rcall("EXISTS", stalledCheckKey) == 1 then
|
|
|
221007
221518
|
return {}
|
|
221008
221519
|
end
|
|
221009
221520
|
rcall("SET", stalledCheckKey, timestamp, "PX", maxCheckTime)
|
|
221010
|
-
-- Trim events before
|
|
221521
|
+
-- Trim events before emitting them to avoid trimming events emitted in this script
|
|
221011
221522
|
trimEvents(metaKey, eventStreamKey)
|
|
221012
221523
|
-- Move all stalled jobs to wait
|
|
221013
221524
|
local stalling = rcall('SMEMBERS', stalledKey)
|
|
@@ -221706,7 +222217,7 @@ const moveToDelayed = {
|
|
|
221706
222217
|
};
|
|
221707
222218
|
|
|
221708
222219
|
const content$k = `--[[
|
|
221709
|
-
Move job from active to a finished status (completed
|
|
222220
|
+
Move job from active to a finished status (completed or failed)
|
|
221710
222221
|
A job can only be moved to completed if it was active.
|
|
221711
222222
|
The job must be locked before it can be moved to a finished status,
|
|
221712
222223
|
and the lock must be released in this script.
|
|
@@ -221760,7 +222271,7 @@ local rcall = redis.call
|
|
|
221760
222271
|
--- Includes
|
|
221761
222272
|
--[[
|
|
221762
222273
|
Functions to collect metrics based on a current and previous count of jobs.
|
|
221763
|
-
|
|
222274
|
+
Granularity is fixed at 1 minute.
|
|
221764
222275
|
]]
|
|
221765
222276
|
--[[
|
|
221766
222277
|
Function to loop in batches.
|
|
@@ -222640,7 +223151,7 @@ if rcall("EXISTS", jobIdKey) == 1 then -- Make sure job exists
|
|
|
222640
223151
|
end
|
|
222641
223152
|
local eventStreamKey = KEYS[4]
|
|
222642
223153
|
local metaKey = KEYS[9]
|
|
222643
|
-
-- Trim events before
|
|
223154
|
+
-- Trim events before emitting them to avoid trimming events emitted in this script
|
|
222644
223155
|
trimEvents(metaKey, eventStreamKey)
|
|
222645
223156
|
local prefix = ARGV[7]
|
|
222646
223157
|
removeDeduplicationKeyIfNeededOnFinalization(prefix, jobAttributes[3], jobId)
|
|
@@ -222850,7 +223361,7 @@ const content$i = `--[[
|
|
|
222850
223361
|
keys, consider that this call may be slow for very large queues.
|
|
222851
223362
|
The queue needs to be "paused" or it will return an error
|
|
222852
223363
|
If the queue has currently active jobs then the script by default will return error,
|
|
222853
|
-
however this behaviour can be
|
|
223364
|
+
however this behaviour can be overridden using the 'force' option.
|
|
222854
223365
|
Input:
|
|
222855
223366
|
KEYS[1] meta
|
|
222856
223367
|
KEYS[2] base
|
|
@@ -223292,15 +223803,15 @@ const paginate = {
|
|
|
223292
223803
|
};
|
|
223293
223804
|
|
|
223294
223805
|
const content$g = `--[[
|
|
223295
|
-
Pauses or resumes a queue
|
|
223806
|
+
Pauses or resumes a queue globally.
|
|
223296
223807
|
Input:
|
|
223297
|
-
KEYS[1] 'wait' or 'paused'
|
|
223808
|
+
KEYS[1] 'wait' or 'paused'
|
|
223298
223809
|
KEYS[2] 'paused' or 'wait'
|
|
223299
223810
|
KEYS[3] 'meta'
|
|
223300
223811
|
KEYS[4] 'prioritized'
|
|
223301
223812
|
KEYS[5] events stream key
|
|
223302
223813
|
KEYS[6] 'delayed'
|
|
223303
|
-
KEYS
|
|
223814
|
+
KEYS[7] 'marker'
|
|
223304
223815
|
ARGV[1] 'paused' or 'resumed'
|
|
223305
223816
|
Event:
|
|
223306
223817
|
publish paused or resumed event.
|
|
@@ -223469,7 +223980,7 @@ const content$e = `--[[
|
|
|
223469
223980
|
ARGV[1] token
|
|
223470
223981
|
ARGV[2] lock duration in milliseconds
|
|
223471
223982
|
Output:
|
|
223472
|
-
"OK" if lock
|
|
223983
|
+
"OK" if lock extended successfully.
|
|
223473
223984
|
]]
|
|
223474
223985
|
local rcall = redis.call
|
|
223475
223986
|
if rcall("GET", KEYS[1]) == ARGV[1] then
|
|
@@ -225160,6 +225671,18 @@ local function getJobSchedulerEveryNextMillis(prevMillis, every, now, offset, st
|
|
|
225160
225671
|
nextMillis = nextMillis > now and nextMillis or now
|
|
225161
225672
|
else
|
|
225162
225673
|
nextMillis = now
|
|
225674
|
+
-- For the first iteration with no startDate and an explicit
|
|
225675
|
+
-- offset, align nextMillis to the next offset slot strictly
|
|
225676
|
+
-- after now. Without this the user-supplied offset is
|
|
225677
|
+
-- recorded but ignored, and the first job fires at now
|
|
225678
|
+
-- instead of the next aligned timestamp (issue #3705).
|
|
225679
|
+
if offset and offset > 0 then
|
|
225680
|
+
local aligned = math.floor(nextMillis / every) * every + offset
|
|
225681
|
+
if aligned <= nextMillis then
|
|
225682
|
+
aligned = aligned + every
|
|
225683
|
+
end
|
|
225684
|
+
nextMillis = aligned
|
|
225685
|
+
end
|
|
225163
225686
|
end
|
|
225164
225687
|
else
|
|
225165
225688
|
nextMillis = prevMillis + every
|
|
@@ -235752,7 +236275,7 @@ class JobScheduler extends QueueBase {
|
|
|
235752
236275
|
// Check if we have a start date for the repeatable job
|
|
235753
236276
|
const { immediately } = repeatOpts, filteredRepeatOpts = __rest(repeatOpts, ["immediately"]);
|
|
235754
236277
|
let nextMillis;
|
|
235755
|
-
const newOffset = null;
|
|
236278
|
+
const newOffset = every && offset ? offset : null;
|
|
235756
236279
|
if (pattern) {
|
|
235757
236280
|
nextMillis = await this.repeatStrategy(now, repeatOpts, jobName);
|
|
235758
236281
|
if (nextMillis < now) {
|
|
@@ -236201,7 +236724,7 @@ class QueueGetters extends QueueBase {
|
|
|
236201
236724
|
/**
|
|
236202
236725
|
* Returns the time to live for a rate limited key in milliseconds.
|
|
236203
236726
|
* @param maxJobs - max jobs to be considered in rate limit state. If not passed
|
|
236204
|
-
* it will return the remaining ttl without considering if max jobs is
|
|
236727
|
+
* it will return the remaining ttl without considering if max jobs is exceeded.
|
|
236205
236728
|
* @returns -2 if the key does not exist.
|
|
236206
236729
|
* -1 if the key exists but has no associated expire.
|
|
236207
236730
|
* @see {@link https://redis.io/commands/pttl/}
|
|
@@ -248881,6 +249404,39 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
248881
249404
|
var deepMerge = createDeepMerge({
|
|
248882
249405
|
arrayStrategy: "concat"
|
|
248883
249406
|
});
|
|
249407
|
+
var REDACTED = "[REDACTED]";
|
|
249408
|
+
var REDACTED_KEY_NAMES = /* @__PURE__ */ new Set([
|
|
249409
|
+
"mnemonic",
|
|
249410
|
+
"connectionString"
|
|
249411
|
+
]);
|
|
249412
|
+
var REDACTED_KEY_SUFFIX = /(PrivateKey|Secret|Password)$/i;
|
|
249413
|
+
function shouldRedactKey(key) {
|
|
249414
|
+
if (REDACTED_KEY_NAMES.has(key)) return true;
|
|
249415
|
+
return REDACTED_KEY_SUFFIX.test(key);
|
|
249416
|
+
}
|
|
249417
|
+
__name(shouldRedactKey, "shouldRedactKey");
|
|
249418
|
+
function redactConfig(config2) {
|
|
249419
|
+
const cloned = structuredClone(config2);
|
|
249420
|
+
redactInPlace(cloned);
|
|
249421
|
+
return cloned;
|
|
249422
|
+
}
|
|
249423
|
+
__name(redactConfig, "redactConfig");
|
|
249424
|
+
function redactInPlace(node) {
|
|
249425
|
+
if (Array.isArray(node)) {
|
|
249426
|
+
for (const item of node) redactInPlace(item);
|
|
249427
|
+
return;
|
|
249428
|
+
}
|
|
249429
|
+
if (node === null || typeof node !== "object") return;
|
|
249430
|
+
const obj = node;
|
|
249431
|
+
for (const key of Object.keys(obj)) {
|
|
249432
|
+
if (shouldRedactKey(key) && obj[key] !== void 0 && obj[key] !== null) {
|
|
249433
|
+
obj[key] = REDACTED;
|
|
249434
|
+
} else {
|
|
249435
|
+
redactInPlace(obj[key]);
|
|
249436
|
+
}
|
|
249437
|
+
}
|
|
249438
|
+
}
|
|
249439
|
+
__name(redactInPlace, "redactInPlace");
|
|
248884
249440
|
function coerceActorsArray(argv) {
|
|
248885
249441
|
const actors = argv.actors;
|
|
248886
249442
|
if (actors === void 0 || Array.isArray(actors)) return argv;
|
|
@@ -248929,7 +249485,9 @@ async function configMiddleware(argv, setConfiguration) {
|
|
|
248929
249485
|
assertNoActorMnemonics(finalConfig);
|
|
248930
249486
|
setConfiguration(finalConfig);
|
|
248931
249487
|
if (argv["dump-config"]) {
|
|
248932
|
-
|
|
249488
|
+
const withSecrets = Boolean(argv["with-secrets"]);
|
|
249489
|
+
const output2 = withSecrets ? finalConfig : redactConfig(finalConfig);
|
|
249490
|
+
console.log(JSON.stringify(output2, null, 2));
|
|
248933
249491
|
process.exit(0);
|
|
248934
249492
|
}
|
|
248935
249493
|
} catch (err) {
|
|
@@ -249078,6 +249636,176 @@ function withDeprecationWarning(module) {
|
|
|
249078
249636
|
}
|
|
249079
249637
|
__name(withDeprecationWarning, "withDeprecationWarning");
|
|
249080
249638
|
|
|
249639
|
+
// src/dumpProviders.ts
|
|
249640
|
+
var CANONICAL_ACTOR_ORDER = [
|
|
249641
|
+
"_root",
|
|
249642
|
+
"producer",
|
|
249643
|
+
"finalizer",
|
|
249644
|
+
"api",
|
|
249645
|
+
"mempool",
|
|
249646
|
+
"bridge",
|
|
249647
|
+
"rewardRedemption"
|
|
249648
|
+
];
|
|
249649
|
+
function enumerateLocator(locator) {
|
|
249650
|
+
const collapsed = /* @__PURE__ */ new Map();
|
|
249651
|
+
const registry = locator.registry;
|
|
249652
|
+
for (const moniker of Object.keys(registry)) {
|
|
249653
|
+
const factories = registry[moniker];
|
|
249654
|
+
if (!factories) continue;
|
|
249655
|
+
for (const factory of factories) {
|
|
249656
|
+
const f = factory;
|
|
249657
|
+
const providerName = f.providerName ?? "<unknown>";
|
|
249658
|
+
const scope = f.scope ?? "<unknown>";
|
|
249659
|
+
const dependencies = f.dependencies ?? [];
|
|
249660
|
+
const fingerprint = `${moniker}|${providerName}|${scope}|${dependencies.join(",")}`;
|
|
249661
|
+
const existing = collapsed.get(fingerprint);
|
|
249662
|
+
if (existing) {
|
|
249663
|
+
existing.count += 1;
|
|
249664
|
+
} else {
|
|
249665
|
+
collapsed.set(fingerprint, {
|
|
249666
|
+
count: 1,
|
|
249667
|
+
dependencies,
|
|
249668
|
+
moniker,
|
|
249669
|
+
providerName,
|
|
249670
|
+
scope
|
|
249671
|
+
});
|
|
249672
|
+
}
|
|
249673
|
+
}
|
|
249674
|
+
}
|
|
249675
|
+
return [
|
|
249676
|
+
...collapsed.values()
|
|
249677
|
+
].toSorted((a, b) => a.moniker.localeCompare(b.moniker) || a.providerName.localeCompare(b.providerName));
|
|
249678
|
+
}
|
|
249679
|
+
__name(enumerateLocator, "enumerateLocator");
|
|
249680
|
+
function buildOwnerIndex(perActor) {
|
|
249681
|
+
const monikerOwners = /* @__PURE__ */ new Map();
|
|
249682
|
+
for (const [actorName, entries] of perActor) {
|
|
249683
|
+
for (const entry of entries) {
|
|
249684
|
+
let owners = monikerOwners.get(entry.moniker);
|
|
249685
|
+
if (!owners) {
|
|
249686
|
+
owners = /* @__PURE__ */ new Set();
|
|
249687
|
+
monikerOwners.set(entry.moniker, owners);
|
|
249688
|
+
}
|
|
249689
|
+
owners.add(actorName);
|
|
249690
|
+
}
|
|
249691
|
+
}
|
|
249692
|
+
return monikerOwners;
|
|
249693
|
+
}
|
|
249694
|
+
__name(buildOwnerIndex, "buildOwnerIndex");
|
|
249695
|
+
function renderDuplicatesSummary(monikerOwners) {
|
|
249696
|
+
const duplicates = [
|
|
249697
|
+
...monikerOwners.entries()
|
|
249698
|
+
].filter(([, owners]) => owners.size > 1).map(([moniker, owners]) => ({
|
|
249699
|
+
moniker,
|
|
249700
|
+
owners: [
|
|
249701
|
+
...owners
|
|
249702
|
+
].toSorted().map(formatGroupForDisplay)
|
|
249703
|
+
})).toSorted((a, b) => a.moniker.localeCompare(b.moniker));
|
|
249704
|
+
if (duplicates.length === 0) return [];
|
|
249705
|
+
const lines = [
|
|
249706
|
+
"Duplicate monikers (registered by more than one locator):"
|
|
249707
|
+
];
|
|
249708
|
+
for (const { moniker, owners } of duplicates) {
|
|
249709
|
+
lines.push(` - ${moniker}: ${owners.join(", ")}`);
|
|
249710
|
+
}
|
|
249711
|
+
lines.push("");
|
|
249712
|
+
return lines;
|
|
249713
|
+
}
|
|
249714
|
+
__name(renderDuplicatesSummary, "renderDuplicatesSummary");
|
|
249715
|
+
function groupActorsBySharedRegistry(locators) {
|
|
249716
|
+
const groups = [];
|
|
249717
|
+
for (const actorName of Object.keys(locators)) {
|
|
249718
|
+
const locator = locators[actorName];
|
|
249719
|
+
const existing = groups.find((g) => g.registry === locator.registry);
|
|
249720
|
+
if (existing) {
|
|
249721
|
+
existing.actorNames.push(actorName);
|
|
249722
|
+
} else {
|
|
249723
|
+
groups.push({
|
|
249724
|
+
actorNames: [
|
|
249725
|
+
actorName
|
|
249726
|
+
],
|
|
249727
|
+
locator,
|
|
249728
|
+
registry: locator.registry
|
|
249729
|
+
});
|
|
249730
|
+
}
|
|
249731
|
+
}
|
|
249732
|
+
return groups;
|
|
249733
|
+
}
|
|
249734
|
+
__name(groupActorsBySharedRegistry, "groupActorsBySharedRegistry");
|
|
249735
|
+
function groupId(actorNames) {
|
|
249736
|
+
return [
|
|
249737
|
+
...actorNames
|
|
249738
|
+
].toSorted().join(",");
|
|
249739
|
+
}
|
|
249740
|
+
__name(groupId, "groupId");
|
|
249741
|
+
function formatGroupForDisplay(groupKey) {
|
|
249742
|
+
const members = groupKey.split(",");
|
|
249743
|
+
return members.length === 1 ? members[0] : `(${members.join(", ")})`;
|
|
249744
|
+
}
|
|
249745
|
+
__name(formatGroupForDisplay, "formatGroupForDisplay");
|
|
249746
|
+
function renderGroupSection(actorNames, entries, monikerOwners) {
|
|
249747
|
+
const sortedActors = [
|
|
249748
|
+
...actorNames
|
|
249749
|
+
].toSorted();
|
|
249750
|
+
const ownGroupKey = groupId(sortedActors);
|
|
249751
|
+
const heading = sortedActors.length === 1 ? `Providers for actor: ${sortedActors[0]} (${entries.length} registered)` : `Providers shared by actors: ${sortedActors.join(", ")} (${entries.length} registered)`;
|
|
249752
|
+
const lines = [
|
|
249753
|
+
heading
|
|
249754
|
+
];
|
|
249755
|
+
if (entries.length === 0) {
|
|
249756
|
+
lines.push(" (none)", "");
|
|
249757
|
+
return lines;
|
|
249758
|
+
}
|
|
249759
|
+
for (let i = 0; i < entries.length; i++) {
|
|
249760
|
+
const entry = entries[i];
|
|
249761
|
+
const isLast = i === entries.length - 1;
|
|
249762
|
+
const branch = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
|
|
249763
|
+
const owners = monikerOwners.get(entry.moniker) ?? /* @__PURE__ */ new Set();
|
|
249764
|
+
const otherOwners = [
|
|
249765
|
+
...owners
|
|
249766
|
+
].filter((o) => o !== ownGroupKey).toSorted().map(formatGroupForDisplay);
|
|
249767
|
+
const dupNote = otherOwners.length > 0 ? ` \u26A0 also in: ${otherOwners.join(", ")}` : "";
|
|
249768
|
+
const depsNote = entry.dependencies.length > 0 ? `, deps: [${entry.dependencies.join(", ")}]` : "";
|
|
249769
|
+
const countNote = entry.count > 1 ? ` (\xD7${entry.count})` : "";
|
|
249770
|
+
lines.push(` ${branch} ${entry.moniker}${countNote} [impl: ${entry.providerName}, scope: ${entry.scope}${depsNote}]${dupNote}`);
|
|
249771
|
+
}
|
|
249772
|
+
lines.push("");
|
|
249773
|
+
return lines;
|
|
249774
|
+
}
|
|
249775
|
+
__name(renderGroupSection, "renderGroupSection");
|
|
249776
|
+
function formatProviderTree(locators) {
|
|
249777
|
+
const groups = groupActorsBySharedRegistry(locators);
|
|
249778
|
+
const groupKeys = groups.map((g) => ({
|
|
249779
|
+
...g,
|
|
249780
|
+
key: groupId(g.actorNames)
|
|
249781
|
+
}));
|
|
249782
|
+
const perGroup = /* @__PURE__ */ new Map();
|
|
249783
|
+
for (const g of groupKeys) perGroup.set(g.key, enumerateLocator(g.locator));
|
|
249784
|
+
const monikerOwners = buildOwnerIndex(perGroup);
|
|
249785
|
+
const orderedGroups = [
|
|
249786
|
+
...groupKeys
|
|
249787
|
+
].toSorted((a, b) => {
|
|
249788
|
+
const aHasRoot = a.actorNames.includes("_root");
|
|
249789
|
+
const bHasRoot = b.actorNames.includes("_root");
|
|
249790
|
+
if (aHasRoot !== bHasRoot) return aHasRoot ? -1 : 1;
|
|
249791
|
+
const ai = CANONICAL_ACTOR_ORDER.indexOf(a.actorNames[0]);
|
|
249792
|
+
const bi = CANONICAL_ACTOR_ORDER.indexOf(b.actorNames[0]);
|
|
249793
|
+
if (ai !== bi) return (ai === -1 ? Number.MAX_SAFE_INTEGER : ai) - (bi === -1 ? Number.MAX_SAFE_INTEGER : bi);
|
|
249794
|
+
return a.key.localeCompare(b.key);
|
|
249795
|
+
});
|
|
249796
|
+
const lines = [
|
|
249797
|
+
"XL1 Provider Dump",
|
|
249798
|
+
"=================",
|
|
249799
|
+
""
|
|
249800
|
+
];
|
|
249801
|
+
for (const g of orderedGroups) {
|
|
249802
|
+
lines.push(...renderGroupSection(g.actorNames.toSorted(), perGroup.get(g.key) ?? [], monikerOwners));
|
|
249803
|
+
}
|
|
249804
|
+
lines.push(...renderDuplicatesSummary(monikerOwners));
|
|
249805
|
+
return lines.join("\n");
|
|
249806
|
+
}
|
|
249807
|
+
__name(formatProviderTree, "formatProviderTree");
|
|
249808
|
+
|
|
249081
249809
|
// src/images.ts
|
|
249082
249810
|
var XL1LogoColorizedAscii = `\x1B[38;2;128;128;128m\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\x1B[0m\x1B[38;2;118;111;144m_\x1B[0m
|
|
249083
249811
|
\x1B[38;2;128;128;128m\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\x1B[0m\x1B[38;2;72;32;223m\u2560\x1B[0m\x1B[38;2;66;21;234m\u2560\x1B[0m
|
|
@@ -249121,7 +249849,8 @@ function defaultScrapePortForActors(actors) {
|
|
|
249121
249849
|
__name(defaultScrapePortForActors, "defaultScrapePortForActors");
|
|
249122
249850
|
var configuration;
|
|
249123
249851
|
var skipInsecureConfirm = false;
|
|
249124
|
-
var
|
|
249852
|
+
var dumpProviders = false;
|
|
249853
|
+
var version = isDefined("1.23.0") ? "1.23.0" : "unknown";
|
|
249125
249854
|
function getConfiguration() {
|
|
249126
249855
|
return configuration;
|
|
249127
249856
|
}
|
|
@@ -249174,6 +249903,10 @@ async function getLocatorsFromConfig(actors, configuration2) {
|
|
|
249174
249903
|
}
|
|
249175
249904
|
const onInsecureGenesisConfirm = skipInsecureConfirm ? void 0 : async () => await promptForInsecureGenesisConfirmation(logger);
|
|
249176
249905
|
const locators = await locatorsFromConfig(context, config2, onInsecureGenesisConfirm);
|
|
249906
|
+
if (dumpProviders) {
|
|
249907
|
+
console.log(formatProviderTree(locators));
|
|
249908
|
+
process.exit(0);
|
|
249909
|
+
}
|
|
249177
249910
|
const healthCheckPort = configuration2.healthCheckPort ?? DEFAULT_HEALTH_CHECK_PORT;
|
|
249178
249911
|
const healthServer = healthCheckPort > 0 && context.statusReporter !== void 0 ? await initHealthEndpoints({
|
|
249179
249912
|
logger,
|
|
@@ -249218,6 +249951,7 @@ $0 <command> [options]`).parserConfiguration({
|
|
|
249218
249951
|
configuration = config2;
|
|
249219
249952
|
});
|
|
249220
249953
|
skipInsecureConfirm = Boolean(argv2["skip-insecure-confirm"]);
|
|
249954
|
+
dumpProviders = Boolean(argv2["dump-providers"]);
|
|
249221
249955
|
}).options(optionsFromGlobalZodRegistry()).wrap(y.terminalWidth()).command(withDeprecationWarning(apiCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(bridgeCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(finalizerCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(mempoolCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(producerCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(rewardRedemptionCommand(getConfiguration, getLocatorsFromConfig))).command(startCommand(getConfiguration, getLocatorsFromConfig)).options({
|
|
249222
249956
|
"config": {
|
|
249223
249957
|
type: "string",
|
|
@@ -249230,7 +249964,17 @@ $0 <command> [options]`).parserConfiguration({
|
|
|
249230
249964
|
},
|
|
249231
249965
|
"dump-config": {
|
|
249232
249966
|
type: "boolean",
|
|
249233
|
-
description: "Just process the configuration and print the resolved config to stdout, then exit.",
|
|
249967
|
+
description: "Just process the configuration and print the resolved config to stdout, then exit. Secrets are redacted unless --with-secrets is also passed.",
|
|
249968
|
+
default: false
|
|
249969
|
+
},
|
|
249970
|
+
"with-secrets": {
|
|
249971
|
+
type: "boolean",
|
|
249972
|
+
description: 'When used with --dump-config, print raw secret values (mnemonic, private keys, passwords) instead of "[REDACTED]". Use only on a developer machine.',
|
|
249973
|
+
default: false
|
|
249974
|
+
},
|
|
249975
|
+
"dump-providers": {
|
|
249976
|
+
type: "boolean",
|
|
249977
|
+
description: "Run the normal command flow up to provider locator construction, print the per-actor provider tree (with duplicate detection), then exit.",
|
|
249234
249978
|
default: false
|
|
249235
249979
|
},
|
|
249236
249980
|
"skip-insecure-confirm": {
|