@xyo-network/chain-services 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/neutral/index.d.ts +0 -1
- package/dist/neutral/index.d.ts.map +1 -1
- package/dist/neutral/index.mjs +257 -552
- package/dist/neutral/index.mjs.map +1 -1
- package/package.json +46 -49
- package/src/BlockProducer/spec/BaseBlockProducerService.spec.ts +4 -3
- package/src/PendingTransactions/spec/BasePendingTransactions.spec.ts +2 -1
- package/src/index.ts +0 -1
- package/dist/neutral/DataLake/AbstractXyoDataLake.d.ts +0 -10
- package/dist/neutral/DataLake/AbstractXyoDataLake.d.ts.map +0 -1
- package/dist/neutral/DataLake/ArchivistXyoDataLake.d.ts +0 -11
- package/dist/neutral/DataLake/ArchivistXyoDataLake.d.ts.map +0 -1
- package/dist/neutral/DataLake/HttpXyoDataLake.d.ts +0 -20
- package/dist/neutral/DataLake/HttpXyoDataLake.d.ts.map +0 -1
- package/dist/neutral/DataLake/index.d.ts +0 -4
- package/dist/neutral/DataLake/index.d.ts.map +0 -1
- package/src/DataLake/AbstractXyoDataLake.ts +0 -38
- package/src/DataLake/ArchivistXyoDataLake.ts +0 -26
- package/src/DataLake/HttpXyoDataLake.ts +0 -105
- package/src/DataLake/index.ts +0 -3
package/dist/neutral/index.mjs
CHANGED
|
@@ -1,33 +1,39 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
-
var
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
5
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
6
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
7
|
+
if (decorator = decorators[i])
|
|
8
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
9
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
3
13
|
|
|
4
14
|
// src/AccountBalance/accountBalanceServiceFromArchivist.ts
|
|
5
15
|
import { exists } from "@xylabs/exists";
|
|
6
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
asHash,
|
|
18
|
+
isHash
|
|
19
|
+
} from "@xylabs/hex";
|
|
7
20
|
import { PayloadBuilder } from "@xyo-network/payload-builder";
|
|
8
21
|
import { LRUCache } from "lru-cache";
|
|
9
22
|
|
|
10
23
|
// src/AccountBalance/BaseAccountBalanceService.ts
|
|
11
24
|
import { creatable as creatable2 } from "@xylabs/creatable";
|
|
12
|
-
import {
|
|
13
|
-
|
|
25
|
+
import {
|
|
26
|
+
AttoXL1
|
|
27
|
+
} from "@xyo-network/xl1-protocol";
|
|
28
|
+
import {
|
|
29
|
+
balanceSummary
|
|
30
|
+
} from "@xyo-network/xl1-protocol-sdk";
|
|
14
31
|
|
|
15
32
|
// src/BaseService.ts
|
|
16
33
|
import { AbstractCreatable, creatable } from "@xylabs/creatable";
|
|
17
34
|
import { span, spanAsync } from "@xylabs/telemetry";
|
|
18
35
|
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");
|
|
26
36
|
var BaseService = class extends AbstractCreatable {
|
|
27
|
-
static {
|
|
28
|
-
__name(this, "BaseService");
|
|
29
|
-
}
|
|
30
|
-
static singletonInitMutex = new Mutex();
|
|
31
37
|
static get singletons() {
|
|
32
38
|
return globalThis["xyoServiceSingletons"] ?? (globalThis["xyoServiceSingletons"] = {});
|
|
33
39
|
}
|
|
@@ -47,33 +53,21 @@ var BaseService = class extends AbstractCreatable {
|
|
|
47
53
|
return await spanAsync(name, fn, this.tracer);
|
|
48
54
|
}
|
|
49
55
|
};
|
|
50
|
-
BaseService
|
|
56
|
+
__publicField(BaseService, "singletonInitMutex", new Mutex());
|
|
57
|
+
BaseService = __decorateClass([
|
|
51
58
|
creatable()
|
|
52
59
|
], BaseService);
|
|
53
60
|
var BaseAccountableService = class extends BaseService {
|
|
54
|
-
|
|
55
|
-
__name(this, "BaseAccountableService");
|
|
56
|
-
}
|
|
61
|
+
// Base class for services that have an account
|
|
57
62
|
};
|
|
58
63
|
function creatableService() {
|
|
59
64
|
return (constructor) => {
|
|
60
65
|
constructor;
|
|
61
66
|
};
|
|
62
67
|
}
|
|
63
|
-
__name(creatableService, "creatableService");
|
|
64
68
|
|
|
65
69
|
// 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");
|
|
73
70
|
var BaseAccountBalanceService = class extends BaseService {
|
|
74
|
-
static {
|
|
75
|
-
__name(this, "BaseAccountBalanceService");
|
|
76
|
-
}
|
|
77
71
|
async balances(head, address) {
|
|
78
72
|
const summary = await balanceSummary({
|
|
79
73
|
chainArchivist: this.params.chainArchivist,
|
|
@@ -87,12 +81,12 @@ var BaseAccountBalanceService = class extends BaseService {
|
|
|
87
81
|
return result;
|
|
88
82
|
}
|
|
89
83
|
};
|
|
90
|
-
BaseAccountBalanceService =
|
|
84
|
+
BaseAccountBalanceService = __decorateClass([
|
|
91
85
|
creatable2()
|
|
92
86
|
], BaseAccountBalanceService);
|
|
93
87
|
|
|
94
88
|
// src/AccountBalance/accountBalanceServiceFromArchivist.ts
|
|
95
|
-
var accountBalanceServiceFromArchivist =
|
|
89
|
+
var accountBalanceServiceFromArchivist = async (archivist) => {
|
|
96
90
|
const summaryArchivistCache = new LRUCache({
|
|
97
91
|
max: 1e5,
|
|
98
92
|
allowStale: true,
|
|
@@ -100,13 +94,13 @@ var accountBalanceServiceFromArchivist = /* @__PURE__ */ __name(async (archivist
|
|
|
100
94
|
updateAgeOnGet: true
|
|
101
95
|
});
|
|
102
96
|
const summaryRepository = {
|
|
103
|
-
get:
|
|
97
|
+
get: (hashes) => {
|
|
104
98
|
const results = hashes.map((hash) => {
|
|
105
99
|
return summaryArchivistCache.get(hash);
|
|
106
100
|
}).filter(exists);
|
|
107
101
|
return results;
|
|
108
|
-
},
|
|
109
|
-
insert:
|
|
102
|
+
},
|
|
103
|
+
insert: async (payloads) => {
|
|
110
104
|
const results = (await PayloadBuilder.addStorageMeta(payloads)).map((payload) => {
|
|
111
105
|
const hash = asHash(payload.hash);
|
|
112
106
|
if (isHash(hash)) {
|
|
@@ -115,28 +109,35 @@ var accountBalanceServiceFromArchivist = /* @__PURE__ */ __name(async (archivist
|
|
|
115
109
|
}
|
|
116
110
|
}).filter(exists);
|
|
117
111
|
return results;
|
|
118
|
-
},
|
|
119
|
-
next:
|
|
112
|
+
},
|
|
113
|
+
next: () => {
|
|
120
114
|
throw new Error("Not implemented");
|
|
121
|
-
}
|
|
115
|
+
}
|
|
122
116
|
};
|
|
123
|
-
const service = await BaseAccountBalanceService.create({
|
|
124
|
-
chainArchivist: archivist,
|
|
125
|
-
summaryRepository
|
|
126
|
-
});
|
|
117
|
+
const service = await BaseAccountBalanceService.create({ chainArchivist: archivist, summaryRepository });
|
|
127
118
|
return service;
|
|
128
|
-
}
|
|
119
|
+
};
|
|
129
120
|
var accountBalanceServiceFromArchivistV2 = accountBalanceServiceFromArchivist;
|
|
130
121
|
|
|
131
122
|
// src/BlockProducer/BaseBlockProducerService.ts
|
|
132
123
|
import { assertEx as assertEx2 } from "@xylabs/assert";
|
|
133
124
|
import { creatable as creatable3 } from "@xylabs/creatable";
|
|
134
125
|
import { exists as exists2 } from "@xylabs/exists";
|
|
135
|
-
import {
|
|
136
|
-
|
|
126
|
+
import {
|
|
127
|
+
hexToBigInt,
|
|
128
|
+
toHex
|
|
129
|
+
} from "@xylabs/hex";
|
|
130
|
+
import {
|
|
131
|
+
FixedPercentageBlockRewardDiviner,
|
|
132
|
+
FixedPercentageBlockRewardDivinerConfigSchema
|
|
133
|
+
} from "@xyo-network/chain-modules";
|
|
137
134
|
import { buildNextBlock, createDeclarationIntent } from "@xyo-network/chain-protocol";
|
|
138
135
|
import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/payload-builder";
|
|
139
|
-
import {
|
|
136
|
+
import {
|
|
137
|
+
asBlockBoundWitness,
|
|
138
|
+
AttoXL1 as AttoXL12,
|
|
139
|
+
BlockNumberSchema
|
|
140
|
+
} from "@xyo-network/xl1-protocol";
|
|
140
141
|
|
|
141
142
|
// src/BlockProducer/generateTransactionFeeTransfers.ts
|
|
142
143
|
import { assertEx } from "@xylabs/assert";
|
|
@@ -174,41 +175,30 @@ async function generateTransactionFeeTransfers(address, transactions) {
|
|
|
174
175
|
}
|
|
175
176
|
return payloads;
|
|
176
177
|
}
|
|
177
|
-
__name(generateTransactionFeeTransfers, "generateTransactionFeeTransfers");
|
|
178
178
|
|
|
179
179
|
// src/BlockProducer/BaseBlockProducerService.ts
|
|
180
|
-
function _ts_decorate3(decorators, target, key, desc) {
|
|
181
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
182
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
183
|
-
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;
|
|
184
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
185
|
-
}
|
|
186
|
-
__name(_ts_decorate3, "_ts_decorate");
|
|
187
180
|
var DEFAULT_BLOCK_SIZE = 10;
|
|
188
181
|
var XYO_PRODUCER_REDECLARATION_DURATION = 1e4;
|
|
189
182
|
var XYO_PRODUCER_REDECLARATION_WINDOW = 500;
|
|
190
|
-
var BaseBlockProducerService = class
|
|
191
|
-
static {
|
|
192
|
-
__name(this, "BaseBlockProducerService");
|
|
193
|
-
}
|
|
183
|
+
var BaseBlockProducerService = class extends BaseService {
|
|
194
184
|
_blockRewardDiviner;
|
|
195
185
|
/**
|
|
196
|
-
|
|
197
|
-
|
|
186
|
+
* The default block size for a block
|
|
187
|
+
*/
|
|
198
188
|
static get DefaultBlockSize() {
|
|
199
189
|
return DEFAULT_BLOCK_SIZE;
|
|
200
190
|
}
|
|
201
191
|
/**
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
192
|
+
* The amount of time for which the producer will redeclare
|
|
193
|
+
* their intent to continue producing blocks
|
|
194
|
+
*/
|
|
205
195
|
static get RedeclarationDuration() {
|
|
206
196
|
return XYO_PRODUCER_REDECLARATION_DURATION;
|
|
207
197
|
}
|
|
208
198
|
/**
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
199
|
+
* The number of blocks within which the producer will redeclare
|
|
200
|
+
* their intent to continue producing blocks
|
|
201
|
+
*/
|
|
212
202
|
static get RedeclarationWindow() {
|
|
213
203
|
return XYO_PRODUCER_REDECLARATION_WINDOW;
|
|
214
204
|
}
|
|
@@ -267,22 +257,16 @@ var BaseBlockProducerService = class _BaseBlockProducerService extends BaseServi
|
|
|
267
257
|
});
|
|
268
258
|
}
|
|
269
259
|
const blockHex = assertEx2(toHex(block), () => "Failed to convert block to hex");
|
|
270
|
-
const blockId = new PayloadBuilder2({
|
|
271
|
-
|
|
272
|
-
}).fields({
|
|
273
|
-
block: blockHex
|
|
274
|
-
}).build();
|
|
275
|
-
const rewards = await this._blockRewardDiviner.divine([
|
|
276
|
-
blockId
|
|
277
|
-
]);
|
|
260
|
+
const blockId = new PayloadBuilder2({ schema: BlockNumberSchema }).fields({ block: blockHex }).build();
|
|
261
|
+
const rewards = await this._blockRewardDiviner.divine([blockId]);
|
|
278
262
|
const [reward] = rewards;
|
|
279
263
|
return reward;
|
|
280
264
|
}
|
|
281
265
|
/**
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
266
|
+
* Handles the producer redeclaration logic
|
|
267
|
+
* @param head The current head block
|
|
268
|
+
* @returns chain stake intent for the producer redeclaration, or undefined if no redeclaration is needed
|
|
269
|
+
*/
|
|
286
270
|
async getProducerRedeclaration(head) {
|
|
287
271
|
if (this.params.config.producer.disableIntentRedeclaration) return;
|
|
288
272
|
const ranges = await this.stakeIntentService.getDeclaredCandidateRanges(this.address, "producer");
|
|
@@ -291,14 +275,14 @@ var BaseBlockProducerService = class _BaseBlockProducerService extends BaseServi
|
|
|
291
275
|
const [, currentDeclarationEnd] = lastRange;
|
|
292
276
|
const currentBlock = head.block;
|
|
293
277
|
const timeToProducerExpiration = currentDeclarationEnd - currentBlock;
|
|
294
|
-
if (timeToProducerExpiration >
|
|
295
|
-
return createDeclarationIntent(this.address, "producer", currentBlock, currentBlock +
|
|
278
|
+
if (timeToProducerExpiration > BaseBlockProducerService.RedeclarationWindow) return;
|
|
279
|
+
return createDeclarationIntent(this.address, "producer", currentBlock, currentBlock + BaseBlockProducerService.RedeclarationDuration);
|
|
296
280
|
}
|
|
297
281
|
async proposeNextValidBlock(head, validateBalances = false) {
|
|
298
282
|
return await this.spanAsync("proposeNextValidBlock", async () => {
|
|
299
283
|
const { block: previousBlock } = assertEx2(asBlockBoundWitness(head), () => "Invalid head block");
|
|
300
284
|
const nextBlock = previousBlock + 1;
|
|
301
|
-
const nextBlockTransactions = await this.pendingTransactionsService.getPendingTransactions(head._hash,
|
|
285
|
+
const nextBlockTransactions = await this.pendingTransactionsService.getPendingTransactions(head._hash, BaseBlockProducerService.DefaultBlockSize);
|
|
302
286
|
const blockPayloads = [];
|
|
303
287
|
const producerRedeclarationPayload = await this.getProducerRedeclaration(head);
|
|
304
288
|
if (producerRedeclarationPayload) blockPayloads.push(producerRedeclarationPayload);
|
|
@@ -312,9 +296,7 @@ var BaseBlockProducerService = class _BaseBlockProducerService extends BaseServi
|
|
|
312
296
|
if (!transfer) return;
|
|
313
297
|
const totalTransferCost = Object.values(transfer?.transfers).reduce((acc, t) => acc + hexToBigInt(t ?? "00"), 0n);
|
|
314
298
|
if (validateBalances) {
|
|
315
|
-
const balance = (await this.balanceService.balances(head._hash, [
|
|
316
|
-
transfer.from
|
|
317
|
-
]))[transfer.from] ?? AttoXL12(0n);
|
|
299
|
+
const balance = (await this.balanceService.balances(head._hash, [transfer.from]))[transfer.from] ?? AttoXL12(0n);
|
|
318
300
|
if (balance >= totalTransferCost) {
|
|
319
301
|
fundedTransfers.push(transfer);
|
|
320
302
|
return tx;
|
|
@@ -325,13 +307,9 @@ var BaseBlockProducerService = class _BaseBlockProducerService extends BaseServi
|
|
|
325
307
|
}
|
|
326
308
|
}))).filter(exists2);
|
|
327
309
|
blockPayloads.push(...fundedTransfers);
|
|
328
|
-
const block = await buildNextBlock(head, fundedNextBlockTransactions, blockPayloads, [
|
|
329
|
-
this.account
|
|
330
|
-
]);
|
|
310
|
+
const block = await buildNextBlock(head, fundedNextBlockTransactions, blockPayloads, [this.account]);
|
|
331
311
|
this.logger?.info(`buildBlock: ${block[0].block} with ${block[1].length} payloads`);
|
|
332
|
-
const errors = await this.validateHydratedBlockState(block, this.chainId, {
|
|
333
|
-
accountBalance: this.balanceService
|
|
334
|
-
});
|
|
312
|
+
const errors = await this.validateHydratedBlockState(block, this.chainId, { accountBalance: this.balanceService });
|
|
335
313
|
if (errors.length > 0) {
|
|
336
314
|
this.logger?.warn(`Validation of produced block failed: ${errors.at(0)?.message}`);
|
|
337
315
|
const rejectedTransactions = block[1];
|
|
@@ -342,28 +320,18 @@ var BaseBlockProducerService = class _BaseBlockProducerService extends BaseServi
|
|
|
342
320
|
});
|
|
343
321
|
}
|
|
344
322
|
};
|
|
345
|
-
BaseBlockProducerService =
|
|
323
|
+
BaseBlockProducerService = __decorateClass([
|
|
346
324
|
creatable3()
|
|
347
325
|
], BaseBlockProducerService);
|
|
348
326
|
|
|
349
327
|
// src/BlockReward/BaseBlockRewardService.ts
|
|
350
328
|
import { creatable as creatable4 } from "@xylabs/creatable";
|
|
351
|
-
function _ts_decorate4(decorators, target, key, desc) {
|
|
352
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
353
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
354
|
-
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;
|
|
355
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
356
|
-
}
|
|
357
|
-
__name(_ts_decorate4, "_ts_decorate");
|
|
358
329
|
var BaseBlockRewardService = class extends BaseService {
|
|
359
|
-
static {
|
|
360
|
-
__name(this, "BaseBlockRewardService");
|
|
361
|
-
}
|
|
362
330
|
getRewardForBlock(_blockNumber) {
|
|
363
331
|
throw new Error("getRewardForBlock method must be implemented in derived classes");
|
|
364
332
|
}
|
|
365
333
|
};
|
|
366
|
-
BaseBlockRewardService =
|
|
334
|
+
BaseBlockRewardService = __decorateClass([
|
|
367
335
|
creatable4()
|
|
368
336
|
], BaseBlockRewardService);
|
|
369
337
|
|
|
@@ -372,17 +340,7 @@ import { assertEx as assertEx3 } from "@xylabs/assert";
|
|
|
372
340
|
import { creatable as creatable5 } from "@xylabs/creatable";
|
|
373
341
|
import { toEthAddress } from "@xylabs/hex";
|
|
374
342
|
import { XyoChainRewards__factory as XyoChainRewardsFactory } from "@xyo-network/typechain";
|
|
375
|
-
function _ts_decorate5(decorators, target, key, desc) {
|
|
376
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
377
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
378
|
-
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;
|
|
379
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
380
|
-
}
|
|
381
|
-
__name(_ts_decorate5, "_ts_decorate");
|
|
382
343
|
var EvmBlockRewardService = class extends BaseBlockRewardService {
|
|
383
|
-
static {
|
|
384
|
-
__name(this, "EvmBlockRewardService");
|
|
385
|
-
}
|
|
386
344
|
_contractAddress;
|
|
387
345
|
get chainService() {
|
|
388
346
|
return assertEx3(this.params.chainService, () => "chainService is required");
|
|
@@ -407,7 +365,7 @@ var EvmBlockRewardService = class extends BaseBlockRewardService {
|
|
|
407
365
|
return await contract.calcBlockReward(blockNumber);
|
|
408
366
|
}
|
|
409
367
|
};
|
|
410
|
-
EvmBlockRewardService =
|
|
368
|
+
EvmBlockRewardService = __decorateClass([
|
|
411
369
|
creatable5()
|
|
412
370
|
], EvmBlockRewardService);
|
|
413
371
|
|
|
@@ -416,17 +374,7 @@ import { assertEx as assertEx4 } from "@xylabs/assert";
|
|
|
416
374
|
import { creatable as creatable6 } from "@xylabs/creatable";
|
|
417
375
|
import { toFixedPoint } from "@xylabs/decimal-precision";
|
|
418
376
|
import { rewardFromBlockNumber } from "@xyo-network/chain-protocol";
|
|
419
|
-
function _ts_decorate6(decorators, target, key, desc) {
|
|
420
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
421
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
422
|
-
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;
|
|
423
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
424
|
-
}
|
|
425
|
-
__name(_ts_decorate6, "_ts_decorate");
|
|
426
377
|
var MemoryBlockRewardService = class extends BaseBlockRewardService {
|
|
427
|
-
static {
|
|
428
|
-
__name(this, "MemoryBlockRewardService");
|
|
429
|
-
}
|
|
430
378
|
rewardFromBlockNumber = rewardFromBlockNumber(18);
|
|
431
379
|
get creatorReward() {
|
|
432
380
|
return assertEx4(this.params.creatorReward, () => "creatorReward is required");
|
|
@@ -458,10 +406,18 @@ var MemoryBlockRewardService = class extends BaseBlockRewardService {
|
|
|
458
406
|
};
|
|
459
407
|
}
|
|
460
408
|
getRewardForBlock(blockNumber) {
|
|
461
|
-
return this.rewardFromBlockNumber(
|
|
409
|
+
return this.rewardFromBlockNumber(
|
|
410
|
+
blockNumber,
|
|
411
|
+
this.initialReward,
|
|
412
|
+
this.stepSize,
|
|
413
|
+
this.stepFactorNumerator,
|
|
414
|
+
this.stepFactorDenominator,
|
|
415
|
+
this.minRewardPerBlock,
|
|
416
|
+
this.creatorReward
|
|
417
|
+
);
|
|
462
418
|
}
|
|
463
419
|
};
|
|
464
|
-
MemoryBlockRewardService =
|
|
420
|
+
MemoryBlockRewardService = __decorateClass([
|
|
465
421
|
creatable6()
|
|
466
422
|
], MemoryBlockRewardService);
|
|
467
423
|
|
|
@@ -469,15 +425,13 @@ MemoryBlockRewardService = _ts_decorate6([
|
|
|
469
425
|
import { assertEx as assertEx5 } from "@xylabs/assert";
|
|
470
426
|
import { isDefined, isNull } from "@xylabs/typeof";
|
|
471
427
|
import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/payload-builder";
|
|
472
|
-
import {
|
|
428
|
+
import {
|
|
429
|
+
asBlockBoundWitness as asBlockBoundWitness2,
|
|
430
|
+
isBlockBoundWitness
|
|
431
|
+
} from "@xyo-network/xl1-protocol";
|
|
473
432
|
import { LRUCache as LRUCache2 } from "lru-cache";
|
|
474
433
|
var ChainBlockNumberIterationService = class extends BaseService {
|
|
475
|
-
|
|
476
|
-
__name(this, "ChainBlockNumberIterationService");
|
|
477
|
-
}
|
|
478
|
-
_blocksByBlockNumber = new LRUCache2({
|
|
479
|
-
max: 1e4
|
|
480
|
-
});
|
|
434
|
+
_blocksByBlockNumber = new LRUCache2({ max: 1e4 });
|
|
481
435
|
get chainArchivist() {
|
|
482
436
|
return assertEx5(this.params.chainArchivist);
|
|
483
437
|
}
|
|
@@ -491,9 +445,7 @@ var ChainBlockNumberIterationService = class extends BaseService {
|
|
|
491
445
|
if (cached) return cached;
|
|
492
446
|
const startingBlock = head;
|
|
493
447
|
const currentBlockHash = await PayloadBuilder3.hash(startingBlock);
|
|
494
|
-
let currentBlock = (await this.chainArchivist.get([
|
|
495
|
-
currentBlockHash
|
|
496
|
-
])).at(0);
|
|
448
|
+
let currentBlock = (await this.chainArchivist.get([currentBlockHash])).at(0);
|
|
497
449
|
while (isDefined(currentBlock)) {
|
|
498
450
|
assertEx5(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${currentBlock?._hash}]`);
|
|
499
451
|
if (isBlockBoundWitness(currentBlock)) {
|
|
@@ -503,9 +455,7 @@ var ChainBlockNumberIterationService = class extends BaseService {
|
|
|
503
455
|
}
|
|
504
456
|
const { previous } = currentBlock;
|
|
505
457
|
if (isNull(previous)) break;
|
|
506
|
-
currentBlock = (await this.chainArchivist.get([
|
|
507
|
-
previous
|
|
508
|
-
])).at(0);
|
|
458
|
+
currentBlock = (await this.chainArchivist.get([previous])).at(0);
|
|
509
459
|
}
|
|
510
460
|
}
|
|
511
461
|
throw new Error(`Block not found: ${block}`);
|
|
@@ -528,9 +478,7 @@ var ChainBlockNumberIterationService = class extends BaseService {
|
|
|
528
478
|
results.push(currentBlock);
|
|
529
479
|
const { previous } = currentBlock;
|
|
530
480
|
if (isNull(previous)) break;
|
|
531
|
-
const nextBlock = await this.chainArchivist.get([
|
|
532
|
-
previous
|
|
533
|
-
]);
|
|
481
|
+
const nextBlock = await this.chainArchivist.get([previous]);
|
|
534
482
|
currentBlock = asBlockBoundWitness2(nextBlock[0]);
|
|
535
483
|
} else {
|
|
536
484
|
const hash = PayloadBuilder3.hash(currentBlock);
|
|
@@ -542,11 +490,7 @@ var ChainBlockNumberIterationService = class extends BaseService {
|
|
|
542
490
|
async updateHead(head) {
|
|
543
491
|
await Promise.resolve();
|
|
544
492
|
this.params.head = head;
|
|
545
|
-
void this.emit("headUpdated", {
|
|
546
|
-
blocks: [
|
|
547
|
-
head
|
|
548
|
-
]
|
|
549
|
-
});
|
|
493
|
+
void this.emit("headUpdated", { blocks: [head] });
|
|
550
494
|
}
|
|
551
495
|
};
|
|
552
496
|
|
|
@@ -556,15 +500,15 @@ import { toAddress, toEthAddress as toEthAddress2 } from "@xylabs/hex";
|
|
|
556
500
|
import { StakedXyoChain__factory as StakedXyoChainFactory } from "@xyo-network/typechain";
|
|
557
501
|
import { getAddress } from "ethers/address";
|
|
558
502
|
var EvmChainService = class extends BaseService {
|
|
559
|
-
static {
|
|
560
|
-
__name(this, "EvmChainService");
|
|
561
|
-
}
|
|
562
503
|
get chainId() {
|
|
563
504
|
return assertEx6(this.params.id);
|
|
564
505
|
}
|
|
565
506
|
get contract() {
|
|
566
507
|
if (this.params.contract === void 0) {
|
|
567
|
-
this.params.contract = StakedXyoChainFactory.connect(
|
|
508
|
+
this.params.contract = StakedXyoChainFactory.connect(
|
|
509
|
+
toEthAddress2(this.chainId),
|
|
510
|
+
this.params.runner
|
|
511
|
+
);
|
|
568
512
|
}
|
|
569
513
|
return assertEx6(this.params.contract);
|
|
570
514
|
}
|
|
@@ -630,9 +574,6 @@ var EvmChainService = class extends BaseService {
|
|
|
630
574
|
// src/ChainService/Memory/Memory.ts
|
|
631
575
|
import { ZERO_ADDRESS } from "@xylabs/hex";
|
|
632
576
|
var MemoryChainService = class extends BaseService {
|
|
633
|
-
static {
|
|
634
|
-
__name(this, "MemoryChainService");
|
|
635
|
-
}
|
|
636
577
|
_simulatedStake = 1n;
|
|
637
578
|
get chainId() {
|
|
638
579
|
return ZERO_ADDRESS;
|
|
@@ -694,17 +635,7 @@ var MemoryChainService = class extends BaseService {
|
|
|
694
635
|
// src/ChainValidator/XyoValidator.ts
|
|
695
636
|
import { assertEx as assertEx7 } from "@xylabs/assert";
|
|
696
637
|
import { creatable as creatable7 } from "@xylabs/creatable";
|
|
697
|
-
function _ts_decorate7(decorators, target, key, desc) {
|
|
698
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
699
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
700
|
-
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;
|
|
701
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
702
|
-
}
|
|
703
|
-
__name(_ts_decorate7, "_ts_decorate");
|
|
704
638
|
var XyoValidator = class extends BaseService {
|
|
705
|
-
static {
|
|
706
|
-
__name(this, "XyoValidator");
|
|
707
|
-
}
|
|
708
639
|
get address() {
|
|
709
640
|
return this.account.address;
|
|
710
641
|
}
|
|
@@ -732,223 +663,34 @@ var XyoValidator = class extends BaseService {
|
|
|
732
663
|
// TODO: Move to validator and inherit this class from validator
|
|
733
664
|
async validatePendingTransaction(hydratedTransaction) {
|
|
734
665
|
const [tx] = hydratedTransaction;
|
|
735
|
-
if ((await this.chainArchivist.get([
|
|
736
|
-
tx._hash
|
|
737
|
-
])).length > 0) return false;
|
|
666
|
+
if ((await this.chainArchivist.get([tx._hash])).length > 0) return false;
|
|
738
667
|
return await Promise.resolve(true);
|
|
739
668
|
}
|
|
740
669
|
};
|
|
741
|
-
XyoValidator =
|
|
670
|
+
XyoValidator = __decorateClass([
|
|
742
671
|
creatable7()
|
|
743
672
|
], XyoValidator);
|
|
744
673
|
|
|
745
|
-
// src/DataLake/AbstractXyoDataLake.ts
|
|
746
|
-
import { ObjectHasher } from "@xyo-network/hash";
|
|
747
|
-
import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/payload-builder";
|
|
748
|
-
import { isAnyPayload } from "@xyo-network/payload-model";
|
|
749
|
-
import { isHashPayload } from "@xyo-network/xl1-protocol";
|
|
750
|
-
var AbstractXyoDataLake = class {
|
|
751
|
-
static {
|
|
752
|
-
__name(this, "AbstractXyoDataLake");
|
|
753
|
-
}
|
|
754
|
-
async fetch(hashes, maxDepth = 10) {
|
|
755
|
-
const results = await this.get(hashes);
|
|
756
|
-
if (maxDepth > 0) {
|
|
757
|
-
const hashPayloads = results.filter(isHashPayload);
|
|
758
|
-
const otherPayloads = results.filter((item) => !isHashPayload(item));
|
|
759
|
-
const found = await this.fetch(hashPayloads.map((item) => item.hash), maxDepth - 1);
|
|
760
|
-
const foundHashes = await Promise.all(found.map(async (item) => isAnyPayload(item) ? await PayloadBuilder4.hash(item) : ObjectHasher.hashBytes(item)));
|
|
761
|
-
const notFound = hashPayloads.filter((item) => !foundHashes.includes(item.hash));
|
|
762
|
-
return [
|
|
763
|
-
...otherPayloads,
|
|
764
|
-
...found,
|
|
765
|
-
...notFound
|
|
766
|
-
];
|
|
767
|
-
}
|
|
768
|
-
return results;
|
|
769
|
-
}
|
|
770
|
-
async trace(hash) {
|
|
771
|
-
const [result] = await this.get([
|
|
772
|
-
hash
|
|
773
|
-
]);
|
|
774
|
-
if (isHashPayload(result)) {
|
|
775
|
-
const [payload, route] = await this.trace(result.hash);
|
|
776
|
-
return [
|
|
777
|
-
payload,
|
|
778
|
-
[
|
|
779
|
-
result,
|
|
780
|
-
...route
|
|
781
|
-
]
|
|
782
|
-
];
|
|
783
|
-
}
|
|
784
|
-
return [
|
|
785
|
-
result,
|
|
786
|
-
[]
|
|
787
|
-
];
|
|
788
|
-
}
|
|
789
|
-
};
|
|
790
|
-
|
|
791
|
-
// src/DataLake/ArchivistXyoDataLake.ts
|
|
792
|
-
import { assertEx as assertEx8 } from "@xylabs/assert";
|
|
793
|
-
import { isAnyPayload as isAnyPayload2 } from "@xyo-network/payload-model";
|
|
794
|
-
var ArchivistXyoDataLake = class extends AbstractXyoDataLake {
|
|
795
|
-
static {
|
|
796
|
-
__name(this, "ArchivistXyoDataLake");
|
|
797
|
-
}
|
|
798
|
-
_archivist;
|
|
799
|
-
constructor(archivist) {
|
|
800
|
-
super();
|
|
801
|
-
this._archivist = archivist;
|
|
802
|
-
}
|
|
803
|
-
async add(items) {
|
|
804
|
-
const payloads = items.filter(isAnyPayload2);
|
|
805
|
-
assertEx8(payloads.length === items.length, () => "Some items are not payloads");
|
|
806
|
-
return await this._archivist.insert(payloads);
|
|
807
|
-
}
|
|
808
|
-
async get(hashes) {
|
|
809
|
-
return await this._archivist.get(hashes);
|
|
810
|
-
}
|
|
811
|
-
};
|
|
812
|
-
|
|
813
|
-
// src/DataLake/HttpXyoDataLake.ts
|
|
814
|
-
import { assertEx as assertEx9 } from "@xylabs/assert";
|
|
815
|
-
import { AxiosJson } from "@xylabs/axios";
|
|
816
|
-
import { exists as exists3 } from "@xylabs/exists";
|
|
817
|
-
import { isArrayBuffer, isDefined as isDefined2 } from "@xylabs/typeof";
|
|
818
|
-
import { isAnyPayload as isAnyPayload3 } from "@xyo-network/payload-model";
|
|
819
|
-
import { isHashPayload as isHashPayload2 } from "@xyo-network/xl1-protocol";
|
|
820
|
-
import { Axios } from "axios";
|
|
821
|
-
var HttpXyoDataLake = class extends AbstractXyoDataLake {
|
|
822
|
-
static {
|
|
823
|
-
__name(this, "HttpXyoDataLake");
|
|
824
|
-
}
|
|
825
|
-
_axiosGet;
|
|
826
|
-
_axiosInsertBlob;
|
|
827
|
-
_axiosInsertJson;
|
|
828
|
-
_endpoint;
|
|
829
|
-
constructor(endpoint) {
|
|
830
|
-
super();
|
|
831
|
-
this._endpoint = endpoint;
|
|
832
|
-
this._axiosInsertJson = new AxiosJson({
|
|
833
|
-
baseURL: endpoint
|
|
834
|
-
});
|
|
835
|
-
this._axiosInsertBlob = new Axios({
|
|
836
|
-
baseURL: endpoint,
|
|
837
|
-
headers: {
|
|
838
|
-
"Content-Type": "application/octet-stream",
|
|
839
|
-
"Accept": "application/octet-stream"
|
|
840
|
-
}
|
|
841
|
-
});
|
|
842
|
-
this._axiosGet = new Axios({
|
|
843
|
-
baseURL: endpoint,
|
|
844
|
-
headers: {
|
|
845
|
-
"Content-Type": "application/json",
|
|
846
|
-
"Accept": "application/octet-stream, application/json"
|
|
847
|
-
}
|
|
848
|
-
});
|
|
849
|
-
}
|
|
850
|
-
get endpoint() {
|
|
851
|
-
return this._endpoint;
|
|
852
|
-
}
|
|
853
|
-
async add(items) {
|
|
854
|
-
const results = [];
|
|
855
|
-
for (const item of items) {
|
|
856
|
-
if (isAnyPayload3(item)) {
|
|
857
|
-
const result = await this.addPayload(item);
|
|
858
|
-
if (isAnyPayload3(result)) {
|
|
859
|
-
results.push(result);
|
|
860
|
-
} else if (isDefined2(result)) {
|
|
861
|
-
assertEx9(false, () => "Expected result to be a Payload");
|
|
862
|
-
}
|
|
863
|
-
} else if (isArrayBuffer(item)) {
|
|
864
|
-
const result = await this.addArrayBuffer(item);
|
|
865
|
-
if (isAnyPayload3(result)) {
|
|
866
|
-
results.push(result);
|
|
867
|
-
} else if (isDefined2(result)) {
|
|
868
|
-
assertEx9(false, () => "Expected result to be a Payload");
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
return results;
|
|
873
|
-
}
|
|
874
|
-
async get(hashes) {
|
|
875
|
-
return (await Promise.all(hashes.map(async (hash) => {
|
|
876
|
-
return await this.getOne(hash);
|
|
877
|
-
}))).filter(exists3);
|
|
878
|
-
}
|
|
879
|
-
async addArrayBuffer(item) {
|
|
880
|
-
const result = await this._axiosInsertBlob.post("/insert", item);
|
|
881
|
-
if (result.status < 200 || result.status >= 300) {
|
|
882
|
-
throw new Error(`Failed to add items [${result.status}]: ${result.statusText}`);
|
|
883
|
-
}
|
|
884
|
-
if (!isArrayBuffer(result.data)) {
|
|
885
|
-
throw new Error("Invalid response from server (expected a ArrayBuffer)");
|
|
886
|
-
}
|
|
887
|
-
return result.data;
|
|
888
|
-
}
|
|
889
|
-
async addPayload(item) {
|
|
890
|
-
const result = await this._axiosInsertJson.post("/insert", item);
|
|
891
|
-
if (result.status < 200 || result.status >= 300) {
|
|
892
|
-
throw new Error(`Failed to add items [${result.status}]: ${result.statusText}`);
|
|
893
|
-
}
|
|
894
|
-
if (!isAnyPayload3(result.data)) {
|
|
895
|
-
throw new Error("Invalid response from server (expected a Payload)");
|
|
896
|
-
}
|
|
897
|
-
return result.data;
|
|
898
|
-
}
|
|
899
|
-
async fetchOne(hash, maxDepth = Number.MAX_SAFE_INTEGER) {
|
|
900
|
-
if (maxDepth <= 0) {
|
|
901
|
-
return void 0;
|
|
902
|
-
}
|
|
903
|
-
const result = await this.getOne(hash);
|
|
904
|
-
if (isHashPayload2(result)) {
|
|
905
|
-
return await this.fetchOne(result.hash, maxDepth - 1);
|
|
906
|
-
}
|
|
907
|
-
return result;
|
|
908
|
-
}
|
|
909
|
-
getOne(hash) {
|
|
910
|
-
return this._axiosGet.get(`/get/${hash}`).then((response) => {
|
|
911
|
-
if (response.status < 200 || response.status >= 300) {
|
|
912
|
-
throw new Error(`Failed to get item [${response.status}]: ${response.statusText}`);
|
|
913
|
-
}
|
|
914
|
-
if (!isAnyPayload3(response.data)) {
|
|
915
|
-
throw new Error("Invalid response from server (expected a Payload)");
|
|
916
|
-
}
|
|
917
|
-
return response.data;
|
|
918
|
-
});
|
|
919
|
-
}
|
|
920
|
-
};
|
|
921
|
-
|
|
922
674
|
// src/Election/BaseElectionService.ts
|
|
923
|
-
import { assertEx as
|
|
675
|
+
import { assertEx as assertEx8 } from "@xylabs/assert";
|
|
924
676
|
import { creatable as creatable8 } from "@xylabs/creatable";
|
|
925
677
|
import { hexToLast4BytesInt, shuffleWithSeed } from "@xyo-network/chain-utils";
|
|
926
|
-
import { PayloadBuilder as
|
|
927
|
-
function _ts_decorate8(decorators, target, key, desc) {
|
|
928
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
929
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
930
|
-
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;
|
|
931
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
932
|
-
}
|
|
933
|
-
__name(_ts_decorate8, "_ts_decorate");
|
|
678
|
+
import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/payload-builder";
|
|
934
679
|
var BaseElectionService = class extends BaseService {
|
|
935
|
-
static {
|
|
936
|
-
__name(this, "BaseElectionService");
|
|
937
|
-
}
|
|
938
680
|
get chainIterator() {
|
|
939
|
-
return
|
|
681
|
+
return assertEx8(this.params.chainIterator, () => "No chain iterator");
|
|
940
682
|
}
|
|
941
683
|
get chainStakeViewer() {
|
|
942
|
-
return
|
|
684
|
+
return assertEx8(this.params.chainStakeViewer, () => "No chain stake viewer");
|
|
943
685
|
}
|
|
944
686
|
get stakeIntentService() {
|
|
945
|
-
return
|
|
687
|
+
return assertEx8(this.params.stakeIntentService, () => "No staked intent service");
|
|
946
688
|
}
|
|
947
689
|
async getCreatorCommitteeForNextBlock(current) {
|
|
948
690
|
return await this.spanAsync("getCreatorCommitteeForNextBlock", async () => {
|
|
949
691
|
const nextBlock = current.block + 1;
|
|
950
692
|
const candidates = await this.stakeIntentService.getDeclaredCandidatesForBlock(nextBlock, "producer");
|
|
951
|
-
const previousBlockHash = await
|
|
693
|
+
const previousBlockHash = await PayloadBuilder4.hash(current);
|
|
952
694
|
return this.generateCreatorCommittee(candidates, previousBlockHash);
|
|
953
695
|
});
|
|
954
696
|
}
|
|
@@ -959,131 +701,100 @@ var BaseElectionService = class extends BaseService {
|
|
|
959
701
|
return creatorArray.slice(0, maxSize);
|
|
960
702
|
}
|
|
961
703
|
};
|
|
962
|
-
BaseElectionService =
|
|
704
|
+
BaseElectionService = __decorateClass([
|
|
963
705
|
creatable8()
|
|
964
706
|
], BaseElectionService);
|
|
965
707
|
|
|
966
708
|
// src/PendingTransactions/BasePendingTransactions.ts
|
|
967
709
|
import { ValueType } from "@opentelemetry/api";
|
|
968
710
|
import { filterAs, filterAsync } from "@xylabs/array";
|
|
969
|
-
import { assertEx as
|
|
711
|
+
import { assertEx as assertEx9 } from "@xylabs/assert";
|
|
970
712
|
import { creatable as creatable9 } from "@xylabs/creatable";
|
|
971
|
-
import { exists as
|
|
713
|
+
import { exists as exists3 } from "@xylabs/exists";
|
|
972
714
|
import { forget } from "@xylabs/forget";
|
|
973
|
-
import { isDefined as
|
|
715
|
+
import { isDefined as isDefined2, isUndefined } from "@xylabs/typeof";
|
|
974
716
|
import { MemoryArchivist } from "@xyo-network/archivist-memory";
|
|
975
717
|
import { findMostRecentBlock } from "@xyo-network/chain-protocol";
|
|
976
|
-
import {
|
|
718
|
+
import {
|
|
719
|
+
asBlockBoundWitnessWithHashStorageMeta,
|
|
720
|
+
isTransactionBoundWitnessWithStorageMeta
|
|
721
|
+
} from "@xyo-network/xl1-protocol";
|
|
977
722
|
import { TransactionJsonSchemaValidator, validateTransaction } from "@xyo-network/xl1-validation";
|
|
978
723
|
import { Mutex as Mutex2 } from "async-mutex";
|
|
979
724
|
|
|
980
725
|
// src/PendingTransactions/bundledPayloadToHydratedTransaction.ts
|
|
981
|
-
import { PayloadBuilder as
|
|
726
|
+
import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/payload-builder";
|
|
982
727
|
import { asTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol";
|
|
983
|
-
var bundledPayloadToHydratedTransaction =
|
|
984
|
-
const withStorageMeta = await
|
|
728
|
+
var bundledPayloadToHydratedTransaction = async (payload) => {
|
|
729
|
+
const withStorageMeta = await PayloadBuilder5.addStorageMeta(payload.payloads);
|
|
985
730
|
const tx = asTransactionBoundWitnessWithStorageMeta(withStorageMeta.find((p) => p._hash === payload.root));
|
|
986
731
|
if (tx) {
|
|
987
|
-
return [
|
|
988
|
-
tx,
|
|
989
|
-
withStorageMeta.filter((p) => p._hash !== payload.root)
|
|
990
|
-
];
|
|
732
|
+
return [tx, withStorageMeta.filter((p) => p._hash !== payload.root)];
|
|
991
733
|
}
|
|
992
|
-
}
|
|
734
|
+
};
|
|
993
735
|
|
|
994
736
|
// src/PendingTransactions/hydratedTransactionToPayloadBundle.ts
|
|
995
|
-
import { PayloadBuilder as
|
|
737
|
+
import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/payload-builder";
|
|
996
738
|
import { PayloadBundleSchema } from "@xyo-network/payload-model";
|
|
997
739
|
import { flattenHydratedTransaction } from "@xyo-network/xl1-protocol-sdk";
|
|
998
|
-
var hydratedTransactionToPayloadBundle =
|
|
740
|
+
var hydratedTransactionToPayloadBundle = (transaction) => {
|
|
999
741
|
const root = transaction[0]._hash;
|
|
1000
742
|
return bundle(root, transaction);
|
|
1001
|
-
}
|
|
1002
|
-
var bundle =
|
|
1003
|
-
const payloads = flattenHydratedTransaction(transaction).flatMap((p) =>
|
|
1004
|
-
return new
|
|
1005
|
-
|
|
1006
|
-
}).fields({
|
|
1007
|
-
payloads,
|
|
1008
|
-
root
|
|
1009
|
-
}).build();
|
|
1010
|
-
}, "bundle");
|
|
743
|
+
};
|
|
744
|
+
var bundle = (root, transaction) => {
|
|
745
|
+
const payloads = flattenHydratedTransaction(transaction).flatMap((p) => PayloadBuilder6.omitStorageMeta(p));
|
|
746
|
+
return new PayloadBuilder6({ schema: PayloadBundleSchema }).fields({ payloads, root }).build();
|
|
747
|
+
};
|
|
1011
748
|
|
|
1012
749
|
// src/PendingTransactions/BasePendingTransactions.ts
|
|
1013
|
-
|
|
1014
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1015
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1016
|
-
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;
|
|
1017
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1018
|
-
}
|
|
1019
|
-
__name(_ts_decorate9, "_ts_decorate");
|
|
1020
|
-
var BasePendingTransactionsService = class _BasePendingTransactionsService extends BaseService {
|
|
1021
|
-
static {
|
|
1022
|
-
__name(this, "BasePendingTransactionsService");
|
|
1023
|
-
}
|
|
1024
|
-
static MutexPriority = {
|
|
1025
|
-
/**
|
|
1026
|
-
* Priority for inserting new transactions
|
|
1027
|
-
*/
|
|
1028
|
-
InsertNewTransactions: 5,
|
|
1029
|
-
/**
|
|
1030
|
-
* Priority for reading pending transactions
|
|
1031
|
-
*/
|
|
1032
|
-
ReadTransactions: 3,
|
|
1033
|
-
/**
|
|
1034
|
-
* Priority for removing finalized/expired/rejected transactions
|
|
1035
|
-
*/
|
|
1036
|
-
PurgeTransactions: 1
|
|
1037
|
-
};
|
|
750
|
+
var BasePendingTransactionsService = class extends BaseService {
|
|
1038
751
|
/**
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
752
|
+
* A mutex to ensure that the counting the number of pending transactions is
|
|
753
|
+
* not called concurrently
|
|
754
|
+
*/
|
|
1042
755
|
_countPendingTransactionsMutex = new Mutex2();
|
|
1043
756
|
/**
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
757
|
+
* A local Archivist optimized for fast retrieval that stores only validated
|
|
758
|
+
* pending transactions
|
|
759
|
+
*/
|
|
1047
760
|
_curatedPendingBundledTransactionsArchivist;
|
|
1048
761
|
/**
|
|
1049
|
-
|
|
1050
|
-
|
|
762
|
+
* The last count of total pending transactions
|
|
763
|
+
*/
|
|
1051
764
|
_pendingTransactionsCount = 0;
|
|
1052
765
|
/**
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
766
|
+
* A set of transaction hashes that are pending removal from the
|
|
767
|
+
* curated pending transactions archivist. This is used to track
|
|
768
|
+
* which transactions need to be removed from the archivist.
|
|
769
|
+
*/
|
|
1057
770
|
_removablePendingTransactionHashes = /* @__PURE__ */ new Set();
|
|
1058
771
|
/**
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
772
|
+
* A mutex to ensure that the curated pending transactions archivist is
|
|
773
|
+
* updated in a thread-safe manner
|
|
774
|
+
*/
|
|
1062
775
|
_updateCuratedPendingTransactionsArchivistMutex = new Mutex2();
|
|
1063
776
|
get chainArchivist() {
|
|
1064
|
-
return
|
|
777
|
+
return assertEx9(this.params.chainArchivist, () => "No completed blocks with data archivist");
|
|
1065
778
|
}
|
|
1066
779
|
get chainId() {
|
|
1067
|
-
return
|
|
780
|
+
return assertEx9(this.params.chainId, () => "No chain id");
|
|
1068
781
|
}
|
|
1069
782
|
get pendingBundledTransactionsArchivist() {
|
|
1070
|
-
return
|
|
783
|
+
return assertEx9(this.params.pendingBundledTransactionsArchivist, () => "No pending bundled transactions archivist");
|
|
1071
784
|
}
|
|
1072
785
|
get pendingBundledTransactionsLocalArchivist() {
|
|
1073
|
-
return
|
|
786
|
+
return assertEx9(this._curatedPendingBundledTransactionsArchivist, () => "No pending bundled transactions curated archivist");
|
|
1074
787
|
}
|
|
1075
788
|
get pendingTransactionsCount() {
|
|
1076
789
|
forget(this.countPendingTransactions());
|
|
1077
790
|
return this._pendingTransactionsCount;
|
|
1078
791
|
}
|
|
1079
792
|
get rejectedTransactionsArchivist() {
|
|
1080
|
-
return
|
|
793
|
+
return assertEx9(this.params.rejectedTransactionsArchivist, () => "No rejected transactions archivist");
|
|
1081
794
|
}
|
|
1082
795
|
async createHandler() {
|
|
1083
796
|
await super.createHandler();
|
|
1084
|
-
this._curatedPendingBundledTransactionsArchivist = await MemoryArchivist.create({
|
|
1085
|
-
account: "random"
|
|
1086
|
-
});
|
|
797
|
+
this._curatedPendingBundledTransactionsArchivist = await MemoryArchivist.create({ account: "random" });
|
|
1087
798
|
this.pendingBundledTransactionsArchivist.on("inserted", ({ payloads }) => {
|
|
1088
799
|
forget(this.insertNewTransactions(payloads));
|
|
1089
800
|
});
|
|
@@ -1095,11 +806,14 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1095
806
|
this.markAnyIncludedTransactionsForRemoval(payloads);
|
|
1096
807
|
forget(this.cleanupWorker());
|
|
1097
808
|
});
|
|
1098
|
-
const pendingTransactionsCounter = this.meter?.createObservableUpDownCounter(
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
809
|
+
const pendingTransactionsCounter = this.meter?.createObservableUpDownCounter(
|
|
810
|
+
"xyo_pending_transactions_counter",
|
|
811
|
+
{
|
|
812
|
+
description: "The current number of pending transactions",
|
|
813
|
+
valueType: ValueType.INT,
|
|
814
|
+
unit: "1"
|
|
815
|
+
}
|
|
816
|
+
);
|
|
1103
817
|
pendingTransactionsCounter?.addCallback((observer) => {
|
|
1104
818
|
observer.observe(this.pendingTransactionsCount);
|
|
1105
819
|
});
|
|
@@ -1107,9 +821,7 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1107
821
|
async getPendingTransactions(head, limit) {
|
|
1108
822
|
return await this.spanAsync("getPendingTransactions", async () => {
|
|
1109
823
|
return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
|
|
1110
|
-
let [lastHead] = filterAs(await this.chainArchivist.get([
|
|
1111
|
-
head
|
|
1112
|
-
]), asBlockBoundWitnessWithHashStorageMeta);
|
|
824
|
+
let [lastHead] = filterAs(await this.chainArchivist.get([head]), asBlockBoundWitnessWithHashStorageMeta);
|
|
1113
825
|
if (isUndefined(lastHead)) return [];
|
|
1114
826
|
await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash);
|
|
1115
827
|
const foundPendingTransactions = [];
|
|
@@ -1123,7 +835,9 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1123
835
|
if (pendingBundledTransactions.length === 0) break;
|
|
1124
836
|
cursor = pendingBundledTransactions.at(-1)?._sequence;
|
|
1125
837
|
const undeletedTransactionBundles = pendingBundledTransactions.filter((tx) => !this._removablePendingTransactionHashes.has(tx.root));
|
|
1126
|
-
const transactions = (await Promise.all(
|
|
838
|
+
const transactions = (await Promise.all(
|
|
839
|
+
undeletedTransactionBundles.map((p) => bundledPayloadToHydratedTransaction(p))
|
|
840
|
+
)).filter(exists3);
|
|
1127
841
|
const activeTransactions = transactions.filter(isTransactionActive(lastHead.block + 1));
|
|
1128
842
|
foundPendingTransactions.push(...activeTransactions);
|
|
1129
843
|
}
|
|
@@ -1134,14 +848,14 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1134
848
|
}
|
|
1135
849
|
}
|
|
1136
850
|
return foundPendingTransactions;
|
|
1137
|
-
},
|
|
851
|
+
}, BasePendingTransactionsService.MutexPriority.ReadTransactions);
|
|
1138
852
|
});
|
|
1139
853
|
}
|
|
1140
854
|
async cleanupWorker() {
|
|
1141
855
|
return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
|
|
1142
856
|
const lastHead = await findMostRecentBlock(this.chainArchivist);
|
|
1143
|
-
if (
|
|
1144
|
-
},
|
|
857
|
+
if (isDefined2(lastHead)) await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash);
|
|
858
|
+
}, BasePendingTransactionsService.MutexPriority.PurgeTransactions);
|
|
1145
859
|
}
|
|
1146
860
|
async countPendingTransactions() {
|
|
1147
861
|
if (this._countPendingTransactionsMutex.isLocked()) return;
|
|
@@ -1164,11 +878,9 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1164
878
|
const unprocessedTransactions = await this.filterAlreadyFinalizedTransactions(payloads);
|
|
1165
879
|
const hydratedUnprocessedTransactions = (await Promise.all(unprocessedTransactions.map(async (tx) => {
|
|
1166
880
|
return await bundledPayloadToHydratedTransaction(tx);
|
|
1167
|
-
}))).filter(
|
|
881
|
+
}))).filter(exists3);
|
|
1168
882
|
const validTransactions = await filterAsync(hydratedUnprocessedTransactions, async (tx) => {
|
|
1169
|
-
const errors = await validateTransaction(tx, this.chainId, [
|
|
1170
|
-
TransactionJsonSchemaValidator
|
|
1171
|
-
]);
|
|
883
|
+
const errors = await validateTransaction(tx, this.chainId, [TransactionJsonSchemaValidator]);
|
|
1172
884
|
if (errors.length > 0) {
|
|
1173
885
|
this.logger?.warn("validateTransaction", errors);
|
|
1174
886
|
}
|
|
@@ -1178,15 +890,15 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1178
890
|
const bundledTransactions = validTransactions.map((tx) => hydratedTransactionToPayloadBundle(tx));
|
|
1179
891
|
await this.pendingBundledTransactionsLocalArchivist.insert(bundledTransactions);
|
|
1180
892
|
}
|
|
1181
|
-
},
|
|
893
|
+
}, BasePendingTransactionsService.MutexPriority.InsertNewTransactions);
|
|
1182
894
|
});
|
|
1183
895
|
}
|
|
1184
896
|
/**
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
897
|
+
* Marks any included transactions in the provided payloads for removal preventing them
|
|
898
|
+
* from being included in the curated pending transactions archivist and from being offered
|
|
899
|
+
* during the next retrieval of pending transactions.
|
|
900
|
+
* @param payloads An array of payloads that may contain transactions.
|
|
901
|
+
*/
|
|
1190
902
|
markAnyIncludedTransactionsForRemoval(payloads) {
|
|
1191
903
|
const hashes = payloads.filter(isTransactionBoundWitnessWithStorageMeta).map((p) => p._hash);
|
|
1192
904
|
for (const hash of hashes) {
|
|
@@ -1197,10 +909,8 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1197
909
|
return await this.spanAsync("pruneCuratedPendingTransactionsArchivist", async () => {
|
|
1198
910
|
const foundPendingTransactionsToDeleteHashes = [];
|
|
1199
911
|
let cursor;
|
|
1200
|
-
let [lastHead] = filterAs(await this.chainArchivist.get([
|
|
1201
|
-
|
|
1202
|
-
]), asBlockBoundWitnessWithHashStorageMeta);
|
|
1203
|
-
while (isDefined3(lastHead)) {
|
|
912
|
+
let [lastHead] = filterAs(await this.chainArchivist.get([head]), asBlockBoundWitnessWithHashStorageMeta);
|
|
913
|
+
while (isDefined2(lastHead)) {
|
|
1204
914
|
const pendingBundledTransactions = await this.pendingBundledTransactionsLocalArchivist.next({
|
|
1205
915
|
limit: 100,
|
|
1206
916
|
order: "asc",
|
|
@@ -1211,14 +921,18 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1211
921
|
}
|
|
1212
922
|
cursor = pendingBundledTransactions.at(-1)?._sequence;
|
|
1213
923
|
const deletedTransactionBundles = pendingBundledTransactions.filter((tx) => this._removablePendingTransactionHashes.has(tx.root));
|
|
1214
|
-
foundPendingTransactionsToDeleteHashes.push(
|
|
924
|
+
foundPendingTransactionsToDeleteHashes.push(
|
|
925
|
+
...deletedTransactionBundles.map((tx) => tx._hash).filter(exists3)
|
|
926
|
+
);
|
|
1215
927
|
const undeletedTransactionBundles = pendingBundledTransactions.filter((tx) => !this._removablePendingTransactionHashes.has(tx.root));
|
|
1216
|
-
const transactions = (await Promise.all(
|
|
928
|
+
const transactions = (await Promise.all(
|
|
929
|
+
undeletedTransactionBundles.map((p) => bundledPayloadToHydratedTransaction(p))
|
|
930
|
+
)).filter(exists3);
|
|
1217
931
|
const expiredTransactions = transactions.filter(isTransactionExpired(lastHead.block + 1));
|
|
1218
932
|
const expiredBundleHashes = expiredTransactions.map((expiredHydratedTx) => (
|
|
1219
933
|
// Find the corresponding payload bundle hash for the expired transaction
|
|
1220
934
|
pendingBundledTransactions.find((bundledTx) => bundledTx.root === expiredHydratedTx[0]._hash)?._hash
|
|
1221
|
-
)).filter(
|
|
935
|
+
)).filter(exists3);
|
|
1222
936
|
foundPendingTransactionsToDeleteHashes.push(...expiredBundleHashes);
|
|
1223
937
|
}
|
|
1224
938
|
const deletedHashes = await this.pendingBundledTransactionsLocalArchivist.delete(foundPendingTransactionsToDeleteHashes);
|
|
@@ -1234,65 +948,86 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1234
948
|
});
|
|
1235
949
|
}
|
|
1236
950
|
};
|
|
1237
|
-
BasePendingTransactionsService
|
|
951
|
+
__publicField(BasePendingTransactionsService, "MutexPriority", {
|
|
952
|
+
/**
|
|
953
|
+
* Priority for inserting new transactions
|
|
954
|
+
*/
|
|
955
|
+
InsertNewTransactions: 5,
|
|
956
|
+
/**
|
|
957
|
+
* Priority for reading pending transactions
|
|
958
|
+
*/
|
|
959
|
+
ReadTransactions: 3,
|
|
960
|
+
/**
|
|
961
|
+
* Priority for removing finalized/expired/rejected transactions
|
|
962
|
+
*/
|
|
963
|
+
PurgeTransactions: 1
|
|
964
|
+
});
|
|
965
|
+
BasePendingTransactionsService = __decorateClass([
|
|
1238
966
|
creatable9()
|
|
1239
967
|
], BasePendingTransactionsService);
|
|
1240
|
-
var isTransactionExpired =
|
|
1241
|
-
var isTransactionActive =
|
|
968
|
+
var isTransactionExpired = (block) => ([txBw]) => txBw.exp < block;
|
|
969
|
+
var isTransactionActive = (block) => ([txBw]) => txBw.nbf <= block && txBw.exp >= block;
|
|
1242
970
|
|
|
1243
971
|
// src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts
|
|
1244
972
|
import { filterAs as filterAs2 } from "@xylabs/array";
|
|
1245
|
-
import { exists as
|
|
973
|
+
import { exists as exists4 } from "@xylabs/exists";
|
|
1246
974
|
import { asOptionalBoundWitness } from "@xyo-network/boundwitness-model";
|
|
1247
975
|
import { payloadSchemasContains } from "@xyo-network/boundwitness-validator";
|
|
1248
976
|
import { BoundWitnessWrapper } from "@xyo-network/boundwitness-wrapper";
|
|
1249
977
|
import { asChainStakeIntent, ChainStakeIntentSchema } from "@xyo-network/xl1-protocol";
|
|
1250
|
-
var getBlockSignedStakeDeclarations =
|
|
978
|
+
var getBlockSignedStakeDeclarations = async (block, archivist, intent) => {
|
|
1251
979
|
const blockData = await archivist.get(block.payload_hashes);
|
|
1252
980
|
const bwsFromBlock = filterAs2(blockData, asOptionalBoundWitness);
|
|
1253
981
|
const bwsFromBlockWithDeclarations = bwsFromBlock.filter((bw) => payloadSchemasContains(bw, ChainStakeIntentSchema));
|
|
1254
982
|
const validBlockBwsWithDeclarations = await filterToValidSignedBoundWitnesses(bwsFromBlockWithDeclarations);
|
|
1255
983
|
return (await Promise.all(validBlockBwsWithDeclarations.map(async (bw) => {
|
|
1256
|
-
const stakeIntentHashes = validBlockBwsWithDeclarations.flatMap(mapBoundWitnessToStakeIntentHashes).filter(
|
|
984
|
+
const stakeIntentHashes = validBlockBwsWithDeclarations.flatMap(mapBoundWitnessToStakeIntentHashes).filter(exists4);
|
|
1257
985
|
const payloads = await archivist.get(stakeIntentHashes);
|
|
1258
986
|
const stakeIntents = filterAs2(payloads, asChainStakeIntent).filter((p) => p.intent === intent).filter((p) => bw.addresses.includes(p.from));
|
|
1259
987
|
return stakeIntents;
|
|
1260
988
|
}))).flat();
|
|
1261
|
-
}
|
|
1262
|
-
var filterToValidSignedBoundWitnesses =
|
|
989
|
+
};
|
|
990
|
+
var filterToValidSignedBoundWitnesses = async (bws) => {
|
|
1263
991
|
const validBwIndexes = await Promise.all(bws.map((bw) => BoundWitnessWrapper.parse(bw).getValid()));
|
|
1264
992
|
return bws.filter((_, index) => validBwIndexes[index]);
|
|
1265
|
-
}
|
|
1266
|
-
var mapBoundWitnessToStakeIntentHashes =
|
|
993
|
+
};
|
|
994
|
+
var mapBoundWitnessToStakeIntentHashes = (bw) => {
|
|
1267
995
|
return bw.payload_schemas.map((schema, index) => schema === ChainStakeIntentSchema ? bw.payload_hashes[index] : void 0);
|
|
1268
|
-
}
|
|
996
|
+
};
|
|
1269
997
|
|
|
1270
998
|
// src/StakeIntent/XyoStakeIntentService.ts
|
|
1271
999
|
import { filterAs as filterAs3 } from "@xylabs/array";
|
|
1272
|
-
import { assertEx as
|
|
1000
|
+
import { assertEx as assertEx10 } from "@xylabs/assert";
|
|
1273
1001
|
import { creatable as creatable10 } from "@xylabs/creatable";
|
|
1274
|
-
import {
|
|
1002
|
+
import {
|
|
1003
|
+
asAddress
|
|
1004
|
+
} from "@xylabs/hex";
|
|
1275
1005
|
import { isUndefined as isUndefined2 } from "@xylabs/typeof";
|
|
1276
|
-
import {
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1006
|
+
import {
|
|
1007
|
+
analyzeChain,
|
|
1008
|
+
ChainStakeIntentAnalyzer,
|
|
1009
|
+
isChainSummaryStakeIntent
|
|
1010
|
+
} from "@xyo-network/chain-analyze";
|
|
1011
|
+
import {
|
|
1012
|
+
DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS,
|
|
1013
|
+
findFirstMatching,
|
|
1014
|
+
IntervalMap
|
|
1015
|
+
} from "@xyo-network/chain-utils";
|
|
1016
|
+
import { PayloadBuilder as PayloadBuilder7 } from "@xyo-network/payload-builder";
|
|
1017
|
+
import {
|
|
1018
|
+
asBlockBoundWitness as asBlockBoundWitness3,
|
|
1019
|
+
asBlockBoundWitnessWithStorageMeta,
|
|
1020
|
+
asChainIndexingServiceStateWithStorageMeta,
|
|
1021
|
+
asChainStakeIntent as asChainStakeIntent2,
|
|
1022
|
+
ChainIndexingServiceStateSchema,
|
|
1023
|
+
isChainIndexingServiceState
|
|
1024
|
+
} from "@xyo-network/xl1-protocol";
|
|
1280
1025
|
import { Mutex as Mutex3 } from "async-mutex";
|
|
1281
1026
|
import { LRUCache as LRUCache3 } from "lru-cache";
|
|
1282
|
-
function _ts_decorate10(decorators, target, key, desc) {
|
|
1283
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1284
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1285
|
-
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;
|
|
1286
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1287
|
-
}
|
|
1288
|
-
__name(_ts_decorate10, "_ts_decorate");
|
|
1289
1027
|
var ACTIVE_STAKE_TTL = 1e3 * 60 * 60 * 2;
|
|
1290
1028
|
var NO_ACTIVE_STAKE_TTL = 1e3 * 2;
|
|
1291
1029
|
var STAKE_CACHE_MAX_ENTRIES = 1e4;
|
|
1292
1030
|
var XyoStakeIntentService = class extends BaseService {
|
|
1293
|
-
static {
|
|
1294
|
-
__name(this, "XyoStakeIntentService");
|
|
1295
|
-
}
|
|
1296
1031
|
// TODO: Use hash instead of block number to handle chain reorgs
|
|
1297
1032
|
_lastIndexedBlockHash = void 0;
|
|
1298
1033
|
// TODO: Interval tree per declaration (bank, validator, etc.)
|
|
@@ -1303,21 +1038,19 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1303
1038
|
// in performance for small sets, and (most importantly) easily
|
|
1304
1039
|
// persisted so we can recover state on restart.
|
|
1305
1040
|
_producers = new IntervalMap();
|
|
1306
|
-
_stakeCache = new LRUCache3({
|
|
1307
|
-
max: STAKE_CACHE_MAX_ENTRIES
|
|
1308
|
-
});
|
|
1041
|
+
_stakeCache = new LRUCache3({ max: STAKE_CACHE_MAX_ENTRIES });
|
|
1309
1042
|
_updateMutex = new Mutex3();
|
|
1310
1043
|
get chainArchivist() {
|
|
1311
|
-
return
|
|
1044
|
+
return assertEx10(this.params.chainArchivist, () => "chainArchivist not set");
|
|
1312
1045
|
}
|
|
1313
1046
|
get chainIterator() {
|
|
1314
|
-
return
|
|
1047
|
+
return assertEx10(this.params.chainIterator, () => "chainIterator not set");
|
|
1315
1048
|
}
|
|
1316
1049
|
get chainStakeViewer() {
|
|
1317
|
-
return
|
|
1050
|
+
return assertEx10(this.params.chainStakeViewer, () => "chainStakeViewer not set");
|
|
1318
1051
|
}
|
|
1319
1052
|
get stakeIntentStateArchivist() {
|
|
1320
|
-
return
|
|
1053
|
+
return assertEx10(this.params.stakeIntentStateArchivist, () => "stakeIntentStateArchivist not set");
|
|
1321
1054
|
}
|
|
1322
1055
|
async createHandler() {
|
|
1323
1056
|
this.chainIterator.on("headUpdated", async () => {
|
|
@@ -1325,22 +1058,20 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1325
1058
|
});
|
|
1326
1059
|
const head = await this.chainIterator.head();
|
|
1327
1060
|
if (isUndefined2(head)) return;
|
|
1328
|
-
const headHash = await
|
|
1061
|
+
const headHash = await PayloadBuilder7.hash(head);
|
|
1329
1062
|
await this.recoverState(headHash);
|
|
1330
1063
|
}
|
|
1331
1064
|
async getDeclaredCandidateRanges(address, intent) {
|
|
1332
1065
|
await Promise.resolve();
|
|
1333
|
-
|
|
1066
|
+
assertEx10(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
|
|
1334
1067
|
const results = this._producers.get(address);
|
|
1335
1068
|
return results ?? [];
|
|
1336
1069
|
}
|
|
1337
1070
|
async getDeclaredCandidatesForBlock(block, intent) {
|
|
1338
1071
|
return await this.spanAsync("getDeclaredCandidatesForBlock", async () => {
|
|
1339
|
-
|
|
1072
|
+
assertEx10(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
|
|
1340
1073
|
const results = this._producers.findAllContaining(block);
|
|
1341
|
-
const candidates = [
|
|
1342
|
-
...results
|
|
1343
|
-
];
|
|
1074
|
+
const candidates = [...results];
|
|
1344
1075
|
const requiredMinimumStake = this.getRequiredMinimumStakeForIntent(intent);
|
|
1345
1076
|
const validCandidates = await this.filterToValidStake(candidates, this.chainStakeViewer, requiredMinimumStake);
|
|
1346
1077
|
return validCandidates;
|
|
@@ -1362,62 +1093,41 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1362
1093
|
await this.updateIndex(true);
|
|
1363
1094
|
}
|
|
1364
1095
|
async filterToValidStake(candidates, chainStakeViewer, requiredMinimumStake) {
|
|
1365
|
-
const candidatesWithStake = await Promise.all(
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
ttl: ACTIVE_STAKE_TTL
|
|
1372
|
-
}
|
|
1096
|
+
const candidatesWithStake = await Promise.all(
|
|
1097
|
+
candidates.map(async (candidate) => {
|
|
1098
|
+
const stake = this._stakeCache.get(candidate);
|
|
1099
|
+
if (stake === void 0) {
|
|
1100
|
+
const activeStake = await chainStakeViewer.activeByAddressStaked(`${candidate}`);
|
|
1101
|
+
if (activeStake > 0n) {
|
|
1102
|
+
this._stakeCache.set(candidate, activeStake, { ttl: ACTIVE_STAKE_TTL });
|
|
1103
|
+
} else {
|
|
1104
|
+
this._stakeCache.set(candidate, activeStake, { ttl: NO_ACTIVE_STAKE_TTL });
|
|
1105
|
+
}
|
|
1106
|
+
return { candidate, stake: activeStake };
|
|
1373
1107
|
} else {
|
|
1374
|
-
|
|
1375
|
-
ttl: NO_ACTIVE_STAKE_TTL
|
|
1376
|
-
});
|
|
1108
|
+
return { candidate, stake };
|
|
1377
1109
|
}
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
stake: activeStake
|
|
1381
|
-
};
|
|
1382
|
-
} else {
|
|
1383
|
-
return {
|
|
1384
|
-
candidate,
|
|
1385
|
-
stake
|
|
1386
|
-
};
|
|
1387
|
-
}
|
|
1388
|
-
}));
|
|
1110
|
+
})
|
|
1111
|
+
);
|
|
1389
1112
|
return candidatesWithStake.filter(({ stake }) => stake >= requiredMinimumStake).map(({ candidate }) => candidate);
|
|
1390
1113
|
}
|
|
1391
1114
|
async persistState(current) {
|
|
1392
1115
|
const state = this._producers.serialize();
|
|
1393
|
-
const payload = new
|
|
1394
|
-
|
|
1395
|
-
}).fields({
|
|
1396
|
-
endBlockHash: current,
|
|
1397
|
-
state
|
|
1398
|
-
}).build();
|
|
1399
|
-
await this.stakeIntentStateArchivist.insert([
|
|
1400
|
-
payload
|
|
1401
|
-
]);
|
|
1116
|
+
const payload = new PayloadBuilder7({ schema: ChainIndexingServiceStateSchema }).fields({ endBlockHash: current, state }).build();
|
|
1117
|
+
await this.stakeIntentStateArchivist.insert([payload]);
|
|
1402
1118
|
}
|
|
1403
1119
|
async recoverState(current) {
|
|
1404
|
-
const currentBlock =
|
|
1405
|
-
current
|
|
1406
|
-
]))?.[0]), () => `Block ${current} not found`);
|
|
1120
|
+
const currentBlock = assertEx10(asBlockBoundWitness3((await this.chainArchivist.get([current]))?.[0]), () => `Block ${current} not found`);
|
|
1407
1121
|
const currentBlockNum = currentBlock.block;
|
|
1408
|
-
const opts = {
|
|
1409
|
-
...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS
|
|
1410
|
-
};
|
|
1122
|
+
const opts = { ...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS };
|
|
1411
1123
|
while (true) {
|
|
1412
|
-
const predicate =
|
|
1124
|
+
const predicate = (p) => {
|
|
1413
1125
|
const state2 = asChainIndexingServiceStateWithStorageMeta(p);
|
|
1414
1126
|
return state2 ? true : false;
|
|
1415
|
-
}
|
|
1127
|
+
};
|
|
1416
1128
|
const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts);
|
|
1417
1129
|
if (isChainIndexingServiceState(state)) {
|
|
1418
|
-
const indexed = (await this.chainArchivist.get([
|
|
1419
|
-
state.endBlockHash
|
|
1420
|
-
]))?.[0];
|
|
1130
|
+
const indexed = (await this.chainArchivist.get([state.endBlockHash]))?.[0];
|
|
1421
1131
|
const indexedBlock = asBlockBoundWitnessWithStorageMeta(indexed);
|
|
1422
1132
|
if (indexedBlock) {
|
|
1423
1133
|
const indexedBlockNum = indexedBlock.block;
|
|
@@ -1442,10 +1152,8 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1442
1152
|
return await this.spanAsync("updateIndex", async () => {
|
|
1443
1153
|
const currentHead = await this.chainIterator.head();
|
|
1444
1154
|
if (isUndefined2(currentHead)) return;
|
|
1445
|
-
const currentHeadHash = await
|
|
1446
|
-
const result = await analyzeChain(this.chainArchivist, [
|
|
1447
|
-
new ChainStakeIntentAnalyzer("producer")
|
|
1448
|
-
], currentHeadHash, this._lastIndexedBlockHash);
|
|
1155
|
+
const currentHeadHash = await PayloadBuilder7.hash(currentHead);
|
|
1156
|
+
const result = await analyzeChain(this.chainArchivist, [new ChainStakeIntentAnalyzer("producer")], currentHeadHash, this._lastIndexedBlockHash);
|
|
1449
1157
|
const signedDeclarations = filterAs3(result.find(isChainSummaryStakeIntent)?.intents ?? [], asChainStakeIntent2);
|
|
1450
1158
|
if (currentHead.block === void 0) return;
|
|
1451
1159
|
const currentHeadBlockNum = currentHead.block;
|
|
@@ -1464,12 +1172,10 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1464
1172
|
});
|
|
1465
1173
|
}
|
|
1466
1174
|
};
|
|
1467
|
-
XyoStakeIntentService =
|
|
1175
|
+
XyoStakeIntentService = __decorateClass([
|
|
1468
1176
|
creatable10()
|
|
1469
1177
|
], XyoStakeIntentService);
|
|
1470
1178
|
export {
|
|
1471
|
-
AbstractXyoDataLake,
|
|
1472
|
-
ArchivistXyoDataLake,
|
|
1473
1179
|
BaseAccountBalanceService,
|
|
1474
1180
|
BaseAccountableService,
|
|
1475
1181
|
BaseBlockProducerService,
|
|
@@ -1481,7 +1187,6 @@ export {
|
|
|
1481
1187
|
DEFAULT_BLOCK_SIZE,
|
|
1482
1188
|
EvmBlockRewardService,
|
|
1483
1189
|
EvmChainService,
|
|
1484
|
-
HttpXyoDataLake,
|
|
1485
1190
|
MemoryBlockRewardService,
|
|
1486
1191
|
MemoryChainService,
|
|
1487
1192
|
XYO_PRODUCER_REDECLARATION_DURATION,
|