@xyo-network/chain-services 1.12.0 → 1.12.1
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 +342 -224
- package/dist/neutral/index.mjs.map +1 -1
- package/package.json +36 -36
package/dist/neutral/index.mjs
CHANGED
|
@@ -1,39 +1,33 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
-
var
|
|
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);
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
13
3
|
|
|
14
4
|
// src/AccountBalance/accountBalanceServiceFromArchivist.ts
|
|
15
5
|
import { exists } from "@xylabs/exists";
|
|
16
|
-
import {
|
|
17
|
-
asHash,
|
|
18
|
-
isHash
|
|
19
|
-
} from "@xylabs/hex";
|
|
6
|
+
import { asHash, isHash } from "@xylabs/hex";
|
|
20
7
|
import { PayloadBuilder } from "@xyo-network/payload-builder";
|
|
21
8
|
import { LRUCache } from "lru-cache";
|
|
22
9
|
|
|
23
10
|
// src/AccountBalance/BaseAccountBalanceService.ts
|
|
24
11
|
import { creatable as creatable2 } from "@xylabs/creatable";
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
} from "@xyo-network/xl1-protocol";
|
|
28
|
-
import {
|
|
29
|
-
balanceSummary
|
|
30
|
-
} from "@xyo-network/xl1-protocol-sdk";
|
|
12
|
+
import { AttoXL1 } from "@xyo-network/xl1-protocol";
|
|
13
|
+
import { balanceSummary } from "@xyo-network/xl1-protocol-sdk";
|
|
31
14
|
|
|
32
15
|
// src/BaseService.ts
|
|
33
16
|
import { AbstractCreatable, creatable } from "@xylabs/creatable";
|
|
34
17
|
import { span, spanAsync } from "@xylabs/telemetry";
|
|
35
18
|
import { Mutex } from "async-mutex";
|
|
19
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
20
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
21
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
22
|
+
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;
|
|
23
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
24
|
+
}
|
|
25
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
36
26
|
var BaseService = class extends AbstractCreatable {
|
|
27
|
+
static {
|
|
28
|
+
__name(this, "BaseService");
|
|
29
|
+
}
|
|
30
|
+
static singletonInitMutex = new Mutex();
|
|
37
31
|
static get singletons() {
|
|
38
32
|
return globalThis["xyoServiceSingletons"] ?? (globalThis["xyoServiceSingletons"] = {});
|
|
39
33
|
}
|
|
@@ -53,21 +47,33 @@ var BaseService = class extends AbstractCreatable {
|
|
|
53
47
|
return await spanAsync(name, fn, this.tracer);
|
|
54
48
|
}
|
|
55
49
|
};
|
|
56
|
-
|
|
57
|
-
BaseService = __decorateClass([
|
|
50
|
+
BaseService = _ts_decorate([
|
|
58
51
|
creatable()
|
|
59
52
|
], BaseService);
|
|
60
53
|
var BaseAccountableService = class extends BaseService {
|
|
61
|
-
|
|
54
|
+
static {
|
|
55
|
+
__name(this, "BaseAccountableService");
|
|
56
|
+
}
|
|
62
57
|
};
|
|
63
58
|
function creatableService() {
|
|
64
59
|
return (constructor) => {
|
|
65
60
|
constructor;
|
|
66
61
|
};
|
|
67
62
|
}
|
|
63
|
+
__name(creatableService, "creatableService");
|
|
68
64
|
|
|
69
65
|
// src/AccountBalance/BaseAccountBalanceService.ts
|
|
66
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
67
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
68
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
69
|
+
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;
|
|
70
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
71
|
+
}
|
|
72
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
70
73
|
var BaseAccountBalanceService = class extends BaseService {
|
|
74
|
+
static {
|
|
75
|
+
__name(this, "BaseAccountBalanceService");
|
|
76
|
+
}
|
|
71
77
|
async balances(head, address) {
|
|
72
78
|
const summary = await balanceSummary({
|
|
73
79
|
chainArchivist: this.params.chainArchivist,
|
|
@@ -82,12 +88,12 @@ var BaseAccountBalanceService = class extends BaseService {
|
|
|
82
88
|
return result;
|
|
83
89
|
}
|
|
84
90
|
};
|
|
85
|
-
BaseAccountBalanceService =
|
|
91
|
+
BaseAccountBalanceService = _ts_decorate2([
|
|
86
92
|
creatable2()
|
|
87
93
|
], BaseAccountBalanceService);
|
|
88
94
|
|
|
89
95
|
// src/AccountBalance/accountBalanceServiceFromArchivist.ts
|
|
90
|
-
var accountBalanceServiceFromArchivist = async (archivist) => {
|
|
96
|
+
var accountBalanceServiceFromArchivist = /* @__PURE__ */ __name(async (archivist) => {
|
|
91
97
|
const summaryArchivistCache = new LRUCache({
|
|
92
98
|
max: 1e5,
|
|
93
99
|
allowStale: true,
|
|
@@ -95,13 +101,13 @@ var accountBalanceServiceFromArchivist = async (archivist) => {
|
|
|
95
101
|
updateAgeOnGet: true
|
|
96
102
|
});
|
|
97
103
|
const summaryRepository = {
|
|
98
|
-
get: (hashes) => {
|
|
104
|
+
get: /* @__PURE__ */ __name((hashes) => {
|
|
99
105
|
const results = hashes.map((hash) => {
|
|
100
106
|
return summaryArchivistCache.get(hash);
|
|
101
107
|
}).filter(exists);
|
|
102
108
|
return results;
|
|
103
|
-
},
|
|
104
|
-
insert: async (payloads) => {
|
|
109
|
+
}, "get"),
|
|
110
|
+
insert: /* @__PURE__ */ __name(async (payloads) => {
|
|
105
111
|
const results = (await PayloadBuilder.addStorageMeta(payloads)).map((payload) => {
|
|
106
112
|
const hash = asHash(payload.hash);
|
|
107
113
|
if (isHash(hash)) {
|
|
@@ -110,35 +116,28 @@ var accountBalanceServiceFromArchivist = async (archivist) => {
|
|
|
110
116
|
}
|
|
111
117
|
}).filter(exists);
|
|
112
118
|
return results;
|
|
113
|
-
},
|
|
114
|
-
next: () => {
|
|
119
|
+
}, "insert"),
|
|
120
|
+
next: /* @__PURE__ */ __name(() => {
|
|
115
121
|
throw new Error("Not implemented");
|
|
116
|
-
}
|
|
122
|
+
}, "next")
|
|
117
123
|
};
|
|
118
|
-
const service = await BaseAccountBalanceService.create({
|
|
124
|
+
const service = await BaseAccountBalanceService.create({
|
|
125
|
+
chainArchivist: archivist,
|
|
126
|
+
summaryRepository
|
|
127
|
+
});
|
|
119
128
|
return service;
|
|
120
|
-
};
|
|
129
|
+
}, "accountBalanceServiceFromArchivist");
|
|
121
130
|
var accountBalanceServiceFromArchivistV2 = accountBalanceServiceFromArchivist;
|
|
122
131
|
|
|
123
132
|
// src/BlockProducer/BaseBlockProducerService.ts
|
|
124
133
|
import { assertEx as assertEx2 } from "@xylabs/assert";
|
|
125
134
|
import { creatable as creatable3 } from "@xylabs/creatable";
|
|
126
135
|
import { exists as exists2 } from "@xylabs/exists";
|
|
127
|
-
import {
|
|
128
|
-
|
|
129
|
-
toHex
|
|
130
|
-
} from "@xylabs/hex";
|
|
131
|
-
import {
|
|
132
|
-
FixedPercentageBlockRewardDiviner,
|
|
133
|
-
FixedPercentageBlockRewardDivinerConfigSchema
|
|
134
|
-
} from "@xyo-network/chain-modules";
|
|
136
|
+
import { hexToBigInt, toHex } from "@xylabs/hex";
|
|
137
|
+
import { FixedPercentageBlockRewardDiviner, FixedPercentageBlockRewardDivinerConfigSchema } from "@xyo-network/chain-modules";
|
|
135
138
|
import { buildNextBlock, createDeclarationIntent } from "@xyo-network/chain-protocol";
|
|
136
139
|
import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/payload-builder";
|
|
137
|
-
import {
|
|
138
|
-
asBlockBoundWitness,
|
|
139
|
-
AttoXL1 as AttoXL12,
|
|
140
|
-
BlockNumberSchema
|
|
141
|
-
} from "@xyo-network/xl1-protocol";
|
|
140
|
+
import { asBlockBoundWitness, AttoXL1 as AttoXL12, BlockNumberSchema } from "@xyo-network/xl1-protocol";
|
|
142
141
|
|
|
143
142
|
// src/BlockProducer/generateTransactionFeeTransfers.ts
|
|
144
143
|
import { assertEx } from "@xylabs/assert";
|
|
@@ -149,7 +148,10 @@ import { transactionRequiredGas } from "@xyo-network/xl1-protocol-sdk";
|
|
|
149
148
|
import { HydratedTransactionWrapper } from "@xyo-network/xl1-wrappers";
|
|
150
149
|
async function generateTransactionFeeTransfers(address, transactions) {
|
|
151
150
|
const txs = await Promise.all(transactions.map(async (tx) => {
|
|
152
|
-
return HydratedTransactionWrapper.parse([
|
|
151
|
+
return HydratedTransactionWrapper.parse([
|
|
152
|
+
await PayloadBuilder2.addStorageMeta(tx[0]),
|
|
153
|
+
await PayloadBuilder2.addStorageMeta(tx[1])
|
|
154
|
+
]);
|
|
153
155
|
}));
|
|
154
156
|
const txBaseFeeCosts = {};
|
|
155
157
|
for (const tx of txs) {
|
|
@@ -179,30 +181,41 @@ async function generateTransactionFeeTransfers(address, transactions) {
|
|
|
179
181
|
}
|
|
180
182
|
return payloads;
|
|
181
183
|
}
|
|
184
|
+
__name(generateTransactionFeeTransfers, "generateTransactionFeeTransfers");
|
|
182
185
|
|
|
183
186
|
// src/BlockProducer/BaseBlockProducerService.ts
|
|
187
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
188
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
189
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
190
|
+
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;
|
|
191
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
192
|
+
}
|
|
193
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
184
194
|
var DEFAULT_BLOCK_SIZE = 10;
|
|
185
195
|
var XYO_PRODUCER_REDECLARATION_DURATION = 1e4;
|
|
186
196
|
var XYO_PRODUCER_REDECLARATION_WINDOW = 500;
|
|
187
|
-
var BaseBlockProducerService = class extends BaseService {
|
|
197
|
+
var BaseBlockProducerService = class _BaseBlockProducerService extends BaseService {
|
|
198
|
+
static {
|
|
199
|
+
__name(this, "BaseBlockProducerService");
|
|
200
|
+
}
|
|
188
201
|
_blockRewardDiviner;
|
|
189
202
|
/**
|
|
190
|
-
|
|
191
|
-
|
|
203
|
+
* The default block size for a block
|
|
204
|
+
*/
|
|
192
205
|
static get DefaultBlockSize() {
|
|
193
206
|
return DEFAULT_BLOCK_SIZE;
|
|
194
207
|
}
|
|
195
208
|
/**
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
209
|
+
* The amount of time for which the producer will redeclare
|
|
210
|
+
* their intent to continue producing blocks
|
|
211
|
+
*/
|
|
199
212
|
static get RedeclarationDuration() {
|
|
200
213
|
return XYO_PRODUCER_REDECLARATION_DURATION;
|
|
201
214
|
}
|
|
202
215
|
/**
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
216
|
+
* The number of blocks within which the producer will redeclare
|
|
217
|
+
* their intent to continue producing blocks
|
|
218
|
+
*/
|
|
206
219
|
static get RedeclarationWindow() {
|
|
207
220
|
return XYO_PRODUCER_REDECLARATION_WINDOW;
|
|
208
221
|
}
|
|
@@ -261,16 +274,22 @@ var BaseBlockProducerService = class extends BaseService {
|
|
|
261
274
|
});
|
|
262
275
|
}
|
|
263
276
|
const blockHex = assertEx2(toHex(block), () => "Failed to convert block to hex");
|
|
264
|
-
const blockId = new PayloadBuilder3({
|
|
265
|
-
|
|
277
|
+
const blockId = new PayloadBuilder3({
|
|
278
|
+
schema: BlockNumberSchema
|
|
279
|
+
}).fields({
|
|
280
|
+
block: blockHex
|
|
281
|
+
}).build();
|
|
282
|
+
const rewards = await this._blockRewardDiviner.divine([
|
|
283
|
+
blockId
|
|
284
|
+
]);
|
|
266
285
|
const [reward] = rewards;
|
|
267
286
|
return reward;
|
|
268
287
|
}
|
|
269
288
|
/**
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
289
|
+
* Handles the producer redeclaration logic
|
|
290
|
+
* @param head The current head block
|
|
291
|
+
* @returns chain stake intent for the producer redeclaration, or undefined if no redeclaration is needed
|
|
292
|
+
*/
|
|
274
293
|
async getProducerRedeclaration(head) {
|
|
275
294
|
if (this.params.config.producer.disableIntentRedeclaration) return;
|
|
276
295
|
const ranges = await this.stakeIntentService.getDeclaredCandidateRanges(this.address, "producer");
|
|
@@ -279,14 +298,14 @@ var BaseBlockProducerService = class extends BaseService {
|
|
|
279
298
|
const [, currentDeclarationEnd] = lastRange;
|
|
280
299
|
const currentBlock = head.block;
|
|
281
300
|
const timeToProducerExpiration = currentDeclarationEnd - currentBlock;
|
|
282
|
-
if (timeToProducerExpiration >
|
|
283
|
-
return createDeclarationIntent(this.address, "producer", currentBlock, currentBlock +
|
|
301
|
+
if (timeToProducerExpiration > _BaseBlockProducerService.RedeclarationWindow) return;
|
|
302
|
+
return createDeclarationIntent(this.address, "producer", currentBlock, currentBlock + _BaseBlockProducerService.RedeclarationDuration);
|
|
284
303
|
}
|
|
285
304
|
async proposeNextValidBlock(head, validateBalances = false) {
|
|
286
305
|
return await this.spanAsync("proposeNextValidBlock", async () => {
|
|
287
306
|
const { block: previousBlock } = assertEx2(asBlockBoundWitness(head), () => "Invalid head block");
|
|
288
307
|
const nextBlock = previousBlock + 1;
|
|
289
|
-
const nextBlockTransactions = await this.pendingTransactionsService.getPendingTransactions(head._hash,
|
|
308
|
+
const nextBlockTransactions = await this.pendingTransactionsService.getPendingTransactions(head._hash, _BaseBlockProducerService.DefaultBlockSize);
|
|
290
309
|
const blockPayloads = [];
|
|
291
310
|
const producerRedeclarationPayload = await this.getProducerRedeclaration(head);
|
|
292
311
|
if (producerRedeclarationPayload) blockPayloads.push(producerRedeclarationPayload);
|
|
@@ -300,7 +319,9 @@ var BaseBlockProducerService = class extends BaseService {
|
|
|
300
319
|
if (!transfer) return;
|
|
301
320
|
const totalTransferCost = Object.values(transfer?.transfers).reduce((acc, t) => acc + hexToBigInt(t ?? "00"), 0n);
|
|
302
321
|
if (validateBalances) {
|
|
303
|
-
const balance = (await this.balanceService.balances(head._hash, [
|
|
322
|
+
const balance = (await this.balanceService.balances(head._hash, [
|
|
323
|
+
transfer.from
|
|
324
|
+
]))[transfer.from] ?? AttoXL12(0n);
|
|
304
325
|
if (balance >= totalTransferCost) {
|
|
305
326
|
fundedTransfers.push(transfer);
|
|
306
327
|
return tx;
|
|
@@ -311,9 +332,13 @@ var BaseBlockProducerService = class extends BaseService {
|
|
|
311
332
|
}
|
|
312
333
|
}))).filter(exists2);
|
|
313
334
|
blockPayloads.push(...fundedTransfers);
|
|
314
|
-
const block = await buildNextBlock(head, fundedNextBlockTransactions, blockPayloads, [
|
|
335
|
+
const block = await buildNextBlock(head, fundedNextBlockTransactions, blockPayloads, [
|
|
336
|
+
this.account
|
|
337
|
+
]);
|
|
315
338
|
this.logger?.info(`buildBlock: ${block[0].block} with ${block[1].length} payloads`);
|
|
316
|
-
const errors = await this.validateHydratedBlockState(block, this.chainId, {
|
|
339
|
+
const errors = await this.validateHydratedBlockState(block, this.chainId, {
|
|
340
|
+
accountBalance: this.balanceService
|
|
341
|
+
});
|
|
317
342
|
if (errors.length > 0) {
|
|
318
343
|
this.logger?.warn(`Validation of produced block failed: ${errors.at(0)?.message}`);
|
|
319
344
|
const rejectedTransactions = block[1];
|
|
@@ -324,18 +349,28 @@ var BaseBlockProducerService = class extends BaseService {
|
|
|
324
349
|
});
|
|
325
350
|
}
|
|
326
351
|
};
|
|
327
|
-
BaseBlockProducerService =
|
|
352
|
+
BaseBlockProducerService = _ts_decorate3([
|
|
328
353
|
creatable3()
|
|
329
354
|
], BaseBlockProducerService);
|
|
330
355
|
|
|
331
356
|
// src/BlockReward/BaseBlockRewardService.ts
|
|
332
357
|
import { creatable as creatable4 } from "@xylabs/creatable";
|
|
358
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
359
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
360
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
361
|
+
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;
|
|
362
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
363
|
+
}
|
|
364
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
333
365
|
var BaseBlockRewardService = class extends BaseService {
|
|
366
|
+
static {
|
|
367
|
+
__name(this, "BaseBlockRewardService");
|
|
368
|
+
}
|
|
334
369
|
getRewardForBlock(_blockNumber) {
|
|
335
370
|
throw new Error("getRewardForBlock method must be implemented in derived classes");
|
|
336
371
|
}
|
|
337
372
|
};
|
|
338
|
-
BaseBlockRewardService =
|
|
373
|
+
BaseBlockRewardService = _ts_decorate4([
|
|
339
374
|
creatable4()
|
|
340
375
|
], BaseBlockRewardService);
|
|
341
376
|
|
|
@@ -344,7 +379,17 @@ import { assertEx as assertEx3 } from "@xylabs/assert";
|
|
|
344
379
|
import { creatable as creatable5 } from "@xylabs/creatable";
|
|
345
380
|
import { toEthAddress } from "@xylabs/hex";
|
|
346
381
|
import { XyoChainRewards__factory as XyoChainRewardsFactory } from "@xyo-network/typechain";
|
|
382
|
+
function _ts_decorate5(decorators, target, key, desc) {
|
|
383
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
384
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
385
|
+
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;
|
|
386
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
387
|
+
}
|
|
388
|
+
__name(_ts_decorate5, "_ts_decorate");
|
|
347
389
|
var EvmBlockRewardService = class extends BaseBlockRewardService {
|
|
390
|
+
static {
|
|
391
|
+
__name(this, "EvmBlockRewardService");
|
|
392
|
+
}
|
|
348
393
|
_contractAddress;
|
|
349
394
|
get chainService() {
|
|
350
395
|
return assertEx3(this.params.chainService, () => "chainService is required");
|
|
@@ -369,7 +414,7 @@ var EvmBlockRewardService = class extends BaseBlockRewardService {
|
|
|
369
414
|
return await contract.calcBlockReward(blockNumber);
|
|
370
415
|
}
|
|
371
416
|
};
|
|
372
|
-
EvmBlockRewardService =
|
|
417
|
+
EvmBlockRewardService = _ts_decorate5([
|
|
373
418
|
creatable5()
|
|
374
419
|
], EvmBlockRewardService);
|
|
375
420
|
|
|
@@ -378,7 +423,17 @@ import { assertEx as assertEx4 } from "@xylabs/assert";
|
|
|
378
423
|
import { creatable as creatable6 } from "@xylabs/creatable";
|
|
379
424
|
import { toFixedPoint } from "@xylabs/decimal-precision";
|
|
380
425
|
import { rewardFromBlockNumber } from "@xyo-network/chain-protocol";
|
|
426
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
427
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
428
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
429
|
+
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;
|
|
430
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
431
|
+
}
|
|
432
|
+
__name(_ts_decorate6, "_ts_decorate");
|
|
381
433
|
var MemoryBlockRewardService = class extends BaseBlockRewardService {
|
|
434
|
+
static {
|
|
435
|
+
__name(this, "MemoryBlockRewardService");
|
|
436
|
+
}
|
|
382
437
|
rewardFromBlockNumber = rewardFromBlockNumber(18);
|
|
383
438
|
get creatorReward() {
|
|
384
439
|
return assertEx4(this.params.creatorReward, () => "creatorReward is required");
|
|
@@ -410,18 +465,10 @@ var MemoryBlockRewardService = class extends BaseBlockRewardService {
|
|
|
410
465
|
};
|
|
411
466
|
}
|
|
412
467
|
getRewardForBlock(blockNumber) {
|
|
413
|
-
return this.rewardFromBlockNumber(
|
|
414
|
-
blockNumber,
|
|
415
|
-
this.initialReward,
|
|
416
|
-
this.stepSize,
|
|
417
|
-
this.stepFactorNumerator,
|
|
418
|
-
this.stepFactorDenominator,
|
|
419
|
-
this.minRewardPerBlock,
|
|
420
|
-
this.creatorReward
|
|
421
|
-
);
|
|
468
|
+
return this.rewardFromBlockNumber(blockNumber, this.initialReward, this.stepSize, this.stepFactorNumerator, this.stepFactorDenominator, this.minRewardPerBlock, this.creatorReward);
|
|
422
469
|
}
|
|
423
470
|
};
|
|
424
|
-
MemoryBlockRewardService =
|
|
471
|
+
MemoryBlockRewardService = _ts_decorate6([
|
|
425
472
|
creatable6()
|
|
426
473
|
], MemoryBlockRewardService);
|
|
427
474
|
|
|
@@ -429,13 +476,15 @@ MemoryBlockRewardService = __decorateClass([
|
|
|
429
476
|
import { assertEx as assertEx5 } from "@xylabs/assert";
|
|
430
477
|
import { isDefined, isNull } from "@xylabs/typeof";
|
|
431
478
|
import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/payload-builder";
|
|
432
|
-
import {
|
|
433
|
-
asBlockBoundWitness as asBlockBoundWitness2,
|
|
434
|
-
isBlockBoundWitness
|
|
435
|
-
} from "@xyo-network/xl1-protocol";
|
|
479
|
+
import { asBlockBoundWitness as asBlockBoundWitness2, isBlockBoundWitness } from "@xyo-network/xl1-protocol";
|
|
436
480
|
import { LRUCache as LRUCache2 } from "lru-cache";
|
|
437
481
|
var ChainBlockNumberIterationService = class extends BaseService {
|
|
438
|
-
|
|
482
|
+
static {
|
|
483
|
+
__name(this, "ChainBlockNumberIterationService");
|
|
484
|
+
}
|
|
485
|
+
_blocksByBlockNumber = new LRUCache2({
|
|
486
|
+
max: 1e4
|
|
487
|
+
});
|
|
439
488
|
get chainArchivist() {
|
|
440
489
|
return assertEx5(this.params.chainArchivist);
|
|
441
490
|
}
|
|
@@ -449,7 +498,9 @@ var ChainBlockNumberIterationService = class extends BaseService {
|
|
|
449
498
|
if (cached) return cached;
|
|
450
499
|
const startingBlock = head;
|
|
451
500
|
const currentBlockHash = await PayloadBuilder4.hash(startingBlock);
|
|
452
|
-
let currentBlock = (await this.chainArchivist.get([
|
|
501
|
+
let currentBlock = (await this.chainArchivist.get([
|
|
502
|
+
currentBlockHash
|
|
503
|
+
])).at(0);
|
|
453
504
|
while (isDefined(currentBlock)) {
|
|
454
505
|
assertEx5(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${currentBlock?._hash}]`);
|
|
455
506
|
if (isBlockBoundWitness(currentBlock)) {
|
|
@@ -459,7 +510,9 @@ var ChainBlockNumberIterationService = class extends BaseService {
|
|
|
459
510
|
}
|
|
460
511
|
const { previous } = currentBlock;
|
|
461
512
|
if (isNull(previous)) break;
|
|
462
|
-
currentBlock = (await this.chainArchivist.get([
|
|
513
|
+
currentBlock = (await this.chainArchivist.get([
|
|
514
|
+
previous
|
|
515
|
+
])).at(0);
|
|
463
516
|
}
|
|
464
517
|
}
|
|
465
518
|
throw new Error(`Block not found: ${block}`);
|
|
@@ -482,7 +535,9 @@ var ChainBlockNumberIterationService = class extends BaseService {
|
|
|
482
535
|
results.push(currentBlock);
|
|
483
536
|
const { previous } = currentBlock;
|
|
484
537
|
if (isNull(previous)) break;
|
|
485
|
-
const nextBlock = await this.chainArchivist.get([
|
|
538
|
+
const nextBlock = await this.chainArchivist.get([
|
|
539
|
+
previous
|
|
540
|
+
]);
|
|
486
541
|
currentBlock = asBlockBoundWitness2(nextBlock[0]);
|
|
487
542
|
} else {
|
|
488
543
|
const hash = PayloadBuilder4.hash(currentBlock);
|
|
@@ -494,7 +549,11 @@ var ChainBlockNumberIterationService = class extends BaseService {
|
|
|
494
549
|
async updateHead(head) {
|
|
495
550
|
await Promise.resolve();
|
|
496
551
|
this.params.head = head;
|
|
497
|
-
void this.emit("headUpdated", {
|
|
552
|
+
void this.emit("headUpdated", {
|
|
553
|
+
blocks: [
|
|
554
|
+
head
|
|
555
|
+
]
|
|
556
|
+
});
|
|
498
557
|
}
|
|
499
558
|
};
|
|
500
559
|
|
|
@@ -504,15 +563,15 @@ import { toAddress, toEthAddress as toEthAddress2 } from "@xylabs/hex";
|
|
|
504
563
|
import { StakedXyoChain__factory as StakedXyoChainFactory } from "@xyo-network/typechain";
|
|
505
564
|
import { getAddress } from "ethers/address";
|
|
506
565
|
var EvmChainService = class extends BaseService {
|
|
566
|
+
static {
|
|
567
|
+
__name(this, "EvmChainService");
|
|
568
|
+
}
|
|
507
569
|
get chainId() {
|
|
508
570
|
return assertEx6(this.params.id);
|
|
509
571
|
}
|
|
510
572
|
get contract() {
|
|
511
573
|
if (this.params.contract === void 0) {
|
|
512
|
-
this.params.contract = StakedXyoChainFactory.connect(
|
|
513
|
-
toEthAddress2(this.chainId),
|
|
514
|
-
this.params.runner
|
|
515
|
-
);
|
|
574
|
+
this.params.contract = StakedXyoChainFactory.connect(toEthAddress2(this.chainId), this.params.runner);
|
|
516
575
|
}
|
|
517
576
|
return assertEx6(this.params.contract);
|
|
518
577
|
}
|
|
@@ -578,6 +637,9 @@ var EvmChainService = class extends BaseService {
|
|
|
578
637
|
// src/ChainService/Memory/Memory.ts
|
|
579
638
|
import { ZERO_ADDRESS } from "@xylabs/hex";
|
|
580
639
|
var MemoryChainService = class extends BaseService {
|
|
640
|
+
static {
|
|
641
|
+
__name(this, "MemoryChainService");
|
|
642
|
+
}
|
|
581
643
|
_simulatedStake = 1n;
|
|
582
644
|
get chainId() {
|
|
583
645
|
return ZERO_ADDRESS;
|
|
@@ -639,7 +701,17 @@ var MemoryChainService = class extends BaseService {
|
|
|
639
701
|
// src/ChainValidator/XyoValidator.ts
|
|
640
702
|
import { assertEx as assertEx7 } from "@xylabs/assert";
|
|
641
703
|
import { creatable as creatable7 } from "@xylabs/creatable";
|
|
704
|
+
function _ts_decorate7(decorators, target, key, desc) {
|
|
705
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
706
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
707
|
+
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;
|
|
708
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
709
|
+
}
|
|
710
|
+
__name(_ts_decorate7, "_ts_decorate");
|
|
642
711
|
var XyoValidator = class extends BaseService {
|
|
712
|
+
static {
|
|
713
|
+
__name(this, "XyoValidator");
|
|
714
|
+
}
|
|
643
715
|
get address() {
|
|
644
716
|
return this.account.address;
|
|
645
717
|
}
|
|
@@ -667,11 +739,13 @@ var XyoValidator = class extends BaseService {
|
|
|
667
739
|
// TODO: Move to validator and inherit this class from validator
|
|
668
740
|
async validatePendingTransaction(hydratedTransaction) {
|
|
669
741
|
const [tx] = hydratedTransaction;
|
|
670
|
-
if ((await this.chainArchivist.get([
|
|
742
|
+
if ((await this.chainArchivist.get([
|
|
743
|
+
tx._hash
|
|
744
|
+
])).length > 0) return false;
|
|
671
745
|
return await Promise.resolve(true);
|
|
672
746
|
}
|
|
673
747
|
};
|
|
674
|
-
XyoValidator =
|
|
748
|
+
XyoValidator = _ts_decorate7([
|
|
675
749
|
creatable7()
|
|
676
750
|
], XyoValidator);
|
|
677
751
|
|
|
@@ -680,7 +754,17 @@ import { assertEx as assertEx8 } from "@xylabs/assert";
|
|
|
680
754
|
import { creatable as creatable8 } from "@xylabs/creatable";
|
|
681
755
|
import { hexToLast4BytesInt, shuffleWithSeed } from "@xyo-network/chain-utils";
|
|
682
756
|
import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/payload-builder";
|
|
757
|
+
function _ts_decorate8(decorators, target, key, desc) {
|
|
758
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
759
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
760
|
+
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;
|
|
761
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
762
|
+
}
|
|
763
|
+
__name(_ts_decorate8, "_ts_decorate");
|
|
683
764
|
var BaseElectionService = class extends BaseService {
|
|
765
|
+
static {
|
|
766
|
+
__name(this, "BaseElectionService");
|
|
767
|
+
}
|
|
684
768
|
get chainIterator() {
|
|
685
769
|
return assertEx8(this.params.chainIterator, () => "No chain iterator");
|
|
686
770
|
}
|
|
@@ -705,7 +789,7 @@ var BaseElectionService = class extends BaseService {
|
|
|
705
789
|
return creatorArray.slice(0, maxSize);
|
|
706
790
|
}
|
|
707
791
|
};
|
|
708
|
-
BaseElectionService =
|
|
792
|
+
BaseElectionService = _ts_decorate8([
|
|
709
793
|
creatable8()
|
|
710
794
|
], BaseElectionService);
|
|
711
795
|
|
|
@@ -719,63 +803,92 @@ import { forget } from "@xylabs/forget";
|
|
|
719
803
|
import { isDefined as isDefined2, isUndefined } from "@xylabs/typeof";
|
|
720
804
|
import { MemoryArchivist } from "@xyo-network/archivist-memory";
|
|
721
805
|
import { findMostRecentBlock } from "@xyo-network/chain-protocol";
|
|
722
|
-
import {
|
|
723
|
-
asBlockBoundWitnessWithHashStorageMeta,
|
|
724
|
-
isTransactionBoundWitnessWithStorageMeta
|
|
725
|
-
} from "@xyo-network/xl1-protocol";
|
|
806
|
+
import { asBlockBoundWitnessWithHashStorageMeta, isTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol";
|
|
726
807
|
import { TransactionJsonSchemaValidator, validateTransaction } from "@xyo-network/xl1-validation";
|
|
727
808
|
import { Mutex as Mutex2 } from "async-mutex";
|
|
728
809
|
|
|
729
810
|
// src/PendingTransactions/bundledPayloadToHydratedTransaction.ts
|
|
730
811
|
import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/payload-builder";
|
|
731
812
|
import { asTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol";
|
|
732
|
-
var bundledPayloadToHydratedTransaction = async (payload) => {
|
|
813
|
+
var bundledPayloadToHydratedTransaction = /* @__PURE__ */ __name(async (payload) => {
|
|
733
814
|
const withStorageMeta = await PayloadBuilder6.addStorageMeta(payload.payloads);
|
|
734
815
|
const tx = asTransactionBoundWitnessWithStorageMeta(withStorageMeta.find((p) => p._hash === payload.root));
|
|
735
816
|
if (tx) {
|
|
736
|
-
return [
|
|
817
|
+
return [
|
|
818
|
+
tx,
|
|
819
|
+
withStorageMeta.filter((p) => p._hash !== payload.root)
|
|
820
|
+
];
|
|
737
821
|
}
|
|
738
|
-
};
|
|
822
|
+
}, "bundledPayloadToHydratedTransaction");
|
|
739
823
|
|
|
740
824
|
// src/PendingTransactions/hydratedTransactionToPayloadBundle.ts
|
|
741
825
|
import { PayloadBuilder as PayloadBuilder7 } from "@xyo-network/payload-builder";
|
|
742
826
|
import { PayloadBundleSchema } from "@xyo-network/payload-model";
|
|
743
827
|
import { flattenHydratedTransaction } from "@xyo-network/xl1-protocol-sdk";
|
|
744
|
-
var hydratedTransactionToPayloadBundle = (transaction) => {
|
|
828
|
+
var hydratedTransactionToPayloadBundle = /* @__PURE__ */ __name((transaction) => {
|
|
745
829
|
const root = transaction[0]._hash;
|
|
746
830
|
return bundle(root, transaction);
|
|
747
|
-
};
|
|
748
|
-
var bundle = (root, transaction) => {
|
|
831
|
+
}, "hydratedTransactionToPayloadBundle");
|
|
832
|
+
var bundle = /* @__PURE__ */ __name((root, transaction) => {
|
|
749
833
|
const payloads = flattenHydratedTransaction(transaction).flatMap((p) => PayloadBuilder7.omitStorageMeta(p));
|
|
750
|
-
return new PayloadBuilder7({
|
|
751
|
-
|
|
834
|
+
return new PayloadBuilder7({
|
|
835
|
+
schema: PayloadBundleSchema
|
|
836
|
+
}).fields({
|
|
837
|
+
payloads,
|
|
838
|
+
root
|
|
839
|
+
}).build();
|
|
840
|
+
}, "bundle");
|
|
752
841
|
|
|
753
842
|
// src/PendingTransactions/BasePendingTransactions.ts
|
|
754
|
-
|
|
843
|
+
function _ts_decorate9(decorators, target, key, desc) {
|
|
844
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
845
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
846
|
+
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;
|
|
847
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
848
|
+
}
|
|
849
|
+
__name(_ts_decorate9, "_ts_decorate");
|
|
850
|
+
var BasePendingTransactionsService = class _BasePendingTransactionsService extends BaseService {
|
|
851
|
+
static {
|
|
852
|
+
__name(this, "BasePendingTransactionsService");
|
|
853
|
+
}
|
|
854
|
+
static MutexPriority = {
|
|
855
|
+
/**
|
|
856
|
+
* Priority for inserting new transactions
|
|
857
|
+
*/
|
|
858
|
+
InsertNewTransactions: 5,
|
|
859
|
+
/**
|
|
860
|
+
* Priority for reading pending transactions
|
|
861
|
+
*/
|
|
862
|
+
ReadTransactions: 3,
|
|
863
|
+
/**
|
|
864
|
+
* Priority for removing finalized/expired/rejected transactions
|
|
865
|
+
*/
|
|
866
|
+
PurgeTransactions: 1
|
|
867
|
+
};
|
|
755
868
|
/**
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
869
|
+
* A mutex to ensure that the counting the number of pending transactions is
|
|
870
|
+
* not called concurrently
|
|
871
|
+
*/
|
|
759
872
|
_countPendingTransactionsMutex = new Mutex2();
|
|
760
873
|
/**
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
874
|
+
* A local Archivist optimized for fast retrieval that stores only validated
|
|
875
|
+
* pending transactions
|
|
876
|
+
*/
|
|
764
877
|
_curatedPendingBundledTransactionsArchivist;
|
|
765
878
|
/**
|
|
766
|
-
|
|
767
|
-
|
|
879
|
+
* The last count of total pending transactions
|
|
880
|
+
*/
|
|
768
881
|
_pendingTransactionsCount = 0;
|
|
769
882
|
/**
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
883
|
+
* A set of transaction hashes that are pending removal from the
|
|
884
|
+
* curated pending transactions archivist. This is used to track
|
|
885
|
+
* which transactions need to be removed from the archivist.
|
|
886
|
+
*/
|
|
774
887
|
_removablePendingTransactionHashes = /* @__PURE__ */ new Set();
|
|
775
888
|
/**
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
889
|
+
* A mutex to ensure that the curated pending transactions archivist is
|
|
890
|
+
* updated in a thread-safe manner
|
|
891
|
+
*/
|
|
779
892
|
_updateCuratedPendingTransactionsArchivistMutex = new Mutex2();
|
|
780
893
|
get chainArchivist() {
|
|
781
894
|
return assertEx9(this.params.chainArchivist, () => "No completed blocks with data archivist");
|
|
@@ -798,7 +911,9 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
798
911
|
}
|
|
799
912
|
async createHandler() {
|
|
800
913
|
await super.createHandler();
|
|
801
|
-
this._curatedPendingBundledTransactionsArchivist = await MemoryArchivist.create({
|
|
914
|
+
this._curatedPendingBundledTransactionsArchivist = await MemoryArchivist.create({
|
|
915
|
+
account: "random"
|
|
916
|
+
});
|
|
802
917
|
this.pendingBundledTransactionsArchivist.on("inserted", ({ payloads }) => {
|
|
803
918
|
forget(this.insertNewTransactions(payloads));
|
|
804
919
|
});
|
|
@@ -810,14 +925,11 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
810
925
|
this.markAnyIncludedTransactionsForRemoval(payloads);
|
|
811
926
|
forget(this.cleanupWorker());
|
|
812
927
|
});
|
|
813
|
-
const pendingTransactionsCounter = this.meter?.createObservableUpDownCounter(
|
|
814
|
-
"
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
unit: "1"
|
|
819
|
-
}
|
|
820
|
-
);
|
|
928
|
+
const pendingTransactionsCounter = this.meter?.createObservableUpDownCounter("xyo_pending_transactions_counter", {
|
|
929
|
+
description: "The current number of pending transactions",
|
|
930
|
+
valueType: ValueType.INT,
|
|
931
|
+
unit: "1"
|
|
932
|
+
});
|
|
821
933
|
pendingTransactionsCounter?.addCallback((observer) => {
|
|
822
934
|
observer.observe(this.pendingTransactionsCount);
|
|
823
935
|
});
|
|
@@ -825,7 +937,9 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
825
937
|
async getPendingTransactions(head, limit) {
|
|
826
938
|
return await this.spanAsync("getPendingTransactions", async () => {
|
|
827
939
|
return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
|
|
828
|
-
let [lastHead] = filterAs(await this.chainArchivist.get([
|
|
940
|
+
let [lastHead] = filterAs(await this.chainArchivist.get([
|
|
941
|
+
head
|
|
942
|
+
]), asBlockBoundWitnessWithHashStorageMeta);
|
|
829
943
|
if (isUndefined(lastHead)) return [];
|
|
830
944
|
await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash);
|
|
831
945
|
const foundPendingTransactions = [];
|
|
@@ -839,9 +953,7 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
839
953
|
if (pendingBundledTransactions.length === 0) break;
|
|
840
954
|
cursor = pendingBundledTransactions.at(-1)?._sequence;
|
|
841
955
|
const undeletedTransactionBundles = pendingBundledTransactions.filter((tx) => !this._removablePendingTransactionHashes.has(tx.root));
|
|
842
|
-
const transactions = (await Promise.all(
|
|
843
|
-
undeletedTransactionBundles.map((p) => bundledPayloadToHydratedTransaction(p))
|
|
844
|
-
)).filter(exists3);
|
|
956
|
+
const transactions = (await Promise.all(undeletedTransactionBundles.map((p) => bundledPayloadToHydratedTransaction(p)))).filter(exists3);
|
|
845
957
|
const activeTransactions = transactions.filter(isTransactionActive(lastHead.block + 1));
|
|
846
958
|
foundPendingTransactions.push(...activeTransactions);
|
|
847
959
|
}
|
|
@@ -852,14 +964,14 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
852
964
|
}
|
|
853
965
|
}
|
|
854
966
|
return foundPendingTransactions;
|
|
855
|
-
},
|
|
967
|
+
}, _BasePendingTransactionsService.MutexPriority.ReadTransactions);
|
|
856
968
|
});
|
|
857
969
|
}
|
|
858
970
|
async cleanupWorker() {
|
|
859
971
|
return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
|
|
860
972
|
const lastHead = await findMostRecentBlock(this.chainArchivist);
|
|
861
973
|
if (isDefined2(lastHead)) await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash);
|
|
862
|
-
},
|
|
974
|
+
}, _BasePendingTransactionsService.MutexPriority.PurgeTransactions);
|
|
863
975
|
}
|
|
864
976
|
async countPendingTransactions() {
|
|
865
977
|
if (this._countPendingTransactionsMutex.isLocked()) return;
|
|
@@ -884,7 +996,9 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
884
996
|
return await bundledPayloadToHydratedTransaction(tx);
|
|
885
997
|
}))).filter(exists3);
|
|
886
998
|
const validTransactions = await filterAsync(hydratedUnprocessedTransactions, async (tx) => {
|
|
887
|
-
const errors = await validateTransaction(tx, this.chainId, [
|
|
999
|
+
const errors = await validateTransaction(tx, this.chainId, [
|
|
1000
|
+
TransactionJsonSchemaValidator
|
|
1001
|
+
]);
|
|
888
1002
|
if (errors.length > 0) {
|
|
889
1003
|
this.logger?.warn("validateTransaction", errors);
|
|
890
1004
|
}
|
|
@@ -894,15 +1008,15 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
894
1008
|
const bundledTransactions = validTransactions.map((tx) => hydratedTransactionToPayloadBundle(tx));
|
|
895
1009
|
await this.pendingBundledTransactionsLocalArchivist.insert(bundledTransactions);
|
|
896
1010
|
}
|
|
897
|
-
},
|
|
1011
|
+
}, _BasePendingTransactionsService.MutexPriority.InsertNewTransactions);
|
|
898
1012
|
});
|
|
899
1013
|
}
|
|
900
1014
|
/**
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1015
|
+
* Marks any included transactions in the provided payloads for removal preventing them
|
|
1016
|
+
* from being included in the curated pending transactions archivist and from being offered
|
|
1017
|
+
* during the next retrieval of pending transactions.
|
|
1018
|
+
* @param payloads An array of payloads that may contain transactions.
|
|
1019
|
+
*/
|
|
906
1020
|
markAnyIncludedTransactionsForRemoval(payloads) {
|
|
907
1021
|
const hashes = payloads.filter(isTransactionBoundWitnessWithStorageMeta).map((p) => p._hash);
|
|
908
1022
|
for (const hash of hashes) {
|
|
@@ -913,7 +1027,9 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
913
1027
|
return await this.spanAsync("pruneCuratedPendingTransactionsArchivist", async () => {
|
|
914
1028
|
const foundPendingTransactionsToDeleteHashes = [];
|
|
915
1029
|
let cursor;
|
|
916
|
-
let [lastHead] = filterAs(await this.chainArchivist.get([
|
|
1030
|
+
let [lastHead] = filterAs(await this.chainArchivist.get([
|
|
1031
|
+
head
|
|
1032
|
+
]), asBlockBoundWitnessWithHashStorageMeta);
|
|
917
1033
|
while (isDefined2(lastHead)) {
|
|
918
1034
|
const pendingBundledTransactions = await this.pendingBundledTransactionsLocalArchivist.next({
|
|
919
1035
|
limit: 100,
|
|
@@ -925,13 +1041,9 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
925
1041
|
}
|
|
926
1042
|
cursor = pendingBundledTransactions.at(-1)?._sequence;
|
|
927
1043
|
const deletedTransactionBundles = pendingBundledTransactions.filter((tx) => this._removablePendingTransactionHashes.has(tx.root));
|
|
928
|
-
foundPendingTransactionsToDeleteHashes.push(
|
|
929
|
-
...deletedTransactionBundles.map((tx) => tx._hash).filter(exists3)
|
|
930
|
-
);
|
|
1044
|
+
foundPendingTransactionsToDeleteHashes.push(...deletedTransactionBundles.map((tx) => tx._hash).filter(exists3));
|
|
931
1045
|
const undeletedTransactionBundles = pendingBundledTransactions.filter((tx) => !this._removablePendingTransactionHashes.has(tx.root));
|
|
932
|
-
const transactions = (await Promise.all(
|
|
933
|
-
undeletedTransactionBundles.map((p) => bundledPayloadToHydratedTransaction(p))
|
|
934
|
-
)).filter(exists3);
|
|
1046
|
+
const transactions = (await Promise.all(undeletedTransactionBundles.map((p) => bundledPayloadToHydratedTransaction(p)))).filter(exists3);
|
|
935
1047
|
const expiredTransactions = transactions.filter(isTransactionExpired(lastHead.block + 1));
|
|
936
1048
|
const expiredBundleHashes = expiredTransactions.map((expiredHydratedTx) => (
|
|
937
1049
|
// Find the corresponding payload bundle hash for the expired transaction
|
|
@@ -952,25 +1064,11 @@ var BasePendingTransactionsService = class extends BaseService {
|
|
|
952
1064
|
});
|
|
953
1065
|
}
|
|
954
1066
|
};
|
|
955
|
-
|
|
956
|
-
/**
|
|
957
|
-
* Priority for inserting new transactions
|
|
958
|
-
*/
|
|
959
|
-
InsertNewTransactions: 5,
|
|
960
|
-
/**
|
|
961
|
-
* Priority for reading pending transactions
|
|
962
|
-
*/
|
|
963
|
-
ReadTransactions: 3,
|
|
964
|
-
/**
|
|
965
|
-
* Priority for removing finalized/expired/rejected transactions
|
|
966
|
-
*/
|
|
967
|
-
PurgeTransactions: 1
|
|
968
|
-
});
|
|
969
|
-
BasePendingTransactionsService = __decorateClass([
|
|
1067
|
+
BasePendingTransactionsService = _ts_decorate9([
|
|
970
1068
|
creatable9()
|
|
971
1069
|
], BasePendingTransactionsService);
|
|
972
|
-
var isTransactionExpired = (block) => ([txBw]) => txBw.exp < block;
|
|
973
|
-
var isTransactionActive = (block) => ([txBw]) => txBw.nbf <= block && txBw.exp >= block;
|
|
1070
|
+
var isTransactionExpired = /* @__PURE__ */ __name((block) => ([txBw]) => txBw.exp < block, "isTransactionExpired");
|
|
1071
|
+
var isTransactionActive = /* @__PURE__ */ __name((block) => ([txBw]) => txBw.nbf <= block && txBw.exp >= block, "isTransactionActive");
|
|
974
1072
|
|
|
975
1073
|
// src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts
|
|
976
1074
|
import { filterAs as filterAs2 } from "@xylabs/array";
|
|
@@ -979,7 +1077,7 @@ import { asOptionalBoundWitness } from "@xyo-network/boundwitness-model";
|
|
|
979
1077
|
import { payloadSchemasContains } from "@xyo-network/boundwitness-validator";
|
|
980
1078
|
import { BoundWitnessWrapper } from "@xyo-network/boundwitness-wrapper";
|
|
981
1079
|
import { asChainStakeIntent, ChainStakeIntentSchema } from "@xyo-network/xl1-protocol";
|
|
982
|
-
var getBlockSignedStakeDeclarations = async (block, archivist, intent) => {
|
|
1080
|
+
var getBlockSignedStakeDeclarations = /* @__PURE__ */ __name(async (block, archivist, intent) => {
|
|
983
1081
|
const blockData = await archivist.get(block.payload_hashes);
|
|
984
1082
|
const bwsFromBlock = filterAs2(blockData, asOptionalBoundWitness);
|
|
985
1083
|
const bwsFromBlockWithDeclarations = bwsFromBlock.filter((bw) => payloadSchemasContains(bw, ChainStakeIntentSchema));
|
|
@@ -990,48 +1088,41 @@ var getBlockSignedStakeDeclarations = async (block, archivist, intent) => {
|
|
|
990
1088
|
const stakeIntents = filterAs2(payloads, asChainStakeIntent).filter((p) => p.intent === intent).filter((p) => bw.addresses.includes(p.from));
|
|
991
1089
|
return stakeIntents;
|
|
992
1090
|
}))).flat();
|
|
993
|
-
};
|
|
994
|
-
var filterToValidSignedBoundWitnesses = async (bws) => {
|
|
1091
|
+
}, "getBlockSignedStakeDeclarations");
|
|
1092
|
+
var filterToValidSignedBoundWitnesses = /* @__PURE__ */ __name(async (bws) => {
|
|
995
1093
|
const validBwIndexes = await Promise.all(bws.map((bw) => BoundWitnessWrapper.parse(bw).getValid()));
|
|
996
1094
|
return bws.filter((_, index) => validBwIndexes[index]);
|
|
997
|
-
};
|
|
998
|
-
var mapBoundWitnessToStakeIntentHashes = (bw) => {
|
|
1095
|
+
}, "filterToValidSignedBoundWitnesses");
|
|
1096
|
+
var mapBoundWitnessToStakeIntentHashes = /* @__PURE__ */ __name((bw) => {
|
|
999
1097
|
return bw.payload_schemas.map((schema, index) => schema === ChainStakeIntentSchema ? bw.payload_hashes[index] : void 0);
|
|
1000
|
-
};
|
|
1098
|
+
}, "mapBoundWitnessToStakeIntentHashes");
|
|
1001
1099
|
|
|
1002
1100
|
// src/StakeIntent/XyoStakeIntentService.ts
|
|
1003
1101
|
import { filterAs as filterAs3 } from "@xylabs/array";
|
|
1004
1102
|
import { assertEx as assertEx10 } from "@xylabs/assert";
|
|
1005
1103
|
import { creatable as creatable10 } from "@xylabs/creatable";
|
|
1006
|
-
import {
|
|
1007
|
-
asAddress
|
|
1008
|
-
} from "@xylabs/hex";
|
|
1104
|
+
import { asAddress } from "@xylabs/hex";
|
|
1009
1105
|
import { isUndefined as isUndefined2 } from "@xylabs/typeof";
|
|
1010
|
-
import {
|
|
1011
|
-
|
|
1012
|
-
ChainStakeIntentAnalyzer,
|
|
1013
|
-
isChainSummaryStakeIntent
|
|
1014
|
-
} from "@xyo-network/chain-analyze";
|
|
1015
|
-
import {
|
|
1016
|
-
DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS,
|
|
1017
|
-
findFirstMatching,
|
|
1018
|
-
IntervalMap
|
|
1019
|
-
} from "@xyo-network/chain-utils";
|
|
1106
|
+
import { analyzeChain, ChainStakeIntentAnalyzer, isChainSummaryStakeIntent } from "@xyo-network/chain-analyze";
|
|
1107
|
+
import { DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS, findFirstMatching, IntervalMap } from "@xyo-network/chain-utils";
|
|
1020
1108
|
import { PayloadBuilder as PayloadBuilder8 } from "@xyo-network/payload-builder";
|
|
1021
|
-
import {
|
|
1022
|
-
asBlockBoundWitness as asBlockBoundWitness3,
|
|
1023
|
-
asBlockBoundWitnessWithStorageMeta,
|
|
1024
|
-
asChainIndexingServiceStateWithStorageMeta,
|
|
1025
|
-
asChainStakeIntent as asChainStakeIntent2,
|
|
1026
|
-
ChainIndexingServiceStateSchema,
|
|
1027
|
-
isChainIndexingServiceState
|
|
1028
|
-
} from "@xyo-network/xl1-protocol";
|
|
1109
|
+
import { asBlockBoundWitness as asBlockBoundWitness3, asBlockBoundWitnessWithStorageMeta, asChainIndexingServiceStateWithStorageMeta, asChainStakeIntent as asChainStakeIntent2, ChainIndexingServiceStateSchema, isChainIndexingServiceState } from "@xyo-network/xl1-protocol";
|
|
1029
1110
|
import { Mutex as Mutex3 } from "async-mutex";
|
|
1030
1111
|
import { LRUCache as LRUCache3 } from "lru-cache";
|
|
1112
|
+
function _ts_decorate10(decorators, target, key, desc) {
|
|
1113
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1114
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1115
|
+
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;
|
|
1116
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1117
|
+
}
|
|
1118
|
+
__name(_ts_decorate10, "_ts_decorate");
|
|
1031
1119
|
var ACTIVE_STAKE_TTL = 1e3 * 60 * 60 * 2;
|
|
1032
1120
|
var NO_ACTIVE_STAKE_TTL = 1e3 * 2;
|
|
1033
1121
|
var STAKE_CACHE_MAX_ENTRIES = 1e4;
|
|
1034
1122
|
var XyoStakeIntentService = class extends BaseService {
|
|
1123
|
+
static {
|
|
1124
|
+
__name(this, "XyoStakeIntentService");
|
|
1125
|
+
}
|
|
1035
1126
|
// TODO: Use hash instead of block number to handle chain reorgs
|
|
1036
1127
|
_lastIndexedBlockHash = void 0;
|
|
1037
1128
|
// TODO: Interval tree per declaration (bank, validator, etc.)
|
|
@@ -1042,7 +1133,9 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1042
1133
|
// in performance for small sets, and (most importantly) easily
|
|
1043
1134
|
// persisted so we can recover state on restart.
|
|
1044
1135
|
_producers = new IntervalMap();
|
|
1045
|
-
_stakeCache = new LRUCache3({
|
|
1136
|
+
_stakeCache = new LRUCache3({
|
|
1137
|
+
max: STAKE_CACHE_MAX_ENTRIES
|
|
1138
|
+
});
|
|
1046
1139
|
_updateMutex = new Mutex3();
|
|
1047
1140
|
get chainArchivist() {
|
|
1048
1141
|
return assertEx10(this.params.chainArchivist, () => "chainArchivist not set");
|
|
@@ -1075,7 +1168,9 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1075
1168
|
return await this.spanAsync("getDeclaredCandidatesForBlock", async () => {
|
|
1076
1169
|
assertEx10(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
|
|
1077
1170
|
const results = this._producers.findAllContaining(block);
|
|
1078
|
-
const candidates = [
|
|
1171
|
+
const candidates = [
|
|
1172
|
+
...results
|
|
1173
|
+
];
|
|
1079
1174
|
const requiredMinimumStake = this.getRequiredMinimumStakeForIntent(intent);
|
|
1080
1175
|
const validCandidates = await this.filterToValidStake(candidates, this.chainStakeViewer, requiredMinimumStake);
|
|
1081
1176
|
return validCandidates;
|
|
@@ -1097,41 +1192,62 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1097
1192
|
await this.updateIndex(true);
|
|
1098
1193
|
}
|
|
1099
1194
|
async filterToValidStake(candidates, chainStakeViewer, requiredMinimumStake) {
|
|
1100
|
-
const candidatesWithStake = await Promise.all(
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
}
|
|
1108
|
-
this._stakeCache.set(candidate, activeStake, { ttl: NO_ACTIVE_STAKE_TTL });
|
|
1109
|
-
}
|
|
1110
|
-
return { candidate, stake: activeStake };
|
|
1195
|
+
const candidatesWithStake = await Promise.all(candidates.map(async (candidate) => {
|
|
1196
|
+
const stake = this._stakeCache.get(candidate);
|
|
1197
|
+
if (stake === void 0) {
|
|
1198
|
+
const activeStake = await chainStakeViewer.activeByAddressStaked(`${candidate}`);
|
|
1199
|
+
if (activeStake > 0n) {
|
|
1200
|
+
this._stakeCache.set(candidate, activeStake, {
|
|
1201
|
+
ttl: ACTIVE_STAKE_TTL
|
|
1202
|
+
});
|
|
1111
1203
|
} else {
|
|
1112
|
-
|
|
1204
|
+
this._stakeCache.set(candidate, activeStake, {
|
|
1205
|
+
ttl: NO_ACTIVE_STAKE_TTL
|
|
1206
|
+
});
|
|
1113
1207
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1208
|
+
return {
|
|
1209
|
+
candidate,
|
|
1210
|
+
stake: activeStake
|
|
1211
|
+
};
|
|
1212
|
+
} else {
|
|
1213
|
+
return {
|
|
1214
|
+
candidate,
|
|
1215
|
+
stake
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
}));
|
|
1116
1219
|
return candidatesWithStake.filter(({ stake }) => stake >= requiredMinimumStake).map(({ candidate }) => candidate);
|
|
1117
1220
|
}
|
|
1118
1221
|
async persistState(current) {
|
|
1119
1222
|
const state = this._producers.serialize();
|
|
1120
|
-
const payload = new PayloadBuilder8({
|
|
1121
|
-
|
|
1223
|
+
const payload = new PayloadBuilder8({
|
|
1224
|
+
schema: ChainIndexingServiceStateSchema
|
|
1225
|
+
}).fields({
|
|
1226
|
+
endBlockHash: current,
|
|
1227
|
+
state
|
|
1228
|
+
}).build();
|
|
1229
|
+
await this.stakeIntentStateArchivist.insert([
|
|
1230
|
+
payload
|
|
1231
|
+
]);
|
|
1122
1232
|
}
|
|
1123
1233
|
async recoverState(current) {
|
|
1124
|
-
const currentBlock = assertEx10(asBlockBoundWitness3((await this.chainArchivist.get([
|
|
1234
|
+
const currentBlock = assertEx10(asBlockBoundWitness3((await this.chainArchivist.get([
|
|
1235
|
+
current
|
|
1236
|
+
]))?.[0]), () => `Block ${current} not found`);
|
|
1125
1237
|
const currentBlockNum = currentBlock.block;
|
|
1126
|
-
const opts = {
|
|
1238
|
+
const opts = {
|
|
1239
|
+
...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS
|
|
1240
|
+
};
|
|
1127
1241
|
while (true) {
|
|
1128
|
-
const predicate = (p) => {
|
|
1242
|
+
const predicate = /* @__PURE__ */ __name((p) => {
|
|
1129
1243
|
const state2 = asChainIndexingServiceStateWithStorageMeta(p);
|
|
1130
1244
|
return state2 ? true : false;
|
|
1131
|
-
};
|
|
1245
|
+
}, "predicate");
|
|
1132
1246
|
const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts);
|
|
1133
1247
|
if (isChainIndexingServiceState(state)) {
|
|
1134
|
-
const indexed = (await this.chainArchivist.get([
|
|
1248
|
+
const indexed = (await this.chainArchivist.get([
|
|
1249
|
+
state.endBlockHash
|
|
1250
|
+
]))?.[0];
|
|
1135
1251
|
const indexedBlock = asBlockBoundWitnessWithStorageMeta(indexed);
|
|
1136
1252
|
if (indexedBlock) {
|
|
1137
1253
|
const indexedBlockNum = indexedBlock.block;
|
|
@@ -1157,7 +1273,9 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1157
1273
|
const currentHead = await this.chainIterator.head();
|
|
1158
1274
|
if (isUndefined2(currentHead)) return;
|
|
1159
1275
|
const currentHeadHash = await PayloadBuilder8.hash(currentHead);
|
|
1160
|
-
const result = await analyzeChain(this.chainArchivist, [
|
|
1276
|
+
const result = await analyzeChain(this.chainArchivist, [
|
|
1277
|
+
new ChainStakeIntentAnalyzer("producer")
|
|
1278
|
+
], currentHeadHash, this._lastIndexedBlockHash);
|
|
1161
1279
|
const signedDeclarations = filterAs3(result.find(isChainSummaryStakeIntent)?.intents ?? [], asChainStakeIntent2);
|
|
1162
1280
|
if (currentHead.block === void 0) return;
|
|
1163
1281
|
const currentHeadBlockNum = currentHead.block;
|
|
@@ -1176,7 +1294,7 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1176
1294
|
});
|
|
1177
1295
|
}
|
|
1178
1296
|
};
|
|
1179
|
-
XyoStakeIntentService =
|
|
1297
|
+
XyoStakeIntentService = _ts_decorate10([
|
|
1180
1298
|
creatable10()
|
|
1181
1299
|
], XyoStakeIntentService);
|
|
1182
1300
|
export {
|