trac-msb 0.2.8 → 0.2.10
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/.github/workflows/acceptance-tests.yml +7 -11
- package/.github/workflows/lint-pr-title.yml +26 -0
- package/.github/workflows/unit-tests.yml +2 -8
- package/CODE_OF_CONDUCT.md +128 -0
- package/README.md +33 -18
- package/docker-compose.yml +1 -0
- package/docs/trac_network_http_api.openapi.yaml +889 -0
- package/msb.mjs +5 -22
- package/package.json +14 -10
- package/proto/network.proto +74 -0
- package/rpc/create_server.js +2 -2
- package/rpc/handlers.js +165 -92
- package/rpc/routes/v1.js +3 -1
- package/rpc/rpc_server.js +4 -4
- package/rpc/rpc_services.js +62 -25
- package/rpc/utils/helpers.js +83 -52
- package/src/config/args.js +46 -0
- package/src/config/config.js +78 -5
- package/src/config/env.js +70 -3
- package/src/core/network/Network.js +34 -70
- 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 +2 -3
- 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 +17 -16
- package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +10 -15
- 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 +5 -5
- package/src/core/network/services/MessageOrchestrator.js +2 -2
- package/src/core/network/services/TransactionPoolService.js +5 -6
- package/src/core/network/services/TransactionRateLimiterService.js +12 -13
- package/src/core/network/services/ValidatorObserverService.js +5 -6
- package/src/core/state/State.js +3 -5
- package/src/index.js +156 -181
- 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/check.js +1 -1
- package/src/utils/cli.js +0 -8
- package/src/utils/constants.js +33 -30
- package/src/utils/fileUtils.js +13 -0
- package/src/utils/normalizers.js +84 -2
- package/src/utils/protobuf/network.cjs +840 -0
- package/src/utils/protobuf/operationHelpers.js +10 -0
- package/src/utils/type.js +26 -0
- package/tests/acceptance/v1/balance/balance.test.mjs +1 -2
- package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +26 -30
- package/tests/acceptance/v1/health/health.test.mjs +33 -0
- package/tests/acceptance/v1/rpc.test.mjs +4 -3
- package/tests/acceptance/v1/tx/tx.test.mjs +27 -16
- package/tests/acceptance/v1/tx-details/tx-details.test.mjs +26 -12
- package/tests/fixtures/check.fixtures.js +33 -32
- package/tests/fixtures/networkV1.fixtures.js +85 -0
- package/tests/fixtures/protobuf.fixtures.js +109 -25
- package/tests/helpers/StateNetworkFactory.js +2 -2
- package/tests/helpers/address.js +6 -0
- package/tests/helpers/autobaseTestHelpers.js +2 -1
- package/tests/helpers/config.js +2 -1
- package/tests/helpers/setupApplyTests.js +59 -56
- 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 +201 -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/fileUtils/readAddressesFromWhitelistFile.test.js +4 -3
- package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +3 -2
- package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +3 -2
- package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
- package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
- package/tests/unit/utils/type/type.test.js +25 -0
- package/tests/unit/utils/utils.test.js +1 -0
- 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,25 +43,23 @@ 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
|
/**
|
|
65
|
-
* @param {
|
|
58
|
+
* @param {Config} config
|
|
66
59
|
**/
|
|
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,12 +88,16 @@ 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
|
|
|
104
98
|
async _open() {
|
|
99
|
+
await fileUtils.ensureCoresStoreDir(this.#config);
|
|
100
|
+
|
|
105
101
|
if (this.#config.enableWallet) {
|
|
106
102
|
await this.#wallet.initKeyPair(
|
|
107
103
|
this.#config.keyPairPath,
|
|
@@ -113,15 +109,12 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
113
109
|
|
|
114
110
|
await this.#state.ready();
|
|
115
111
|
await this.#network.ready();
|
|
116
|
-
this.#stateEventsListener();
|
|
112
|
+
await this.#stateEventsListener();
|
|
117
113
|
|
|
118
114
|
if (this.#config.enableWallet) {
|
|
119
115
|
printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#config.enableWallet);
|
|
120
116
|
}
|
|
121
117
|
|
|
122
|
-
this.#partialTransferValidator = new PartialTransfer(this.state, this.#wallet, this.#config);
|
|
123
|
-
this.#partialTransactionValidator = new PartialTransaction(this.state, this.#wallet ,this.#config);
|
|
124
|
-
|
|
125
118
|
await this.#network.replicate(
|
|
126
119
|
this.#state,
|
|
127
120
|
this.#store,
|
|
@@ -131,6 +124,8 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
131
124
|
const adminEntry = await this.#state.getAdminEntry();
|
|
132
125
|
await this.#setUpRoleAutomatically(adminEntry);
|
|
133
126
|
|
|
127
|
+
|
|
128
|
+
|
|
134
129
|
console.log(`isIndexer: ${this.#state.isIndexer()}`);
|
|
135
130
|
console.log(`isWriter: ${this.#state.isWritable()}`);
|
|
136
131
|
console.log("MSB Unsigned Length:", this.#state.getUnsignedLength());
|
|
@@ -182,41 +177,6 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
182
177
|
return await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
|
|
183
178
|
}
|
|
184
179
|
|
|
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
180
|
async #setUpRoleAutomatically() {
|
|
221
181
|
if (!this.#state.isWritable() && this.#config.enableRoleRequester) {
|
|
222
182
|
console.log("Requesting writer role... This may take a moment.");
|
|
@@ -296,14 +256,17 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
296
256
|
}
|
|
297
257
|
|
|
298
258
|
const txValidity = await PeerWallet.blake3(this.#config.bootstrap);
|
|
299
|
-
const addAdminMessage = await
|
|
300
|
-
.
|
|
259
|
+
const addAdminMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
260
|
+
.buildCompleteAddAdminMessage(
|
|
261
|
+
this.#wallet.address,
|
|
301
262
|
this.#state.writingKey,
|
|
302
|
-
txValidity
|
|
303
|
-
)
|
|
263
|
+
txValidity,
|
|
264
|
+
)
|
|
265
|
+
const encodedPayload = safeEncodeApplyOperation(addAdminMessage);
|
|
304
266
|
|
|
305
|
-
await this.#state.append(
|
|
267
|
+
await this.#state.append(encodedPayload);
|
|
306
268
|
}
|
|
269
|
+
|
|
307
270
|
async #handleAdminRecovery() {
|
|
308
271
|
if (!this.#config.enableWallet) {
|
|
309
272
|
throw new Error("Can not initialize an admin - wallet is not enabled.");
|
|
@@ -329,10 +292,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
329
292
|
}
|
|
330
293
|
|
|
331
294
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
332
|
-
const adminRecoveryMessage = await
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
295
|
+
const adminRecoveryMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
296
|
+
.buildPartialAdminRecoveryMessage(
|
|
297
|
+
this.#wallet.address,
|
|
298
|
+
this.#state.writingKey,
|
|
299
|
+
txValidity,
|
|
300
|
+
"json"
|
|
301
|
+
)
|
|
336
302
|
|
|
337
303
|
const success = await this.broadcastPartialTransaction(adminRecoveryMessage);
|
|
338
304
|
|
|
@@ -366,12 +332,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
366
332
|
|
|
367
333
|
for (const addressToWhitelist of addresses) {
|
|
368
334
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
369
|
-
const
|
|
370
|
-
.
|
|
335
|
+
const appendWhitelistMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
336
|
+
.buildCompleteAppendWhitelistMessage(
|
|
337
|
+
this.#wallet.address,
|
|
338
|
+
addressToWhitelist,
|
|
371
339
|
txValidity,
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
340
|
+
)
|
|
341
|
+
const encodedPayload = safeEncodeApplyOperation(appendWhitelistMessage)
|
|
375
342
|
messages.set(addressToWhitelist, encodedPayload);
|
|
376
343
|
}
|
|
377
344
|
|
|
@@ -445,10 +412,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
445
412
|
}
|
|
446
413
|
|
|
447
414
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
415
|
+
|
|
416
|
+
const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
417
|
+
.buildPartialAddWriterMessage(
|
|
418
|
+
this.#wallet.address,
|
|
419
|
+
this.#state.writingKey,
|
|
420
|
+
txValidity,
|
|
421
|
+
'json'
|
|
452
422
|
)
|
|
453
423
|
|
|
454
424
|
const success = await this.broadcastPartialTransaction(assembledMessage);
|
|
@@ -477,10 +447,12 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
477
447
|
}
|
|
478
448
|
|
|
479
449
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
480
|
-
const assembledMessage = await
|
|
481
|
-
.
|
|
482
|
-
|
|
483
|
-
|
|
450
|
+
const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
451
|
+
.buildPartialRemoveWriterMessage(
|
|
452
|
+
this.#wallet.address,
|
|
453
|
+
nodeEntry.wk,
|
|
454
|
+
txValidity,
|
|
455
|
+
"json"
|
|
484
456
|
)
|
|
485
457
|
|
|
486
458
|
const success = await this.broadcastPartialTransaction(assembledMessage);
|
|
@@ -492,10 +464,10 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
492
464
|
console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
|
|
493
465
|
}
|
|
494
466
|
|
|
495
|
-
async #
|
|
467
|
+
async #updateWriterToIndexerRole(addressToUpdate, toAdd) {
|
|
496
468
|
if (!this.#config.enableWallet) {
|
|
497
469
|
throw new Error(
|
|
498
|
-
`Can not request indexer role for: ${
|
|
470
|
+
`Can not request indexer role for: ${addressToUpdate} - wallet is not enabled.`
|
|
499
471
|
);
|
|
500
472
|
}
|
|
501
473
|
|
|
@@ -503,29 +475,29 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
503
475
|
|
|
504
476
|
if (!adminEntry) {
|
|
505
477
|
throw new Error(
|
|
506
|
-
`Can not request indexer role for: ${
|
|
478
|
+
`Can not request indexer role for: ${addressToUpdate} - admin entry has not been initialized.`
|
|
507
479
|
);
|
|
508
480
|
}
|
|
509
481
|
|
|
510
|
-
if (!isAddressValid(
|
|
482
|
+
if (!isAddressValid(addressToUpdate, this.#config.addressPrefix)) {
|
|
511
483
|
throw new Error(
|
|
512
|
-
`Can not request indexer role for: ${
|
|
484
|
+
`Can not request indexer role for: ${addressToUpdate} - invalid address.`
|
|
513
485
|
);
|
|
514
486
|
}
|
|
515
487
|
|
|
516
488
|
if (!this.#isAdmin(adminEntry) && !this.#state.isWritable()) {
|
|
517
489
|
throw new Error(
|
|
518
|
-
`Can not request indexer role for: ${
|
|
490
|
+
`Can not request indexer role for: ${addressToUpdate} - You are not an admin or writer.`
|
|
519
491
|
);
|
|
520
492
|
}
|
|
521
|
-
const nodeEntry = await this.#state.getNodeEntry(
|
|
493
|
+
const nodeEntry = await this.#state.getNodeEntry(addressToUpdate);
|
|
522
494
|
if (!nodeEntry) {
|
|
523
495
|
throw new Error(
|
|
524
|
-
`Can not request indexer role for: ${
|
|
496
|
+
`Can not request indexer role for: ${addressToUpdate} - node entry has not been not initialized.`
|
|
525
497
|
);
|
|
526
498
|
}
|
|
527
499
|
|
|
528
|
-
const indexerNodeEntry = await this.#state.getNodeEntry(
|
|
500
|
+
const indexerNodeEntry = await this.#state.getNodeEntry(addressToUpdate);
|
|
529
501
|
const indexerListHasAddress = await this.#state.isWkInIndexersEntry(
|
|
530
502
|
indexerNodeEntry.wk,
|
|
531
503
|
);
|
|
@@ -533,7 +505,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
533
505
|
if (toAdd) {
|
|
534
506
|
if (indexerListHasAddress) {
|
|
535
507
|
throw new Error(
|
|
536
|
-
`Cannot update indexer role for: ${
|
|
508
|
+
`Cannot update indexer role for: ${addressToUpdate} - address is already in indexers list.`
|
|
537
509
|
);
|
|
538
510
|
}
|
|
539
511
|
|
|
@@ -545,71 +517,86 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
545
517
|
|
|
546
518
|
if (!canAddIndexer) {
|
|
547
519
|
throw new Error(
|
|
548
|
-
`Can not request indexer role for: ${
|
|
520
|
+
`Can not request indexer role for: ${addressToUpdate} - node is not whitelisted, not a writer or already an indexer.`
|
|
549
521
|
);
|
|
550
522
|
}
|
|
551
523
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
524
|
+
|
|
525
|
+
const assembledAddIndexerMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
526
|
+
.buildCompleteAddIndexerMessage(
|
|
527
|
+
this.#wallet.address,
|
|
528
|
+
addressToUpdate,
|
|
529
|
+
txValidity,
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
const encodedPayload = safeEncodeApplyOperation(assembledAddIndexerMessage);
|
|
533
|
+
|
|
534
|
+
await this.#state.append(encodedPayload);
|
|
555
535
|
} else {
|
|
556
536
|
const canRemoveIndexer =
|
|
557
537
|
!toAdd && nodeEntry.isIndexer && indexerListHasAddress;
|
|
558
538
|
|
|
559
539
|
if (!canRemoveIndexer) {
|
|
560
540
|
throw new Error(
|
|
561
|
-
`Can not remove indexer role for: ${
|
|
541
|
+
`Can not remove indexer role for: ${addressToUpdate} - node is not an indexer or address is not in indexers list.`
|
|
562
542
|
);
|
|
563
543
|
}
|
|
564
544
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
565
|
-
const
|
|
566
|
-
.
|
|
545
|
+
const assembledRemoveIndexerMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
546
|
+
.buildCompleteRemoveIndexerMessage(
|
|
547
|
+
this.#wallet.address,
|
|
548
|
+
addressToUpdate,
|
|
549
|
+
txValidity,
|
|
550
|
+
)
|
|
551
|
+
const encodedPayload = safeEncodeApplyOperation(assembledRemoveIndexerMessage);
|
|
567
552
|
|
|
568
|
-
await this.#state.append(
|
|
553
|
+
await this.#state.append(encodedPayload);
|
|
569
554
|
}
|
|
570
555
|
}
|
|
571
556
|
|
|
572
|
-
async #banValidator(
|
|
557
|
+
async #banValidator(addresstToBan) {
|
|
573
558
|
if (!this.#config.enableWallet) {
|
|
574
559
|
throw new Error(
|
|
575
|
-
`Can not ban writer with address: ${
|
|
560
|
+
`Can not ban writer with address: ${addresstToBan} - wallet is not enabled.`
|
|
576
561
|
);
|
|
577
562
|
}
|
|
578
563
|
const adminEntry = await this.#state.getAdminEntry();
|
|
579
564
|
|
|
580
565
|
if (!adminEntry) {
|
|
581
566
|
throw new Error(
|
|
582
|
-
`Can not ban writer with address: ${
|
|
567
|
+
`Can not ban writer with address: ${addresstToBan} - admin entry has not been initialized.`
|
|
583
568
|
);
|
|
584
569
|
}
|
|
585
570
|
|
|
586
|
-
if (!isAddressValid(
|
|
571
|
+
if (!isAddressValid(addresstToBan, this.#config.addressPrefix)) {
|
|
587
572
|
throw new Error(
|
|
588
|
-
`Can not ban writer with address: ${
|
|
573
|
+
`Can not ban writer with address: ${addresstToBan} - invalid address.`
|
|
589
574
|
);
|
|
590
575
|
}
|
|
591
576
|
|
|
592
577
|
if (!this.#isAdmin(adminEntry)) {
|
|
593
578
|
throw new Error(
|
|
594
|
-
`Can not ban writer with address: ${
|
|
579
|
+
`Can not ban writer with address: ${addresstToBan} - You are not an admin.`
|
|
595
580
|
);
|
|
596
581
|
}
|
|
597
582
|
|
|
598
|
-
const isWhitelisted = await this.#state.isAddressWhitelisted(
|
|
599
|
-
const nodeEntry = await this.#state.getNodeEntry(
|
|
583
|
+
const isWhitelisted = await this.#state.isAddressWhitelisted(addresstToBan);
|
|
584
|
+
const nodeEntry = await this.#state.getNodeEntry(addresstToBan);
|
|
600
585
|
|
|
601
586
|
if (!isWhitelisted || null === nodeEntry || nodeEntry.isIndexer === true) {
|
|
602
587
|
throw new Error(
|
|
603
|
-
`Can not ban writer with address: ${
|
|
588
|
+
`Can not ban writer with address: ${addresstToBan} - node is not whitelisted or is an indexer.`
|
|
604
589
|
);
|
|
605
590
|
}
|
|
606
591
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
607
|
-
const assembledBanValidatorMessage = await
|
|
608
|
-
.
|
|
609
|
-
address,
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
592
|
+
const assembledBanValidatorMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
593
|
+
.buildCompleteBanWriterMessage(
|
|
594
|
+
this.#wallet.address,
|
|
595
|
+
addresstToBan,
|
|
596
|
+
txValidity,
|
|
597
|
+
)
|
|
598
|
+
const encodedPayload = safeEncodeApplyOperation(assembledBanValidatorMessage)
|
|
599
|
+
await this.#state.append(encodedPayload);
|
|
613
600
|
}
|
|
614
601
|
|
|
615
602
|
async #deployBootstrap(externalBootstrap, channel) {
|
|
@@ -682,12 +669,15 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
682
669
|
}
|
|
683
670
|
|
|
684
671
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
685
|
-
|
|
686
|
-
|
|
672
|
+
|
|
673
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
674
|
+
.buildPartialBootstrapDeploymentMessage(
|
|
675
|
+
this.#wallet.address,
|
|
687
676
|
externalBootstrap,
|
|
688
677
|
channel,
|
|
689
|
-
txValidity
|
|
690
|
-
|
|
678
|
+
txValidity,
|
|
679
|
+
"json"
|
|
680
|
+
)
|
|
691
681
|
|
|
692
682
|
const success = await this.broadcastPartialTransaction(payload);
|
|
693
683
|
|
|
@@ -703,31 +693,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
703
693
|
|
|
704
694
|
}
|
|
705
695
|
|
|
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) {
|
|
696
|
+
async #handleTransferOperation(recipientAddress, amount) {
|
|
731
697
|
if (!this.#config.enableWallet) {
|
|
732
698
|
throw new Error(
|
|
733
699
|
"Can not perform transfer - wallet is not enabled."
|
|
@@ -740,7 +706,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
740
706
|
);
|
|
741
707
|
}
|
|
742
708
|
|
|
743
|
-
if (!isAddressValid(
|
|
709
|
+
if (!isAddressValid(recipientAddress, this.#config.addressPrefix)) {
|
|
744
710
|
throw new Error("Invalid recipient address");
|
|
745
711
|
}
|
|
746
712
|
|
|
@@ -765,7 +731,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
765
731
|
const fee = this.#state.getFee();
|
|
766
732
|
const feeBigInt = bufferToBigInt(fee);
|
|
767
733
|
const senderBalance = bufferToBigInt(senderEntry.balance);
|
|
768
|
-
const isSelfTransfer =
|
|
734
|
+
const isSelfTransfer = recipientAddress === this.#wallet.address;
|
|
769
735
|
const totalDeductedAmount = isSelfTransfer ? feeBigInt : amountBigInt + feeBigInt;
|
|
770
736
|
|
|
771
737
|
if (!(senderBalance >= totalDeductedAmount)) {
|
|
@@ -773,13 +739,14 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
773
739
|
}
|
|
774
740
|
|
|
775
741
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
776
|
-
const payload = await
|
|
777
|
-
.
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
742
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
743
|
+
.buildPartialTransferOperationMessage(
|
|
744
|
+
this.#wallet.address,
|
|
745
|
+
recipientAddress,
|
|
746
|
+
amountBuffer,
|
|
747
|
+
txValidity,
|
|
748
|
+
"json"
|
|
749
|
+
)
|
|
783
750
|
|
|
784
751
|
const expectedNewBalance = senderBalance - totalDeductedAmount;
|
|
785
752
|
console.info('Transfer Details:');
|
|
@@ -794,7 +761,6 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
794
761
|
console.info(`Total: ${bigIntToDecimalString(totalDeductedAmount)}`);
|
|
795
762
|
}
|
|
796
763
|
console.log(`Expected Balance After Transfer: ${bigIntToDecimalString(expectedNewBalance)}`);
|
|
797
|
-
|
|
798
764
|
const success = await this.broadcastPartialTransaction(payload);
|
|
799
765
|
if (!success) {
|
|
800
766
|
throw new Error("Failed to broadcast transfer transaction after multiple attempts.");
|
|
@@ -804,7 +770,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
804
770
|
|
|
805
771
|
}
|
|
806
772
|
|
|
807
|
-
async #
|
|
773
|
+
async #balanceMigrationOperation() {
|
|
808
774
|
|
|
809
775
|
const isInitDisabled = await this.#state.isInitalizationDisabled()
|
|
810
776
|
|
|
@@ -849,11 +815,18 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
849
815
|
await fileUtils.createMigrationEntryFile(addressBalancePair, migrationNumber);
|
|
850
816
|
|
|
851
817
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
852
|
-
|
|
853
|
-
|
|
818
|
+
|
|
819
|
+
let messages = [];
|
|
820
|
+
|
|
821
|
+
for (const [recipientAddress, amountBuffer] of addressBalancePair) {
|
|
822
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config).buildCompleteBalanceInitializationMessage(
|
|
823
|
+
this.#wallet.address,
|
|
824
|
+
recipientAddress,
|
|
825
|
+
amountBuffer,
|
|
854
826
|
txValidity,
|
|
855
|
-
|
|
856
|
-
);
|
|
827
|
+
)
|
|
828
|
+
messages.push(safeEncodeApplyOperation(payload));
|
|
829
|
+
}
|
|
857
830
|
|
|
858
831
|
console.log(`Total balance to migrate: ${bigIntToDecimalString(totalBalance)} across ${totalAddresses} addresses.`);
|
|
859
832
|
|
|
@@ -903,6 +876,10 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
903
876
|
if (!this.#config.enableWallet) {
|
|
904
877
|
throw new Error("Can not initialize an admin - wallet is not enabled.");
|
|
905
878
|
}
|
|
879
|
+
const isInitDisabled = await this.#state.isInitalizationDisabled();
|
|
880
|
+
if (isInitDisabled) {
|
|
881
|
+
throw new Error("Can not disable initialization - it is already disabled.");
|
|
882
|
+
}
|
|
906
883
|
const adminEntry = await this.#state.getAdminEntry();
|
|
907
884
|
|
|
908
885
|
if (!adminEntry) {
|
|
@@ -912,15 +889,24 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
912
889
|
if (!this.#isAdmin(adminEntry)) {
|
|
913
890
|
throw new Error('Cannot perform whitelisting - you are not the admin!.');
|
|
914
891
|
}
|
|
915
|
-
|
|
892
|
+
if (!this.#wallet) {
|
|
893
|
+
throw new Error("Can not initialize an admin - wallet is not initialized.");
|
|
894
|
+
}
|
|
895
|
+
if (!this.#state.writingKey) {
|
|
896
|
+
throw new Error("Can not initialize an admin - writing key is not initialized.");
|
|
897
|
+
}
|
|
916
898
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
917
|
-
|
|
918
|
-
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
902
|
+
.buildCompleteDisableInitializationMessage(
|
|
903
|
+
this.#wallet.address,
|
|
919
904
|
this.#state.writingKey,
|
|
920
905
|
txValidity,
|
|
921
906
|
)
|
|
922
907
|
console.log('Disabling initialization...');
|
|
923
|
-
|
|
908
|
+
const encodedPayload = safeEncodeApplyOperation(payload);
|
|
909
|
+
await this.#state.append(encodedPayload);
|
|
924
910
|
}
|
|
925
911
|
|
|
926
912
|
async interactiveMode() {
|
|
@@ -951,26 +937,22 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
951
937
|
if (rl) rl.close();
|
|
952
938
|
await this.close();
|
|
953
939
|
},
|
|
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(
|
|
940
|
+
"/add_admin": async () => await this.#handleAdminCreation(),
|
|
941
|
+
"/add_admin --recovery": async () => await this.#handleAdminRecovery(),
|
|
942
|
+
"/add_whitelist": async () => await this.#handleWhitelistOperations(),
|
|
943
|
+
"/add_writer": async () => await this.#requestWriterRole(true),
|
|
944
|
+
"/remove_writer": async () => await this.#requestWriterRole(false),
|
|
945
|
+
"/core": async () => await coreInfoCommand(this.#state),
|
|
946
|
+
"/indexers_list": async () => console.log(await this.#state.getIndexersEntry()),
|
|
947
|
+
"/validator_pool": () => this.#network.validatorConnectionManager.prettyPrint(),
|
|
948
|
+
"/stats": async () => await verifyDag(
|
|
967
949
|
this.#state,
|
|
968
950
|
this.#network,
|
|
969
951
|
this.#wallet,
|
|
970
952
|
this.#state.writingKey
|
|
971
953
|
),
|
|
972
|
-
"/balance_migration": () => this.#
|
|
973
|
-
"/disable_initialization": () => this.#disableInitialization()
|
|
954
|
+
"/balance_migration": async () => await this.#balanceMigrationOperation(),
|
|
955
|
+
"/disable_initialization": async () => await this.#disableInitialization()
|
|
974
956
|
};
|
|
975
957
|
|
|
976
958
|
if (exactHandlers[command]) {
|
|
@@ -988,20 +970,20 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
988
970
|
|
|
989
971
|
if (input.startsWith("/add_indexer")) {
|
|
990
972
|
const address = parts[0];
|
|
991
|
-
await this.#
|
|
973
|
+
await this.#updateWriterToIndexerRole(address, true);
|
|
992
974
|
} else if (input.startsWith("/remove_indexer")) {
|
|
993
975
|
const address = parts[0];
|
|
994
|
-
await this.#
|
|
976
|
+
await this.#updateWriterToIndexerRole(address, false);
|
|
995
977
|
} else if (input.startsWith("/ban_writer")) {
|
|
996
978
|
const address = parts[0];
|
|
997
|
-
await this.#
|
|
979
|
+
await this.#banValidator(address);
|
|
998
980
|
} else if (input.startsWith("/deployment")) {
|
|
999
981
|
const bootstrapToDeploy = parts[0];
|
|
1000
982
|
const channel = parts[1] || randomBytes(32).toString("hex");
|
|
1001
983
|
if (channel.length !== 64 || !isHexString(channel)) {
|
|
1002
984
|
throw new Error("Channel must be a 32-byte hex string");
|
|
1003
985
|
}
|
|
1004
|
-
await this.#
|
|
986
|
+
await this.#deployBootstrap(bootstrapToDeploy, channel);
|
|
1005
987
|
} else if (input.startsWith("/get_validator_addr")) {
|
|
1006
988
|
const wkHexString = parts[0];
|
|
1007
989
|
await getValidatorAddressCommand(this.#state, wkHexString, this.#config.addressPrefix);
|
|
@@ -1045,13 +1027,6 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
1045
1027
|
const result = getUnconfirmedLengthCommand(this.#state);
|
|
1046
1028
|
if (rl) rl.prompt();
|
|
1047
1029
|
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
1030
|
} else if (input.startsWith("/get_tx_payloads_bulk")) {
|
|
1056
1031
|
if (!payload) {
|
|
1057
1032
|
throw new Error("Missing payload for fetching tx payloads.");
|