@xyo-network/chain-services 1.8.4 → 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/BlockReward/EvmBlockRewardService.d.ts.map +1 -1
- package/dist/neutral/ChainService/Evm/Evm.d.ts.map +1 -1
- package/dist/neutral/index.d.ts +0 -1
- package/dist/neutral/index.d.ts.map +1 -1
- package/dist/neutral/index.mjs +259 -555
- package/dist/neutral/index.mjs.map +1 -1
- package/package.json +46 -49
- package/src/BlockProducer/spec/BaseBlockProducerService.spec.ts +4 -3
- package/src/BlockReward/EvmBlockRewardService.ts +1 -1
- package/src/ChainService/Evm/Evm.ts +1 -2
- 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,47 +320,27 @@ 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
|
|
|
370
338
|
// src/BlockReward/EvmBlockRewardService.ts
|
|
371
339
|
import { assertEx as assertEx3 } from "@xylabs/assert";
|
|
372
340
|
import { creatable as creatable5 } from "@xylabs/creatable";
|
|
373
|
-
import { toEthAddress } from "@
|
|
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,30 +490,25 @@ 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
|
|
|
553
497
|
// src/ChainService/Evm/Evm.ts
|
|
554
498
|
import { assertEx as assertEx6 } from "@xylabs/assert";
|
|
555
|
-
import { toAddress } from "@xylabs/hex";
|
|
556
|
-
import { toEthAddress as toEthAddress2 } from "@xyo-network/chain-ethereum";
|
|
499
|
+
import { toAddress, toEthAddress as toEthAddress2 } from "@xylabs/hex";
|
|
557
500
|
import { StakedXyoChain__factory as StakedXyoChainFactory } from "@xyo-network/typechain";
|
|
558
501
|
import { getAddress } from "ethers/address";
|
|
559
502
|
var EvmChainService = class extends BaseService {
|
|
560
|
-
static {
|
|
561
|
-
__name(this, "EvmChainService");
|
|
562
|
-
}
|
|
563
503
|
get chainId() {
|
|
564
504
|
return assertEx6(this.params.id);
|
|
565
505
|
}
|
|
566
506
|
get contract() {
|
|
567
507
|
if (this.params.contract === void 0) {
|
|
568
|
-
this.params.contract = StakedXyoChainFactory.connect(
|
|
508
|
+
this.params.contract = StakedXyoChainFactory.connect(
|
|
509
|
+
toEthAddress2(this.chainId),
|
|
510
|
+
this.params.runner
|
|
511
|
+
);
|
|
569
512
|
}
|
|
570
513
|
return assertEx6(this.params.contract);
|
|
571
514
|
}
|
|
@@ -631,9 +574,6 @@ var EvmChainService = class extends BaseService {
|
|
|
631
574
|
// src/ChainService/Memory/Memory.ts
|
|
632
575
|
import { ZERO_ADDRESS } from "@xylabs/hex";
|
|
633
576
|
var MemoryChainService = class extends BaseService {
|
|
634
|
-
static {
|
|
635
|
-
__name(this, "MemoryChainService");
|
|
636
|
-
}
|
|
637
577
|
_simulatedStake = 1n;
|
|
638
578
|
get chainId() {
|
|
639
579
|
return ZERO_ADDRESS;
|
|
@@ -695,17 +635,7 @@ var MemoryChainService = class extends BaseService {
|
|
|
695
635
|
// src/ChainValidator/XyoValidator.ts
|
|
696
636
|
import { assertEx as assertEx7 } from "@xylabs/assert";
|
|
697
637
|
import { creatable as creatable7 } from "@xylabs/creatable";
|
|
698
|
-
function _ts_decorate7(decorators, target, key, desc) {
|
|
699
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
700
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
701
|
-
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;
|
|
702
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
703
|
-
}
|
|
704
|
-
__name(_ts_decorate7, "_ts_decorate");
|
|
705
638
|
var XyoValidator = class extends BaseService {
|
|
706
|
-
static {
|
|
707
|
-
__name(this, "XyoValidator");
|
|
708
|
-
}
|
|
709
639
|
get address() {
|
|
710
640
|
return this.account.address;
|
|
711
641
|
}
|
|
@@ -733,223 +663,34 @@ var XyoValidator = class extends BaseService {
|
|
|
733
663
|
// TODO: Move to validator and inherit this class from validator
|
|
734
664
|
async validatePendingTransaction(hydratedTransaction) {
|
|
735
665
|
const [tx] = hydratedTransaction;
|
|
736
|
-
if ((await this.chainArchivist.get([
|
|
737
|
-
tx._hash
|
|
738
|
-
])).length > 0) return false;
|
|
666
|
+
if ((await this.chainArchivist.get([tx._hash])).length > 0) return false;
|
|
739
667
|
return await Promise.resolve(true);
|
|
740
668
|
}
|
|
741
669
|
};
|
|
742
|
-
XyoValidator =
|
|
670
|
+
XyoValidator = __decorateClass([
|
|
743
671
|
creatable7()
|
|
744
672
|
], XyoValidator);
|
|
745
673
|
|
|
746
|
-
// src/DataLake/AbstractXyoDataLake.ts
|
|
747
|
-
import { ObjectHasher } from "@xyo-network/hash";
|
|
748
|
-
import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/payload-builder";
|
|
749
|
-
import { isAnyPayload } from "@xyo-network/payload-model";
|
|
750
|
-
import { isHashPayload } from "@xyo-network/xl1-protocol";
|
|
751
|
-
var AbstractXyoDataLake = class {
|
|
752
|
-
static {
|
|
753
|
-
__name(this, "AbstractXyoDataLake");
|
|
754
|
-
}
|
|
755
|
-
async fetch(hashes, maxDepth = 10) {
|
|
756
|
-
const results = await this.get(hashes);
|
|
757
|
-
if (maxDepth > 0) {
|
|
758
|
-
const hashPayloads = results.filter(isHashPayload);
|
|
759
|
-
const otherPayloads = results.filter((item) => !isHashPayload(item));
|
|
760
|
-
const found = await this.fetch(hashPayloads.map((item) => item.hash), maxDepth - 1);
|
|
761
|
-
const foundHashes = await Promise.all(found.map(async (item) => isAnyPayload(item) ? await PayloadBuilder4.hash(item) : ObjectHasher.hashBytes(item)));
|
|
762
|
-
const notFound = hashPayloads.filter((item) => !foundHashes.includes(item.hash));
|
|
763
|
-
return [
|
|
764
|
-
...otherPayloads,
|
|
765
|
-
...found,
|
|
766
|
-
...notFound
|
|
767
|
-
];
|
|
768
|
-
}
|
|
769
|
-
return results;
|
|
770
|
-
}
|
|
771
|
-
async trace(hash) {
|
|
772
|
-
const [result] = await this.get([
|
|
773
|
-
hash
|
|
774
|
-
]);
|
|
775
|
-
if (isHashPayload(result)) {
|
|
776
|
-
const [payload, route] = await this.trace(result.hash);
|
|
777
|
-
return [
|
|
778
|
-
payload,
|
|
779
|
-
[
|
|
780
|
-
result,
|
|
781
|
-
...route
|
|
782
|
-
]
|
|
783
|
-
];
|
|
784
|
-
}
|
|
785
|
-
return [
|
|
786
|
-
result,
|
|
787
|
-
[]
|
|
788
|
-
];
|
|
789
|
-
}
|
|
790
|
-
};
|
|
791
|
-
|
|
792
|
-
// src/DataLake/ArchivistXyoDataLake.ts
|
|
793
|
-
import { assertEx as assertEx8 } from "@xylabs/assert";
|
|
794
|
-
import { isAnyPayload as isAnyPayload2 } from "@xyo-network/payload-model";
|
|
795
|
-
var ArchivistXyoDataLake = class extends AbstractXyoDataLake {
|
|
796
|
-
static {
|
|
797
|
-
__name(this, "ArchivistXyoDataLake");
|
|
798
|
-
}
|
|
799
|
-
_archivist;
|
|
800
|
-
constructor(archivist) {
|
|
801
|
-
super();
|
|
802
|
-
this._archivist = archivist;
|
|
803
|
-
}
|
|
804
|
-
async add(items) {
|
|
805
|
-
const payloads = items.filter(isAnyPayload2);
|
|
806
|
-
assertEx8(payloads.length === items.length, () => "Some items are not payloads");
|
|
807
|
-
return await this._archivist.insert(payloads);
|
|
808
|
-
}
|
|
809
|
-
async get(hashes) {
|
|
810
|
-
return await this._archivist.get(hashes);
|
|
811
|
-
}
|
|
812
|
-
};
|
|
813
|
-
|
|
814
|
-
// src/DataLake/HttpXyoDataLake.ts
|
|
815
|
-
import { assertEx as assertEx9 } from "@xylabs/assert";
|
|
816
|
-
import { AxiosJson } from "@xylabs/axios";
|
|
817
|
-
import { exists as exists3 } from "@xylabs/exists";
|
|
818
|
-
import { isArrayBuffer, isDefined as isDefined2 } from "@xylabs/typeof";
|
|
819
|
-
import { isAnyPayload as isAnyPayload3 } from "@xyo-network/payload-model";
|
|
820
|
-
import { isHashPayload as isHashPayload2 } from "@xyo-network/xl1-protocol";
|
|
821
|
-
import { Axios } from "axios";
|
|
822
|
-
var HttpXyoDataLake = class extends AbstractXyoDataLake {
|
|
823
|
-
static {
|
|
824
|
-
__name(this, "HttpXyoDataLake");
|
|
825
|
-
}
|
|
826
|
-
_axiosGet;
|
|
827
|
-
_axiosInsertBlob;
|
|
828
|
-
_axiosInsertJson;
|
|
829
|
-
_endpoint;
|
|
830
|
-
constructor(endpoint) {
|
|
831
|
-
super();
|
|
832
|
-
this._endpoint = endpoint;
|
|
833
|
-
this._axiosInsertJson = new AxiosJson({
|
|
834
|
-
baseURL: endpoint
|
|
835
|
-
});
|
|
836
|
-
this._axiosInsertBlob = new Axios({
|
|
837
|
-
baseURL: endpoint,
|
|
838
|
-
headers: {
|
|
839
|
-
"Content-Type": "application/octet-stream",
|
|
840
|
-
"Accept": "application/octet-stream"
|
|
841
|
-
}
|
|
842
|
-
});
|
|
843
|
-
this._axiosGet = new Axios({
|
|
844
|
-
baseURL: endpoint,
|
|
845
|
-
headers: {
|
|
846
|
-
"Content-Type": "application/json",
|
|
847
|
-
"Accept": "application/octet-stream, application/json"
|
|
848
|
-
}
|
|
849
|
-
});
|
|
850
|
-
}
|
|
851
|
-
get endpoint() {
|
|
852
|
-
return this._endpoint;
|
|
853
|
-
}
|
|
854
|
-
async add(items) {
|
|
855
|
-
const results = [];
|
|
856
|
-
for (const item of items) {
|
|
857
|
-
if (isAnyPayload3(item)) {
|
|
858
|
-
const result = await this.addPayload(item);
|
|
859
|
-
if (isAnyPayload3(result)) {
|
|
860
|
-
results.push(result);
|
|
861
|
-
} else if (isDefined2(result)) {
|
|
862
|
-
assertEx9(false, () => "Expected result to be a Payload");
|
|
863
|
-
}
|
|
864
|
-
} else if (isArrayBuffer(item)) {
|
|
865
|
-
const result = await this.addArrayBuffer(item);
|
|
866
|
-
if (isAnyPayload3(result)) {
|
|
867
|
-
results.push(result);
|
|
868
|
-
} else if (isDefined2(result)) {
|
|
869
|
-
assertEx9(false, () => "Expected result to be a Payload");
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
return results;
|
|
874
|
-
}
|
|
875
|
-
async get(hashes) {
|
|
876
|
-
return (await Promise.all(hashes.map(async (hash) => {
|
|
877
|
-
return await this.getOne(hash);
|
|
878
|
-
}))).filter(exists3);
|
|
879
|
-
}
|
|
880
|
-
async addArrayBuffer(item) {
|
|
881
|
-
const result = await this._axiosInsertBlob.post("/insert", item);
|
|
882
|
-
if (result.status < 200 || result.status >= 300) {
|
|
883
|
-
throw new Error(`Failed to add items [${result.status}]: ${result.statusText}`);
|
|
884
|
-
}
|
|
885
|
-
if (!isArrayBuffer(result.data)) {
|
|
886
|
-
throw new Error("Invalid response from server (expected a ArrayBuffer)");
|
|
887
|
-
}
|
|
888
|
-
return result.data;
|
|
889
|
-
}
|
|
890
|
-
async addPayload(item) {
|
|
891
|
-
const result = await this._axiosInsertJson.post("/insert", item);
|
|
892
|
-
if (result.status < 200 || result.status >= 300) {
|
|
893
|
-
throw new Error(`Failed to add items [${result.status}]: ${result.statusText}`);
|
|
894
|
-
}
|
|
895
|
-
if (!isAnyPayload3(result.data)) {
|
|
896
|
-
throw new Error("Invalid response from server (expected a Payload)");
|
|
897
|
-
}
|
|
898
|
-
return result.data;
|
|
899
|
-
}
|
|
900
|
-
async fetchOne(hash, maxDepth = Number.MAX_SAFE_INTEGER) {
|
|
901
|
-
if (maxDepth <= 0) {
|
|
902
|
-
return void 0;
|
|
903
|
-
}
|
|
904
|
-
const result = await this.getOne(hash);
|
|
905
|
-
if (isHashPayload2(result)) {
|
|
906
|
-
return await this.fetchOne(result.hash, maxDepth - 1);
|
|
907
|
-
}
|
|
908
|
-
return result;
|
|
909
|
-
}
|
|
910
|
-
getOne(hash) {
|
|
911
|
-
return this._axiosGet.get(`/get/${hash}`).then((response) => {
|
|
912
|
-
if (response.status < 200 || response.status >= 300) {
|
|
913
|
-
throw new Error(`Failed to get item [${response.status}]: ${response.statusText}`);
|
|
914
|
-
}
|
|
915
|
-
if (!isAnyPayload3(response.data)) {
|
|
916
|
-
throw new Error("Invalid response from server (expected a Payload)");
|
|
917
|
-
}
|
|
918
|
-
return response.data;
|
|
919
|
-
});
|
|
920
|
-
}
|
|
921
|
-
};
|
|
922
|
-
|
|
923
674
|
// src/Election/BaseElectionService.ts
|
|
924
|
-
import { assertEx as
|
|
675
|
+
import { assertEx as assertEx8 } from "@xylabs/assert";
|
|
925
676
|
import { creatable as creatable8 } from "@xylabs/creatable";
|
|
926
677
|
import { hexToLast4BytesInt, shuffleWithSeed } from "@xyo-network/chain-utils";
|
|
927
|
-
import { PayloadBuilder as
|
|
928
|
-
function _ts_decorate8(decorators, target, key, desc) {
|
|
929
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
930
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
931
|
-
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;
|
|
932
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
933
|
-
}
|
|
934
|
-
__name(_ts_decorate8, "_ts_decorate");
|
|
678
|
+
import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/payload-builder";
|
|
935
679
|
var BaseElectionService = class extends BaseService {
|
|
936
|
-
static {
|
|
937
|
-
__name(this, "BaseElectionService");
|
|
938
|
-
}
|
|
939
680
|
get chainIterator() {
|
|
940
|
-
return
|
|
681
|
+
return assertEx8(this.params.chainIterator, () => "No chain iterator");
|
|
941
682
|
}
|
|
942
683
|
get chainStakeViewer() {
|
|
943
|
-
return
|
|
684
|
+
return assertEx8(this.params.chainStakeViewer, () => "No chain stake viewer");
|
|
944
685
|
}
|
|
945
686
|
get stakeIntentService() {
|
|
946
|
-
return
|
|
687
|
+
return assertEx8(this.params.stakeIntentService, () => "No staked intent service");
|
|
947
688
|
}
|
|
948
689
|
async getCreatorCommitteeForNextBlock(current) {
|
|
949
690
|
return await this.spanAsync("getCreatorCommitteeForNextBlock", async () => {
|
|
950
691
|
const nextBlock = current.block + 1;
|
|
951
692
|
const candidates = await this.stakeIntentService.getDeclaredCandidatesForBlock(nextBlock, "producer");
|
|
952
|
-
const previousBlockHash = await
|
|
693
|
+
const previousBlockHash = await PayloadBuilder4.hash(current);
|
|
953
694
|
return this.generateCreatorCommittee(candidates, previousBlockHash);
|
|
954
695
|
});
|
|
955
696
|
}
|
|
@@ -960,131 +701,100 @@ var BaseElectionService = class extends BaseService {
|
|
|
960
701
|
return creatorArray.slice(0, maxSize);
|
|
961
702
|
}
|
|
962
703
|
};
|
|
963
|
-
BaseElectionService =
|
|
704
|
+
BaseElectionService = __decorateClass([
|
|
964
705
|
creatable8()
|
|
965
706
|
], BaseElectionService);
|
|
966
707
|
|
|
967
708
|
// src/PendingTransactions/BasePendingTransactions.ts
|
|
968
709
|
import { ValueType } from "@opentelemetry/api";
|
|
969
710
|
import { filterAs, filterAsync } from "@xylabs/array";
|
|
970
|
-
import { assertEx as
|
|
711
|
+
import { assertEx as assertEx9 } from "@xylabs/assert";
|
|
971
712
|
import { creatable as creatable9 } from "@xylabs/creatable";
|
|
972
|
-
import { exists as
|
|
713
|
+
import { exists as exists3 } from "@xylabs/exists";
|
|
973
714
|
import { forget } from "@xylabs/forget";
|
|
974
|
-
import { isDefined as
|
|
715
|
+
import { isDefined as isDefined2, isUndefined } from "@xylabs/typeof";
|
|
975
716
|
import { MemoryArchivist } from "@xyo-network/archivist-memory";
|
|
976
717
|
import { findMostRecentBlock } from "@xyo-network/chain-protocol";
|
|
977
|
-
import {
|
|
718
|
+
import {
|
|
719
|
+
asBlockBoundWitnessWithHashStorageMeta,
|
|
720
|
+
isTransactionBoundWitnessWithStorageMeta
|
|
721
|
+
} from "@xyo-network/xl1-protocol";
|
|
978
722
|
import { TransactionJsonSchemaValidator, validateTransaction } from "@xyo-network/xl1-validation";
|
|
979
723
|
import { Mutex as Mutex2 } from "async-mutex";
|
|
980
724
|
|
|
981
725
|
// src/PendingTransactions/bundledPayloadToHydratedTransaction.ts
|
|
982
|
-
import { PayloadBuilder as
|
|
726
|
+
import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/payload-builder";
|
|
983
727
|
import { asTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol";
|
|
984
|
-
var bundledPayloadToHydratedTransaction =
|
|
985
|
-
const withStorageMeta = await
|
|
728
|
+
var bundledPayloadToHydratedTransaction = async (payload) => {
|
|
729
|
+
const withStorageMeta = await PayloadBuilder5.addStorageMeta(payload.payloads);
|
|
986
730
|
const tx = asTransactionBoundWitnessWithStorageMeta(withStorageMeta.find((p) => p._hash === payload.root));
|
|
987
731
|
if (tx) {
|
|
988
|
-
return [
|
|
989
|
-
tx,
|
|
990
|
-
withStorageMeta.filter((p) => p._hash !== payload.root)
|
|
991
|
-
];
|
|
732
|
+
return [tx, withStorageMeta.filter((p) => p._hash !== payload.root)];
|
|
992
733
|
}
|
|
993
|
-
}
|
|
734
|
+
};
|
|
994
735
|
|
|
995
736
|
// src/PendingTransactions/hydratedTransactionToPayloadBundle.ts
|
|
996
|
-
import { PayloadBuilder as
|
|
737
|
+
import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/payload-builder";
|
|
997
738
|
import { PayloadBundleSchema } from "@xyo-network/payload-model";
|
|
998
739
|
import { flattenHydratedTransaction } from "@xyo-network/xl1-protocol-sdk";
|
|
999
|
-
var hydratedTransactionToPayloadBundle =
|
|
740
|
+
var hydratedTransactionToPayloadBundle = (transaction) => {
|
|
1000
741
|
const root = transaction[0]._hash;
|
|
1001
742
|
return bundle(root, transaction);
|
|
1002
|
-
}
|
|
1003
|
-
var bundle =
|
|
1004
|
-
const payloads = flattenHydratedTransaction(transaction).flatMap((p) =>
|
|
1005
|
-
return new
|
|
1006
|
-
|
|
1007
|
-
}).fields({
|
|
1008
|
-
payloads,
|
|
1009
|
-
root
|
|
1010
|
-
}).build();
|
|
1011
|
-
}, "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
|
+
};
|
|
1012
748
|
|
|
1013
749
|
// src/PendingTransactions/BasePendingTransactions.ts
|
|
1014
|
-
|
|
1015
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1016
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1017
|
-
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;
|
|
1018
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1019
|
-
}
|
|
1020
|
-
__name(_ts_decorate9, "_ts_decorate");
|
|
1021
|
-
var BasePendingTransactionsService = class _BasePendingTransactionsService extends BaseService {
|
|
1022
|
-
static {
|
|
1023
|
-
__name(this, "BasePendingTransactionsService");
|
|
1024
|
-
}
|
|
1025
|
-
static MutexPriority = {
|
|
1026
|
-
/**
|
|
1027
|
-
* Priority for inserting new transactions
|
|
1028
|
-
*/
|
|
1029
|
-
InsertNewTransactions: 5,
|
|
1030
|
-
/**
|
|
1031
|
-
* Priority for reading pending transactions
|
|
1032
|
-
*/
|
|
1033
|
-
ReadTransactions: 3,
|
|
1034
|
-
/**
|
|
1035
|
-
* Priority for removing finalized/expired/rejected transactions
|
|
1036
|
-
*/
|
|
1037
|
-
PurgeTransactions: 1
|
|
1038
|
-
};
|
|
750
|
+
var BasePendingTransactionsService = class extends BaseService {
|
|
1039
751
|
/**
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
752
|
+
* A mutex to ensure that the counting the number of pending transactions is
|
|
753
|
+
* not called concurrently
|
|
754
|
+
*/
|
|
1043
755
|
_countPendingTransactionsMutex = new Mutex2();
|
|
1044
756
|
/**
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
757
|
+
* A local Archivist optimized for fast retrieval that stores only validated
|
|
758
|
+
* pending transactions
|
|
759
|
+
*/
|
|
1048
760
|
_curatedPendingBundledTransactionsArchivist;
|
|
1049
761
|
/**
|
|
1050
|
-
|
|
1051
|
-
|
|
762
|
+
* The last count of total pending transactions
|
|
763
|
+
*/
|
|
1052
764
|
_pendingTransactionsCount = 0;
|
|
1053
765
|
/**
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
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
|
+
*/
|
|
1058
770
|
_removablePendingTransactionHashes = /* @__PURE__ */ new Set();
|
|
1059
771
|
/**
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
772
|
+
* A mutex to ensure that the curated pending transactions archivist is
|
|
773
|
+
* updated in a thread-safe manner
|
|
774
|
+
*/
|
|
1063
775
|
_updateCuratedPendingTransactionsArchivistMutex = new Mutex2();
|
|
1064
776
|
get chainArchivist() {
|
|
1065
|
-
return
|
|
777
|
+
return assertEx9(this.params.chainArchivist, () => "No completed blocks with data archivist");
|
|
1066
778
|
}
|
|
1067
779
|
get chainId() {
|
|
1068
|
-
return
|
|
780
|
+
return assertEx9(this.params.chainId, () => "No chain id");
|
|
1069
781
|
}
|
|
1070
782
|
get pendingBundledTransactionsArchivist() {
|
|
1071
|
-
return
|
|
783
|
+
return assertEx9(this.params.pendingBundledTransactionsArchivist, () => "No pending bundled transactions archivist");
|
|
1072
784
|
}
|
|
1073
785
|
get pendingBundledTransactionsLocalArchivist() {
|
|
1074
|
-
return
|
|
786
|
+
return assertEx9(this._curatedPendingBundledTransactionsArchivist, () => "No pending bundled transactions curated archivist");
|
|
1075
787
|
}
|
|
1076
788
|
get pendingTransactionsCount() {
|
|
1077
789
|
forget(this.countPendingTransactions());
|
|
1078
790
|
return this._pendingTransactionsCount;
|
|
1079
791
|
}
|
|
1080
792
|
get rejectedTransactionsArchivist() {
|
|
1081
|
-
return
|
|
793
|
+
return assertEx9(this.params.rejectedTransactionsArchivist, () => "No rejected transactions archivist");
|
|
1082
794
|
}
|
|
1083
795
|
async createHandler() {
|
|
1084
796
|
await super.createHandler();
|
|
1085
|
-
this._curatedPendingBundledTransactionsArchivist = await MemoryArchivist.create({
|
|
1086
|
-
account: "random"
|
|
1087
|
-
});
|
|
797
|
+
this._curatedPendingBundledTransactionsArchivist = await MemoryArchivist.create({ account: "random" });
|
|
1088
798
|
this.pendingBundledTransactionsArchivist.on("inserted", ({ payloads }) => {
|
|
1089
799
|
forget(this.insertNewTransactions(payloads));
|
|
1090
800
|
});
|
|
@@ -1096,11 +806,14 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1096
806
|
this.markAnyIncludedTransactionsForRemoval(payloads);
|
|
1097
807
|
forget(this.cleanupWorker());
|
|
1098
808
|
});
|
|
1099
|
-
const pendingTransactionsCounter = this.meter?.createObservableUpDownCounter(
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
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
|
+
);
|
|
1104
817
|
pendingTransactionsCounter?.addCallback((observer) => {
|
|
1105
818
|
observer.observe(this.pendingTransactionsCount);
|
|
1106
819
|
});
|
|
@@ -1108,9 +821,7 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1108
821
|
async getPendingTransactions(head, limit) {
|
|
1109
822
|
return await this.spanAsync("getPendingTransactions", async () => {
|
|
1110
823
|
return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
|
|
1111
|
-
let [lastHead] = filterAs(await this.chainArchivist.get([
|
|
1112
|
-
head
|
|
1113
|
-
]), asBlockBoundWitnessWithHashStorageMeta);
|
|
824
|
+
let [lastHead] = filterAs(await this.chainArchivist.get([head]), asBlockBoundWitnessWithHashStorageMeta);
|
|
1114
825
|
if (isUndefined(lastHead)) return [];
|
|
1115
826
|
await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash);
|
|
1116
827
|
const foundPendingTransactions = [];
|
|
@@ -1124,7 +835,9 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1124
835
|
if (pendingBundledTransactions.length === 0) break;
|
|
1125
836
|
cursor = pendingBundledTransactions.at(-1)?._sequence;
|
|
1126
837
|
const undeletedTransactionBundles = pendingBundledTransactions.filter((tx) => !this._removablePendingTransactionHashes.has(tx.root));
|
|
1127
|
-
const transactions = (await Promise.all(
|
|
838
|
+
const transactions = (await Promise.all(
|
|
839
|
+
undeletedTransactionBundles.map((p) => bundledPayloadToHydratedTransaction(p))
|
|
840
|
+
)).filter(exists3);
|
|
1128
841
|
const activeTransactions = transactions.filter(isTransactionActive(lastHead.block + 1));
|
|
1129
842
|
foundPendingTransactions.push(...activeTransactions);
|
|
1130
843
|
}
|
|
@@ -1135,14 +848,14 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1135
848
|
}
|
|
1136
849
|
}
|
|
1137
850
|
return foundPendingTransactions;
|
|
1138
|
-
},
|
|
851
|
+
}, BasePendingTransactionsService.MutexPriority.ReadTransactions);
|
|
1139
852
|
});
|
|
1140
853
|
}
|
|
1141
854
|
async cleanupWorker() {
|
|
1142
855
|
return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
|
|
1143
856
|
const lastHead = await findMostRecentBlock(this.chainArchivist);
|
|
1144
|
-
if (
|
|
1145
|
-
},
|
|
857
|
+
if (isDefined2(lastHead)) await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash);
|
|
858
|
+
}, BasePendingTransactionsService.MutexPriority.PurgeTransactions);
|
|
1146
859
|
}
|
|
1147
860
|
async countPendingTransactions() {
|
|
1148
861
|
if (this._countPendingTransactionsMutex.isLocked()) return;
|
|
@@ -1165,11 +878,9 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1165
878
|
const unprocessedTransactions = await this.filterAlreadyFinalizedTransactions(payloads);
|
|
1166
879
|
const hydratedUnprocessedTransactions = (await Promise.all(unprocessedTransactions.map(async (tx) => {
|
|
1167
880
|
return await bundledPayloadToHydratedTransaction(tx);
|
|
1168
|
-
}))).filter(
|
|
881
|
+
}))).filter(exists3);
|
|
1169
882
|
const validTransactions = await filterAsync(hydratedUnprocessedTransactions, async (tx) => {
|
|
1170
|
-
const errors = await validateTransaction(tx, this.chainId, [
|
|
1171
|
-
TransactionJsonSchemaValidator
|
|
1172
|
-
]);
|
|
883
|
+
const errors = await validateTransaction(tx, this.chainId, [TransactionJsonSchemaValidator]);
|
|
1173
884
|
if (errors.length > 0) {
|
|
1174
885
|
this.logger?.warn("validateTransaction", errors);
|
|
1175
886
|
}
|
|
@@ -1179,15 +890,15 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1179
890
|
const bundledTransactions = validTransactions.map((tx) => hydratedTransactionToPayloadBundle(tx));
|
|
1180
891
|
await this.pendingBundledTransactionsLocalArchivist.insert(bundledTransactions);
|
|
1181
892
|
}
|
|
1182
|
-
},
|
|
893
|
+
}, BasePendingTransactionsService.MutexPriority.InsertNewTransactions);
|
|
1183
894
|
});
|
|
1184
895
|
}
|
|
1185
896
|
/**
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
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
|
+
*/
|
|
1191
902
|
markAnyIncludedTransactionsForRemoval(payloads) {
|
|
1192
903
|
const hashes = payloads.filter(isTransactionBoundWitnessWithStorageMeta).map((p) => p._hash);
|
|
1193
904
|
for (const hash of hashes) {
|
|
@@ -1198,10 +909,8 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1198
909
|
return await this.spanAsync("pruneCuratedPendingTransactionsArchivist", async () => {
|
|
1199
910
|
const foundPendingTransactionsToDeleteHashes = [];
|
|
1200
911
|
let cursor;
|
|
1201
|
-
let [lastHead] = filterAs(await this.chainArchivist.get([
|
|
1202
|
-
|
|
1203
|
-
]), asBlockBoundWitnessWithHashStorageMeta);
|
|
1204
|
-
while (isDefined3(lastHead)) {
|
|
912
|
+
let [lastHead] = filterAs(await this.chainArchivist.get([head]), asBlockBoundWitnessWithHashStorageMeta);
|
|
913
|
+
while (isDefined2(lastHead)) {
|
|
1205
914
|
const pendingBundledTransactions = await this.pendingBundledTransactionsLocalArchivist.next({
|
|
1206
915
|
limit: 100,
|
|
1207
916
|
order: "asc",
|
|
@@ -1212,14 +921,18 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1212
921
|
}
|
|
1213
922
|
cursor = pendingBundledTransactions.at(-1)?._sequence;
|
|
1214
923
|
const deletedTransactionBundles = pendingBundledTransactions.filter((tx) => this._removablePendingTransactionHashes.has(tx.root));
|
|
1215
|
-
foundPendingTransactionsToDeleteHashes.push(
|
|
924
|
+
foundPendingTransactionsToDeleteHashes.push(
|
|
925
|
+
...deletedTransactionBundles.map((tx) => tx._hash).filter(exists3)
|
|
926
|
+
);
|
|
1216
927
|
const undeletedTransactionBundles = pendingBundledTransactions.filter((tx) => !this._removablePendingTransactionHashes.has(tx.root));
|
|
1217
|
-
const transactions = (await Promise.all(
|
|
928
|
+
const transactions = (await Promise.all(
|
|
929
|
+
undeletedTransactionBundles.map((p) => bundledPayloadToHydratedTransaction(p))
|
|
930
|
+
)).filter(exists3);
|
|
1218
931
|
const expiredTransactions = transactions.filter(isTransactionExpired(lastHead.block + 1));
|
|
1219
932
|
const expiredBundleHashes = expiredTransactions.map((expiredHydratedTx) => (
|
|
1220
933
|
// Find the corresponding payload bundle hash for the expired transaction
|
|
1221
934
|
pendingBundledTransactions.find((bundledTx) => bundledTx.root === expiredHydratedTx[0]._hash)?._hash
|
|
1222
|
-
)).filter(
|
|
935
|
+
)).filter(exists3);
|
|
1223
936
|
foundPendingTransactionsToDeleteHashes.push(...expiredBundleHashes);
|
|
1224
937
|
}
|
|
1225
938
|
const deletedHashes = await this.pendingBundledTransactionsLocalArchivist.delete(foundPendingTransactionsToDeleteHashes);
|
|
@@ -1235,65 +948,86 @@ var BasePendingTransactionsService = class _BasePendingTransactionsService exten
|
|
|
1235
948
|
});
|
|
1236
949
|
}
|
|
1237
950
|
};
|
|
1238
|
-
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([
|
|
1239
966
|
creatable9()
|
|
1240
967
|
], BasePendingTransactionsService);
|
|
1241
|
-
var isTransactionExpired =
|
|
1242
|
-
var isTransactionActive =
|
|
968
|
+
var isTransactionExpired = (block) => ([txBw]) => txBw.exp < block;
|
|
969
|
+
var isTransactionActive = (block) => ([txBw]) => txBw.nbf <= block && txBw.exp >= block;
|
|
1243
970
|
|
|
1244
971
|
// src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts
|
|
1245
972
|
import { filterAs as filterAs2 } from "@xylabs/array";
|
|
1246
|
-
import { exists as
|
|
973
|
+
import { exists as exists4 } from "@xylabs/exists";
|
|
1247
974
|
import { asOptionalBoundWitness } from "@xyo-network/boundwitness-model";
|
|
1248
975
|
import { payloadSchemasContains } from "@xyo-network/boundwitness-validator";
|
|
1249
976
|
import { BoundWitnessWrapper } from "@xyo-network/boundwitness-wrapper";
|
|
1250
977
|
import { asChainStakeIntent, ChainStakeIntentSchema } from "@xyo-network/xl1-protocol";
|
|
1251
|
-
var getBlockSignedStakeDeclarations =
|
|
978
|
+
var getBlockSignedStakeDeclarations = async (block, archivist, intent) => {
|
|
1252
979
|
const blockData = await archivist.get(block.payload_hashes);
|
|
1253
980
|
const bwsFromBlock = filterAs2(blockData, asOptionalBoundWitness);
|
|
1254
981
|
const bwsFromBlockWithDeclarations = bwsFromBlock.filter((bw) => payloadSchemasContains(bw, ChainStakeIntentSchema));
|
|
1255
982
|
const validBlockBwsWithDeclarations = await filterToValidSignedBoundWitnesses(bwsFromBlockWithDeclarations);
|
|
1256
983
|
return (await Promise.all(validBlockBwsWithDeclarations.map(async (bw) => {
|
|
1257
|
-
const stakeIntentHashes = validBlockBwsWithDeclarations.flatMap(mapBoundWitnessToStakeIntentHashes).filter(
|
|
984
|
+
const stakeIntentHashes = validBlockBwsWithDeclarations.flatMap(mapBoundWitnessToStakeIntentHashes).filter(exists4);
|
|
1258
985
|
const payloads = await archivist.get(stakeIntentHashes);
|
|
1259
986
|
const stakeIntents = filterAs2(payloads, asChainStakeIntent).filter((p) => p.intent === intent).filter((p) => bw.addresses.includes(p.from));
|
|
1260
987
|
return stakeIntents;
|
|
1261
988
|
}))).flat();
|
|
1262
|
-
}
|
|
1263
|
-
var filterToValidSignedBoundWitnesses =
|
|
989
|
+
};
|
|
990
|
+
var filterToValidSignedBoundWitnesses = async (bws) => {
|
|
1264
991
|
const validBwIndexes = await Promise.all(bws.map((bw) => BoundWitnessWrapper.parse(bw).getValid()));
|
|
1265
992
|
return bws.filter((_, index) => validBwIndexes[index]);
|
|
1266
|
-
}
|
|
1267
|
-
var mapBoundWitnessToStakeIntentHashes =
|
|
993
|
+
};
|
|
994
|
+
var mapBoundWitnessToStakeIntentHashes = (bw) => {
|
|
1268
995
|
return bw.payload_schemas.map((schema, index) => schema === ChainStakeIntentSchema ? bw.payload_hashes[index] : void 0);
|
|
1269
|
-
}
|
|
996
|
+
};
|
|
1270
997
|
|
|
1271
998
|
// src/StakeIntent/XyoStakeIntentService.ts
|
|
1272
999
|
import { filterAs as filterAs3 } from "@xylabs/array";
|
|
1273
|
-
import { assertEx as
|
|
1000
|
+
import { assertEx as assertEx10 } from "@xylabs/assert";
|
|
1274
1001
|
import { creatable as creatable10 } from "@xylabs/creatable";
|
|
1275
|
-
import {
|
|
1002
|
+
import {
|
|
1003
|
+
asAddress
|
|
1004
|
+
} from "@xylabs/hex";
|
|
1276
1005
|
import { isUndefined as isUndefined2 } from "@xylabs/typeof";
|
|
1277
|
-
import {
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
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";
|
|
1281
1025
|
import { Mutex as Mutex3 } from "async-mutex";
|
|
1282
1026
|
import { LRUCache as LRUCache3 } from "lru-cache";
|
|
1283
|
-
function _ts_decorate10(decorators, target, key, desc) {
|
|
1284
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1285
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1286
|
-
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;
|
|
1287
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1288
|
-
}
|
|
1289
|
-
__name(_ts_decorate10, "_ts_decorate");
|
|
1290
1027
|
var ACTIVE_STAKE_TTL = 1e3 * 60 * 60 * 2;
|
|
1291
1028
|
var NO_ACTIVE_STAKE_TTL = 1e3 * 2;
|
|
1292
1029
|
var STAKE_CACHE_MAX_ENTRIES = 1e4;
|
|
1293
1030
|
var XyoStakeIntentService = class extends BaseService {
|
|
1294
|
-
static {
|
|
1295
|
-
__name(this, "XyoStakeIntentService");
|
|
1296
|
-
}
|
|
1297
1031
|
// TODO: Use hash instead of block number to handle chain reorgs
|
|
1298
1032
|
_lastIndexedBlockHash = void 0;
|
|
1299
1033
|
// TODO: Interval tree per declaration (bank, validator, etc.)
|
|
@@ -1304,21 +1038,19 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1304
1038
|
// in performance for small sets, and (most importantly) easily
|
|
1305
1039
|
// persisted so we can recover state on restart.
|
|
1306
1040
|
_producers = new IntervalMap();
|
|
1307
|
-
_stakeCache = new LRUCache3({
|
|
1308
|
-
max: STAKE_CACHE_MAX_ENTRIES
|
|
1309
|
-
});
|
|
1041
|
+
_stakeCache = new LRUCache3({ max: STAKE_CACHE_MAX_ENTRIES });
|
|
1310
1042
|
_updateMutex = new Mutex3();
|
|
1311
1043
|
get chainArchivist() {
|
|
1312
|
-
return
|
|
1044
|
+
return assertEx10(this.params.chainArchivist, () => "chainArchivist not set");
|
|
1313
1045
|
}
|
|
1314
1046
|
get chainIterator() {
|
|
1315
|
-
return
|
|
1047
|
+
return assertEx10(this.params.chainIterator, () => "chainIterator not set");
|
|
1316
1048
|
}
|
|
1317
1049
|
get chainStakeViewer() {
|
|
1318
|
-
return
|
|
1050
|
+
return assertEx10(this.params.chainStakeViewer, () => "chainStakeViewer not set");
|
|
1319
1051
|
}
|
|
1320
1052
|
get stakeIntentStateArchivist() {
|
|
1321
|
-
return
|
|
1053
|
+
return assertEx10(this.params.stakeIntentStateArchivist, () => "stakeIntentStateArchivist not set");
|
|
1322
1054
|
}
|
|
1323
1055
|
async createHandler() {
|
|
1324
1056
|
this.chainIterator.on("headUpdated", async () => {
|
|
@@ -1326,22 +1058,20 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1326
1058
|
});
|
|
1327
1059
|
const head = await this.chainIterator.head();
|
|
1328
1060
|
if (isUndefined2(head)) return;
|
|
1329
|
-
const headHash = await
|
|
1061
|
+
const headHash = await PayloadBuilder7.hash(head);
|
|
1330
1062
|
await this.recoverState(headHash);
|
|
1331
1063
|
}
|
|
1332
1064
|
async getDeclaredCandidateRanges(address, intent) {
|
|
1333
1065
|
await Promise.resolve();
|
|
1334
|
-
|
|
1066
|
+
assertEx10(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
|
|
1335
1067
|
const results = this._producers.get(address);
|
|
1336
1068
|
return results ?? [];
|
|
1337
1069
|
}
|
|
1338
1070
|
async getDeclaredCandidatesForBlock(block, intent) {
|
|
1339
1071
|
return await this.spanAsync("getDeclaredCandidatesForBlock", async () => {
|
|
1340
|
-
|
|
1072
|
+
assertEx10(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
|
|
1341
1073
|
const results = this._producers.findAllContaining(block);
|
|
1342
|
-
const candidates = [
|
|
1343
|
-
...results
|
|
1344
|
-
];
|
|
1074
|
+
const candidates = [...results];
|
|
1345
1075
|
const requiredMinimumStake = this.getRequiredMinimumStakeForIntent(intent);
|
|
1346
1076
|
const validCandidates = await this.filterToValidStake(candidates, this.chainStakeViewer, requiredMinimumStake);
|
|
1347
1077
|
return validCandidates;
|
|
@@ -1363,62 +1093,41 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1363
1093
|
await this.updateIndex(true);
|
|
1364
1094
|
}
|
|
1365
1095
|
async filterToValidStake(candidates, chainStakeViewer, requiredMinimumStake) {
|
|
1366
|
-
const candidatesWithStake = await Promise.all(
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
ttl: ACTIVE_STAKE_TTL
|
|
1373
|
-
}
|
|
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 };
|
|
1374
1107
|
} else {
|
|
1375
|
-
|
|
1376
|
-
ttl: NO_ACTIVE_STAKE_TTL
|
|
1377
|
-
});
|
|
1108
|
+
return { candidate, stake };
|
|
1378
1109
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
stake: activeStake
|
|
1382
|
-
};
|
|
1383
|
-
} else {
|
|
1384
|
-
return {
|
|
1385
|
-
candidate,
|
|
1386
|
-
stake
|
|
1387
|
-
};
|
|
1388
|
-
}
|
|
1389
|
-
}));
|
|
1110
|
+
})
|
|
1111
|
+
);
|
|
1390
1112
|
return candidatesWithStake.filter(({ stake }) => stake >= requiredMinimumStake).map(({ candidate }) => candidate);
|
|
1391
1113
|
}
|
|
1392
1114
|
async persistState(current) {
|
|
1393
1115
|
const state = this._producers.serialize();
|
|
1394
|
-
const payload = new
|
|
1395
|
-
|
|
1396
|
-
}).fields({
|
|
1397
|
-
endBlockHash: current,
|
|
1398
|
-
state
|
|
1399
|
-
}).build();
|
|
1400
|
-
await this.stakeIntentStateArchivist.insert([
|
|
1401
|
-
payload
|
|
1402
|
-
]);
|
|
1116
|
+
const payload = new PayloadBuilder7({ schema: ChainIndexingServiceStateSchema }).fields({ endBlockHash: current, state }).build();
|
|
1117
|
+
await this.stakeIntentStateArchivist.insert([payload]);
|
|
1403
1118
|
}
|
|
1404
1119
|
async recoverState(current) {
|
|
1405
|
-
const currentBlock =
|
|
1406
|
-
current
|
|
1407
|
-
]))?.[0]), () => `Block ${current} not found`);
|
|
1120
|
+
const currentBlock = assertEx10(asBlockBoundWitness3((await this.chainArchivist.get([current]))?.[0]), () => `Block ${current} not found`);
|
|
1408
1121
|
const currentBlockNum = currentBlock.block;
|
|
1409
|
-
const opts = {
|
|
1410
|
-
...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS
|
|
1411
|
-
};
|
|
1122
|
+
const opts = { ...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS };
|
|
1412
1123
|
while (true) {
|
|
1413
|
-
const predicate =
|
|
1124
|
+
const predicate = (p) => {
|
|
1414
1125
|
const state2 = asChainIndexingServiceStateWithStorageMeta(p);
|
|
1415
1126
|
return state2 ? true : false;
|
|
1416
|
-
}
|
|
1127
|
+
};
|
|
1417
1128
|
const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts);
|
|
1418
1129
|
if (isChainIndexingServiceState(state)) {
|
|
1419
|
-
const indexed = (await this.chainArchivist.get([
|
|
1420
|
-
state.endBlockHash
|
|
1421
|
-
]))?.[0];
|
|
1130
|
+
const indexed = (await this.chainArchivist.get([state.endBlockHash]))?.[0];
|
|
1422
1131
|
const indexedBlock = asBlockBoundWitnessWithStorageMeta(indexed);
|
|
1423
1132
|
if (indexedBlock) {
|
|
1424
1133
|
const indexedBlockNum = indexedBlock.block;
|
|
@@ -1443,10 +1152,8 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1443
1152
|
return await this.spanAsync("updateIndex", async () => {
|
|
1444
1153
|
const currentHead = await this.chainIterator.head();
|
|
1445
1154
|
if (isUndefined2(currentHead)) return;
|
|
1446
|
-
const currentHeadHash = await
|
|
1447
|
-
const result = await analyzeChain(this.chainArchivist, [
|
|
1448
|
-
new ChainStakeIntentAnalyzer("producer")
|
|
1449
|
-
], currentHeadHash, this._lastIndexedBlockHash);
|
|
1155
|
+
const currentHeadHash = await PayloadBuilder7.hash(currentHead);
|
|
1156
|
+
const result = await analyzeChain(this.chainArchivist, [new ChainStakeIntentAnalyzer("producer")], currentHeadHash, this._lastIndexedBlockHash);
|
|
1450
1157
|
const signedDeclarations = filterAs3(result.find(isChainSummaryStakeIntent)?.intents ?? [], asChainStakeIntent2);
|
|
1451
1158
|
if (currentHead.block === void 0) return;
|
|
1452
1159
|
const currentHeadBlockNum = currentHead.block;
|
|
@@ -1465,12 +1172,10 @@ var XyoStakeIntentService = class extends BaseService {
|
|
|
1465
1172
|
});
|
|
1466
1173
|
}
|
|
1467
1174
|
};
|
|
1468
|
-
XyoStakeIntentService =
|
|
1175
|
+
XyoStakeIntentService = __decorateClass([
|
|
1469
1176
|
creatable10()
|
|
1470
1177
|
], XyoStakeIntentService);
|
|
1471
1178
|
export {
|
|
1472
|
-
AbstractXyoDataLake,
|
|
1473
|
-
ArchivistXyoDataLake,
|
|
1474
1179
|
BaseAccountBalanceService,
|
|
1475
1180
|
BaseAccountableService,
|
|
1476
1181
|
BaseBlockProducerService,
|
|
@@ -1482,7 +1187,6 @@ export {
|
|
|
1482
1187
|
DEFAULT_BLOCK_SIZE,
|
|
1483
1188
|
EvmBlockRewardService,
|
|
1484
1189
|
EvmChainService,
|
|
1485
|
-
HttpXyoDataLake,
|
|
1486
1190
|
MemoryBlockRewardService,
|
|
1487
1191
|
MemoryChainService,
|
|
1488
1192
|
XYO_PRODUCER_REDECLARATION_DURATION,
|