trac-msb 0.3.0-beta.1 → 0.3.0-beta.2
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/package.json +2 -2
- package/rpc/handlers.js +18 -0
- package/rpc/routes/v1.js +4 -0
- package/src/core/state/State.js +28 -0
- package/src/index.js +26 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trac-msb",
|
|
3
3
|
"main": "msb.mjs",
|
|
4
|
-
"version": "0.3.0-beta.
|
|
4
|
+
"version": "0.3.0-beta.2",
|
|
5
5
|
"pear": {
|
|
6
6
|
"name": "trac-msb",
|
|
7
7
|
"type": "terminal"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"lint:fix": "eslint . --fix",
|
|
27
27
|
"protobuf": "node scripts/generate-protobufs.js",
|
|
28
28
|
"docs:check": "node scripts/docs/docs-checker.js",
|
|
29
|
-
"test:acceptance": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testTimeout=200000 tests/acceptance/v1/rpc.test.mjs tests/acceptance/v1/htlc/htlc-routing.test.mjs --runInBand",
|
|
29
|
+
"test:acceptance": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testTimeout=200000 tests/acceptance/v1/rpc.test.mjs tests/acceptance/v1/htlc/htlc-routing.test.mjs tests/acceptance/v1/current-epoch/current-epoch-routing.test.mjs tests/acceptance/v1/consensus-config/consensus-config-routing.test.mjs --runInBand",
|
|
30
30
|
"test:integration": "brittle-node -t 1200000 tests/integration/integration.test.js",
|
|
31
31
|
"test:unit:node": "brittle-node -t 60000 tests/unit/unit.test.js",
|
|
32
32
|
"test:unit:bare": "brittle-bare -t 60000 tests/unit/unit.test.js",
|
package/rpc/handlers.js
CHANGED
|
@@ -456,3 +456,21 @@ export async function handleAccountDetails({ msbInstance, respond, req }) {
|
|
|
456
456
|
stakedBalance: bufferToBigInt(nodeEntry.stakedBalance).toString(),
|
|
457
457
|
});
|
|
458
458
|
}
|
|
459
|
+
|
|
460
|
+
export async function handleCurrentEpoch({ req, msbInstance, respond }) {
|
|
461
|
+
const confirmed = getConfirmedParameter(buildRequestUrl(req));
|
|
462
|
+
if (confirmed === null) {
|
|
463
|
+
return respond(400, { error: 'Parameter "confirmed" must be exactly "true" or "false"' });
|
|
464
|
+
}
|
|
465
|
+
const current_epoch = await msbInstance.getCurrentEpoch(confirmed);
|
|
466
|
+
respond(200, { current_epoch });
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export async function handleConsensusConfig({ req, msbInstance, respond }) {
|
|
470
|
+
const confirmed = getConfirmedParameter(buildRequestUrl(req));
|
|
471
|
+
if (confirmed === null) {
|
|
472
|
+
return respond(400, { error: 'Parameter "confirmed" must be exactly "true" or "false"' });
|
|
473
|
+
}
|
|
474
|
+
const consensusConfig = await msbInstance.getConsensusConfig(confirmed);
|
|
475
|
+
respond(200, consensusConfig);
|
|
476
|
+
}
|
package/rpc/routes/v1.js
CHANGED
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
handleHtlcClaim,
|
|
16
16
|
handleHtlcRefund,
|
|
17
17
|
handleHtlc,
|
|
18
|
+
handleCurrentEpoch,
|
|
19
|
+
handleConsensusConfig,
|
|
18
20
|
} from '../handlers.js';
|
|
19
21
|
|
|
20
22
|
export const v1Routes = [
|
|
@@ -34,4 +36,6 @@ export const v1Routes = [
|
|
|
34
36
|
{ method: 'POST', path: '/tx-payloads-bulk', handler: handleFetchBulkTxPayloads },
|
|
35
37
|
{ method: 'GET', path: '/tx/details', handler: handleTransactionExtendedDetails },
|
|
36
38
|
{ method: 'GET', path: '/account', handler: handleAccountDetails },
|
|
39
|
+
{ method: 'GET', path: '/current-epoch', exact: true, handler: handleCurrentEpoch },
|
|
40
|
+
{ method: 'GET', path: '/consensus-config', exact: true, handler: handleConsensusConfig },
|
|
37
41
|
];
|
package/src/core/state/State.js
CHANGED
|
@@ -676,6 +676,12 @@ class State extends ReadyResource {
|
|
|
676
676
|
for await (const entry of historyStream) {
|
|
677
677
|
if (isTransactionRecordPut(entry)) {
|
|
678
678
|
hashes.push({ hash: entry.key, confirmed_length: entry.seq });
|
|
679
|
+
} else if (entry.type === 'put' && entry.key.startsWith(EntryType.EPOCH_HASH)) {
|
|
680
|
+
// Epoch records share this history, but have their own key namespace.
|
|
681
|
+
const hash = entry.key.slice(EntryType.EPOCH_HASH.length);
|
|
682
|
+
if (hash.length === HASH_BYTE_LENGTH * 2 && isHexString(hash)) {
|
|
683
|
+
hashes.push({ hash, confirmed_length: entry.seq });
|
|
684
|
+
}
|
|
679
685
|
}
|
|
680
686
|
}
|
|
681
687
|
|
|
@@ -5561,6 +5567,28 @@ class State extends ReadyResource {
|
|
|
5561
5567
|
return Status.SUCCESS;
|
|
5562
5568
|
}
|
|
5563
5569
|
|
|
5570
|
+
async getUnsignedConsensusConfig() {
|
|
5571
|
+
// Keep the pointer and record in the same view while unsigned state can change.
|
|
5572
|
+
const snapshot = this.#base.view.snapshot();
|
|
5573
|
+
try {
|
|
5574
|
+
const currentConfigPointer = (await snapshot.get(EntryType.CONSENSUS_CONFIG_CURRENT))?.value;
|
|
5575
|
+
if (_.isNil(currentConfigPointer)) return null;
|
|
5576
|
+
|
|
5577
|
+
if (!b4a.isBuffer(currentConfigPointer) || currentConfigPointer.length !== CONSENSUS_CONFIG_INDEX_SIZE) {
|
|
5578
|
+
throw new Error('Invalid current consensus config pointer.');
|
|
5579
|
+
}
|
|
5580
|
+
|
|
5581
|
+
const currentConfigIndex = currentConfigPointer.readUInt32BE(0);
|
|
5582
|
+
const encodedConsensusConfig = (await snapshot.get(EntryType.CONSENSUS_CONFIG_RECORD + currentConfigIndex))?.value;
|
|
5583
|
+
if (_.isNil(encodedConsensusConfig)) {
|
|
5584
|
+
throw new Error(`Consensus config record ${currentConfigIndex} does not exist.`);
|
|
5585
|
+
}
|
|
5586
|
+
|
|
5587
|
+
return decodeVersionedConsensusConfig(encodedConsensusConfig);
|
|
5588
|
+
} finally {
|
|
5589
|
+
await snapshot.close();
|
|
5590
|
+
}
|
|
5591
|
+
}
|
|
5564
5592
|
}
|
|
5565
5593
|
|
|
5566
5594
|
export default State;
|
package/src/index.js
CHANGED
|
@@ -37,7 +37,8 @@ import {
|
|
|
37
37
|
encodeApplyOperation,
|
|
38
38
|
encodeConsensusConfig,
|
|
39
39
|
safeDecodeApplyOperation,
|
|
40
|
-
safeEncodeApplyOperation
|
|
40
|
+
safeEncodeApplyOperation,
|
|
41
|
+
decodeEpochRecord
|
|
41
42
|
} from "./codecs/apply/applyOperationCodec.js";
|
|
42
43
|
import { encodeVdfConfig } from "./codecs/consensus/v1/vdfConfigCodec.js";
|
|
43
44
|
import PartialTransactionValidator from "./core/network/protocols/validators/shared/validators/PartialTransactionValidator.js";
|
|
@@ -425,7 +426,16 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
425
426
|
|
|
426
427
|
async fetchBulkTxPayloads(hashes) {
|
|
427
428
|
const response = { results: [], missing: [] };
|
|
428
|
-
const results = await Promise.all(hashes.map((hash) =>
|
|
429
|
+
const results = await Promise.all(hashes.map(async (hash) => {
|
|
430
|
+
const transaction = await this.getConfirmedTxInfo(hash);
|
|
431
|
+
if (transaction) return transaction.decoded;
|
|
432
|
+
|
|
433
|
+
const epochRecord = await this.#state.getEpochProof(hash);
|
|
434
|
+
if (epochRecord === null) return null;
|
|
435
|
+
|
|
436
|
+
// This hash identifies the stored epoch record, not an original transaction.
|
|
437
|
+
return { type: OperationType.SET_EPOCH, seo: decodeEpochRecord(epochRecord) };
|
|
438
|
+
}));
|
|
429
439
|
|
|
430
440
|
results.forEach((result, index) => {
|
|
431
441
|
const hash = hashes[index];
|
|
@@ -434,7 +444,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
434
444
|
return;
|
|
435
445
|
}
|
|
436
446
|
|
|
437
|
-
const decodedResult = normalizeDecodedPayloadForJson(result
|
|
447
|
+
const decodedResult = normalizeDecodedPayloadForJson(result, this.#config);
|
|
438
448
|
response.results.push({ hash, payload: decodedResult });
|
|
439
449
|
});
|
|
440
450
|
|
|
@@ -1290,6 +1300,19 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
1290
1300
|
expectedKeys.every(key => Object.hasOwn(value, key))
|
|
1291
1301
|
);
|
|
1292
1302
|
}
|
|
1303
|
+
|
|
1304
|
+
async getCurrentEpoch(confirmed = true) {
|
|
1305
|
+
const epoch = confirmed
|
|
1306
|
+
? await this.#state.getCurrentEpoch()
|
|
1307
|
+
: await this.#state.getCurrentEpochUnsigned();
|
|
1308
|
+
return epoch === null ? null : epoch.toString();
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
async getConsensusConfig(confirmed = true) {
|
|
1312
|
+
return confirmed
|
|
1313
|
+
? this.#state.getSignedConsensusConfig()
|
|
1314
|
+
: this.#state.getUnsignedConsensusConfig();
|
|
1315
|
+
}
|
|
1293
1316
|
}
|
|
1294
1317
|
|
|
1295
1318
|
export default MainSettlementBus;
|