@xyo-network/chain-services 1.5.29 → 1.5.31
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 +254 -393
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/types/AccountBalance/XyoChainAccountBalanceService.d.ts +8 -1
- package/dist/types/AccountBalance/XyoChainAccountBalanceService.d.ts.map +1 -1
- package/dist/types/AccountBalance/accountBalanceServiceFromArchivist.d.ts.map +1 -1
- package/dist/types/BaseService.d.ts +2 -1
- package/dist/types/BaseService.d.ts.map +1 -1
- package/dist/types/BlockProducer/XyoBlockProducer.d.ts +4 -4
- package/dist/types/BlockProducer/XyoBlockProducer.d.ts.map +1 -1
- package/dist/types/{XyoChainBlockNumberIterator.d.ts → ChainBlockNumberIteration/ChainBlockNumberIterationService.d.ts} +4 -10
- package/dist/types/ChainBlockNumberIteration/ChainBlockNumberIterationService.d.ts.map +1 -0
- package/dist/types/ChainBlockNumberIteration/index.d.ts +3 -0
- package/dist/types/ChainBlockNumberIteration/index.d.ts.map +1 -0
- package/dist/types/ChainBlockNumberIteration/model/BlockNumberIteration.d.ts +7 -0
- package/dist/types/ChainBlockNumberIteration/model/BlockNumberIteration.d.ts.map +1 -0
- package/dist/types/ChainBlockNumberIteration/model/index.d.ts +2 -0
- package/dist/types/ChainBlockNumberIteration/model/index.d.ts.map +1 -0
- package/dist/types/ChainIndexService.d.ts +2 -2
- package/dist/types/ChainIndexService.d.ts.map +1 -1
- package/dist/types/ChainValidator/XyoValidator.d.ts.map +1 -1
- package/dist/types/PendingTransactions/PendingTransactions.d.ts +16 -6
- package/dist/types/PendingTransactions/PendingTransactions.d.ts.map +1 -1
- package/dist/types/PendingTransactions/bundledPayloadToHydratedTransaction.d.ts +4 -0
- package/dist/types/PendingTransactions/bundledPayloadToHydratedTransaction.d.ts.map +1 -0
- package/dist/types/PendingTransactions/hydratedTransactionToPayloadBundle.d.ts +4 -0
- package/dist/types/PendingTransactions/hydratedTransactionToPayloadBundle.d.ts.map +1 -0
- package/dist/types/StakeIntent/XyoStakeIntentService.d.ts.map +1 -1
- package/dist/types/Staker/Evm/Evm.d.ts +5 -8
- package/dist/types/Staker/Evm/Evm.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +39 -39
- package/src/AccountBalance/XyoChainAccountBalanceService.ts +36 -7
- package/src/AccountBalance/accountBalanceServiceFromArchivist.ts +1 -0
- package/src/BaseService.ts +2 -1
- package/src/BlockProducer/XyoBlockProducer.ts +6 -6
- package/src/{XyoChainBlockNumberIterator.ts → ChainBlockNumberIteration/ChainBlockNumberIterationService.ts} +16 -31
- package/src/ChainBlockNumberIteration/index.ts +2 -0
- package/src/ChainBlockNumberIteration/model/BlockNumberIteration.ts +7 -0
- package/src/ChainBlockNumberIteration/model/index.ts +1 -0
- package/src/ChainIndexService.ts +2 -2
- package/src/ChainValidator/XyoValidator.ts +1 -7
- package/src/PendingTransactions/PendingTransactions.ts +73 -57
- package/src/PendingTransactions/bundledPayloadToHydratedTransaction.ts +14 -0
- package/src/PendingTransactions/hydratedTransactionToPayloadBundle.ts +18 -0
- package/src/StakeIntent/XyoStakeIntentService.ts +7 -6
- package/src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts +2 -2
- package/src/Staker/Evm/Evm.ts +34 -39
- package/src/index.ts +1 -2
- package/dist/types/BaseEthProvider.d.ts +0 -56
- package/dist/types/BaseEthProvider.d.ts.map +0 -1
- package/dist/types/XyoChainBlockNumberIterator.d.ts.map +0 -1
- package/src/BaseEthProvider.ts +0 -219
package/dist/neutral/index.mjs
CHANGED
|
@@ -30,6 +30,7 @@ var accountBalanceServiceFromArchivist = /* @__PURE__ */ __name(async (archivist
|
|
|
30
30
|
isPositiveBigInt(value) ? value.positive : "0"
|
|
31
31
|
]));
|
|
32
32
|
}, "getBalances"),
|
|
33
|
+
name: "ArchivistAccountBalanceService",
|
|
33
34
|
async sync(head2) {
|
|
34
35
|
const analysis = await analyzeChain(archivist, [
|
|
35
36
|
new BalanceAnalyzer()
|
|
@@ -58,8 +59,9 @@ var accountBalanceServiceFromArchivist = /* @__PURE__ */ __name(async (archivist
|
|
|
58
59
|
// src/AccountBalance/XyoChainAccountBalanceService.ts
|
|
59
60
|
import { assertEx } from "@xylabs/assert";
|
|
60
61
|
import { toHex } from "@xylabs/hex";
|
|
61
|
-
import { analyzeChain as analyzeChain2, BalanceAnalyzer as BalanceAnalyzer2, isChainSummaryBalances as isChainSummaryBalances2 } from "@xyo-network/chain-analyze";
|
|
62
|
+
import { analyzeChain as analyzeChain2, BalanceAnalyzer as BalanceAnalyzer2, ChainSummaryBalancesSchema as ChainSummaryBalancesSchema2, isChainSummaryBalances as isChainSummaryBalances2 } from "@xyo-network/chain-analyze";
|
|
62
63
|
import { toPositiveBigInt } from "@xyo-network/chain-protocol";
|
|
64
|
+
import { PayloadBuilder } from "@xyo-network/payload-builder";
|
|
63
65
|
|
|
64
66
|
// src/BaseService.ts
|
|
65
67
|
import { BaseEmitter } from "@xylabs/events";
|
|
@@ -123,7 +125,14 @@ var XyoChainAccountBalanceService = class extends BaseService {
|
|
|
123
125
|
__name(this, "XyoChainAccountBalanceService");
|
|
124
126
|
}
|
|
125
127
|
_balances = {};
|
|
126
|
-
|
|
128
|
+
/**
|
|
129
|
+
* The most recent head that was indexed to
|
|
130
|
+
*/
|
|
131
|
+
_firstBlock = null;
|
|
132
|
+
/**
|
|
133
|
+
* The oldest block that was indexed through
|
|
134
|
+
*/
|
|
135
|
+
_lastBlock = null;
|
|
127
136
|
get chainArchivist() {
|
|
128
137
|
return assertEx(this.params.chainArchivist, () => "chainArchivist is required");
|
|
129
138
|
}
|
|
@@ -141,170 +150,30 @@ var XyoChainAccountBalanceService = class extends BaseService {
|
|
|
141
150
|
return result;
|
|
142
151
|
}
|
|
143
152
|
async sync(head) {
|
|
153
|
+
const startingBalances = new PayloadBuilder({
|
|
154
|
+
schema: ChainSummaryBalancesSchema2
|
|
155
|
+
}).fields({
|
|
156
|
+
balances: this._balances,
|
|
157
|
+
firstBlock: this._firstBlock,
|
|
158
|
+
lastBlock: this._lastBlock
|
|
159
|
+
}).build();
|
|
144
160
|
const analysis = await analyzeChain2(this.chainArchivist, [
|
|
145
|
-
new BalanceAnalyzer2()
|
|
146
|
-
], head, this.
|
|
147
|
-
|
|
161
|
+
new BalanceAnalyzer2(void 0, void 0, startingBalances)
|
|
162
|
+
], head, this._firstBlock);
|
|
163
|
+
const allAddressesBalances = analysis.find(isChainSummaryBalances2);
|
|
164
|
+
if (allAddressesBalances === void 0) return;
|
|
165
|
+
this._balances = {
|
|
166
|
+
...this._balances,
|
|
167
|
+
...allAddressesBalances.balances
|
|
168
|
+
};
|
|
169
|
+
this._firstBlock = allAddressesBalances.firstBlock;
|
|
170
|
+
if (this._lastBlock === null) this._lastBlock = allAddressesBalances.lastBlock;
|
|
148
171
|
}
|
|
149
172
|
};
|
|
150
173
|
XyoChainAccountBalanceService = _ts_decorate([
|
|
151
174
|
creatableService()
|
|
152
175
|
], XyoChainAccountBalanceService);
|
|
153
176
|
|
|
154
|
-
// src/BaseEthProvider.ts
|
|
155
|
-
var BaseEthProvider = class {
|
|
156
|
-
static {
|
|
157
|
-
__name(this, "BaseEthProvider");
|
|
158
|
-
}
|
|
159
|
-
eth_accounts() {
|
|
160
|
-
throw new Error("Method not implemented.");
|
|
161
|
-
}
|
|
162
|
-
eth_blockNumber() {
|
|
163
|
-
throw new Error("Method not implemented.");
|
|
164
|
-
}
|
|
165
|
-
eth_call(_transaction, _blockNumber) {
|
|
166
|
-
throw new Error("Method not implemented.");
|
|
167
|
-
}
|
|
168
|
-
eth_clearSubscriptions(_keepSyncing) {
|
|
169
|
-
throw new Error("Method not implemented.");
|
|
170
|
-
}
|
|
171
|
-
eth_coinbase() {
|
|
172
|
-
throw new Error("Method not implemented.");
|
|
173
|
-
}
|
|
174
|
-
eth_compileLLL(_code) {
|
|
175
|
-
throw new Error("Method not implemented.");
|
|
176
|
-
}
|
|
177
|
-
eth_compileSerpent(_code) {
|
|
178
|
-
throw new Error("Method not implemented.");
|
|
179
|
-
}
|
|
180
|
-
eth_compileSolidity(_code) {
|
|
181
|
-
throw new Error("Method not implemented.");
|
|
182
|
-
}
|
|
183
|
-
eth_estimateGas(_transaction, _blockNumber) {
|
|
184
|
-
throw new Error("Method not implemented.");
|
|
185
|
-
}
|
|
186
|
-
eth_feeHistory(_blockCount, _newestBlock, _rewardPercentiles) {
|
|
187
|
-
throw new Error("Method not implemented.");
|
|
188
|
-
}
|
|
189
|
-
eth_gasPrice() {
|
|
190
|
-
throw new Error("Method not implemented.");
|
|
191
|
-
}
|
|
192
|
-
eth_getBalance(_address, _blockNumber) {
|
|
193
|
-
throw new Error("Method not implemented.");
|
|
194
|
-
}
|
|
195
|
-
eth_getBlockByHash(_blockHash, _hydrated) {
|
|
196
|
-
throw new Error("Method not implemented.");
|
|
197
|
-
}
|
|
198
|
-
eth_getBlockByNumber(_blockNumber, _hydrated) {
|
|
199
|
-
throw new Error("Method not implemented.");
|
|
200
|
-
}
|
|
201
|
-
eth_getBlockTransactionCountByHash(_blockHash) {
|
|
202
|
-
throw new Error("Method not implemented.");
|
|
203
|
-
}
|
|
204
|
-
eth_getBlockTransactionCountByNumber(_blockNumber) {
|
|
205
|
-
throw new Error("Method not implemented.");
|
|
206
|
-
}
|
|
207
|
-
eth_getCode(_address, _blockNumber) {
|
|
208
|
-
throw new Error("Method not implemented.");
|
|
209
|
-
}
|
|
210
|
-
eth_getCompilers() {
|
|
211
|
-
throw new Error("Method not implemented.");
|
|
212
|
-
}
|
|
213
|
-
eth_getFilterChanges(_filterIdentifier) {
|
|
214
|
-
throw new Error("Method not implemented.");
|
|
215
|
-
}
|
|
216
|
-
eth_getFilterLogs(_filterIdentifier) {
|
|
217
|
-
throw new Error("Method not implemented.");
|
|
218
|
-
}
|
|
219
|
-
eth_getLogs(_filter) {
|
|
220
|
-
throw new Error("Method not implemented.");
|
|
221
|
-
}
|
|
222
|
-
eth_getStorageAt(_address, _storageSlot, _blockNumber) {
|
|
223
|
-
throw new Error("Method not implemented.");
|
|
224
|
-
}
|
|
225
|
-
eth_getTransactionByBlockHashAndIndex(_blockHash, _transactionIndex) {
|
|
226
|
-
throw new Error("Method not implemented.");
|
|
227
|
-
}
|
|
228
|
-
eth_getTransactionByBlockNumberAndIndex(_blockNumber, _transactionIndex) {
|
|
229
|
-
throw new Error("Method not implemented.");
|
|
230
|
-
}
|
|
231
|
-
eth_getTransactionByHash(_transactionHash) {
|
|
232
|
-
throw new Error("Method not implemented.");
|
|
233
|
-
}
|
|
234
|
-
eth_getTransactionCount(_address, _blockNumber) {
|
|
235
|
-
throw new Error("Method not implemented.");
|
|
236
|
-
}
|
|
237
|
-
eth_getTransactionReceipt(_transactionHash) {
|
|
238
|
-
throw new Error("Method not implemented.");
|
|
239
|
-
}
|
|
240
|
-
eth_getUncleByBlockHashAndIndex(_blockHash, _uncleIndex) {
|
|
241
|
-
throw new Error("Method not implemented.");
|
|
242
|
-
}
|
|
243
|
-
eth_getUncleByBlockNumberAndIndex(_blockNumber, _uncleIndex) {
|
|
244
|
-
throw new Error("Method not implemented.");
|
|
245
|
-
}
|
|
246
|
-
eth_getUncleCountByBlockHash(_blockHash) {
|
|
247
|
-
throw new Error("Method not implemented.");
|
|
248
|
-
}
|
|
249
|
-
eth_getUncleCountByBlockNumber(_blockNumber) {
|
|
250
|
-
throw new Error("Method not implemented.");
|
|
251
|
-
}
|
|
252
|
-
eth_getWork() {
|
|
253
|
-
throw new Error("Method not implemented.");
|
|
254
|
-
}
|
|
255
|
-
eth_hashrate() {
|
|
256
|
-
throw new Error("Method not implemented.");
|
|
257
|
-
}
|
|
258
|
-
eth_maxPriorityFeePerGas() {
|
|
259
|
-
throw new Error("Method not implemented.");
|
|
260
|
-
}
|
|
261
|
-
eth_mining() {
|
|
262
|
-
throw new Error("Method not implemented.");
|
|
263
|
-
}
|
|
264
|
-
eth_newBlockFilter() {
|
|
265
|
-
throw new Error("Method not implemented.");
|
|
266
|
-
}
|
|
267
|
-
eth_newFilter(_filter) {
|
|
268
|
-
throw new Error("Method not implemented.");
|
|
269
|
-
}
|
|
270
|
-
eth_newPendingTransactionFilter() {
|
|
271
|
-
throw new Error("Method not implemented.");
|
|
272
|
-
}
|
|
273
|
-
eth_protocolVersion() {
|
|
274
|
-
throw new Error("Method not implemented.");
|
|
275
|
-
}
|
|
276
|
-
eth_sendRawTransaction(_transaction) {
|
|
277
|
-
throw new Error("Method not implemented.");
|
|
278
|
-
}
|
|
279
|
-
eth_sendTransaction(_transaction) {
|
|
280
|
-
throw new Error("Method not implemented.");
|
|
281
|
-
}
|
|
282
|
-
eth_sign(_address, _message) {
|
|
283
|
-
throw new Error("Method not implemented.");
|
|
284
|
-
}
|
|
285
|
-
eth_signTransaction(_transaction) {
|
|
286
|
-
throw new Error("Method not implemented.");
|
|
287
|
-
}
|
|
288
|
-
eth_submitHashrate(_hashRate, _id) {
|
|
289
|
-
throw new Error("Method not implemented.");
|
|
290
|
-
}
|
|
291
|
-
eth_submitWork(_nonce, _hash, _digest) {
|
|
292
|
-
throw new Error("Method not implemented.");
|
|
293
|
-
}
|
|
294
|
-
eth_subscribe(..._params) {
|
|
295
|
-
throw new Error("Method not implemented.");
|
|
296
|
-
}
|
|
297
|
-
eth_syncing() {
|
|
298
|
-
throw new Error("Method not implemented.");
|
|
299
|
-
}
|
|
300
|
-
eth_uninstallFilter(_filterIdentifier) {
|
|
301
|
-
throw new Error("Method not implemented.");
|
|
302
|
-
}
|
|
303
|
-
eth_unsubscribe(_subscriptionId) {
|
|
304
|
-
throw new Error("Method not implemented.");
|
|
305
|
-
}
|
|
306
|
-
};
|
|
307
|
-
|
|
308
177
|
// src/BlockProducer/XyoBlockProducer.ts
|
|
309
178
|
import { assertEx as assertEx3 } from "@xylabs/assert";
|
|
310
179
|
import { exists } from "@xylabs/exists";
|
|
@@ -312,7 +181,7 @@ import { hexToBigInt, toHex as toHex2 } from "@xylabs/hex";
|
|
|
312
181
|
import { isUndefined } from "@xylabs/typeof";
|
|
313
182
|
import { FixedPercentageBlockRewardDiviner, FixedPercentageBlockRewardDivinerConfigSchema } from "@xyo-network/chain-modules";
|
|
314
183
|
import { buildBlock } from "@xyo-network/chain-protocol";
|
|
315
|
-
import { PayloadBuilder } from "@xyo-network/payload-builder";
|
|
184
|
+
import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/payload-builder";
|
|
316
185
|
import { asBlockBoundWitness, BlockNumberSchema, ChainStakeIntentSchema } from "@xyo-network/xl1-protocol";
|
|
317
186
|
|
|
318
187
|
// src/BlockProducer/generateTransactionFeeTransfers.ts
|
|
@@ -394,8 +263,8 @@ var XyoBlockProducer = class _XyoBlockProducer extends BaseService {
|
|
|
394
263
|
get pendingTransactionsService() {
|
|
395
264
|
return assertEx3(this.params.pendingTransactionsService, () => "Missing pendingTransactionsService");
|
|
396
265
|
}
|
|
397
|
-
get
|
|
398
|
-
return assertEx3(this.params.
|
|
266
|
+
get rejectedTransactionsArchivist() {
|
|
267
|
+
return assertEx3(this.params.rejectedTransactionsArchivist, () => "No rejected bundled transactions archivist");
|
|
399
268
|
}
|
|
400
269
|
get rewardAddress() {
|
|
401
270
|
return assertEx3(this.params.rewardAddress, () => "No reward address provided");
|
|
@@ -428,7 +297,7 @@ var XyoBlockProducer = class _XyoBlockProducer extends BaseService {
|
|
|
428
297
|
});
|
|
429
298
|
}
|
|
430
299
|
const blockHex = assertEx3(toHex2(block), () => "Failed to convert block to hex");
|
|
431
|
-
const blockId = new
|
|
300
|
+
const blockId = new PayloadBuilder2({
|
|
432
301
|
schema: BlockNumberSchema
|
|
433
302
|
}).fields({
|
|
434
303
|
block: blockHex
|
|
@@ -454,7 +323,7 @@ var XyoBlockProducer = class _XyoBlockProducer extends BaseService {
|
|
|
454
323
|
const currentBlock = head.block;
|
|
455
324
|
const timeToProducerExpiration = currentDeclarationEnd - currentBlock;
|
|
456
325
|
if (timeToProducerExpiration > XYO_PRODUCER_RESTAKE_WINDOW) return;
|
|
457
|
-
const intent = new
|
|
326
|
+
const intent = new PayloadBuilder2({
|
|
458
327
|
schema: ChainStakeIntentSchema
|
|
459
328
|
}).fields({
|
|
460
329
|
from: this.address,
|
|
@@ -502,7 +371,7 @@ var XyoBlockProducer = class _XyoBlockProducer extends BaseService {
|
|
|
502
371
|
if (errors.length > 0) {
|
|
503
372
|
this.logger?.warn(`Validation of produced block failed: ${errors.at(0)?.message}`);
|
|
504
373
|
const rejectedTransactions = block[1];
|
|
505
|
-
await this.
|
|
374
|
+
await this.rejectedTransactionsArchivist.insert(rejectedTransactions);
|
|
506
375
|
} else {
|
|
507
376
|
return block;
|
|
508
377
|
}
|
|
@@ -616,9 +485,95 @@ XyoBlockRewardService = _ts_decorate4([
|
|
|
616
485
|
])
|
|
617
486
|
], XyoBlockRewardService);
|
|
618
487
|
|
|
619
|
-
// src/
|
|
488
|
+
// src/ChainBlockNumberIteration/ChainBlockNumberIterationService.ts
|
|
620
489
|
import { assertEx as assertEx6 } from "@xylabs/assert";
|
|
621
|
-
import {
|
|
490
|
+
import { isDefined as isDefined2, isNull } from "@xylabs/typeof";
|
|
491
|
+
import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/payload-builder";
|
|
492
|
+
import { asBlockBoundWitness as asBlockBoundWitness2, isBlockBoundWitness } from "@xyo-network/xl1-protocol";
|
|
493
|
+
import { LRUCache } from "lru-cache";
|
|
494
|
+
var ChainBlockNumberIterationService = class extends BaseService {
|
|
495
|
+
static {
|
|
496
|
+
__name(this, "ChainBlockNumberIterationService");
|
|
497
|
+
}
|
|
498
|
+
_blocksByBlockNumber = new LRUCache({
|
|
499
|
+
max: 1e4
|
|
500
|
+
});
|
|
501
|
+
get chainArchivist() {
|
|
502
|
+
return assertEx6(this.params.chainArchivist);
|
|
503
|
+
}
|
|
504
|
+
get chainIdentification() {
|
|
505
|
+
return {
|
|
506
|
+
id: assertEx6(this.params.head?.chain)
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
async get(block) {
|
|
510
|
+
const head = await this.head();
|
|
511
|
+
assertEx6(head.block >= block, () => `Block requested is newer than the current head [${block}]`);
|
|
512
|
+
const cached = this._blocksByBlockNumber.get(block);
|
|
513
|
+
if (cached) return cached;
|
|
514
|
+
const startingBlock = head;
|
|
515
|
+
const currentBlockHash = await PayloadBuilder3.hash(startingBlock);
|
|
516
|
+
let currentBlock = (await this.chainArchivist.get([
|
|
517
|
+
currentBlockHash
|
|
518
|
+
])).at(0);
|
|
519
|
+
while (isDefined2(currentBlock)) {
|
|
520
|
+
assertEx6(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${currentBlock?._hash}]`);
|
|
521
|
+
if (isBlockBoundWitness(currentBlock)) {
|
|
522
|
+
this._blocksByBlockNumber.set(currentBlock.block, currentBlock);
|
|
523
|
+
if (currentBlock.block === block) {
|
|
524
|
+
return currentBlock;
|
|
525
|
+
}
|
|
526
|
+
const { previous } = currentBlock;
|
|
527
|
+
if (isNull(previous)) break;
|
|
528
|
+
currentBlock = (await this.chainArchivist.get([
|
|
529
|
+
previous
|
|
530
|
+
])).at(0);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
throw new Error(`Block not found: ${block}`);
|
|
534
|
+
}
|
|
535
|
+
async head() {
|
|
536
|
+
return await Promise.resolve(assertEx6(this.params.head));
|
|
537
|
+
}
|
|
538
|
+
async next(block) {
|
|
539
|
+
const currentBlock = block;
|
|
540
|
+
const nextBlockNumber = currentBlock + 1;
|
|
541
|
+
return await this.get(nextBlockNumber);
|
|
542
|
+
}
|
|
543
|
+
// TODO: Decide on inclusive/exclusive (probably need inclusive to account for chain head)
|
|
544
|
+
// and then communicate via method name and documentation
|
|
545
|
+
async previous(block = void 0, count = 1) {
|
|
546
|
+
const results = [];
|
|
547
|
+
let currentBlock = isDefined2(block) ? await this.get(block) : await this.head();
|
|
548
|
+
while (currentBlock && results.length < count) {
|
|
549
|
+
if (isBlockBoundWitness(currentBlock)) {
|
|
550
|
+
results.push(currentBlock);
|
|
551
|
+
const { previous } = currentBlock;
|
|
552
|
+
if (isNull(previous)) break;
|
|
553
|
+
const nextBlock = await this.chainArchivist.get([
|
|
554
|
+
previous
|
|
555
|
+
]);
|
|
556
|
+
currentBlock = asBlockBoundWitness2(nextBlock[0]);
|
|
557
|
+
} else {
|
|
558
|
+
const hash = PayloadBuilder3.hash(currentBlock);
|
|
559
|
+
assertEx6(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${hash}]`);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return results;
|
|
563
|
+
}
|
|
564
|
+
async updateHead(head) {
|
|
565
|
+
await Promise.resolve();
|
|
566
|
+
this.params.head = head;
|
|
567
|
+
void this.emit("headUpdated", {
|
|
568
|
+
blocks: [
|
|
569
|
+
head
|
|
570
|
+
]
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
// src/ChainValidator/XyoValidator.ts
|
|
576
|
+
import { assertEx as assertEx7 } from "@xylabs/assert";
|
|
622
577
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
623
578
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
624
579
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -626,12 +581,6 @@ function _ts_decorate5(decorators, target, key, desc) {
|
|
|
626
581
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
627
582
|
}
|
|
628
583
|
__name(_ts_decorate5, "_ts_decorate");
|
|
629
|
-
var addStorageMeta = /* @__PURE__ */ __name(async ([tx, payloads]) => {
|
|
630
|
-
return [
|
|
631
|
-
await PayloadBuilder2.addStorageMeta(tx),
|
|
632
|
-
await PayloadBuilder2.addStorageMeta(payloads)
|
|
633
|
-
];
|
|
634
|
-
}, "addStorageMeta");
|
|
635
584
|
var XyoValidator = class extends BaseService {
|
|
636
585
|
static {
|
|
637
586
|
__name(this, "XyoValidator");
|
|
@@ -640,29 +589,29 @@ var XyoValidator = class extends BaseService {
|
|
|
640
589
|
return this.account.address;
|
|
641
590
|
}
|
|
642
591
|
get account() {
|
|
643
|
-
return
|
|
592
|
+
return assertEx7(this.params.account, () => "account is required");
|
|
644
593
|
}
|
|
645
594
|
get chainArchivist() {
|
|
646
|
-
return
|
|
595
|
+
return assertEx7(this.params.chainArchivist, () => "chainArchivist is required");
|
|
647
596
|
}
|
|
648
597
|
get chainInfo() {
|
|
649
|
-
return
|
|
598
|
+
return assertEx7(this.params.chainInformation, () => "chainInfo is required");
|
|
650
599
|
}
|
|
651
600
|
get electionService() {
|
|
652
|
-
return
|
|
601
|
+
return assertEx7(this.params.electionService, () => "electionService is required");
|
|
653
602
|
}
|
|
654
603
|
get pendingBundledTransactionsArchivist() {
|
|
655
|
-
return
|
|
604
|
+
return assertEx7(this.params.pendingBundledTransactionsArchivist, () => "pendingBundledTransactions is required");
|
|
656
605
|
}
|
|
657
606
|
get rewardService() {
|
|
658
|
-
return
|
|
607
|
+
return assertEx7(this.params.rewardService, () => "rewardService is required");
|
|
659
608
|
}
|
|
660
609
|
validatePendingBlock(_block) {
|
|
661
610
|
return [];
|
|
662
611
|
}
|
|
663
612
|
// TODO: Move to validator and inherit this class from validator
|
|
664
613
|
async validatePendingTransaction(hydratedTransaction) {
|
|
665
|
-
const [tx] =
|
|
614
|
+
const [tx] = hydratedTransaction;
|
|
666
615
|
if ((await this.chainArchivist.get([
|
|
667
616
|
tx._hash
|
|
668
617
|
])).length > 0) return false;
|
|
@@ -674,9 +623,9 @@ XyoValidator = _ts_decorate5([
|
|
|
674
623
|
], XyoValidator);
|
|
675
624
|
|
|
676
625
|
// src/Election/XyoElectionService.ts
|
|
677
|
-
import { assertEx as
|
|
626
|
+
import { assertEx as assertEx8 } from "@xylabs/assert";
|
|
678
627
|
import { hexToLast4BytesInt, shuffleWithSeed } from "@xyo-network/chain-utils";
|
|
679
|
-
import { PayloadBuilder as
|
|
628
|
+
import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/payload-builder";
|
|
680
629
|
function _ts_decorate6(decorators, target, key, desc) {
|
|
681
630
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
682
631
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -696,19 +645,19 @@ var XyoElectionService = class extends BaseService {
|
|
|
696
645
|
super(params);
|
|
697
646
|
}
|
|
698
647
|
get chainIterator() {
|
|
699
|
-
return
|
|
648
|
+
return assertEx8(this.params.chainIterator, () => "No chain iterator");
|
|
700
649
|
}
|
|
701
650
|
get chainStakeViewer() {
|
|
702
|
-
return
|
|
651
|
+
return assertEx8(this.params.chainStakeViewer, () => "No chain stake viewer");
|
|
703
652
|
}
|
|
704
653
|
get stakeIntentService() {
|
|
705
|
-
return
|
|
654
|
+
return assertEx8(this.params.stakeIntentService, () => "No staked intent service");
|
|
706
655
|
}
|
|
707
656
|
async getCreatorCommitteeForNextBlock(current) {
|
|
708
657
|
return await this.spanAsync("getCreatorCommitteeForNextBlock", async () => {
|
|
709
658
|
const nextBlock = current.block + 1;
|
|
710
659
|
const candidates = await this.stakeIntentService.getDeclaredCandidatesForBlock(nextBlock, "producer");
|
|
711
|
-
const previousBlockHash = await
|
|
660
|
+
const previousBlockHash = await PayloadBuilder4.hash(current);
|
|
712
661
|
return this.generateCreatorCommittee(candidates, previousBlockHash);
|
|
713
662
|
});
|
|
714
663
|
}
|
|
@@ -730,16 +679,49 @@ XyoElectionService = _ts_decorate6([
|
|
|
730
679
|
// src/PendingTransactions/PendingTransactions.ts
|
|
731
680
|
import { ValueType } from "@opentelemetry/api";
|
|
732
681
|
import { filterAsync } from "@xylabs/array";
|
|
733
|
-
import { assertEx as
|
|
682
|
+
import { assertEx as assertEx9 } from "@xylabs/assert";
|
|
734
683
|
import { exists as exists2 } from "@xylabs/exists";
|
|
735
684
|
import { forget } from "@xylabs/forget";
|
|
736
685
|
import { MemoryArchivist } from "@xyo-network/archivist-memory";
|
|
737
686
|
import { globalAttributes } from "@xyo-network/chain-telemetry";
|
|
738
687
|
import { validateTransaction } from "@xyo-network/chain-validation";
|
|
739
|
-
import { PayloadBuilder as
|
|
740
|
-
import {
|
|
741
|
-
import { flattenHydratedTransaction } from "@xyo-network/xl1-protocol-sdk";
|
|
688
|
+
import { PayloadBuilder as PayloadBuilder7 } from "@xyo-network/payload-builder";
|
|
689
|
+
import { asTransactionBoundWitnessWithStorageMeta as asTransactionBoundWitnessWithStorageMeta2, isTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol";
|
|
742
690
|
import { Mutex as Mutex2 } from "async-mutex";
|
|
691
|
+
|
|
692
|
+
// src/PendingTransactions/bundledPayloadToHydratedTransaction.ts
|
|
693
|
+
import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/payload-builder";
|
|
694
|
+
import { asTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol";
|
|
695
|
+
var bundledPayloadToHydratedTransaction = /* @__PURE__ */ __name(async (payload) => {
|
|
696
|
+
const withStorageMeta = await PayloadBuilder5.addStorageMeta(payload.payloads);
|
|
697
|
+
const tx = asTransactionBoundWitnessWithStorageMeta(withStorageMeta.find((p) => p._hash === payload.root));
|
|
698
|
+
if (tx) {
|
|
699
|
+
return [
|
|
700
|
+
tx,
|
|
701
|
+
withStorageMeta.filter((p) => p._hash !== payload.root)
|
|
702
|
+
];
|
|
703
|
+
}
|
|
704
|
+
}, "bundledPayloadToHydratedTransaction");
|
|
705
|
+
|
|
706
|
+
// src/PendingTransactions/hydratedTransactionToPayloadBundle.ts
|
|
707
|
+
import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/payload-builder";
|
|
708
|
+
import { PayloadBundleSchema } from "@xyo-network/payload-model";
|
|
709
|
+
import { flattenHydratedTransaction } from "@xyo-network/xl1-protocol-sdk";
|
|
710
|
+
var hydratedTransactionToPayloadBundle = /* @__PURE__ */ __name((transaction) => {
|
|
711
|
+
const root = transaction[0]._hash;
|
|
712
|
+
return bundle(root, transaction);
|
|
713
|
+
}, "hydratedTransactionToPayloadBundle");
|
|
714
|
+
var bundle = /* @__PURE__ */ __name((root, transaction) => {
|
|
715
|
+
const payloads = flattenHydratedTransaction(transaction).flatMap((p) => PayloadBuilder6.omitStorageMeta(p));
|
|
716
|
+
return new PayloadBuilder6({
|
|
717
|
+
schema: PayloadBundleSchema
|
|
718
|
+
}).fields({
|
|
719
|
+
payloads,
|
|
720
|
+
root
|
|
721
|
+
}).build();
|
|
722
|
+
}, "bundle");
|
|
723
|
+
|
|
724
|
+
// src/PendingTransactions/PendingTransactions.ts
|
|
743
725
|
function _ts_decorate7(decorators, target, key, desc) {
|
|
744
726
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
745
727
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -747,17 +729,6 @@ function _ts_decorate7(decorators, target, key, desc) {
|
|
|
747
729
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
748
730
|
}
|
|
749
731
|
__name(_ts_decorate7, "_ts_decorate");
|
|
750
|
-
async function bundledPayloadsToHydratedTransaction(payload) {
|
|
751
|
-
const withStorageMeta = await PayloadBuilder4.addStorageMeta(payload.payloads);
|
|
752
|
-
const tx = asOptionalTransactionBoundWitnessWithStorageMeta(withStorageMeta.find((p) => p._hash === payload.root));
|
|
753
|
-
if (tx) {
|
|
754
|
-
return [
|
|
755
|
-
tx,
|
|
756
|
-
withStorageMeta.map((p) => p._hash === payload.root ? void 0 : p).filter(exists2)
|
|
757
|
-
];
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
__name(bundledPayloadsToHydratedTransaction, "bundledPayloadsToHydratedTransaction");
|
|
761
732
|
globalAttributes.setAttribute("XyoPendingTransactionsService:status", "unknown");
|
|
762
733
|
var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends BaseService {
|
|
763
734
|
static {
|
|
@@ -795,6 +766,11 @@ var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends
|
|
|
795
766
|
* The last count of total pending transactions
|
|
796
767
|
*/
|
|
797
768
|
_pendingTransactionsCount = 0;
|
|
769
|
+
/**
|
|
770
|
+
* A set of transaction hashes that are pending removal from the
|
|
771
|
+
* curated pending transactions archivist. This is used to track
|
|
772
|
+
* which transactions need to be removed from the archivist.
|
|
773
|
+
*/
|
|
798
774
|
_removablePendingTransactionHashes = /* @__PURE__ */ new Set();
|
|
799
775
|
/**
|
|
800
776
|
* A mutex to ensure that the curated pending transactions archivist is
|
|
@@ -802,23 +778,23 @@ var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends
|
|
|
802
778
|
*/
|
|
803
779
|
_updateCuratedPendingTransactionsArchivistMutex = new Mutex2();
|
|
804
780
|
get chainArchivist() {
|
|
805
|
-
return
|
|
781
|
+
return assertEx9(this.params.chainArchivist, () => "No completed blocks with data archivist");
|
|
806
782
|
}
|
|
807
783
|
get chainIdentification() {
|
|
808
|
-
return
|
|
784
|
+
return assertEx9(this.params.chainIdentification, () => "No chain id");
|
|
809
785
|
}
|
|
810
786
|
get pendingBundledTransactionsArchivist() {
|
|
811
|
-
return
|
|
787
|
+
return assertEx9(this.params.pendingBundledTransactionsArchivist, () => "No pending bundled transactions archivist");
|
|
812
788
|
}
|
|
813
789
|
get pendingBundledTransactionsLocalArchivist() {
|
|
814
|
-
return
|
|
790
|
+
return assertEx9(this._curatedPendingBundledTransactionsArchivist, () => "No pending bundled transactions curated archivist");
|
|
815
791
|
}
|
|
816
792
|
get pendingTransactionsCount() {
|
|
817
793
|
forget(this.countPendingTransactions());
|
|
818
794
|
return this._pendingTransactionsCount;
|
|
819
795
|
}
|
|
820
|
-
get
|
|
821
|
-
return
|
|
796
|
+
get rejectedTransactionsArchivist() {
|
|
797
|
+
return assertEx9(this.params.rejectedTransactionsArchivist, () => "No rejected transactions archivist");
|
|
822
798
|
}
|
|
823
799
|
async createHandler() {
|
|
824
800
|
await super.createHandler();
|
|
@@ -829,10 +805,10 @@ var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends
|
|
|
829
805
|
await this.insertNewTransactions(payloads);
|
|
830
806
|
});
|
|
831
807
|
this.chainArchivist.on("inserted", ({ payloads }) => {
|
|
832
|
-
this.
|
|
808
|
+
this.markAnyIncludedTransactionsForRemoval(payloads);
|
|
833
809
|
});
|
|
834
|
-
this.
|
|
835
|
-
this.
|
|
810
|
+
this.rejectedTransactionsArchivist.on("inserted", ({ payloads }) => {
|
|
811
|
+
this.markAnyIncludedTransactionsForRemoval(payloads);
|
|
836
812
|
});
|
|
837
813
|
const pendingTransactionsCounter = this.meter?.createObservableUpDownCounter("xyo_pending_transactions_counter", {
|
|
838
814
|
description: "The current number of pending transactions",
|
|
@@ -861,13 +837,13 @@ var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends
|
|
|
861
837
|
const deletedTransactionBundles = payloads.filter((tx) => this._removablePendingTransactionHashes.has(tx.root));
|
|
862
838
|
foundPendingTransactionsToDeleteHashes.push(...deletedTransactionBundles.map((tx) => tx._hash).filter(exists2));
|
|
863
839
|
const undeletedTransactionBundles = payloads.filter((tx) => !this._removablePendingTransactionHashes.has(tx.root));
|
|
864
|
-
const transactions = (await Promise.all(undeletedTransactionBundles.map((p) =>
|
|
840
|
+
const transactions = (await Promise.all(undeletedTransactionBundles.map((p) => bundledPayloadToHydratedTransaction(p)))).filter(exists2);
|
|
865
841
|
foundPendingTransactions.push(...transactions);
|
|
866
842
|
}
|
|
843
|
+
await this.pendingBundledTransactionsLocalArchivist.delete(foundPendingTransactionsToDeleteHashes);
|
|
867
844
|
for (const hash of foundPendingTransactionsToDeleteHashes) {
|
|
868
845
|
this._removablePendingTransactionHashes.delete(hash);
|
|
869
846
|
}
|
|
870
|
-
await this.pendingBundledTransactionsLocalArchivist.delete(foundPendingTransactionsToDeleteHashes);
|
|
871
847
|
return foundPendingTransactions;
|
|
872
848
|
}, _XyoPendingTransactionsService.MutexPriority.ReadTransactions);
|
|
873
849
|
});
|
|
@@ -887,12 +863,13 @@ var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends
|
|
|
887
863
|
return nonFinalizedTransactions;
|
|
888
864
|
}
|
|
889
865
|
async insertNewTransactions(payloads) {
|
|
866
|
+
if (payloads.length === 0) return;
|
|
890
867
|
this.logger?.log("insertNewTransactions", payloads);
|
|
891
868
|
return await this.spanAsync("InsertNewTransactions", async () => {
|
|
892
869
|
return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
|
|
893
870
|
const unprocessedTransactions = await this.filterAlreadyFinalizedTransactions(payloads);
|
|
894
871
|
const hydratedUnprocessedTransactions = (await Promise.all(unprocessedTransactions.map(async (tx) => {
|
|
895
|
-
return await
|
|
872
|
+
return await bundledPayloadToHydratedTransaction(tx);
|
|
896
873
|
}))).filter(exists2);
|
|
897
874
|
const validTransactions = await filterAsync(hydratedUnprocessedTransactions, async (tx) => {
|
|
898
875
|
const errors = await validateTransaction(tx, this.chainIdentification.id);
|
|
@@ -902,40 +879,36 @@ var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends
|
|
|
902
879
|
return errors.length > 0 ? false : true;
|
|
903
880
|
});
|
|
904
881
|
if (validTransactions.length > 0) {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
root: tx[0]._hash,
|
|
908
|
-
payloads: flattenHydratedTransaction(tx)
|
|
909
|
-
};
|
|
910
|
-
}));
|
|
882
|
+
const bundledTransactions = validTransactions.map((tx) => hydratedTransactionToPayloadBundle(tx));
|
|
883
|
+
await this.pendingBundledTransactionsLocalArchivist.insert(bundledTransactions);
|
|
911
884
|
}
|
|
912
885
|
}, _XyoPendingTransactionsService.MutexPriority.InsertNewTransactions);
|
|
913
886
|
});
|
|
914
887
|
}
|
|
888
|
+
/**
|
|
889
|
+
* Marks any included transactions in the provided payloads for removal preventing them
|
|
890
|
+
* from being included in the curated pending transactions archivist and from being offered
|
|
891
|
+
* during the next retrieval of pending transactions.
|
|
892
|
+
* @param payloads An array of payloads that may contain transactions.
|
|
893
|
+
*/
|
|
894
|
+
markAnyIncludedTransactionsForRemoval(payloads) {
|
|
895
|
+
const hashes = payloads.filter(isTransactionBoundWitnessWithStorageMeta).map((p) => p._hash);
|
|
896
|
+
for (const hash of hashes) {
|
|
897
|
+
this._removablePendingTransactionHashes.add(hash);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
915
900
|
async removeBundledTransactions(bundledPayloads, priority) {
|
|
916
901
|
return await this.spanAsync(priority, async () => {
|
|
917
902
|
return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
|
|
918
903
|
const bundledTransactions = (await Promise.all(bundledPayloads.map(async (payload) => {
|
|
919
|
-
const withStorageMeta = await
|
|
920
|
-
const tx =
|
|
904
|
+
const withStorageMeta = await PayloadBuilder7.addStorageMeta(payload.payloads);
|
|
905
|
+
const tx = asTransactionBoundWitnessWithStorageMeta2(withStorageMeta.find((p) => p._hash === payload.root));
|
|
921
906
|
return tx !== void 0 && payload._hash !== void 0 ? tx : void 0;
|
|
922
907
|
}))).filter(exists2);
|
|
923
908
|
await this.pendingBundledTransactionsLocalArchivist.delete(bundledTransactions.map((btx) => btx._hash));
|
|
924
909
|
}, _XyoPendingTransactionsService.MutexPriority[priority]);
|
|
925
910
|
});
|
|
926
911
|
}
|
|
927
|
-
removeFinalizedTransactions(payloads) {
|
|
928
|
-
const finalizedTransactionHashes = payloads.filter(isTransactionBoundWitnessWithStorageMeta).map((p) => p._hash);
|
|
929
|
-
for (const hash of finalizedTransactionHashes) {
|
|
930
|
-
this._removablePendingTransactionHashes.add(hash);
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
removeRejectedBundledTransactions(payloads) {
|
|
934
|
-
const rejectedTransactionHashes = payloads.filter(isTransactionBoundWitnessWithStorageMeta).map((p) => p._hash);
|
|
935
|
-
for (const hash of rejectedTransactionHashes) {
|
|
936
|
-
this._removablePendingTransactionHashes.add(hash);
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
912
|
};
|
|
940
913
|
XyoPendingTransactionsService = _ts_decorate7([
|
|
941
914
|
creatableService()
|
|
@@ -947,7 +920,7 @@ import { exists as exists3 } from "@xylabs/exists";
|
|
|
947
920
|
import { asOptionalBoundWitness } from "@xyo-network/boundwitness-model";
|
|
948
921
|
import { payloadSchemasContains } from "@xyo-network/boundwitness-validator";
|
|
949
922
|
import { BoundWitnessWrapper } from "@xyo-network/boundwitness-wrapper";
|
|
950
|
-
import {
|
|
923
|
+
import { asChainStakeIntent, ChainStakeIntentSchema as ChainStakeIntentSchema2 } from "@xyo-network/xl1-protocol";
|
|
951
924
|
var getBlockSignedStakeDeclarations = /* @__PURE__ */ __name(async (block, archivist, intent) => {
|
|
952
925
|
const blockData = await archivist.get(block.payload_hashes);
|
|
953
926
|
const bwsFromBlock = filterAs(blockData, asOptionalBoundWitness);
|
|
@@ -956,7 +929,7 @@ var getBlockSignedStakeDeclarations = /* @__PURE__ */ __name(async (block, archi
|
|
|
956
929
|
return (await Promise.all(validBlockBwsWithDeclarations.map(async (bw) => {
|
|
957
930
|
const stakeIntentHashes = validBlockBwsWithDeclarations.flatMap(mapBoundWitnessToStakeIntentHashes).filter(exists3);
|
|
958
931
|
const payloads = await archivist.get(stakeIntentHashes);
|
|
959
|
-
const stakeIntents = filterAs(payloads,
|
|
932
|
+
const stakeIntents = filterAs(payloads, asChainStakeIntent).filter((p) => p.intent === intent).filter((p) => bw.addresses.includes(p.from));
|
|
960
933
|
return stakeIntents;
|
|
961
934
|
}))).flat();
|
|
962
935
|
}, "getBlockSignedStakeDeclarations");
|
|
@@ -970,14 +943,14 @@ var mapBoundWitnessToStakeIntentHashes = /* @__PURE__ */ __name((bw) => {
|
|
|
970
943
|
|
|
971
944
|
// src/StakeIntent/XyoStakeIntentService.ts
|
|
972
945
|
import { filterAs as filterAs2 } from "@xylabs/array";
|
|
973
|
-
import { assertEx as
|
|
946
|
+
import { assertEx as assertEx10 } from "@xylabs/assert";
|
|
974
947
|
import { asAddress } from "@xylabs/hex";
|
|
975
948
|
import { analyzeChain as analyzeChain3, ChainStakeIntentAnalyzer, isChainSummaryStakeIntent } from "@xyo-network/chain-analyze";
|
|
976
949
|
import { DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS, findFirstMatching, IntervalMap } from "@xyo-network/chain-utils";
|
|
977
|
-
import { PayloadBuilder as
|
|
978
|
-
import {
|
|
950
|
+
import { PayloadBuilder as PayloadBuilder8 } from "@xyo-network/payload-builder";
|
|
951
|
+
import { asBlockBoundWitness as asBlockBoundWitness3, asBlockBoundWitnessWithStorageMeta, asChainIndexingServiceStateWithStorageMeta, asChainStakeIntent as asChainStakeIntent2, ChainIndexingServiceStateSchema, isChainIndexingServiceState } from "@xyo-network/xl1-protocol";
|
|
979
952
|
import { Mutex as Mutex3 } from "async-mutex";
|
|
980
|
-
import { LRUCache } from "lru-cache";
|
|
953
|
+
import { LRUCache as LRUCache2 } from "lru-cache";
|
|
981
954
|
function _ts_decorate8(decorators, target, key, desc) {
|
|
982
955
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
983
956
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1006,7 +979,7 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1006
979
|
// in performance for small sets, and (most importantly) easily
|
|
1007
980
|
// persisted so we can recover state on restart.
|
|
1008
981
|
_producers = new IntervalMap();
|
|
1009
|
-
_stakeCache = new
|
|
982
|
+
_stakeCache = new LRUCache2({
|
|
1010
983
|
max: STAKE_CACHE_MAX_ENTRIES
|
|
1011
984
|
});
|
|
1012
985
|
_updateMutex = new Mutex3();
|
|
@@ -1017,33 +990,33 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1017
990
|
});
|
|
1018
991
|
}
|
|
1019
992
|
get chainArchivist() {
|
|
1020
|
-
return
|
|
993
|
+
return assertEx10(this.params.chainArchivist, () => "chainArchivist not set");
|
|
1021
994
|
}
|
|
1022
995
|
get chainIterator() {
|
|
1023
|
-
return
|
|
996
|
+
return assertEx10(this.params.chainIterator, () => "chainIterator not set");
|
|
1024
997
|
}
|
|
1025
998
|
get chainStakeViewer() {
|
|
1026
|
-
return
|
|
999
|
+
return assertEx10(this.params.chainStakeViewer, () => "chainStakeViewer not set");
|
|
1027
1000
|
}
|
|
1028
1001
|
get stakeIntentStateArchivist() {
|
|
1029
|
-
return
|
|
1002
|
+
return assertEx10(this.params.stakeIntentStateArchivist, () => "stakeIntentStateArchivist not set");
|
|
1030
1003
|
}
|
|
1031
1004
|
async createHandler() {
|
|
1032
1005
|
const head = await this.chainIterator.head();
|
|
1033
|
-
const headHash = await
|
|
1006
|
+
const headHash = await PayloadBuilder8.hash(head);
|
|
1034
1007
|
if (head?.block === void 0) return;
|
|
1035
1008
|
await this.recoverState(headHash);
|
|
1036
1009
|
await this.updateIndex(true);
|
|
1037
1010
|
}
|
|
1038
1011
|
async getDeclaredCandidateRanges(address, intent) {
|
|
1039
1012
|
await Promise.resolve();
|
|
1040
|
-
|
|
1013
|
+
assertEx10(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
|
|
1041
1014
|
const results = this._producers.get(address);
|
|
1042
1015
|
return results ?? [];
|
|
1043
1016
|
}
|
|
1044
1017
|
async getDeclaredCandidatesForBlock(block, intent) {
|
|
1045
1018
|
return await this.spanAsync("getDeclaredCandidatesForBlock", async () => {
|
|
1046
|
-
|
|
1019
|
+
assertEx10(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
|
|
1047
1020
|
const results = this._producers.findAllContaining(block);
|
|
1048
1021
|
const candidates = [
|
|
1049
1022
|
...results
|
|
@@ -1085,7 +1058,7 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1085
1058
|
}
|
|
1086
1059
|
async persistState(current) {
|
|
1087
1060
|
const state = this._producers.serialize();
|
|
1088
|
-
const payload = new
|
|
1061
|
+
const payload = new PayloadBuilder8({
|
|
1089
1062
|
schema: ChainIndexingServiceStateSchema
|
|
1090
1063
|
}).fields({
|
|
1091
1064
|
endBlockHash: current,
|
|
@@ -1096,7 +1069,7 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1096
1069
|
]);
|
|
1097
1070
|
}
|
|
1098
1071
|
async recoverState(current) {
|
|
1099
|
-
const currentBlock =
|
|
1072
|
+
const currentBlock = assertEx10(asBlockBoundWitness3((await this.chainArchivist.get([
|
|
1100
1073
|
current
|
|
1101
1074
|
]))?.[0]), () => `Block ${current} not found`);
|
|
1102
1075
|
const currentBlockNum = currentBlock.block;
|
|
@@ -1105,7 +1078,7 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1105
1078
|
};
|
|
1106
1079
|
while (true) {
|
|
1107
1080
|
const predicate = /* @__PURE__ */ __name((p) => {
|
|
1108
|
-
const state2 =
|
|
1081
|
+
const state2 = asChainIndexingServiceStateWithStorageMeta(p);
|
|
1109
1082
|
return state2 ? true : false;
|
|
1110
1083
|
}, "predicate");
|
|
1111
1084
|
const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts);
|
|
@@ -1113,7 +1086,7 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1113
1086
|
const indexed = (await this.chainArchivist.get([
|
|
1114
1087
|
state.endBlockHash
|
|
1115
1088
|
]))?.[0];
|
|
1116
|
-
const indexedBlock =
|
|
1089
|
+
const indexedBlock = asBlockBoundWitnessWithStorageMeta(indexed);
|
|
1117
1090
|
if (indexedBlock) {
|
|
1118
1091
|
const indexedBlockNum = indexedBlock.block;
|
|
1119
1092
|
if (indexedBlockNum <= currentBlockNum) {
|
|
@@ -1136,11 +1109,11 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1136
1109
|
await this._updateMutex.runExclusive(async () => {
|
|
1137
1110
|
return await this.spanAsync("updateIndex", async () => {
|
|
1138
1111
|
const currentHead = await this.chainIterator.head();
|
|
1139
|
-
const currentHeadHash = await
|
|
1112
|
+
const currentHeadHash = await PayloadBuilder8.hash(currentHead);
|
|
1140
1113
|
const result = await analyzeChain3(this.chainArchivist, [
|
|
1141
1114
|
new ChainStakeIntentAnalyzer("producer")
|
|
1142
1115
|
], currentHeadHash, this._lastIndexedBlockHash);
|
|
1143
|
-
const signedDeclarations = filterAs2(result.find(isChainSummaryStakeIntent)?.intents ?? [],
|
|
1116
|
+
const signedDeclarations = filterAs2(result.find(isChainSummaryStakeIntent)?.intents ?? [], asChainStakeIntent2);
|
|
1144
1117
|
if (currentHead.block === void 0) return;
|
|
1145
1118
|
const currentHeadBlockNum = currentHead.block;
|
|
1146
1119
|
if (displayProgress) this.logger?.info(`Updating index through 0x${currentHeadBlockNum}`);
|
|
@@ -1167,200 +1140,89 @@ XyoStakeIntentService = _ts_decorate8([
|
|
|
1167
1140
|
], XyoStakeIntentService);
|
|
1168
1141
|
|
|
1169
1142
|
// src/Staker/Evm/Evm.ts
|
|
1170
|
-
import {
|
|
1143
|
+
import { assertEx as assertEx11 } from "@xylabs/assert";
|
|
1171
1144
|
import { toAddress } from "@xylabs/hex";
|
|
1145
|
+
import { toEthAddress as toEthAddress2 } from "@xyo-network/chain-ethereum";
|
|
1172
1146
|
import { StakedXyoChain__factory as StakedXyoChainFactory } from "@xyo-network/typechain";
|
|
1173
1147
|
import { getAddress } from "ethers/address";
|
|
1174
|
-
var EvmChainService = class extends
|
|
1148
|
+
var EvmChainService = class extends BaseService {
|
|
1175
1149
|
static {
|
|
1176
1150
|
__name(this, "EvmChainService");
|
|
1177
1151
|
}
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1152
|
+
get contract() {
|
|
1153
|
+
if (this.params.contract === void 0) {
|
|
1154
|
+
this.params.contract = StakedXyoChainFactory.connect(toEthAddress2(this.id), this.params.runner);
|
|
1155
|
+
}
|
|
1156
|
+
return assertEx11(this.params.contract);
|
|
1182
1157
|
}
|
|
1183
1158
|
get id() {
|
|
1184
|
-
return this.params.id;
|
|
1159
|
+
return assertEx11(this.params.id);
|
|
1185
1160
|
}
|
|
1186
1161
|
get runner() {
|
|
1187
|
-
return this.params.runner;
|
|
1188
|
-
}
|
|
1189
|
-
static create({ id, runner, logger, traceProvider, meterProvider }) {
|
|
1190
|
-
const contractAddress = getAddress(id);
|
|
1191
|
-
const contract = StakedXyoChainFactory.connect(contractAddress, runner);
|
|
1192
|
-
return new this({
|
|
1193
|
-
id,
|
|
1194
|
-
contract,
|
|
1195
|
-
runner,
|
|
1196
|
-
logger,
|
|
1197
|
-
traceProvider,
|
|
1198
|
-
meterProvider
|
|
1199
|
-
});
|
|
1162
|
+
return assertEx11(this.params.runner);
|
|
1200
1163
|
}
|
|
1201
1164
|
async active() {
|
|
1202
|
-
return await this.
|
|
1165
|
+
return await this.contract.active();
|
|
1203
1166
|
}
|
|
1204
1167
|
async activeByAddressStaked(address) {
|
|
1205
|
-
return await this.
|
|
1168
|
+
return await this.contract.activeByAddressStaked(getAddress(address));
|
|
1206
1169
|
}
|
|
1207
1170
|
async activeByStaker(address) {
|
|
1208
|
-
return await this.
|
|
1171
|
+
return await this.contract.activeByStaker(getAddress(address));
|
|
1209
1172
|
}
|
|
1210
1173
|
async addStake(staked, amount) {
|
|
1211
|
-
const result = await this.
|
|
1174
|
+
const result = await this.contract.addStake(getAddress(staked), amount);
|
|
1212
1175
|
await result.wait();
|
|
1213
1176
|
return true;
|
|
1214
1177
|
}
|
|
1215
1178
|
async chainId() {
|
|
1216
|
-
return toAddress(await this.
|
|
1179
|
+
return toAddress(await this.contract.chainId());
|
|
1217
1180
|
}
|
|
1218
1181
|
async forkedAtBlockNumber() {
|
|
1219
|
-
return await this.
|
|
1182
|
+
return await this.contract.forkedAtBlockNumber();
|
|
1220
1183
|
}
|
|
1221
1184
|
async forkedAtHash() {
|
|
1222
|
-
return await this.
|
|
1185
|
+
return await this.contract.forkedAtHash();
|
|
1223
1186
|
}
|
|
1224
1187
|
async forkedChainId() {
|
|
1225
|
-
return toAddress(await this.
|
|
1188
|
+
return toAddress(await this.contract.forkedChainId());
|
|
1226
1189
|
}
|
|
1227
1190
|
async minWithdrawalBlocks() {
|
|
1228
|
-
return await this.
|
|
1191
|
+
return await this.contract.minWithdrawalBlocks();
|
|
1229
1192
|
}
|
|
1230
1193
|
async pending() {
|
|
1231
|
-
return await this.
|
|
1194
|
+
return await this.contract.pending();
|
|
1232
1195
|
}
|
|
1233
1196
|
async pendingByStaker(staker) {
|
|
1234
|
-
return await this.
|
|
1197
|
+
return await this.contract.pendingByStaker(getAddress(staker));
|
|
1235
1198
|
}
|
|
1236
1199
|
async removeStake(slot) {
|
|
1237
|
-
const result = await this.
|
|
1200
|
+
const result = await this.contract.removeStake(slot);
|
|
1238
1201
|
await result.wait();
|
|
1239
1202
|
return true;
|
|
1240
1203
|
}
|
|
1241
1204
|
async rewardsContract() {
|
|
1242
|
-
return await this.
|
|
1205
|
+
return await this.contract.rewardsContract();
|
|
1243
1206
|
}
|
|
1244
1207
|
async stakingTokenAddress() {
|
|
1245
|
-
return await this.
|
|
1208
|
+
return await this.contract.stakingTokenAddress();
|
|
1246
1209
|
}
|
|
1247
1210
|
async withdrawStake(slot) {
|
|
1248
|
-
const result = await this.
|
|
1211
|
+
const result = await this.contract.withdrawStake(slot);
|
|
1249
1212
|
await result.wait();
|
|
1250
1213
|
return true;
|
|
1251
1214
|
}
|
|
1252
1215
|
async withdrawn() {
|
|
1253
|
-
return await this.
|
|
1216
|
+
return await this.contract.withdrawn();
|
|
1254
1217
|
}
|
|
1255
1218
|
async withdrawnByStaker(staker) {
|
|
1256
|
-
return await this.
|
|
1257
|
-
}
|
|
1258
|
-
};
|
|
1259
|
-
|
|
1260
|
-
// src/XyoChainBlockNumberIterator.ts
|
|
1261
|
-
import { assertEx as assertEx10 } from "@xylabs/assert";
|
|
1262
|
-
import { BaseEmitter as BaseEmitter2 } from "@xylabs/events";
|
|
1263
|
-
import { isDefined as isDefined2, isNull } from "@xylabs/typeof";
|
|
1264
|
-
import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/payload-builder";
|
|
1265
|
-
import { asBlockBoundWitness as asBlockBoundWitness2, asOptionalBlockBoundWitness as asOptionalBlockBoundWitness2, isBlockBoundWitness } from "@xyo-network/xl1-protocol";
|
|
1266
|
-
import { LRUCache as LRUCache2 } from "lru-cache";
|
|
1267
|
-
var XyoChainBlockNumberIterator = class _XyoChainBlockNumberIterator extends BaseEmitter2 {
|
|
1268
|
-
static {
|
|
1269
|
-
__name(this, "XyoChainBlockNumberIterator");
|
|
1270
|
-
}
|
|
1271
|
-
_blocksByBlockNumber = new LRUCache2({
|
|
1272
|
-
max: 1e4
|
|
1273
|
-
});
|
|
1274
|
-
_chainArchivist;
|
|
1275
|
-
_chainInformation;
|
|
1276
|
-
_head;
|
|
1277
|
-
constructor(params) {
|
|
1278
|
-
super({});
|
|
1279
|
-
const { chainArchivist: archivist, head } = params;
|
|
1280
|
-
this._chainArchivist = archivist;
|
|
1281
|
-
this._head = head;
|
|
1282
|
-
this._chainInformation = {
|
|
1283
|
-
id: head.chain
|
|
1284
|
-
};
|
|
1285
|
-
}
|
|
1286
|
-
get archivist() {
|
|
1287
|
-
return this._chainArchivist;
|
|
1288
|
-
}
|
|
1289
|
-
get chainIdentification() {
|
|
1290
|
-
return this._chainInformation;
|
|
1291
|
-
}
|
|
1292
|
-
static async create(params) {
|
|
1293
|
-
await Promise.resolve();
|
|
1294
|
-
return new _XyoChainBlockNumberIterator(params);
|
|
1295
|
-
}
|
|
1296
|
-
async get(block) {
|
|
1297
|
-
assertEx10(this._head.block >= block, () => `Block requested is newer than the current head [${block}]`);
|
|
1298
|
-
const cached = this._blocksByBlockNumber.get(block);
|
|
1299
|
-
if (cached) return cached;
|
|
1300
|
-
const startingBlock = this._head;
|
|
1301
|
-
const currentBlockHash = await PayloadBuilder6.hash(startingBlock);
|
|
1302
|
-
let currentBlock = (await this._chainArchivist.get([
|
|
1303
|
-
currentBlockHash
|
|
1304
|
-
])).at(0);
|
|
1305
|
-
while (isDefined2(currentBlock)) {
|
|
1306
|
-
assertEx10(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${currentBlock?._hash}]`);
|
|
1307
|
-
if (isBlockBoundWitness(currentBlock)) {
|
|
1308
|
-
this._blocksByBlockNumber.set(currentBlock.block, currentBlock);
|
|
1309
|
-
if (currentBlock.block === block) {
|
|
1310
|
-
return currentBlock;
|
|
1311
|
-
}
|
|
1312
|
-
const { previous } = currentBlock;
|
|
1313
|
-
if (isNull(previous)) break;
|
|
1314
|
-
currentBlock = (await this._chainArchivist.get([
|
|
1315
|
-
previous
|
|
1316
|
-
])).at(0);
|
|
1317
|
-
}
|
|
1318
|
-
}
|
|
1319
|
-
throw new Error(`Block not found: ${block}`);
|
|
1320
|
-
}
|
|
1321
|
-
async head() {
|
|
1322
|
-
return await Promise.resolve(this._head);
|
|
1323
|
-
}
|
|
1324
|
-
async next(block) {
|
|
1325
|
-
const currentBlock = block;
|
|
1326
|
-
const nextBlockNumber = currentBlock + 1;
|
|
1327
|
-
return await this.get(nextBlockNumber);
|
|
1328
|
-
}
|
|
1329
|
-
// TODO: Decide on inclusive/exclusive (probably need inclusive to account for chain head)
|
|
1330
|
-
// and then communicate via method name and documentation
|
|
1331
|
-
async previous(block = void 0, count = 1) {
|
|
1332
|
-
const results = [];
|
|
1333
|
-
let currentBlock = isDefined2(block) ? await this.get(block) : this._head;
|
|
1334
|
-
while (currentBlock && results.length < count) {
|
|
1335
|
-
if (isBlockBoundWitness(currentBlock)) {
|
|
1336
|
-
results.push(currentBlock);
|
|
1337
|
-
const { previous } = currentBlock;
|
|
1338
|
-
if (isNull(previous)) break;
|
|
1339
|
-
const nextBlock = await this._chainArchivist.get([
|
|
1340
|
-
previous
|
|
1341
|
-
]);
|
|
1342
|
-
currentBlock = asOptionalBlockBoundWitness2(nextBlock[0]);
|
|
1343
|
-
} else {
|
|
1344
|
-
const hash = PayloadBuilder6.hash(currentBlock);
|
|
1345
|
-
assertEx10(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${hash}]`);
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
return results;
|
|
1349
|
-
}
|
|
1350
|
-
async updateHead(head) {
|
|
1351
|
-
await Promise.resolve();
|
|
1352
|
-
this._head = head;
|
|
1353
|
-
void this.emit("headUpdated", {
|
|
1354
|
-
blocks: [
|
|
1355
|
-
head
|
|
1356
|
-
]
|
|
1357
|
-
});
|
|
1219
|
+
return await this.contract.withdrawnByStaker(getAddress(staker));
|
|
1358
1220
|
}
|
|
1359
1221
|
};
|
|
1360
1222
|
export {
|
|
1361
1223
|
BaseAccountableService,
|
|
1362
|
-
BaseEthProvider,
|
|
1363
1224
|
BaseService,
|
|
1225
|
+
ChainBlockNumberIterationService,
|
|
1364
1226
|
DEFAULT_BLOCK_SIZE,
|
|
1365
1227
|
EvmBlockRewardService,
|
|
1366
1228
|
EvmChainService,
|
|
@@ -1369,7 +1231,6 @@ export {
|
|
|
1369
1231
|
XyoBlockProducer,
|
|
1370
1232
|
XyoBlockRewardService,
|
|
1371
1233
|
XyoChainAccountBalanceService,
|
|
1372
|
-
XyoChainBlockNumberIterator,
|
|
1373
1234
|
XyoElectionService,
|
|
1374
1235
|
XyoPendingTransactionsService,
|
|
1375
1236
|
XyoStakeIntentService,
|