trac-msb 0.2.8 → 0.2.9
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/msb.mjs +3 -3
- package/package.json +8 -3
- package/proto/network.proto +74 -0
- package/rpc/create_server.js +2 -2
- package/rpc/handlers.js +2 -2
- package/rpc/rpc_server.js +2 -2
- package/rpc/rpc_services.js +44 -3
- package/rpc/utils/helpers.js +1 -1
- package/src/config/env.js +2 -0
- package/src/core/network/Network.js +29 -61
- package/src/core/network/identity/NetworkWalletFactory.js +2 -2
- package/src/core/network/protocols/LegacyProtocol.js +67 -0
- package/src/core/network/protocols/NetworkMessages.js +48 -0
- package/src/core/network/protocols/ProtocolInterface.js +31 -0
- package/src/core/network/protocols/ProtocolSession.js +59 -0
- package/src/core/network/protocols/V1Protocol.js +64 -0
- package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
- package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
- package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
- package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +1 -2
- package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
- package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
- package/src/core/network/{messaging → protocols/shared}/handlers/TransferOperationHandler.js +16 -15
- package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +7 -11
- package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +2 -2
- package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +5 -5
- package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +4 -4
- package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +4 -4
- package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +14 -12
- package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
- package/src/core/network/services/ConnectionManager.js +4 -4
- package/src/core/network/services/MessageOrchestrator.js +1 -1
- package/src/core/network/services/TransactionPoolService.js +1 -2
- package/src/core/network/services/TransactionRateLimiterService.js +5 -3
- package/src/core/state/State.js +1 -2
- package/src/index.js +153 -180
- package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
- package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
- package/src/messages/network/v1/networkMessageFactory.js +12 -0
- package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
- package/src/messages/state/ApplyStateMessageDirector.js +516 -0
- package/src/messages/state/applyStateMessageFactory.js +12 -0
- package/src/utils/buffer.js +53 -1
- package/src/utils/cli.js +0 -8
- package/src/utils/constants.js +34 -14
- package/src/utils/normalizers.js +84 -2
- package/src/utils/protobuf/network.cjs +840 -0
- package/src/utils/protobuf/operationHelpers.js +10 -0
- package/tests/acceptance/v1/rpc.test.mjs +1 -1
- package/tests/fixtures/networkV1.fixtures.js +84 -0
- package/tests/fixtures/protobuf.fixtures.js +83 -0
- package/tests/helpers/config.js +1 -1
- package/tests/helpers/setupApplyTests.js +53 -46
- package/tests/unit/messages/messages.test.js +12 -0
- package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
- package/tests/unit/messages/network/NetworkMessageDirector.test.js +203 -0
- package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
- package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
- package/tests/unit/network/ConnectionManager.test.js +6 -5
- package/tests/unit/network/networkModule.test.js +3 -2
- package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
- package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +9 -6
- package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +10 -7
- package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -21
- package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +53 -38
- package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +46 -35
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +13 -16
- package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +17 -11
- package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +11 -12
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +9 -7
- package/tests/unit/state/apply/common/commonScenarioHelper.js +15 -14
- package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +9 -4
- package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +17 -11
- package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +19 -14
- package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +37 -29
- package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +9 -7
- package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +11 -9
- package/tests/unit/unit.test.js +1 -1
- package/tests/unit/utils/buffer/buffer.test.js +62 -1
- package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
- package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
- package/docs/networking-dualstack-plan.md +0 -75
- package/docs/networking-layer-redesign.md +0 -155
- package/src/core/network/messaging/NetworkMessages.js +0 -64
- package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -113
- package/src/core/network/messaging/handlers/ResponseHandler.js +0 -107
- package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -114
- package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -149
- package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -98
- package/src/core/network/messaging/validators/AdminResponse.js +0 -58
- package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
- package/src/messages/base/StateBuilder.js +0 -25
- package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -425
- package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
- package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -296
- package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
- package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
- package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -138
- package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -69
- package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -126
- package/tests/integration/apply/addIndexer.test.js +0 -239
- package/tests/integration/apply/addWhitelist.test.js +0 -53
- package/tests/integration/apply/addWriter.test.js +0 -245
- package/tests/integration/apply/apply.test.js +0 -19
- package/tests/integration/apply/banValidator.test.js +0 -116
- package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
- package/tests/integration/apply/postTx/postTx.test.js +0 -196
- package/tests/integration/apply/removeIndexer.test.js +0 -132
- package/tests/integration/apply/removeWriter.test.js +0 -168
- package/tests/integration/apply/transfer.test.js +0 -83
- package/tests/integration/integration.test.js +0 -9
- package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
- package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -17
- package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -68
- package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -17
- package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -424
- package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
- package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
- package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -59
- package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -278
- package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
- /package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +0 -0
- /package/src/utils/{operations.js → applyOperations.js} +0 -0
package/src/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
/** @typedef {import('pear-interface')} */ /* global Pear */
|
|
3
2
|
import ReadyResource from "ready-resource";
|
|
4
3
|
import Corestore from "corestore";
|
|
@@ -8,26 +7,21 @@ import readline from "readline";
|
|
|
8
7
|
import tty from "tty";
|
|
9
8
|
import { sleep, isHexString } from "./utils/helpers.js";
|
|
10
9
|
import { verifyDag, printHelp, printWalletInfo, printBalance } from "./utils/cli.js";
|
|
11
|
-
import
|
|
10
|
+
import { applyStateMessageFactory } from "./messages/state/applyStateMessageFactory.js";
|
|
12
11
|
import { isAddressValid } from "./core/state/utils/address.js";
|
|
13
12
|
import Network from "./core/network/Network.js";
|
|
14
13
|
import Check from "./utils/check.js";
|
|
15
14
|
import State from "./core/state/State.js";
|
|
16
|
-
import PartialStateMessageOperations from "./messages/partialStateMessages/PartialStateMessageOperations.js";
|
|
17
15
|
import {
|
|
18
16
|
EventType,
|
|
19
17
|
WHITELIST_SLEEP_INTERVAL,
|
|
20
18
|
BOOTSTRAP_HEXSTRING_LENGTH,
|
|
21
|
-
OperationType,
|
|
22
19
|
CustomEventType,
|
|
23
20
|
BALANCE_MIGRATION_SLEEP_INTERVAL,
|
|
24
21
|
WHITELIST_MIGRATION_DIR
|
|
25
22
|
} from "./utils/constants.js";
|
|
26
23
|
import { randomBytes } from "hypercore-crypto";
|
|
27
24
|
import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString } from "./utils/amountSerialization.js"
|
|
28
|
-
import { normalizeTransferOperation, normalizeTransactionOperation } from "./utils/normalizers.js"
|
|
29
|
-
import PartialTransfer from "./core/network/messaging/validators/PartialTransfer.js";
|
|
30
|
-
import PartialTransaction from "./core/network/messaging/validators/PartialTransaction.js";
|
|
31
25
|
import fileUtils from './utils/fileUtils.js';
|
|
32
26
|
import migrationUtils from './utils/migrationUtils.js';
|
|
33
27
|
import {
|
|
@@ -49,16 +43,15 @@ import {
|
|
|
49
43
|
getLicenseAddressCommand,
|
|
50
44
|
getLicenseCountCommand
|
|
51
45
|
} from "./utils/cliCommands.js";
|
|
46
|
+
import {safeEncodeApplyOperation} from "./utils/protobuf/operationHelpers.js";
|
|
47
|
+
|
|
52
48
|
export class MainSettlementBus extends ReadyResource {
|
|
53
|
-
// internal attributes
|
|
54
49
|
#store;
|
|
55
50
|
#wallet;
|
|
56
51
|
#network;
|
|
57
52
|
#readline_instance;
|
|
58
53
|
#state;
|
|
59
54
|
#isClosing = false;
|
|
60
|
-
#partialTransferValidator;
|
|
61
|
-
#partialTransactionValidator;
|
|
62
55
|
#config
|
|
63
56
|
|
|
64
57
|
/**
|
|
@@ -67,7 +60,6 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
67
60
|
constructor(config) {
|
|
68
61
|
super();
|
|
69
62
|
this.#config = config
|
|
70
|
-
|
|
71
63
|
this.#store = new Corestore(this.#config.storesFullPath);
|
|
72
64
|
this.#wallet = new PeerWallet({ networkPrefix: this.#config.addressPrefix });
|
|
73
65
|
this.#readline_instance = null;
|
|
@@ -96,8 +88,10 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
96
88
|
return this.#network;
|
|
97
89
|
}
|
|
98
90
|
|
|
99
|
-
// This can be null if enable_wallet is false
|
|
100
91
|
get wallet() {
|
|
92
|
+
if (!this.#config.enableWallet) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
101
95
|
return this.#wallet;
|
|
102
96
|
}
|
|
103
97
|
|
|
@@ -113,15 +107,12 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
113
107
|
|
|
114
108
|
await this.#state.ready();
|
|
115
109
|
await this.#network.ready();
|
|
116
|
-
this.#stateEventsListener();
|
|
110
|
+
await this.#stateEventsListener();
|
|
117
111
|
|
|
118
112
|
if (this.#config.enableWallet) {
|
|
119
113
|
printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#config.enableWallet);
|
|
120
114
|
}
|
|
121
115
|
|
|
122
|
-
this.#partialTransferValidator = new PartialTransfer(this.state, this.#wallet, this.#config);
|
|
123
|
-
this.#partialTransactionValidator = new PartialTransaction(this.state, this.#wallet ,this.#config);
|
|
124
|
-
|
|
125
116
|
await this.#network.replicate(
|
|
126
117
|
this.#state,
|
|
127
118
|
this.#store,
|
|
@@ -131,6 +122,8 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
131
122
|
const adminEntry = await this.#state.getAdminEntry();
|
|
132
123
|
await this.#setUpRoleAutomatically(adminEntry);
|
|
133
124
|
|
|
125
|
+
|
|
126
|
+
|
|
134
127
|
console.log(`isIndexer: ${this.#state.isIndexer()}`);
|
|
135
128
|
console.log(`isWriter: ${this.#state.isWritable()}`);
|
|
136
129
|
console.log("MSB Unsigned Length:", this.#state.getUnsignedLength());
|
|
@@ -182,41 +175,6 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
182
175
|
return await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
|
|
183
176
|
}
|
|
184
177
|
|
|
185
|
-
async broadcastTransactionCommand(payload) {
|
|
186
|
-
if (!payload) {
|
|
187
|
-
throw new Error("Transaction payload is required for broadcast_transaction command.");
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
let normalizedPayload;
|
|
191
|
-
let isValid = false;
|
|
192
|
-
let hash;
|
|
193
|
-
|
|
194
|
-
if (payload.type === OperationType.TRANSFER) {
|
|
195
|
-
normalizedPayload = normalizeTransferOperation(payload, this.#config);
|
|
196
|
-
isValid = await this.#partialTransferValidator.validate(normalizedPayload);
|
|
197
|
-
hash = b4a.toString(normalizedPayload.tro.tx, "hex");
|
|
198
|
-
} else if (payload.type === OperationType.TX) {
|
|
199
|
-
normalizedPayload = normalizeTransactionOperation(payload, this.#config);
|
|
200
|
-
isValid = await this.#partialTransactionValidator.validate(normalizedPayload);
|
|
201
|
-
hash = b4a.toString(normalizedPayload.txo.tx, "hex");
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (!isValid) {
|
|
205
|
-
throw new Error("Invalid transaction payload.");
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const signedLength = this.#state.getSignedLength();
|
|
209
|
-
const unsignedLength = this.#state.getUnsignedLength();
|
|
210
|
-
|
|
211
|
-
const success = await this.broadcastPartialTransaction(payload);
|
|
212
|
-
|
|
213
|
-
if (!success) {
|
|
214
|
-
throw new Error("Failed to broadcast transaction after multiple attempts.");
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return { message: "Transaction broadcasted successfully.", signedLength, unsignedLength, tx: hash };
|
|
218
|
-
}
|
|
219
|
-
|
|
220
178
|
async #setUpRoleAutomatically() {
|
|
221
179
|
if (!this.#state.isWritable() && this.#config.enableRoleRequester) {
|
|
222
180
|
console.log("Requesting writer role... This may take a moment.");
|
|
@@ -296,14 +254,17 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
296
254
|
}
|
|
297
255
|
|
|
298
256
|
const txValidity = await PeerWallet.blake3(this.#config.bootstrap);
|
|
299
|
-
const addAdminMessage = await
|
|
300
|
-
.
|
|
257
|
+
const addAdminMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
258
|
+
.buildCompleteAddAdminMessage(
|
|
259
|
+
this.#wallet.address,
|
|
301
260
|
this.#state.writingKey,
|
|
302
|
-
txValidity
|
|
303
|
-
)
|
|
261
|
+
txValidity,
|
|
262
|
+
)
|
|
263
|
+
const encodedPayload = safeEncodeApplyOperation(addAdminMessage);
|
|
304
264
|
|
|
305
|
-
await this.#state.append(
|
|
265
|
+
await this.#state.append(encodedPayload);
|
|
306
266
|
}
|
|
267
|
+
|
|
307
268
|
async #handleAdminRecovery() {
|
|
308
269
|
if (!this.#config.enableWallet) {
|
|
309
270
|
throw new Error("Can not initialize an admin - wallet is not enabled.");
|
|
@@ -329,10 +290,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
329
290
|
}
|
|
330
291
|
|
|
331
292
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
332
|
-
const adminRecoveryMessage = await
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
293
|
+
const adminRecoveryMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
294
|
+
.buildPartialAdminRecoveryMessage(
|
|
295
|
+
this.#wallet.address,
|
|
296
|
+
this.#state.writingKey,
|
|
297
|
+
txValidity,
|
|
298
|
+
"json"
|
|
299
|
+
)
|
|
336
300
|
|
|
337
301
|
const success = await this.broadcastPartialTransaction(adminRecoveryMessage);
|
|
338
302
|
|
|
@@ -366,12 +330,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
366
330
|
|
|
367
331
|
for (const addressToWhitelist of addresses) {
|
|
368
332
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
369
|
-
const
|
|
370
|
-
.
|
|
333
|
+
const appendWhitelistMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
334
|
+
.buildCompleteAppendWhitelistMessage(
|
|
335
|
+
this.#wallet.address,
|
|
336
|
+
addressToWhitelist,
|
|
371
337
|
txValidity,
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
338
|
+
)
|
|
339
|
+
const encodedPayload = safeEncodeApplyOperation(appendWhitelistMessage)
|
|
375
340
|
messages.set(addressToWhitelist, encodedPayload);
|
|
376
341
|
}
|
|
377
342
|
|
|
@@ -445,10 +410,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
445
410
|
}
|
|
446
411
|
|
|
447
412
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
413
|
+
|
|
414
|
+
const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
415
|
+
.buildPartialAddWriterMessage(
|
|
416
|
+
this.#wallet.address,
|
|
417
|
+
this.#state.writingKey,
|
|
418
|
+
txValidity,
|
|
419
|
+
'json'
|
|
452
420
|
)
|
|
453
421
|
|
|
454
422
|
const success = await this.broadcastPartialTransaction(assembledMessage);
|
|
@@ -477,10 +445,12 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
477
445
|
}
|
|
478
446
|
|
|
479
447
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
480
|
-
const assembledMessage = await
|
|
481
|
-
.
|
|
482
|
-
|
|
483
|
-
|
|
448
|
+
const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
449
|
+
.buildPartialRemoveWriterMessage(
|
|
450
|
+
this.#wallet.address,
|
|
451
|
+
nodeEntry.wk,
|
|
452
|
+
txValidity,
|
|
453
|
+
"json"
|
|
484
454
|
)
|
|
485
455
|
|
|
486
456
|
const success = await this.broadcastPartialTransaction(assembledMessage);
|
|
@@ -492,10 +462,10 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
492
462
|
console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
|
|
493
463
|
}
|
|
494
464
|
|
|
495
|
-
async #
|
|
465
|
+
async #updateWriterToIndexerRole(addressToUpdate, toAdd) {
|
|
496
466
|
if (!this.#config.enableWallet) {
|
|
497
467
|
throw new Error(
|
|
498
|
-
`Can not request indexer role for: ${
|
|
468
|
+
`Can not request indexer role for: ${addressToUpdate} - wallet is not enabled.`
|
|
499
469
|
);
|
|
500
470
|
}
|
|
501
471
|
|
|
@@ -503,29 +473,29 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
503
473
|
|
|
504
474
|
if (!adminEntry) {
|
|
505
475
|
throw new Error(
|
|
506
|
-
`Can not request indexer role for: ${
|
|
476
|
+
`Can not request indexer role for: ${addressToUpdate} - admin entry has not been initialized.`
|
|
507
477
|
);
|
|
508
478
|
}
|
|
509
479
|
|
|
510
|
-
if (!isAddressValid(
|
|
480
|
+
if (!isAddressValid(addressToUpdate, this.#config.addressPrefix)) {
|
|
511
481
|
throw new Error(
|
|
512
|
-
`Can not request indexer role for: ${
|
|
482
|
+
`Can not request indexer role for: ${addressToUpdate} - invalid address.`
|
|
513
483
|
);
|
|
514
484
|
}
|
|
515
485
|
|
|
516
486
|
if (!this.#isAdmin(adminEntry) && !this.#state.isWritable()) {
|
|
517
487
|
throw new Error(
|
|
518
|
-
`Can not request indexer role for: ${
|
|
488
|
+
`Can not request indexer role for: ${addressToUpdate} - You are not an admin or writer.`
|
|
519
489
|
);
|
|
520
490
|
}
|
|
521
|
-
const nodeEntry = await this.#state.getNodeEntry(
|
|
491
|
+
const nodeEntry = await this.#state.getNodeEntry(addressToUpdate);
|
|
522
492
|
if (!nodeEntry) {
|
|
523
493
|
throw new Error(
|
|
524
|
-
`Can not request indexer role for: ${
|
|
494
|
+
`Can not request indexer role for: ${addressToUpdate} - node entry has not been not initialized.`
|
|
525
495
|
);
|
|
526
496
|
}
|
|
527
497
|
|
|
528
|
-
const indexerNodeEntry = await this.#state.getNodeEntry(
|
|
498
|
+
const indexerNodeEntry = await this.#state.getNodeEntry(addressToUpdate);
|
|
529
499
|
const indexerListHasAddress = await this.#state.isWkInIndexersEntry(
|
|
530
500
|
indexerNodeEntry.wk,
|
|
531
501
|
);
|
|
@@ -533,7 +503,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
533
503
|
if (toAdd) {
|
|
534
504
|
if (indexerListHasAddress) {
|
|
535
505
|
throw new Error(
|
|
536
|
-
`Cannot update indexer role for: ${
|
|
506
|
+
`Cannot update indexer role for: ${addressToUpdate} - address is already in indexers list.`
|
|
537
507
|
);
|
|
538
508
|
}
|
|
539
509
|
|
|
@@ -545,71 +515,86 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
545
515
|
|
|
546
516
|
if (!canAddIndexer) {
|
|
547
517
|
throw new Error(
|
|
548
|
-
`Can not request indexer role for: ${
|
|
518
|
+
`Can not request indexer role for: ${addressToUpdate} - node is not whitelisted, not a writer or already an indexer.`
|
|
549
519
|
);
|
|
550
520
|
}
|
|
551
521
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
522
|
+
|
|
523
|
+
const assembledAddIndexerMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
524
|
+
.buildCompleteAddIndexerMessage(
|
|
525
|
+
this.#wallet.address,
|
|
526
|
+
addressToUpdate,
|
|
527
|
+
txValidity,
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
const encodedPayload = safeEncodeApplyOperation(assembledAddIndexerMessage);
|
|
531
|
+
|
|
532
|
+
await this.#state.append(encodedPayload);
|
|
555
533
|
} else {
|
|
556
534
|
const canRemoveIndexer =
|
|
557
535
|
!toAdd && nodeEntry.isIndexer && indexerListHasAddress;
|
|
558
536
|
|
|
559
537
|
if (!canRemoveIndexer) {
|
|
560
538
|
throw new Error(
|
|
561
|
-
`Can not remove indexer role for: ${
|
|
539
|
+
`Can not remove indexer role for: ${addressToUpdate} - node is not an indexer or address is not in indexers list.`
|
|
562
540
|
);
|
|
563
541
|
}
|
|
564
542
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
565
|
-
const
|
|
566
|
-
.
|
|
543
|
+
const assembledRemoveIndexerMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
544
|
+
.buildCompleteRemoveIndexerMessage(
|
|
545
|
+
this.#wallet.address,
|
|
546
|
+
addressToUpdate,
|
|
547
|
+
txValidity,
|
|
548
|
+
)
|
|
549
|
+
const encodedPayload = safeEncodeApplyOperation(assembledRemoveIndexerMessage);
|
|
567
550
|
|
|
568
|
-
await this.#state.append(
|
|
551
|
+
await this.#state.append(encodedPayload);
|
|
569
552
|
}
|
|
570
553
|
}
|
|
571
554
|
|
|
572
|
-
async #banValidator(
|
|
555
|
+
async #banValidator(addresstToBan) {
|
|
573
556
|
if (!this.#config.enableWallet) {
|
|
574
557
|
throw new Error(
|
|
575
|
-
`Can not ban writer with address: ${
|
|
558
|
+
`Can not ban writer with address: ${addresstToBan} - wallet is not enabled.`
|
|
576
559
|
);
|
|
577
560
|
}
|
|
578
561
|
const adminEntry = await this.#state.getAdminEntry();
|
|
579
562
|
|
|
580
563
|
if (!adminEntry) {
|
|
581
564
|
throw new Error(
|
|
582
|
-
`Can not ban writer with address: ${
|
|
565
|
+
`Can not ban writer with address: ${addresstToBan} - admin entry has not been initialized.`
|
|
583
566
|
);
|
|
584
567
|
}
|
|
585
568
|
|
|
586
|
-
if (!isAddressValid(
|
|
569
|
+
if (!isAddressValid(addresstToBan, this.#config.addressPrefix)) {
|
|
587
570
|
throw new Error(
|
|
588
|
-
`Can not ban writer with address: ${
|
|
571
|
+
`Can not ban writer with address: ${addresstToBan} - invalid address.`
|
|
589
572
|
);
|
|
590
573
|
}
|
|
591
574
|
|
|
592
575
|
if (!this.#isAdmin(adminEntry)) {
|
|
593
576
|
throw new Error(
|
|
594
|
-
`Can not ban writer with address: ${
|
|
577
|
+
`Can not ban writer with address: ${addresstToBan} - You are not an admin.`
|
|
595
578
|
);
|
|
596
579
|
}
|
|
597
580
|
|
|
598
|
-
const isWhitelisted = await this.#state.isAddressWhitelisted(
|
|
599
|
-
const nodeEntry = await this.#state.getNodeEntry(
|
|
581
|
+
const isWhitelisted = await this.#state.isAddressWhitelisted(addresstToBan);
|
|
582
|
+
const nodeEntry = await this.#state.getNodeEntry(addresstToBan);
|
|
600
583
|
|
|
601
584
|
if (!isWhitelisted || null === nodeEntry || nodeEntry.isIndexer === true) {
|
|
602
585
|
throw new Error(
|
|
603
|
-
`Can not ban writer with address: ${
|
|
586
|
+
`Can not ban writer with address: ${addresstToBan} - node is not whitelisted or is an indexer.`
|
|
604
587
|
);
|
|
605
588
|
}
|
|
606
589
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
607
|
-
const assembledBanValidatorMessage = await
|
|
608
|
-
.
|
|
609
|
-
address,
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
590
|
+
const assembledBanValidatorMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
591
|
+
.buildCompleteBanWriterMessage(
|
|
592
|
+
this.#wallet.address,
|
|
593
|
+
addresstToBan,
|
|
594
|
+
txValidity,
|
|
595
|
+
)
|
|
596
|
+
const encodedPayload = safeEncodeApplyOperation(assembledBanValidatorMessage)
|
|
597
|
+
await this.#state.append(encodedPayload);
|
|
613
598
|
}
|
|
614
599
|
|
|
615
600
|
async #deployBootstrap(externalBootstrap, channel) {
|
|
@@ -682,12 +667,15 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
682
667
|
}
|
|
683
668
|
|
|
684
669
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
685
|
-
|
|
686
|
-
|
|
670
|
+
|
|
671
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
672
|
+
.buildPartialBootstrapDeploymentMessage(
|
|
673
|
+
this.#wallet.address,
|
|
687
674
|
externalBootstrap,
|
|
688
675
|
channel,
|
|
689
|
-
txValidity
|
|
690
|
-
|
|
676
|
+
txValidity,
|
|
677
|
+
"json"
|
|
678
|
+
)
|
|
691
679
|
|
|
692
680
|
const success = await this.broadcastPartialTransaction(payload);
|
|
693
681
|
|
|
@@ -703,31 +691,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
703
691
|
|
|
704
692
|
}
|
|
705
693
|
|
|
706
|
-
async #
|
|
707
|
-
await this.#updateIndexerRole(address, true);
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
async #handleRemoveIndexerOperation(address) {
|
|
711
|
-
await this.#updateIndexerRole(address, false);
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
async #handleAddWriterOperation() {
|
|
715
|
-
await this.#requestWriterRole(true);
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
async #handleRemoveWriterOperation() {
|
|
719
|
-
await this.#requestWriterRole(false);
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
async #handleBanValidatorOperation(address) {
|
|
723
|
-
await this.#banValidator(address);
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
async #handleBootstrapDeploymentOperation(bootstrapHex, channel) {
|
|
727
|
-
await this.#deployBootstrap(bootstrapHex, channel);
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
async #handleTransferOperation(address, amount) {
|
|
694
|
+
async #handleTransferOperation(recipientAddress, amount) {
|
|
731
695
|
if (!this.#config.enableWallet) {
|
|
732
696
|
throw new Error(
|
|
733
697
|
"Can not perform transfer - wallet is not enabled."
|
|
@@ -740,7 +704,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
740
704
|
);
|
|
741
705
|
}
|
|
742
706
|
|
|
743
|
-
if (!isAddressValid(
|
|
707
|
+
if (!isAddressValid(recipientAddress, this.#config.addressPrefix)) {
|
|
744
708
|
throw new Error("Invalid recipient address");
|
|
745
709
|
}
|
|
746
710
|
|
|
@@ -765,7 +729,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
765
729
|
const fee = this.#state.getFee();
|
|
766
730
|
const feeBigInt = bufferToBigInt(fee);
|
|
767
731
|
const senderBalance = bufferToBigInt(senderEntry.balance);
|
|
768
|
-
const isSelfTransfer =
|
|
732
|
+
const isSelfTransfer = recipientAddress === this.#wallet.address;
|
|
769
733
|
const totalDeductedAmount = isSelfTransfer ? feeBigInt : amountBigInt + feeBigInt;
|
|
770
734
|
|
|
771
735
|
if (!(senderBalance >= totalDeductedAmount)) {
|
|
@@ -773,13 +737,14 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
773
737
|
}
|
|
774
738
|
|
|
775
739
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
776
|
-
const payload = await
|
|
777
|
-
.
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
740
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
741
|
+
.buildPartialTransferOperationMessage(
|
|
742
|
+
this.#wallet.address,
|
|
743
|
+
recipientAddress,
|
|
744
|
+
amountBuffer,
|
|
745
|
+
txValidity,
|
|
746
|
+
"json"
|
|
747
|
+
)
|
|
783
748
|
|
|
784
749
|
const expectedNewBalance = senderBalance - totalDeductedAmount;
|
|
785
750
|
console.info('Transfer Details:');
|
|
@@ -794,7 +759,6 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
794
759
|
console.info(`Total: ${bigIntToDecimalString(totalDeductedAmount)}`);
|
|
795
760
|
}
|
|
796
761
|
console.log(`Expected Balance After Transfer: ${bigIntToDecimalString(expectedNewBalance)}`);
|
|
797
|
-
|
|
798
762
|
const success = await this.broadcastPartialTransaction(payload);
|
|
799
763
|
if (!success) {
|
|
800
764
|
throw new Error("Failed to broadcast transfer transaction after multiple attempts.");
|
|
@@ -804,7 +768,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
804
768
|
|
|
805
769
|
}
|
|
806
770
|
|
|
807
|
-
async #
|
|
771
|
+
async #balanceMigrationOperation() {
|
|
808
772
|
|
|
809
773
|
const isInitDisabled = await this.#state.isInitalizationDisabled()
|
|
810
774
|
|
|
@@ -849,11 +813,18 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
849
813
|
await fileUtils.createMigrationEntryFile(addressBalancePair, migrationNumber);
|
|
850
814
|
|
|
851
815
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
852
|
-
|
|
853
|
-
|
|
816
|
+
|
|
817
|
+
let messages = [];
|
|
818
|
+
|
|
819
|
+
for (const [recipientAddress, amountBuffer] of addressBalancePair) {
|
|
820
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config).buildCompleteBalanceInitializationMessage(
|
|
821
|
+
this.#wallet.address,
|
|
822
|
+
recipientAddress,
|
|
823
|
+
amountBuffer,
|
|
854
824
|
txValidity,
|
|
855
|
-
|
|
856
|
-
);
|
|
825
|
+
)
|
|
826
|
+
messages.push(safeEncodeApplyOperation(payload));
|
|
827
|
+
}
|
|
857
828
|
|
|
858
829
|
console.log(`Total balance to migrate: ${bigIntToDecimalString(totalBalance)} across ${totalAddresses} addresses.`);
|
|
859
830
|
|
|
@@ -903,6 +874,10 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
903
874
|
if (!this.#config.enableWallet) {
|
|
904
875
|
throw new Error("Can not initialize an admin - wallet is not enabled.");
|
|
905
876
|
}
|
|
877
|
+
const isInitDisabled = await this.#state.isInitalizationDisabled();
|
|
878
|
+
if (isInitDisabled) {
|
|
879
|
+
throw new Error("Can not disable initialization - it is already disabled.");
|
|
880
|
+
}
|
|
906
881
|
const adminEntry = await this.#state.getAdminEntry();
|
|
907
882
|
|
|
908
883
|
if (!adminEntry) {
|
|
@@ -912,15 +887,24 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
912
887
|
if (!this.#isAdmin(adminEntry)) {
|
|
913
888
|
throw new Error('Cannot perform whitelisting - you are not the admin!.');
|
|
914
889
|
}
|
|
915
|
-
|
|
890
|
+
if (!this.#wallet) {
|
|
891
|
+
throw new Error("Can not initialize an admin - wallet is not initialized.");
|
|
892
|
+
}
|
|
893
|
+
if (!this.#state.writingKey) {
|
|
894
|
+
throw new Error("Can not initialize an admin - writing key is not initialized.");
|
|
895
|
+
}
|
|
916
896
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
917
|
-
|
|
918
|
-
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
900
|
+
.buildCompleteDisableInitializationMessage(
|
|
901
|
+
this.#wallet.address,
|
|
919
902
|
this.#state.writingKey,
|
|
920
903
|
txValidity,
|
|
921
904
|
)
|
|
922
905
|
console.log('Disabling initialization...');
|
|
923
|
-
|
|
906
|
+
const encodedPayload = safeEncodeApplyOperation(payload);
|
|
907
|
+
await this.#state.append(encodedPayload);
|
|
924
908
|
}
|
|
925
909
|
|
|
926
910
|
async interactiveMode() {
|
|
@@ -951,26 +935,22 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
951
935
|
if (rl) rl.close();
|
|
952
936
|
await this.close();
|
|
953
937
|
},
|
|
954
|
-
"/add_admin": () => this.#handleAdminCreation(),
|
|
955
|
-
"/add_admin --recovery": () => this.#handleAdminRecovery(),
|
|
956
|
-
"/add_whitelist": () => this.#handleWhitelistOperations(),
|
|
957
|
-
"/add_writer": () => this.#
|
|
958
|
-
"/remove_writer": () => this.#
|
|
959
|
-
"/core": () => coreInfoCommand(this.#state),
|
|
960
|
-
"/indexers_list": async () =>
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
"/validator_pool": () => {
|
|
964
|
-
this.#network.validatorConnectionManager.prettyPrint();
|
|
965
|
-
},
|
|
966
|
-
"/stats": () => verifyDag(
|
|
938
|
+
"/add_admin": async () => await this.#handleAdminCreation(),
|
|
939
|
+
"/add_admin --recovery": async () => await this.#handleAdminRecovery(),
|
|
940
|
+
"/add_whitelist": async () => await this.#handleWhitelistOperations(),
|
|
941
|
+
"/add_writer": async () => await this.#requestWriterRole(true),
|
|
942
|
+
"/remove_writer": async () => await this.#requestWriterRole(false),
|
|
943
|
+
"/core": async () => await coreInfoCommand(this.#state),
|
|
944
|
+
"/indexers_list": async () => console.log(await this.#state.getIndexersEntry()),
|
|
945
|
+
"/validator_pool": () => this.#network.validatorConnectionManager.prettyPrint(),
|
|
946
|
+
"/stats": async () => await verifyDag(
|
|
967
947
|
this.#state,
|
|
968
948
|
this.#network,
|
|
969
949
|
this.#wallet,
|
|
970
950
|
this.#state.writingKey
|
|
971
951
|
),
|
|
972
|
-
"/balance_migration": () => this.#
|
|
973
|
-
"/disable_initialization": () => this.#disableInitialization()
|
|
952
|
+
"/balance_migration": async () => await this.#balanceMigrationOperation(),
|
|
953
|
+
"/disable_initialization": async () => await this.#disableInitialization()
|
|
974
954
|
};
|
|
975
955
|
|
|
976
956
|
if (exactHandlers[command]) {
|
|
@@ -988,20 +968,20 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
988
968
|
|
|
989
969
|
if (input.startsWith("/add_indexer")) {
|
|
990
970
|
const address = parts[0];
|
|
991
|
-
await this.#
|
|
971
|
+
await this.#updateWriterToIndexerRole(address, true);
|
|
992
972
|
} else if (input.startsWith("/remove_indexer")) {
|
|
993
973
|
const address = parts[0];
|
|
994
|
-
await this.#
|
|
974
|
+
await this.#updateWriterToIndexerRole(address, false);
|
|
995
975
|
} else if (input.startsWith("/ban_writer")) {
|
|
996
976
|
const address = parts[0];
|
|
997
|
-
await this.#
|
|
977
|
+
await this.#banValidator(address);
|
|
998
978
|
} else if (input.startsWith("/deployment")) {
|
|
999
979
|
const bootstrapToDeploy = parts[0];
|
|
1000
980
|
const channel = parts[1] || randomBytes(32).toString("hex");
|
|
1001
981
|
if (channel.length !== 64 || !isHexString(channel)) {
|
|
1002
982
|
throw new Error("Channel must be a 32-byte hex string");
|
|
1003
983
|
}
|
|
1004
|
-
await this.#
|
|
984
|
+
await this.#deployBootstrap(bootstrapToDeploy, channel);
|
|
1005
985
|
} else if (input.startsWith("/get_validator_addr")) {
|
|
1006
986
|
const wkHexString = parts[0];
|
|
1007
987
|
await getValidatorAddressCommand(this.#state, wkHexString, this.#config.addressPrefix);
|
|
@@ -1045,13 +1025,6 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
1045
1025
|
const result = getUnconfirmedLengthCommand(this.#state);
|
|
1046
1026
|
if (rl) rl.prompt();
|
|
1047
1027
|
return result;
|
|
1048
|
-
} else if (input.startsWith("/broadcast_transaction")) {
|
|
1049
|
-
if (!payload) {
|
|
1050
|
-
throw new Error("Transaction payload is required for broadcast_transaction command.");
|
|
1051
|
-
}
|
|
1052
|
-
const result = await this.broadcastTransactionCommand(payload);
|
|
1053
|
-
if (rl) rl.prompt();
|
|
1054
|
-
return result;
|
|
1055
1028
|
} else if (input.startsWith("/get_tx_payloads_bulk")) {
|
|
1056
1029
|
if (!payload) {
|
|
1057
1030
|
throw new Error("Missing payload for fetching tx payloads.");
|