@xyo-network/chain-services 1.23.0 → 2.0.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/neutral/index.mjs
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
-
var
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
5
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
6
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
7
|
+
if (decorator = decorators[i])
|
|
8
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
9
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
3
13
|
|
|
4
14
|
// src/BlockReward/EvmBlockRewardViewer.ts
|
|
5
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
AbstractCreatable,
|
|
17
|
+
assertEx,
|
|
18
|
+
creatable,
|
|
19
|
+
toEthAddress
|
|
20
|
+
} from "@xylabs/sdk-js";
|
|
6
21
|
import { IXyoChainRewards__factory } from "@xyo-network/typechain";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
__name(_ts_decorate, "_ts_decorate");
|
|
15
|
-
var EvmBlockRewardViewer = class _EvmBlockRewardViewer extends AbstractCreatable {
|
|
16
|
-
static {
|
|
17
|
-
__name(this, "EvmBlockRewardViewer");
|
|
18
|
-
}
|
|
19
|
-
static defaultMoniker = BlockRewardViewerMoniker;
|
|
20
|
-
static monikers = [
|
|
21
|
-
BlockRewardViewerMoniker
|
|
22
|
-
];
|
|
23
|
-
moniker = _EvmBlockRewardViewer.defaultMoniker;
|
|
22
|
+
import {
|
|
23
|
+
asAttoXL1,
|
|
24
|
+
BlockRewardViewerMoniker
|
|
25
|
+
} from "@xyo-network/xl1-sdk";
|
|
26
|
+
var EvmBlockRewardViewer = class extends AbstractCreatable {
|
|
27
|
+
moniker = EvmBlockRewardViewer.defaultMoniker;
|
|
24
28
|
_contractAddress;
|
|
25
29
|
get chainContractViewer() {
|
|
26
30
|
return assertEx(this.params.chainContractViewer, () => "chainContractViewer is required");
|
|
@@ -41,22 +45,19 @@ var EvmBlockRewardViewer = class _EvmBlockRewardViewer extends AbstractCreatable
|
|
|
41
45
|
this._contractAddress = await this.chainContractViewer.rewardsContract();
|
|
42
46
|
} catch (ex) {
|
|
43
47
|
const error = ex;
|
|
44
|
-
throw new Error(`Failed to get rewards contract address: ${error.message}`, {
|
|
45
|
-
cause: ex
|
|
46
|
-
});
|
|
48
|
+
throw new Error(`Failed to get rewards contract address: ${error.message}`, { cause: ex });
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
};
|
|
50
|
-
EvmBlockRewardViewer
|
|
52
|
+
__publicField(EvmBlockRewardViewer, "defaultMoniker", BlockRewardViewerMoniker);
|
|
53
|
+
__publicField(EvmBlockRewardViewer, "monikers", [BlockRewardViewerMoniker]);
|
|
54
|
+
EvmBlockRewardViewer = __decorateClass([
|
|
51
55
|
creatable()
|
|
52
56
|
], EvmBlockRewardViewer);
|
|
53
57
|
|
|
54
58
|
// src/ChainValidator/XyoValidator.ts
|
|
55
59
|
import { AbstractCreatableProvider, BlockViewerMoniker } from "@xyo-network/xl1-sdk";
|
|
56
60
|
var XyoValidator = class extends AbstractCreatableProvider {
|
|
57
|
-
static {
|
|
58
|
-
__name(this, "XyoValidator");
|
|
59
|
-
}
|
|
60
61
|
moniker = "Validator";
|
|
61
62
|
_blockViewer;
|
|
62
63
|
// get address() {
|
|
@@ -97,24 +98,12 @@ var XyoValidator = class extends AbstractCreatableProvider {
|
|
|
97
98
|
// src/Election/BaseElectionService.ts
|
|
98
99
|
import { assertEx as assertEx2 } from "@xylabs/sdk-js";
|
|
99
100
|
import { hexToLast4BytesInt, shuffleWithSeed } from "@xyo-network/chain-utils";
|
|
100
|
-
import {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
__name(_ts_decorate2, "_ts_decorate");
|
|
108
|
-
var BaseElectionService = class _BaseElectionService extends AbstractCreatableProvider2 {
|
|
109
|
-
static {
|
|
110
|
-
__name(this, "BaseElectionService");
|
|
111
|
-
}
|
|
112
|
-
static defaultMoniker = "Election";
|
|
113
|
-
static dependencies = [];
|
|
114
|
-
static monikers = [
|
|
115
|
-
"Election"
|
|
116
|
-
];
|
|
117
|
-
moniker = _BaseElectionService.defaultMoniker;
|
|
101
|
+
import {
|
|
102
|
+
AbstractCreatableProvider as AbstractCreatableProvider2,
|
|
103
|
+
creatableProvider
|
|
104
|
+
} from "@xyo-network/xl1-sdk";
|
|
105
|
+
var BaseElectionService = class extends AbstractCreatableProvider2 {
|
|
106
|
+
moniker = BaseElectionService.defaultMoniker;
|
|
118
107
|
get blockViewer() {
|
|
119
108
|
return assertEx2(this.params.blockViewer, () => "No block viewer");
|
|
120
109
|
}
|
|
@@ -139,32 +128,51 @@ var BaseElectionService = class _BaseElectionService extends AbstractCreatablePr
|
|
|
139
128
|
return creatorArray.slice(0, maxSize);
|
|
140
129
|
}
|
|
141
130
|
};
|
|
142
|
-
BaseElectionService
|
|
131
|
+
__publicField(BaseElectionService, "defaultMoniker", "Election");
|
|
132
|
+
__publicField(BaseElectionService, "dependencies", []);
|
|
133
|
+
__publicField(BaseElectionService, "monikers", ["Election"]);
|
|
134
|
+
BaseElectionService = __decorateClass([
|
|
143
135
|
creatableProvider()
|
|
144
136
|
], BaseElectionService);
|
|
145
137
|
|
|
146
138
|
// src/implementation/head/createBootstrapHead.ts
|
|
147
139
|
import { buildNextBlock, createGenesisBlock } from "@xyo-network/chain-protocol";
|
|
148
140
|
import { createDeclarationIntent } from "@xyo-network/xl1-sdk";
|
|
149
|
-
var createBootstrapHead =
|
|
141
|
+
var createBootstrapHead = async (account, chainId, genesisBlockRewardAmount, genesisBlockRewardAddress) => {
|
|
150
142
|
const chain = [];
|
|
151
143
|
const genesisBlock = await createGenesisBlock(account, chainId, genesisBlockRewardAmount, genesisBlockRewardAddress);
|
|
152
144
|
chain.push(genesisBlock);
|
|
153
|
-
const producerDeclarationPayload = createDeclarationIntent(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
145
|
+
const producerDeclarationPayload = createDeclarationIntent(
|
|
146
|
+
account.address,
|
|
147
|
+
"producer",
|
|
148
|
+
genesisBlock[0].block,
|
|
149
|
+
genesisBlock[0].block + 1e4
|
|
150
|
+
);
|
|
151
|
+
const producerDeclarationBlock = await buildNextBlock(
|
|
152
|
+
genesisBlock[0],
|
|
153
|
+
[],
|
|
154
|
+
[producerDeclarationPayload],
|
|
155
|
+
[account]
|
|
156
|
+
);
|
|
159
157
|
chain.push(producerDeclarationBlock);
|
|
160
158
|
return chain;
|
|
161
|
-
}
|
|
159
|
+
};
|
|
162
160
|
|
|
163
161
|
// src/implementation/processPendingBlocks.ts
|
|
164
162
|
import { assertEx as assertEx3, isDefined } from "@xylabs/sdk-js";
|
|
165
163
|
import { ChainHeadSelector } from "@xyo-network/chain-analyze";
|
|
166
164
|
import { BlockRejectionSchema, isSignedHydratedBlockWithHashMeta } from "@xyo-network/xl1-sdk";
|
|
167
|
-
async function processPendingBlocks({
|
|
165
|
+
async function processPendingBlocks({
|
|
166
|
+
blockValidationViewer,
|
|
167
|
+
blockViewer,
|
|
168
|
+
context,
|
|
169
|
+
logger,
|
|
170
|
+
mempoolViewer,
|
|
171
|
+
finalizationRunner,
|
|
172
|
+
allowedProducers,
|
|
173
|
+
minCandidates,
|
|
174
|
+
deadLetterQueueRunner
|
|
175
|
+
}) {
|
|
168
176
|
const start = Date.now();
|
|
169
177
|
const currentBlock = await blockViewer.currentBlock();
|
|
170
178
|
const headSelector = new ChainHeadSelector({
|
|
@@ -172,9 +180,7 @@ async function processPendingBlocks({ blockValidationViewer, blockViewer, contex
|
|
|
172
180
|
logger,
|
|
173
181
|
mempoolViewer,
|
|
174
182
|
blockViewer,
|
|
175
|
-
windowedFinalizedChain: [
|
|
176
|
-
currentBlock
|
|
177
|
-
],
|
|
183
|
+
windowedFinalizedChain: [currentBlock],
|
|
178
184
|
allowedProducers,
|
|
179
185
|
minCandidates
|
|
180
186
|
});
|
|
@@ -192,12 +198,7 @@ async function processPendingBlocks({ blockValidationViewer, blockViewer, contex
|
|
|
192
198
|
const candidateBlocks = bestHeadChain.filter((b) => {
|
|
193
199
|
return isDefined(oldHeadBlock) ? b[0].block > oldHeadBlock.block : true;
|
|
194
200
|
});
|
|
195
|
-
const validationResults = await Promise.all(candidateBlocks.map((candidateBlock) => blockValidationViewer.validateBlocks([
|
|
196
|
-
candidateBlock
|
|
197
|
-
], {
|
|
198
|
-
value: true,
|
|
199
|
-
state: true
|
|
200
|
-
})));
|
|
201
|
+
const validationResults = await Promise.all(candidateBlocks.map((candidateBlock) => blockValidationViewer.validateBlocks([candidateBlock], { value: true, state: true })));
|
|
201
202
|
const blocksToFinalize = [];
|
|
202
203
|
for (const [i, block] of candidateBlocks.entries()) {
|
|
203
204
|
const result = validationResults[i][0];
|
|
@@ -210,12 +211,7 @@ async function processPendingBlocks({ blockValidationViewer, blockViewer, contex
|
|
|
210
211
|
hash: block[0]._hash,
|
|
211
212
|
name: "BlockValidationError",
|
|
212
213
|
message: String(e.message ?? e)
|
|
213
|
-
})) : [
|
|
214
|
-
{
|
|
215
|
-
hash: block[0]._hash,
|
|
216
|
-
name: "BlockValidationError"
|
|
217
|
-
}
|
|
218
|
-
];
|
|
214
|
+
})) : [{ hash: block[0]._hash, name: "BlockValidationError" }];
|
|
219
215
|
await deadLetterQueueRunner.rejectBlock({
|
|
220
216
|
schema: BlockRejectionSchema,
|
|
221
217
|
block,
|
|
@@ -236,27 +232,15 @@ async function processPendingBlocks({ blockValidationViewer, blockViewer, contex
|
|
|
236
232
|
logger?.info("No head found to validate", currentBlock?.[0]._hash);
|
|
237
233
|
}
|
|
238
234
|
}
|
|
239
|
-
__name(processPendingBlocks, "processPendingBlocks");
|
|
240
235
|
|
|
241
236
|
// src/NetworkStakeStepReward/BaseNetworkStakeStepRewardService.ts
|
|
242
|
-
import {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
__name(_ts_decorate3, "_ts_decorate");
|
|
250
|
-
var BaseNetworkStakeStepRewardService = class _BaseNetworkStakeStepRewardService extends AbstractCreatableProvider3 {
|
|
251
|
-
static {
|
|
252
|
-
__name(this, "BaseNetworkStakeStepRewardService");
|
|
253
|
-
}
|
|
254
|
-
static defaultMoniker = NetworkStakeStepRewardViewerMoniker;
|
|
255
|
-
static dependencies = [];
|
|
256
|
-
static monikers = [
|
|
257
|
-
NetworkStakeStepRewardViewerMoniker
|
|
258
|
-
];
|
|
259
|
-
moniker = _BaseNetworkStakeStepRewardService.defaultMoniker;
|
|
237
|
+
import {
|
|
238
|
+
AbstractCreatableProvider as AbstractCreatableProvider3,
|
|
239
|
+
creatableProvider as creatableProvider2,
|
|
240
|
+
NetworkStakeStepRewardViewerMoniker
|
|
241
|
+
} from "@xyo-network/xl1-sdk";
|
|
242
|
+
var BaseNetworkStakeStepRewardService = class extends AbstractCreatableProvider3 {
|
|
243
|
+
moniker = BaseNetworkStakeStepRewardService.defaultMoniker;
|
|
260
244
|
networkStakeStepRewardAddressHistory(_address) {
|
|
261
245
|
throw new Error("Method [networkStakeStepRewardAddressHistory] not implemented.");
|
|
262
246
|
}
|
|
@@ -312,28 +296,62 @@ var BaseNetworkStakeStepRewardService = class _BaseNetworkStakeStepRewardService
|
|
|
312
296
|
throw new Error("Method [networkStakeStepRewardsForStepLevel] not implemented.");
|
|
313
297
|
}
|
|
314
298
|
};
|
|
315
|
-
BaseNetworkStakeStepRewardService
|
|
299
|
+
__publicField(BaseNetworkStakeStepRewardService, "defaultMoniker", NetworkStakeStepRewardViewerMoniker);
|
|
300
|
+
__publicField(BaseNetworkStakeStepRewardService, "dependencies", []);
|
|
301
|
+
__publicField(BaseNetworkStakeStepRewardService, "monikers", [NetworkStakeStepRewardViewerMoniker]);
|
|
302
|
+
BaseNetworkStakeStepRewardService = __decorateClass([
|
|
316
303
|
creatableProvider2()
|
|
317
304
|
], BaseNetworkStakeStepRewardService);
|
|
318
305
|
|
|
319
306
|
// src/simple/block/runner/SimpleBlockRunner.ts
|
|
320
|
-
import {
|
|
307
|
+
import {
|
|
308
|
+
assertEx as assertEx5,
|
|
309
|
+
exists,
|
|
310
|
+
hexToBigInt,
|
|
311
|
+
isDefined as isDefined2
|
|
312
|
+
} from "@xylabs/sdk-js";
|
|
321
313
|
import { FixedPercentageBlockRewardDiviner, FixedPercentageBlockRewardDivinerConfigSchema } from "@xyo-network/chain-modules";
|
|
322
314
|
import { buildNextBlock as buildNextBlock2 } from "@xyo-network/chain-protocol";
|
|
323
|
-
import {
|
|
324
|
-
|
|
315
|
+
import {
|
|
316
|
+
MemoryArchivist,
|
|
317
|
+
PayloadBuilder as PayloadBuilder2
|
|
318
|
+
} from "@xyo-network/sdk-js";
|
|
319
|
+
import {
|
|
320
|
+
AbstractCreatableProvider as AbstractCreatableProvider4,
|
|
321
|
+
AccountBalanceViewerMoniker,
|
|
322
|
+
asBlockBoundWitness,
|
|
323
|
+
AttoXL1,
|
|
324
|
+
BlockNumberSchema,
|
|
325
|
+
BlockRejectionSchema as BlockRejectionSchema2,
|
|
326
|
+
BlockRewardViewerMoniker as BlockRewardViewerMoniker2,
|
|
327
|
+
BlockRunnerMoniker,
|
|
328
|
+
BlockValidationViewerMoniker,
|
|
329
|
+
creatableProvider as creatableProvider3,
|
|
330
|
+
createDeclarationIntent as createDeclarationIntent2,
|
|
331
|
+
DeadLetterQueueRunnerMoniker,
|
|
332
|
+
defaultRewardRatio,
|
|
333
|
+
FinalizationViewerMoniker,
|
|
334
|
+
isSignedHydratedBlockWithHashMeta as isSignedHydratedBlockWithHashMeta2,
|
|
335
|
+
isTransfer,
|
|
336
|
+
MempoolViewerMoniker,
|
|
337
|
+
TimeSyncViewerMoniker,
|
|
338
|
+
TransactionRejectionSchema,
|
|
339
|
+
XYO_STEP_REWARD_ADDRESS
|
|
340
|
+
} from "@xyo-network/xl1-sdk";
|
|
325
341
|
|
|
326
342
|
// src/simple/block/runner/generateTransactionFeeTransfers.ts
|
|
327
343
|
import { hexFromBigInt } from "@xylabs/sdk-js";
|
|
328
344
|
import { assertEx as assertEx4 } from "@xylabs/sdk-js";
|
|
329
345
|
import { PayloadBuilder } from "@xyo-network/sdk-js";
|
|
330
|
-
import {
|
|
346
|
+
import {
|
|
347
|
+
HydratedTransactionWrapper,
|
|
348
|
+
transactionRequiredGas,
|
|
349
|
+
TransferSchema,
|
|
350
|
+
XYO_ZERO_ADDRESS
|
|
351
|
+
} from "@xyo-network/xl1-sdk";
|
|
331
352
|
async function generateTransactionFeeTransfers(address, transactions) {
|
|
332
353
|
const txs = await Promise.all(transactions.map(async (tx) => {
|
|
333
|
-
return HydratedTransactionWrapper.parse([
|
|
334
|
-
await PayloadBuilder.addStorageMeta(tx[0]),
|
|
335
|
-
await PayloadBuilder.addStorageMeta(tx[1])
|
|
336
|
-
]);
|
|
354
|
+
return HydratedTransactionWrapper.parse([await PayloadBuilder.addStorageMeta(tx[0]), await PayloadBuilder.addStorageMeta(tx[1])]);
|
|
337
355
|
}));
|
|
338
356
|
const txBaseFeeCosts = {};
|
|
339
357
|
for (const tx of txs) {
|
|
@@ -363,27 +381,24 @@ async function generateTransactionFeeTransfers(address, transactions) {
|
|
|
363
381
|
}
|
|
364
382
|
return payloads;
|
|
365
383
|
}
|
|
366
|
-
__name(generateTransactionFeeTransfers, "generateTransactionFeeTransfers");
|
|
367
384
|
|
|
368
385
|
// src/simple/block/runner/identifyOffendingTransactions.ts
|
|
369
|
-
import {
|
|
386
|
+
import {
|
|
387
|
+
HydratedTransactionWrapper as HydratedTransactionWrapper2,
|
|
388
|
+
netBalancesForPayloads,
|
|
389
|
+
transactionRequiredGas as transactionRequiredGas2
|
|
390
|
+
} from "@xyo-network/xl1-sdk";
|
|
370
391
|
async function scoreTransaction(tx) {
|
|
371
392
|
const wrapper = await HydratedTransactionWrapper2.parse(tx);
|
|
372
393
|
const from = wrapper.boundWitness.from;
|
|
373
394
|
const gasPrice = wrapper.fees.gasPrice;
|
|
374
395
|
const gasCost = transactionRequiredGas2(tx) * gasPrice;
|
|
375
396
|
const baseCost = wrapper.fees.base;
|
|
376
|
-
const netBalances = netBalancesForPayloads({
|
|
377
|
-
singletons: {}
|
|
378
|
-
}, tx[1]);
|
|
397
|
+
const netBalances = netBalancesForPayloads({ singletons: {} }, tx[1]);
|
|
379
398
|
const fromNet = netBalances[from] ?? 0n;
|
|
380
399
|
const transferOut = fromNet < 0n ? -fromNet : 0n;
|
|
381
|
-
return {
|
|
382
|
-
cost: gasCost + baseCost + transferOut,
|
|
383
|
-
gasPrice
|
|
384
|
-
};
|
|
400
|
+
return { cost: gasCost + baseCost + transferOut, gasPrice };
|
|
385
401
|
}
|
|
386
|
-
__name(scoreTransaction, "scoreTransaction");
|
|
387
402
|
async function identifyOffendingTransactions(args) {
|
|
388
403
|
const { errors, candidateTransactions } = args;
|
|
389
404
|
const candidateHashes = new Set(candidateTransactions.map((tx) => tx[0]._hash));
|
|
@@ -394,12 +409,7 @@ async function identifyOffendingTransactions(args) {
|
|
|
394
409
|
if (cause?.hash && candidateHashes.has(cause.hash)) txInvalidHashes.add(cause.hash);
|
|
395
410
|
}
|
|
396
411
|
if (txInvalidHashes.size > 0) {
|
|
397
|
-
return {
|
|
398
|
-
offendingHashes: [
|
|
399
|
-
...txInvalidHashes
|
|
400
|
-
],
|
|
401
|
-
reason: "tx-invalid"
|
|
402
|
-
};
|
|
412
|
+
return { offendingHashes: [...txInvalidHashes], reason: "tx-invalid" };
|
|
403
413
|
}
|
|
404
414
|
const balanceOffenderHashes = /* @__PURE__ */ new Set();
|
|
405
415
|
for (const error of errors) {
|
|
@@ -409,59 +419,24 @@ async function identifyOffendingTransactions(args) {
|
|
|
409
419
|
}
|
|
410
420
|
}
|
|
411
421
|
if (balanceOffenderHashes.size === 0) {
|
|
412
|
-
return {
|
|
413
|
-
offendingHashes: [],
|
|
414
|
-
reason: "unknown"
|
|
415
|
-
};
|
|
422
|
+
return { offendingHashes: [], reason: "unknown" };
|
|
416
423
|
}
|
|
417
424
|
const offenders = candidateTransactions.filter((tx) => balanceOffenderHashes.has(tx[0]._hash));
|
|
418
|
-
const scored = await Promise.all(offenders.map(async (tx) => ({
|
|
419
|
-
tx,
|
|
420
|
-
...await scoreTransaction(tx)
|
|
421
|
-
})));
|
|
425
|
+
const scored = await Promise.all(offenders.map(async (tx) => ({ tx, ...await scoreTransaction(tx) })));
|
|
422
426
|
scored.sort((a, b) => {
|
|
423
427
|
if (a.cost !== b.cost) return a.cost < b.cost ? 1 : -1;
|
|
424
428
|
if (a.gasPrice !== b.gasPrice) return a.gasPrice < b.gasPrice ? -1 : 1;
|
|
425
429
|
return a.tx[0]._hash < b.tx[0]._hash ? -1 : 1;
|
|
426
430
|
});
|
|
427
|
-
return {
|
|
428
|
-
offendingHashes: [
|
|
429
|
-
scored[0].tx[0]._hash
|
|
430
|
-
],
|
|
431
|
-
reason: "block-balance"
|
|
432
|
-
};
|
|
431
|
+
return { offendingHashes: [scored[0].tx[0]._hash], reason: "block-balance" };
|
|
433
432
|
}
|
|
434
|
-
__name(identifyOffendingTransactions, "identifyOffendingTransactions");
|
|
435
433
|
|
|
436
434
|
// src/simple/block/runner/SimpleBlockRunner.ts
|
|
437
|
-
function _ts_decorate4(decorators, target, key, desc) {
|
|
438
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
439
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
440
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
441
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
442
|
-
}
|
|
443
|
-
__name(_ts_decorate4, "_ts_decorate");
|
|
444
435
|
var DEFAULT_BLOCK_SIZE = 10;
|
|
445
436
|
var XYO_PRODUCER_REDECLARATION_DURATION = 100;
|
|
446
437
|
var XYO_PRODUCER_REDECLARATION_WINDOW = 100;
|
|
447
|
-
var SimpleBlockRunner = class
|
|
448
|
-
|
|
449
|
-
__name(this, "SimpleBlockRunner");
|
|
450
|
-
}
|
|
451
|
-
static defaultMoniker = BlockRunnerMoniker;
|
|
452
|
-
static dependencies = [
|
|
453
|
-
AccountBalanceViewerMoniker,
|
|
454
|
-
BlockRewardViewerMoniker2,
|
|
455
|
-
BlockValidationViewerMoniker,
|
|
456
|
-
FinalizationViewerMoniker,
|
|
457
|
-
MempoolRunnerMoniker,
|
|
458
|
-
MempoolViewerMoniker,
|
|
459
|
-
TimeSyncViewerMoniker
|
|
460
|
-
];
|
|
461
|
-
static monikers = [
|
|
462
|
-
BlockRunnerMoniker
|
|
463
|
-
];
|
|
464
|
-
moniker = _SimpleBlockRunner.defaultMoniker;
|
|
438
|
+
var SimpleBlockRunner = class extends AbstractCreatableProvider4 {
|
|
439
|
+
moniker = SimpleBlockRunner.defaultMoniker;
|
|
465
440
|
_blockRewardDiviner;
|
|
466
441
|
_deadLetterQueueRunner;
|
|
467
442
|
// TODO(producer-exclusion-set): uncapped for v1. If memory grows in long-running producers,
|
|
@@ -475,27 +450,26 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
475
450
|
_blockRewardViewer;
|
|
476
451
|
_blockValidationViewer;
|
|
477
452
|
_finalizationViewer;
|
|
478
|
-
_mempoolRunner;
|
|
479
453
|
_mempoolViewer;
|
|
480
454
|
_rewardAddress;
|
|
481
455
|
_timeSyncViewer;
|
|
482
456
|
/**
|
|
483
|
-
|
|
484
|
-
|
|
457
|
+
* The default block size for a block
|
|
458
|
+
*/
|
|
485
459
|
static get DefaultBlockSize() {
|
|
486
460
|
return DEFAULT_BLOCK_SIZE;
|
|
487
461
|
}
|
|
488
462
|
/**
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
463
|
+
* The amount of time for which the producer will redeclare
|
|
464
|
+
* their intent to continue producing blocks
|
|
465
|
+
*/
|
|
492
466
|
static get RedeclarationDuration() {
|
|
493
467
|
return XYO_PRODUCER_REDECLARATION_DURATION;
|
|
494
468
|
}
|
|
495
469
|
/**
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
470
|
+
* The number of blocks within which the producer will redeclare
|
|
471
|
+
* their intent to continue producing blocks
|
|
472
|
+
*/
|
|
499
473
|
static get RedeclarationWindow() {
|
|
500
474
|
return XYO_PRODUCER_REDECLARATION_WINDOW;
|
|
501
475
|
}
|
|
@@ -520,9 +494,6 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
520
494
|
get heartbeatInterval() {
|
|
521
495
|
return this.params.heartbeatInterval ?? 36e5;
|
|
522
496
|
}
|
|
523
|
-
get mempoolRunner() {
|
|
524
|
-
return this._mempoolRunner;
|
|
525
|
-
}
|
|
526
497
|
get mempoolViewer() {
|
|
527
498
|
return this._mempoolViewer;
|
|
528
499
|
}
|
|
@@ -552,7 +523,6 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
552
523
|
this._blockRewardViewer = await this.locateAndCreate(BlockRewardViewerMoniker2);
|
|
553
524
|
this._blockValidationViewer = await this.locator.getInstance(BlockValidationViewerMoniker);
|
|
554
525
|
this._finalizationViewer = await this.locateAndCreate(FinalizationViewerMoniker);
|
|
555
|
-
this._mempoolRunner = await this.locateAndCreate(MempoolRunnerMoniker);
|
|
556
526
|
this._mempoolViewer = await this.locateAndCreate(MempoolViewerMoniker);
|
|
557
527
|
this._rewardAddress = this.params.rewardAddress;
|
|
558
528
|
this._timeSyncViewer = await this.locateAndCreate(TimeSyncViewerMoniker);
|
|
@@ -577,40 +547,43 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
577
547
|
}
|
|
578
548
|
});
|
|
579
549
|
}
|
|
580
|
-
const blockId = new PayloadBuilder2({
|
|
581
|
-
|
|
582
|
-
}).fields({
|
|
583
|
-
block
|
|
584
|
-
}).build();
|
|
585
|
-
const rewards = await this._blockRewardDiviner.divine([
|
|
586
|
-
blockId
|
|
587
|
-
]);
|
|
550
|
+
const blockId = new PayloadBuilder2({ schema: BlockNumberSchema }).fields({ block }).build();
|
|
551
|
+
const rewards = await this._blockRewardDiviner.divine([blockId]);
|
|
588
552
|
return rewards;
|
|
589
553
|
}
|
|
590
554
|
/**
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
555
|
+
* Handles the producer redeclaration logic
|
|
556
|
+
* @param head The current head block
|
|
557
|
+
* @returns chain stake intent for the producer redeclaration, or undefined if no redeclaration is needed
|
|
558
|
+
*/
|
|
595
559
|
getProducerRedeclaration(head) {
|
|
596
560
|
if (this.params.disableIntentRedeclaration) return;
|
|
597
561
|
const currentBlock = head.block;
|
|
598
562
|
if (isDefined2(this._lastRedeclarationBlock)) {
|
|
599
|
-
const lastDeclarationExpiry = this._lastRedeclarationBlock +
|
|
563
|
+
const lastDeclarationExpiry = this._lastRedeclarationBlock + SimpleBlockRunner.RedeclarationDuration;
|
|
600
564
|
if (currentBlock < lastDeclarationExpiry) return;
|
|
601
565
|
}
|
|
602
566
|
this._lastRedeclarationBlock = currentBlock;
|
|
603
|
-
return createDeclarationIntent2(this.address, "producer", currentBlock, currentBlock +
|
|
604
|
-
}
|
|
605
|
-
|
|
567
|
+
return createDeclarationIntent2(this.address, "producer", currentBlock, currentBlock + SimpleBlockRunner.RedeclarationDuration);
|
|
568
|
+
}
|
|
569
|
+
// `validateBalances` resolves from (a) the explicit method argument when
|
|
570
|
+
// passed, (b) the constructor `params.validateBalances`, or (c) `true`.
|
|
571
|
+
// True is the safe default: `filterByFunded` then enforces the same
|
|
572
|
+
// cumulative-outflow rule the post-submit block validator uses
|
|
573
|
+
// (`base + priority + gasLimit + transfer amounts`). With the old default
|
|
574
|
+
// of `false`, a tx whose declared gasLimit exceeded the sender's balance
|
|
575
|
+
// would pass the producer's filter, get submitted, and then land in
|
|
576
|
+
// `rejected_blocks` — silently wedging the chain because the producer's
|
|
577
|
+
// `_lastProducedBlock` cache muted retries. Reproduced in the
|
|
578
|
+
// api-local-mongodb-beta test rig.
|
|
579
|
+
async proposeNextValidBlock(head, validateBalances, force = false) {
|
|
580
|
+
const shouldValidateBalances = validateBalances ?? this.params.validateBalances ?? true;
|
|
606
581
|
return await this.spanAsync("proposeNextValidBlock", async () => {
|
|
607
582
|
try {
|
|
608
583
|
const { block: previousBlock } = assertEx5(asBlockBoundWitness(head), () => "Invalid head block");
|
|
609
584
|
const nextBlock = previousBlock + 1;
|
|
610
585
|
const chainId = await this.finalizationViewer.chainId();
|
|
611
|
-
const pendingTransactionsRaw = await this.mempoolViewer.pendingTransactions({
|
|
612
|
-
limit: _SimpleBlockRunner.DefaultBlockSize
|
|
613
|
-
});
|
|
586
|
+
const pendingTransactionsRaw = await this.mempoolViewer.pendingTransactions({ limit: SimpleBlockRunner.DefaultBlockSize });
|
|
614
587
|
const pendingTransactions = pendingTransactionsRaw.filter((tx) => !this._excludedTransactionHashes.has(tx[0]._hash));
|
|
615
588
|
const nextBlockTransactions = await this.rejectWrongChainTransactions(pendingTransactions, chainId);
|
|
616
589
|
this.logger?.log(`Pending Tx Count ${nextBlockTransactions.length}`);
|
|
@@ -627,10 +600,8 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
627
600
|
if (timeDuration > 100) {
|
|
628
601
|
this.logger?.warn(`[Slow] Generated time payload in ${timeDuration}ms`);
|
|
629
602
|
}
|
|
630
|
-
const [initialFundedTransactions, initialFundedTransfers] = await this.filterByFunded(head, nextBlockTransactions, transactionTransfers,
|
|
631
|
-
const stepRewardPoolBalance = (await this.accountBalanceViewer.accountBalances([
|
|
632
|
-
XYO_STEP_REWARD_ADDRESS
|
|
633
|
-
]))[XYO_STEP_REWARD_ADDRESS];
|
|
603
|
+
const [initialFundedTransactions, initialFundedTransfers] = await this.filterByFunded(head, nextBlockTransactions, transactionTransfers, shouldValidateBalances);
|
|
604
|
+
const stepRewardPoolBalance = (await this.accountBalanceViewer.accountBalances([XYO_STEP_REWARD_ADDRESS]))[XYO_STEP_REWARD_ADDRESS];
|
|
634
605
|
const result = await this.runBuildValidateRetryLoop({
|
|
635
606
|
head,
|
|
636
607
|
chainId,
|
|
@@ -641,9 +612,6 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
641
612
|
initialFundedTransfers
|
|
642
613
|
});
|
|
643
614
|
if (isSignedHydratedBlockWithHashMeta2(result.block)) {
|
|
644
|
-
await this.mempoolRunner.submitBlocks([
|
|
645
|
-
result.block
|
|
646
|
-
]);
|
|
647
615
|
return result.block;
|
|
648
616
|
}
|
|
649
617
|
if (result.block) await this.rejectExhaustedBlock(result.block, result.errors);
|
|
@@ -653,39 +621,66 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
653
621
|
}
|
|
654
622
|
}, this.context);
|
|
655
623
|
}
|
|
624
|
+
/**
|
|
625
|
+
* Compute the cumulative outflow a single tx would charge to its `from`
|
|
626
|
+
* address, using the same rule as `BlockCumulativeBalanceValidator`:
|
|
627
|
+
* `outflow = base + priority + gasLimit + sum(transfer amounts to addresses
|
|
628
|
+
* other than from)`. Mirroring the validator exactly here ensures the
|
|
629
|
+
* producer doesn't include a tx that the post-submit block validator will
|
|
630
|
+
* reject, which would otherwise wedge the chain because the producer's
|
|
631
|
+
* `_lastProducedBlock` cache mutes retries.
|
|
632
|
+
*/
|
|
633
|
+
computeTransactionOutflow(tx) {
|
|
634
|
+
const [bw, payloads] = tx;
|
|
635
|
+
const {
|
|
636
|
+
base,
|
|
637
|
+
gasLimit,
|
|
638
|
+
priority
|
|
639
|
+
} = bw.fees;
|
|
640
|
+
let outflow = hexToBigInt(base) + hexToBigInt(priority) + hexToBigInt(gasLimit);
|
|
641
|
+
const txPayloadHashes = new Set(bw.payload_hashes);
|
|
642
|
+
for (const payload of payloads) {
|
|
643
|
+
if (!txPayloadHashes.has(payload._hash)) continue;
|
|
644
|
+
if (!isTransfer(payload)) continue;
|
|
645
|
+
if (payload.from !== bw.from) continue;
|
|
646
|
+
for (const [to, amount] of Object.entries(payload.transfers)) {
|
|
647
|
+
if (to === payload.from) continue;
|
|
648
|
+
outflow += hexToBigInt(amount ?? "00");
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return outflow;
|
|
652
|
+
}
|
|
656
653
|
// remove unfunded transactions and block transfers
|
|
657
654
|
async filterByFunded(head, txs, transfers, validateBalances = false) {
|
|
658
655
|
const fundedTransfers = [];
|
|
659
656
|
const fundedTransactions = (await Promise.all(txs.map(async (tx) => {
|
|
660
657
|
const transfer = transfers.find((transfer2) => transfer2.from === tx[0].from);
|
|
661
658
|
if (!transfer) return;
|
|
662
|
-
const totalTransferCost = Object.values(transfer?.transfers).reduce((acc, t) => acc + hexToBigInt(t ?? "00"), 0n);
|
|
663
659
|
if (validateBalances) {
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
if (balance >= totalTransferCost) {
|
|
660
|
+
const totalOutflow = this.computeTransactionOutflow(tx);
|
|
661
|
+
const balance = (await this.accountBalanceViewer.accountBalances([transfer.from]))[transfer.from] ?? AttoXL1(0n);
|
|
662
|
+
if (balance >= totalOutflow) {
|
|
668
663
|
fundedTransfers.push(transfer);
|
|
669
664
|
return tx;
|
|
670
665
|
}
|
|
666
|
+
this.logger?.debug(
|
|
667
|
+
`filterByFunded: dropping tx ${tx[0]._hash} from ${transfer.from} \u2014 outflow ${totalOutflow} > balance ${balance}`
|
|
668
|
+
);
|
|
671
669
|
} else {
|
|
672
670
|
fundedTransfers.push(transfer);
|
|
673
671
|
return tx;
|
|
674
672
|
}
|
|
675
673
|
}))).filter(exists);
|
|
676
|
-
return [
|
|
677
|
-
fundedTransactions,
|
|
678
|
-
fundedTransfers
|
|
679
|
-
];
|
|
674
|
+
return [fundedTransactions, fundedTransfers];
|
|
680
675
|
}
|
|
681
676
|
async generateTimePayload() {
|
|
682
677
|
return await this.timeSyncViewer.currentTimePayload();
|
|
683
678
|
}
|
|
684
679
|
/**
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
680
|
+
* Check if a heartbeat block is required based on network activity.
|
|
681
|
+
* @param head The current head block
|
|
682
|
+
* @returns True if a heartbeat is required, false otherwise
|
|
683
|
+
*/
|
|
689
684
|
heartbeatRequired(head) {
|
|
690
685
|
const epoch = head.$epoch;
|
|
691
686
|
if (isDefined2(epoch) && Date.now() - epoch > this.heartbeatInterval) {
|
|
@@ -729,50 +724,51 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
729
724
|
await (dlq ? Promise.all(mismatched.map((tx) => dlq.rejectTransaction({
|
|
730
725
|
schema: TransactionRejectionSchema,
|
|
731
726
|
transaction: tx,
|
|
732
|
-
errors: [
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
}
|
|
738
|
-
],
|
|
727
|
+
errors: [{
|
|
728
|
+
hash: tx[0]._hash,
|
|
729
|
+
name: "TransactionChainMismatch",
|
|
730
|
+
message: `Transaction chain ${tx[0].chain} does not match local chain ${localChain}`
|
|
731
|
+
}],
|
|
739
732
|
rejector: "producer"
|
|
740
733
|
}))) : this.rejectedTransactionsArchivist.insert(mismatched.map((tx) => tx[0])));
|
|
741
734
|
}
|
|
742
735
|
return matched;
|
|
743
736
|
}
|
|
744
737
|
async runBuildValidateRetryLoop(args) {
|
|
745
|
-
const {
|
|
738
|
+
const {
|
|
739
|
+
chainId,
|
|
740
|
+
head,
|
|
741
|
+
initialFundedTransactions,
|
|
742
|
+
initialFundedTransfers,
|
|
743
|
+
nonTxPayloads,
|
|
744
|
+
stepRewardPoolBalance,
|
|
745
|
+
timePayload
|
|
746
|
+
} = args;
|
|
746
747
|
const maxAttempts = Math.max(1, initialFundedTransactions.length);
|
|
747
748
|
let candidateTransactions = initialFundedTransactions;
|
|
748
749
|
let candidateTransfers = initialFundedTransfers;
|
|
749
750
|
let lastBlock;
|
|
750
751
|
let lastErrors = [];
|
|
751
752
|
for (let attempt = 0; attempt <= maxAttempts; attempt++) {
|
|
752
|
-
const blockPayloads = [
|
|
753
|
-
...nonTxPayloads,
|
|
754
|
-
...candidateTransfers,
|
|
755
|
-
timePayload
|
|
756
|
-
];
|
|
753
|
+
const blockPayloads = [...nonTxPayloads, ...candidateTransfers, timePayload];
|
|
757
754
|
this.logger?.info(`Building block ${head.block + 1}${attempt > 0 ? ` (retry ${attempt})` : ""}`);
|
|
758
|
-
lastBlock = await buildNextBlock2(
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
755
|
+
lastBlock = await buildNextBlock2(
|
|
756
|
+
head,
|
|
757
|
+
candidateTransactions,
|
|
758
|
+
blockPayloads,
|
|
759
|
+
[this.account],
|
|
760
|
+
XYO_STEP_REWARD_ADDRESS,
|
|
761
|
+
stepRewardPoolBalance,
|
|
762
|
+
void 0,
|
|
763
|
+
chainId
|
|
764
|
+
);
|
|
765
|
+
const validated = await this.blockValidationViewer.validateBlock(lastBlock, { head: head._hash });
|
|
764
766
|
if (isSignedHydratedBlockWithHashMeta2(validated)) {
|
|
765
|
-
return {
|
|
766
|
-
block: validated,
|
|
767
|
-
errors: []
|
|
768
|
-
};
|
|
767
|
+
return { block: validated, errors: [] };
|
|
769
768
|
}
|
|
770
769
|
lastErrors = validated;
|
|
771
770
|
if (attempt === maxAttempts) break;
|
|
772
|
-
const { offendingHashes, reason } = await identifyOffendingTransactions({
|
|
773
|
-
candidateTransactions,
|
|
774
|
-
errors: validated
|
|
775
|
-
});
|
|
771
|
+
const { offendingHashes, reason } = await identifyOffendingTransactions({ candidateTransactions, errors: validated });
|
|
776
772
|
if (offendingHashes.length === 0 || reason === "unknown") break;
|
|
777
773
|
for (const offendingHash of offendingHashes) this._excludedTransactionHashes.add(offendingHash);
|
|
778
774
|
const offendingSet = new Set(offendingHashes);
|
|
@@ -781,26 +777,28 @@ var SimpleBlockRunner = class _SimpleBlockRunner extends AbstractCreatableProvid
|
|
|
781
777
|
candidateTransfers = (await generateTransactionFeeTransfers(this.address, candidateTransactions)).filter((t) => remainingFromAddresses.has(t.from));
|
|
782
778
|
this.logger?.warn(`Block validation failed (attempt ${attempt + 1}); excluded ${offendingHashes.length} tx(s), retrying`);
|
|
783
779
|
}
|
|
784
|
-
return {
|
|
785
|
-
block: lastBlock,
|
|
786
|
-
errors: lastErrors
|
|
787
|
-
};
|
|
780
|
+
return { block: lastBlock, errors: lastErrors };
|
|
788
781
|
}
|
|
789
782
|
};
|
|
790
|
-
SimpleBlockRunner
|
|
783
|
+
__publicField(SimpleBlockRunner, "defaultMoniker", BlockRunnerMoniker);
|
|
784
|
+
__publicField(SimpleBlockRunner, "dependencies", [
|
|
785
|
+
AccountBalanceViewerMoniker,
|
|
786
|
+
BlockRewardViewerMoniker2,
|
|
787
|
+
BlockValidationViewerMoniker,
|
|
788
|
+
FinalizationViewerMoniker,
|
|
789
|
+
MempoolViewerMoniker,
|
|
790
|
+
TimeSyncViewerMoniker
|
|
791
|
+
]);
|
|
792
|
+
__publicField(SimpleBlockRunner, "monikers", [BlockRunnerMoniker]);
|
|
793
|
+
SimpleBlockRunner = __decorateClass([
|
|
791
794
|
creatableProvider3()
|
|
792
795
|
], SimpleBlockRunner);
|
|
793
796
|
|
|
794
797
|
// src/StepStake/BaseStepStakeService.ts
|
|
795
798
|
import { AbstractCreatableProvider as AbstractCreatableProvider5, StepStakeViewerMoniker } from "@xyo-network/xl1-sdk";
|
|
796
799
|
var AbstractStepStakeService = class _AbstractStepStakeService extends AbstractCreatableProvider5 {
|
|
797
|
-
static {
|
|
798
|
-
__name(this, "AbstractStepStakeService");
|
|
799
|
-
}
|
|
800
800
|
static defaultMoniker = StepStakeViewerMoniker;
|
|
801
|
-
static monikers = [
|
|
802
|
-
StepStakeViewerMoniker
|
|
803
|
-
];
|
|
801
|
+
static monikers = [StepStakeViewerMoniker];
|
|
804
802
|
moniker = _AbstractStepStakeService.defaultMoniker;
|
|
805
803
|
stepStake(_step) {
|
|
806
804
|
throw new Error("Method [stepStake] not implemented.");
|
|
@@ -822,4 +820,4 @@ export {
|
|
|
822
820
|
createBootstrapHead,
|
|
823
821
|
processPendingBlocks
|
|
824
822
|
};
|
|
825
|
-
//# sourceMappingURL=index.mjs.map
|
|
823
|
+
//# sourceMappingURL=index.mjs.map
|