trac-msb 0.2.7 → 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/.github/workflows/publish.yml +8 -16
- package/msb.mjs +13 -25
- package/package.json +8 -4
- package/proto/network.proto +74 -0
- package/rpc/{create_server.mjs → create_server.js} +4 -4
- package/rpc/{handlers.mjs → handlers.js} +7 -7
- package/rpc/routes/{index.mjs → index.js} +1 -1
- package/rpc/routes/{v1.mjs → v1.js} +1 -1
- package/rpc/rpc_server.js +10 -0
- package/rpc/rpc_services.js +48 -7
- package/rpc/utils/{helpers.mjs → helpers.js} +1 -1
- package/src/config/config.js +137 -0
- package/src/config/env.js +63 -0
- package/src/core/network/Network.js +133 -119
- package/src/core/network/identity/NetworkWalletFactory.js +5 -6
- 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/ValidatorResponse.js +2 -2
- package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +13 -6
- 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/protocols/shared/handlers/TransferOperationHandler.js +57 -0
- package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +21 -26
- package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +3 -3
- package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +15 -12
- package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +10 -11
- package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +10 -7
- package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +40 -22
- package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
- package/src/core/network/services/ConnectionManager.js +13 -19
- package/src/core/network/services/MessageOrchestrator.js +10 -22
- package/src/core/network/services/TransactionPoolService.js +10 -10
- package/src/core/network/services/TransactionRateLimiterService.js +5 -3
- package/src/core/network/services/ValidatorObserverService.js +46 -21
- package/src/core/state/State.js +137 -141
- package/src/core/state/utils/address.js +18 -16
- package/src/core/state/utils/adminEntry.js +17 -16
- package/src/core/state/utils/deploymentEntry.js +15 -15
- package/src/core/state/utils/transaction.js +3 -95
- package/src/index.js +250 -325
- 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 +21 -17
- package/src/utils/cli.js +0 -8
- package/src/utils/cliCommands.js +11 -11
- package/src/utils/constants.js +36 -24
- package/src/utils/fileUtils.js +1 -4
- package/src/utils/helpers.js +9 -20
- package/src/utils/migrationUtils.js +2 -2
- package/src/utils/normalizers.js +94 -11
- package/src/utils/protobuf/network.cjs +840 -0
- package/src/utils/protobuf/operationHelpers.js +10 -0
- package/tests/acceptance/v1/account/account.test.mjs +2 -2
- package/tests/acceptance/v1/balance/balance.test.mjs +1 -1
- package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +11 -2
- package/tests/acceptance/v1/rpc.test.mjs +10 -10
- package/tests/acceptance/v1/tx/tx.test.mjs +4 -2
- package/tests/acceptance/v1/tx-details/tx-details.test.mjs +7 -3
- package/tests/fixtures/check.fixtures.js +42 -42
- package/tests/fixtures/networkV1.fixtures.js +84 -0
- package/tests/fixtures/protobuf.fixtures.js +110 -26
- package/tests/helpers/StateNetworkFactory.js +3 -5
- package/tests/helpers/autobaseTestHelpers.js +1 -2
- package/tests/helpers/config.js +3 -0
- package/tests/helpers/setupApplyTests.js +113 -99
- package/tests/helpers/transactionPayloads.mjs +26 -12
- 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 +10 -7
- package/tests/unit/network/NetworkWalletFactory.test.js +14 -14
- 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 +11 -8
- package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +11 -7
- package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -20
- package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +57 -48
- package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +2 -1
- package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +72 -57
- package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +3 -7
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +12 -14
- package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +18 -13
- package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +2 -1
- package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +2 -1
- package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +27 -30
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +2 -1
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +24 -21
- package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +5 -4
- package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +4 -3
- package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +2 -1
- package/tests/unit/state/apply/common/commonScenarioHelper.js +16 -16
- package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +10 -5
- package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +2 -2
- package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +2 -1
- package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +2 -1
- package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +2 -1
- package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +2 -1
- package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +16 -9
- package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +6 -5
- package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +23 -19
- package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +45 -36
- package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +48 -45
- package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +32 -29
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +2 -1
- package/tests/unit/state/stateModule.test.js +0 -1
- package/tests/unit/state/stateTestUtils.js +7 -3
- package/tests/unit/state/utils/address.test.js +3 -3
- package/tests/unit/state/utils/adminEntry.test.js +10 -9
- package/tests/unit/unit.test.js +1 -1
- package/tests/unit/utils/buffer/buffer.test.js +62 -1
- package/tests/unit/utils/check/adminControlOperation.test.js +3 -3
- package/tests/unit/utils/check/balanceInitializationOperation.test.js +2 -2
- package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +2 -3
- package/tests/unit/utils/check/common.test.js +7 -6
- package/tests/unit/utils/check/coreAdminOperation.test.js +3 -3
- package/tests/unit/utils/check/roleAccessOperation.test.js +3 -2
- package/tests/unit/utils/check/transactionOperation.test.js +3 -3
- package/tests/unit/utils/check/transferOperation.test.js +3 -3
- package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +2 -1
- package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +2 -1
- package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +7 -0
- package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
- package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
- package/tests/unit/utils/utils.test.js +0 -1
- package/rpc/rpc_server.mjs +0 -10
- package/src/core/network/messaging/NetworkMessages.js +0 -63
- package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -112
- package/src/core/network/messaging/handlers/ResponseHandler.js +0 -108
- package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -116
- package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -143
- package/src/core/network/messaging/handlers/TransferOperationHandler.js +0 -52
- package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -94
- package/src/core/network/messaging/validators/AdminResponse.js +0 -58
- package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
- package/src/core/state/utils/indexerEntry.js +0 -105
- package/src/messages/base/StateBuilder.js +0 -25
- package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -421
- package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
- package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -299
- package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
- package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
- package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -131
- package/src/utils/crypto.js +0 -11
- package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -68
- package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -125
- package/tests/integration/apply/addIndexer.test.js +0 -237
- package/tests/integration/apply/addWhitelist.test.js +0 -53
- package/tests/integration/apply/addWriter.test.js +0 -244
- package/tests/integration/apply/apply.test.js +0 -19
- package/tests/integration/apply/banValidator.test.js +0 -109
- package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
- package/tests/integration/apply/postTx/postTx.test.js +0 -222
- package/tests/integration/apply/removeIndexer.test.js +0 -128
- package/tests/integration/apply/removeWriter.test.js +0 -167
- package/tests/integration/apply/transfer.test.js +0 -81
- 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 -16
- package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -69
- package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -16
- package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -442
- 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 -58
- package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -277
- package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
- package/tests/unit/state/utils/indexerEntry.test.js +0 -83
- package/tests/unit/state/utils/transaction.test.js +0 -97
- package/tests/unit/utils/crypto/createHash.test.js +0 -15
- /package/rpc/{constants.mjs → constants.js} +0 -0
- /package/rpc/{cors.mjs → cors.js} +0 -0
- /package/rpc/utils/{confirmedParameter.mjs → confirmedParameter.js} +0 -0
- /package/rpc/utils/{url.mjs → url.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";
|
|
@@ -6,36 +5,23 @@ import PeerWallet from "trac-wallet";
|
|
|
6
5
|
import b4a from "b4a";
|
|
7
6
|
import readline from "readline";
|
|
8
7
|
import tty from "tty";
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import { safeDecodeApplyOperation } from "./utils/protobuf/operationHelpers.js";
|
|
14
|
-
import { bufferToAddress, isAddressValid } from "./core/state/utils/address.js";
|
|
8
|
+
import { sleep, isHexString } from "./utils/helpers.js";
|
|
9
|
+
import { verifyDag, printHelp, printWalletInfo, printBalance } from "./utils/cli.js";
|
|
10
|
+
import { applyStateMessageFactory } from "./messages/state/applyStateMessageFactory.js";
|
|
11
|
+
import { isAddressValid } from "./core/state/utils/address.js";
|
|
15
12
|
import Network from "./core/network/Network.js";
|
|
16
13
|
import Check from "./utils/check.js";
|
|
17
14
|
import State from "./core/state/State.js";
|
|
18
|
-
import PartialStateMessageOperations from "./messages/partialStateMessages/PartialStateMessageOperations.js";
|
|
19
15
|
import {
|
|
20
16
|
EventType,
|
|
21
17
|
WHITELIST_SLEEP_INTERVAL,
|
|
22
18
|
BOOTSTRAP_HEXSTRING_LENGTH,
|
|
23
|
-
EntryType,
|
|
24
|
-
OperationType,
|
|
25
|
-
MAX_MESSAGE_SEND_ATTEMPTS,
|
|
26
19
|
CustomEventType,
|
|
27
20
|
BALANCE_MIGRATION_SLEEP_INTERVAL,
|
|
28
21
|
WHITELIST_MIGRATION_DIR
|
|
29
22
|
} from "./utils/constants.js";
|
|
30
|
-
import partialStateMessageOperations from "./messages/partialStateMessages/PartialStateMessageOperations.js";
|
|
31
23
|
import { randomBytes } from "hypercore-crypto";
|
|
32
|
-
import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString
|
|
33
|
-
import { ZERO_WK } from "./utils/buffer.js";
|
|
34
|
-
import { normalizeDecodedPayloadForJson, normalizeTransferOperation, normalizeTransactionOperation } from "./utils/normalizers.js"
|
|
35
|
-
import PartialTransfer from "./core/network/messaging/validators/PartialTransfer.js";
|
|
36
|
-
import { blake3Hash } from "./utils/crypto.js";
|
|
37
|
-
import deploymentEntryUtils from "./core/state/utils/deploymentEntry.js";
|
|
38
|
-
import PartialTransaction from "./core/network/messaging/validators/PartialTransaction.js";
|
|
24
|
+
import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString } from "./utils/amountSerialization.js"
|
|
39
25
|
import fileUtils from './utils/fileUtils.js';
|
|
40
26
|
import migrationUtils from './utils/migrationUtils.js';
|
|
41
27
|
import {
|
|
@@ -57,131 +43,76 @@ import {
|
|
|
57
43
|
getLicenseAddressCommand,
|
|
58
44
|
getLicenseCountCommand
|
|
59
45
|
} from "./utils/cliCommands.js";
|
|
46
|
+
import {safeEncodeApplyOperation} from "./utils/protobuf/operationHelpers.js";
|
|
47
|
+
|
|
60
48
|
export class MainSettlementBus extends ReadyResource {
|
|
61
|
-
// internal attributes
|
|
62
|
-
#options;
|
|
63
|
-
#stores_directory;
|
|
64
|
-
#key_pair_path;
|
|
65
|
-
#bootstrap;
|
|
66
|
-
#channel;
|
|
67
49
|
#store;
|
|
68
|
-
#enable_wallet;
|
|
69
50
|
#wallet;
|
|
70
51
|
#network;
|
|
71
52
|
#readline_instance;
|
|
72
|
-
#enable_validator_observer;
|
|
73
|
-
#enable_role_requester;
|
|
74
53
|
#state;
|
|
75
54
|
#isClosing = false;
|
|
76
|
-
#
|
|
77
|
-
#partialTransferValidator;
|
|
78
|
-
#partialTransactionValidator;
|
|
79
|
-
#maxRetries
|
|
55
|
+
#config
|
|
80
56
|
|
|
81
|
-
|
|
57
|
+
/**
|
|
58
|
+
* @param {object} config
|
|
59
|
+
**/
|
|
60
|
+
constructor(config) {
|
|
82
61
|
super();
|
|
83
|
-
this.#
|
|
84
|
-
this.#
|
|
85
|
-
this.#
|
|
86
|
-
this.#enable_wallet = options.enable_wallet !== false;
|
|
87
|
-
this.enable_interactive_mode = options.enable_interactive_mode !== false;
|
|
88
|
-
this.#is_admin_mode = options.store_name === 'admin';
|
|
89
|
-
this.#enable_role_requester =
|
|
90
|
-
options.enable_role_requester !== undefined
|
|
91
|
-
? options.enable_role_requester
|
|
92
|
-
: false;
|
|
93
|
-
this.#enable_validator_observer =
|
|
94
|
-
options.enable_validator_observer !== undefined
|
|
95
|
-
? options.enable_validator_observer
|
|
96
|
-
: true;
|
|
97
|
-
this.#bootstrap = options.bootstrap
|
|
98
|
-
? b4a.from(options.bootstrap, "hex")
|
|
99
|
-
: null;
|
|
100
|
-
|
|
101
|
-
if (!options.channel) {
|
|
102
|
-
throw new Error(
|
|
103
|
-
"MainSettlementBus: Channel is required. Application cannot start without channel."
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
this.#channel = b4a.alloc(32).fill(options.channel);
|
|
108
|
-
this.#store = new Corestore(this.#stores_directory + options.store_name);
|
|
109
|
-
this.#wallet = new PeerWallet(options);
|
|
62
|
+
this.#config = config
|
|
63
|
+
this.#store = new Corestore(this.#config.storesFullPath);
|
|
64
|
+
this.#wallet = new PeerWallet({ networkPrefix: this.#config.addressPrefix });
|
|
110
65
|
this.#readline_instance = null;
|
|
111
|
-
this.#maxRetries = Number(options.max_retries) ? options.max_retries : MAX_MESSAGE_SEND_ATTEMPTS
|
|
112
66
|
|
|
113
|
-
if (this.
|
|
67
|
+
if (this.#config.enableInteractiveMode) {
|
|
114
68
|
try {
|
|
115
69
|
this.#readline_instance = readline.createInterface({
|
|
116
70
|
input: new tty.ReadStream(0),
|
|
117
71
|
output: new tty.WriteStream(1),
|
|
118
72
|
});
|
|
119
|
-
} catch (
|
|
120
|
-
}
|
|
73
|
+
} catch (_ignored) {}
|
|
121
74
|
}
|
|
122
75
|
|
|
123
|
-
this.check = new Check();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
get options() {
|
|
127
|
-
return this.#options;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
get stores_directory() {
|
|
131
|
-
return this.#stores_directory;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
get key_pair_path() {
|
|
135
|
-
return this.#key_pair_path;
|
|
76
|
+
this.check = new Check(this.#config);
|
|
136
77
|
}
|
|
137
78
|
|
|
138
|
-
get
|
|
139
|
-
return this.#
|
|
79
|
+
get config() {
|
|
80
|
+
return this.#config
|
|
140
81
|
}
|
|
141
82
|
|
|
142
83
|
get state() {
|
|
143
84
|
return this.#state;
|
|
144
85
|
}
|
|
145
86
|
|
|
146
|
-
get channel() {
|
|
147
|
-
return this.#channel;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
87
|
get network() {
|
|
151
88
|
return this.#network;
|
|
152
89
|
}
|
|
153
90
|
|
|
154
|
-
// This can be null if enable_wallet is false
|
|
155
91
|
get wallet() {
|
|
92
|
+
if (!this.#config.enableWallet) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
156
95
|
return this.#wallet;
|
|
157
96
|
}
|
|
158
97
|
|
|
159
|
-
get tracPublicKey() {
|
|
160
|
-
if (!this.#wallet) return null;
|
|
161
|
-
return this.#wallet.publicKey;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
98
|
async _open() {
|
|
165
|
-
if (this.#
|
|
99
|
+
if (this.#config.enableWallet) {
|
|
166
100
|
await this.#wallet.initKeyPair(
|
|
167
|
-
this.
|
|
101
|
+
this.#config.keyPairPath,
|
|
168
102
|
this.#readline_instance
|
|
169
103
|
);
|
|
170
104
|
}
|
|
171
|
-
this.#state = new State(this.#store, this
|
|
172
|
-
this.#network = new Network(this.#state, this.#
|
|
105
|
+
this.#state = new State(this.#store, this.#wallet, this.#config);
|
|
106
|
+
this.#network = new Network(this.#state, this.#config, this.#wallet.address);
|
|
173
107
|
|
|
174
108
|
await this.#state.ready();
|
|
175
109
|
await this.#network.ready();
|
|
176
|
-
this.#stateEventsListener();
|
|
110
|
+
await this.#stateEventsListener();
|
|
177
111
|
|
|
178
|
-
if (this.#
|
|
179
|
-
printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#
|
|
112
|
+
if (this.#config.enableWallet) {
|
|
113
|
+
printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#config.enableWallet);
|
|
180
114
|
}
|
|
181
115
|
|
|
182
|
-
this.#partialTransferValidator = new PartialTransfer(this.state);
|
|
183
|
-
this.#partialTransactionValidator = new PartialTransaction(this.state);
|
|
184
|
-
|
|
185
116
|
await this.#network.replicate(
|
|
186
117
|
this.#state,
|
|
187
118
|
this.#store,
|
|
@@ -191,12 +122,14 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
191
122
|
const adminEntry = await this.#state.getAdminEntry();
|
|
192
123
|
await this.#setUpRoleAutomatically(adminEntry);
|
|
193
124
|
|
|
125
|
+
|
|
126
|
+
|
|
194
127
|
console.log(`isIndexer: ${this.#state.isIndexer()}`);
|
|
195
128
|
console.log(`isWriter: ${this.#state.isWritable()}`);
|
|
196
129
|
console.log("MSB Unsigned Length:", this.#state.getUnsignedLength());
|
|
197
130
|
console.log("MSB Signed Length:", this.#state.getSignedLength());
|
|
198
131
|
|
|
199
|
-
await printBalance(this.#wallet.address, this.#state, this.#
|
|
132
|
+
await printBalance(this.#wallet.address, this.#state, this.#config.enableWallet);
|
|
200
133
|
}
|
|
201
134
|
|
|
202
135
|
async _close() {
|
|
@@ -239,56 +172,11 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
239
172
|
}
|
|
240
173
|
|
|
241
174
|
async broadcastPartialTransaction(partialTransactionPayload) {
|
|
242
|
-
await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
async broadcastTransactionCommand(payload) {
|
|
246
|
-
if (!payload) {
|
|
247
|
-
throw new Error("Transaction payload is required for broadcast_transaction command.");
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
let normalizedPayload;
|
|
251
|
-
let isValid = false;
|
|
252
|
-
let hash;
|
|
253
|
-
|
|
254
|
-
if (payload.type === OperationType.TRANSFER) {
|
|
255
|
-
normalizedPayload = normalizeTransferOperation(payload);
|
|
256
|
-
isValid = await this.#partialTransferValidator.validate(normalizedPayload);
|
|
257
|
-
hash = b4a.toString(normalizedPayload.tro.tx, "hex");
|
|
258
|
-
} else if (payload.type === OperationType.TX) {
|
|
259
|
-
normalizedPayload = normalizeTransactionOperation(payload);
|
|
260
|
-
isValid = await this.#partialTransactionValidator.validate(normalizedPayload);
|
|
261
|
-
hash = b4a.toString(normalizedPayload.txo.tx, "hex");
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (!isValid) {
|
|
265
|
-
throw new Error("Invalid transaction payload.");
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const signedLength = this.#state.getSignedLength();
|
|
269
|
-
const unsignedLength = this.#state.getUnsignedLength();
|
|
270
|
-
|
|
271
|
-
for (let attempt = 0; attempt <= this.#maxRetries; attempt++) { // should iterate once if maxRetries === 0
|
|
272
|
-
await this.broadcastPartialTransaction(payload);
|
|
273
|
-
await sleep(1000 * (attempt + 1)); // linear backoff wait time
|
|
274
|
-
const tx = await this.#state.get(hash);
|
|
275
|
-
|
|
276
|
-
if (tx !== null) {
|
|
277
|
-
break;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
this.network.validatorConnectionManager.rotate(); // force change connection rotation for the next retry
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
if (await this.#state.get(hash) === null) {
|
|
284
|
-
throw new Error("Failed to broadcast transaction after multiple attempts.");
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
return { message: "Transaction broadcasted successfully.", signedLength, unsignedLength, tx: hash };
|
|
175
|
+
return await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
|
|
288
176
|
}
|
|
289
177
|
|
|
290
178
|
async #setUpRoleAutomatically() {
|
|
291
|
-
if (!this.#state.isWritable() && this.#
|
|
179
|
+
if (!this.#state.isWritable() && this.#config.enableRoleRequester) {
|
|
292
180
|
console.log("Requesting writer role... This may take a moment.");
|
|
293
181
|
await this.#requestWriterRole(false);
|
|
294
182
|
setTimeout(async () => {
|
|
@@ -299,15 +187,12 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
299
187
|
}
|
|
300
188
|
|
|
301
189
|
#isAdmin(adminEntry) {
|
|
302
|
-
if (!adminEntry || this.#
|
|
303
|
-
return
|
|
304
|
-
this.#wallet.address === adminEntry.address &&
|
|
305
|
-
b4a.equals(adminEntry.wk, this.#state.writingKey)
|
|
306
|
-
);
|
|
190
|
+
if (!adminEntry || !this.#config.enableWallet) return false;
|
|
191
|
+
return this.#wallet.address === adminEntry.address && b4a.equals(adminEntry.wk, this.#state.writingKey)
|
|
307
192
|
}
|
|
308
193
|
|
|
309
194
|
async #isAllowedToRequestRole(adminEntry, nodeEntry) {
|
|
310
|
-
return nodeEntry
|
|
195
|
+
return nodeEntry?.isWhitelisted && !this.#isAdmin(adminEntry);
|
|
311
196
|
}
|
|
312
197
|
|
|
313
198
|
async #stateEventsListener() {
|
|
@@ -338,18 +223,15 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
338
223
|
});
|
|
339
224
|
|
|
340
225
|
this.#state.base.on(EventType.UNWRITABLE, async () => {
|
|
341
|
-
if (this.#enable_wallet === false) {
|
|
342
|
-
console.log("Current node is unwritable");
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
226
|
console.log("Current node is unwritable");
|
|
346
227
|
});
|
|
347
228
|
}
|
|
348
229
|
|
|
349
230
|
async #handleAdminCreation() {
|
|
350
|
-
if (this.#
|
|
231
|
+
if (!this.#config.enableWallet) {
|
|
351
232
|
throw new Error("Can not initialize an admin - wallet is not enabled.");
|
|
352
233
|
}
|
|
234
|
+
|
|
353
235
|
const adminEntry = await this.#state.getAdminEntry();
|
|
354
236
|
|
|
355
237
|
if (adminEntry) {
|
|
@@ -365,25 +247,29 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
365
247
|
"Can not initialize an admin - writing key is not initialized."
|
|
366
248
|
);
|
|
367
249
|
}
|
|
368
|
-
if (!b4a.equals(this.#state.writingKey, this.#bootstrap)) {
|
|
250
|
+
if (!b4a.equals(this.#state.writingKey, this.#config.bootstrap)) {
|
|
369
251
|
throw new Error(
|
|
370
252
|
"Can not initialize an admin - bootstrap is not equal to writing key."
|
|
371
253
|
);
|
|
372
254
|
}
|
|
373
255
|
|
|
374
|
-
const txValidity = await
|
|
375
|
-
const addAdminMessage = await
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
256
|
+
const txValidity = await PeerWallet.blake3(this.#config.bootstrap);
|
|
257
|
+
const addAdminMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
258
|
+
.buildCompleteAddAdminMessage(
|
|
259
|
+
this.#wallet.address,
|
|
260
|
+
this.#state.writingKey,
|
|
261
|
+
txValidity,
|
|
262
|
+
)
|
|
263
|
+
const encodedPayload = safeEncodeApplyOperation(addAdminMessage);
|
|
380
264
|
|
|
381
|
-
await this.#state.append(
|
|
265
|
+
await this.#state.append(encodedPayload);
|
|
382
266
|
}
|
|
267
|
+
|
|
383
268
|
async #handleAdminRecovery() {
|
|
384
|
-
if (this.#
|
|
269
|
+
if (!this.#config.enableWallet) {
|
|
385
270
|
throw new Error("Can not initialize an admin - wallet is not enabled.");
|
|
386
271
|
}
|
|
272
|
+
|
|
387
273
|
const adminEntry = await this.#state.getAdminEntry();
|
|
388
274
|
|
|
389
275
|
if (!adminEntry) {
|
|
@@ -404,22 +290,28 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
404
290
|
}
|
|
405
291
|
|
|
406
292
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
407
|
-
const adminRecoveryMessage = await
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
293
|
+
const adminRecoveryMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
294
|
+
.buildPartialAdminRecoveryMessage(
|
|
295
|
+
this.#wallet.address,
|
|
296
|
+
this.#state.writingKey,
|
|
297
|
+
txValidity,
|
|
298
|
+
"json"
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
const success = await this.broadcastPartialTransaction(adminRecoveryMessage);
|
|
302
|
+
|
|
303
|
+
if (!success) {
|
|
304
|
+
throw new Error("Failed to broadcast transaction after multiple attempts.");
|
|
305
|
+
}
|
|
412
306
|
|
|
413
|
-
await this.broadcastPartialTransaction(adminRecoveryMessage);
|
|
414
307
|
console.info(`Transaction hash: ${adminRecoveryMessage.rao.tx}`);
|
|
415
308
|
}
|
|
416
309
|
|
|
417
310
|
async #handleWhitelistOperations() {
|
|
418
|
-
if (this.#
|
|
311
|
+
if (!this.#config.enableWallet) {
|
|
419
312
|
throw new Error("Cannot perform whitelisting - wallet is not enabled.");
|
|
420
313
|
}
|
|
421
314
|
|
|
422
|
-
if (this.#enable_wallet === false) return;
|
|
423
315
|
const adminEntry = await this.#state.getAdminEntry();
|
|
424
316
|
|
|
425
317
|
if (!this.#isAdmin(adminEntry)) {
|
|
@@ -430,7 +322,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
430
322
|
const addresses = await fileUtils.readAddressesFromWhitelistFile();
|
|
431
323
|
|
|
432
324
|
for (const address of addresses) {
|
|
433
|
-
await migrationUtils.validateAddressFromIncomingFile(this.#state, address, adminEntry);
|
|
325
|
+
await migrationUtils.validateAddressFromIncomingFile(this.#state, this.#config, address, adminEntry);
|
|
434
326
|
}
|
|
435
327
|
await fileUtils.validateWhitelistMigrationData(addresses, WHITELIST_MIGRATION_DIR);
|
|
436
328
|
const migrationNumber = await fileUtils.getNextMigrationNumber(WHITELIST_MIGRATION_DIR);
|
|
@@ -438,11 +330,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
438
330
|
|
|
439
331
|
for (const addressToWhitelist of addresses) {
|
|
440
332
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
333
|
+
const appendWhitelistMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
334
|
+
.buildCompleteAppendWhitelistMessage(
|
|
335
|
+
this.#wallet.address,
|
|
336
|
+
addressToWhitelist,
|
|
337
|
+
txValidity,
|
|
338
|
+
)
|
|
339
|
+
const encodedPayload = safeEncodeApplyOperation(appendWhitelistMessage)
|
|
446
340
|
messages.set(addressToWhitelist, encodedPayload);
|
|
447
341
|
}
|
|
448
342
|
|
|
@@ -476,12 +370,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
476
370
|
}
|
|
477
371
|
|
|
478
372
|
async #requestWriterRole(toAdd) {
|
|
479
|
-
if (this.#
|
|
373
|
+
if (!this.#config.enableWallet) {
|
|
480
374
|
throw new Error("Cannot request writer role - wallet is not enabled");
|
|
481
375
|
}
|
|
376
|
+
|
|
482
377
|
const adminEntry = await this.#state.getAdminEntry();
|
|
483
378
|
const nodeEntry = await this.#state.getNodeEntry(this.#wallet.address);
|
|
484
|
-
const isAlreadyWriter = !!
|
|
379
|
+
const isAlreadyWriter = !!nodeEntry?.isWriter;
|
|
485
380
|
|
|
486
381
|
if (toAdd) {
|
|
487
382
|
if (isAlreadyWriter) {
|
|
@@ -515,13 +410,21 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
515
410
|
}
|
|
516
411
|
|
|
517
412
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
518
|
-
const assembledMessage = await PartialStateMessageOperations.assembleAddWriterMessage(
|
|
519
|
-
this.#wallet,
|
|
520
|
-
this.#state.writingKey.toString('hex'),
|
|
521
|
-
txValidity.toString('hex')
|
|
522
|
-
)
|
|
523
413
|
|
|
524
|
-
await this
|
|
414
|
+
const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
415
|
+
.buildPartialAddWriterMessage(
|
|
416
|
+
this.#wallet.address,
|
|
417
|
+
this.#state.writingKey,
|
|
418
|
+
txValidity,
|
|
419
|
+
'json'
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
const success = await this.broadcastPartialTransaction(assembledMessage);
|
|
423
|
+
|
|
424
|
+
if (!success) {
|
|
425
|
+
throw new Error("Failed to broadcast transaction after multiple attempts.");
|
|
426
|
+
}
|
|
427
|
+
|
|
525
428
|
console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
|
|
526
429
|
return;
|
|
527
430
|
}
|
|
@@ -542,21 +445,27 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
542
445
|
}
|
|
543
446
|
|
|
544
447
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
545
|
-
const assembledMessage = await
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
448
|
+
const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
449
|
+
.buildPartialRemoveWriterMessage(
|
|
450
|
+
this.#wallet.address,
|
|
451
|
+
nodeEntry.wk,
|
|
452
|
+
txValidity,
|
|
453
|
+
"json"
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
const success = await this.broadcastPartialTransaction(assembledMessage);
|
|
457
|
+
|
|
458
|
+
if (!success) {
|
|
459
|
+
throw new Error("Failed to broadcast transaction after multiple attempts.");
|
|
460
|
+
}
|
|
550
461
|
|
|
551
|
-
await this.broadcastPartialTransaction(assembledMessage);
|
|
552
462
|
console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
|
|
553
|
-
return;
|
|
554
463
|
}
|
|
555
464
|
|
|
556
|
-
async #
|
|
557
|
-
if (this.#
|
|
465
|
+
async #updateWriterToIndexerRole(addressToUpdate, toAdd) {
|
|
466
|
+
if (!this.#config.enableWallet) {
|
|
558
467
|
throw new Error(
|
|
559
|
-
`Can not request indexer role for: ${
|
|
468
|
+
`Can not request indexer role for: ${addressToUpdate} - wallet is not enabled.`
|
|
560
469
|
);
|
|
561
470
|
}
|
|
562
471
|
|
|
@@ -564,29 +473,29 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
564
473
|
|
|
565
474
|
if (!adminEntry) {
|
|
566
475
|
throw new Error(
|
|
567
|
-
`Can not request indexer role for: ${
|
|
476
|
+
`Can not request indexer role for: ${addressToUpdate} - admin entry has not been initialized.`
|
|
568
477
|
);
|
|
569
478
|
}
|
|
570
479
|
|
|
571
|
-
if (!isAddressValid(
|
|
480
|
+
if (!isAddressValid(addressToUpdate, this.#config.addressPrefix)) {
|
|
572
481
|
throw new Error(
|
|
573
|
-
`Can not request indexer role for: ${
|
|
482
|
+
`Can not request indexer role for: ${addressToUpdate} - invalid address.`
|
|
574
483
|
);
|
|
575
484
|
}
|
|
576
485
|
|
|
577
486
|
if (!this.#isAdmin(adminEntry) && !this.#state.isWritable()) {
|
|
578
487
|
throw new Error(
|
|
579
|
-
`Can not request indexer role for: ${
|
|
488
|
+
`Can not request indexer role for: ${addressToUpdate} - You are not an admin or writer.`
|
|
580
489
|
);
|
|
581
490
|
}
|
|
582
|
-
const nodeEntry = await this.#state.getNodeEntry(
|
|
491
|
+
const nodeEntry = await this.#state.getNodeEntry(addressToUpdate);
|
|
583
492
|
if (!nodeEntry) {
|
|
584
493
|
throw new Error(
|
|
585
|
-
`Can not request indexer role for: ${
|
|
494
|
+
`Can not request indexer role for: ${addressToUpdate} - node entry has not been not initialized.`
|
|
586
495
|
);
|
|
587
496
|
}
|
|
588
497
|
|
|
589
|
-
const indexerNodeEntry = await this.#state.getNodeEntry(
|
|
498
|
+
const indexerNodeEntry = await this.#state.getNodeEntry(addressToUpdate);
|
|
590
499
|
const indexerListHasAddress = await this.#state.isWkInIndexersEntry(
|
|
591
500
|
indexerNodeEntry.wk,
|
|
592
501
|
);
|
|
@@ -594,7 +503,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
594
503
|
if (toAdd) {
|
|
595
504
|
if (indexerListHasAddress) {
|
|
596
505
|
throw new Error(
|
|
597
|
-
`Cannot update indexer role for: ${
|
|
506
|
+
`Cannot update indexer role for: ${addressToUpdate} - address is already in indexers list.`
|
|
598
507
|
);
|
|
599
508
|
}
|
|
600
509
|
|
|
@@ -606,72 +515,90 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
606
515
|
|
|
607
516
|
if (!canAddIndexer) {
|
|
608
517
|
throw new Error(
|
|
609
|
-
`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.`
|
|
610
519
|
);
|
|
611
520
|
}
|
|
612
521
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
613
|
-
|
|
614
|
-
await this.#
|
|
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);
|
|
615
533
|
} else {
|
|
616
534
|
const canRemoveIndexer =
|
|
617
535
|
!toAdd && nodeEntry.isIndexer && indexerListHasAddress;
|
|
618
536
|
|
|
619
537
|
if (!canRemoveIndexer) {
|
|
620
538
|
throw new Error(
|
|
621
|
-
`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.`
|
|
622
540
|
);
|
|
623
541
|
}
|
|
624
542
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
625
|
-
const
|
|
626
|
-
|
|
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);
|
|
550
|
+
|
|
551
|
+
await this.#state.append(encodedPayload);
|
|
627
552
|
}
|
|
628
553
|
}
|
|
629
554
|
|
|
630
|
-
async #banValidator(
|
|
631
|
-
if (this.#
|
|
555
|
+
async #banValidator(addresstToBan) {
|
|
556
|
+
if (!this.#config.enableWallet) {
|
|
632
557
|
throw new Error(
|
|
633
|
-
`Can not ban writer with address: ${
|
|
558
|
+
`Can not ban writer with address: ${addresstToBan} - wallet is not enabled.`
|
|
634
559
|
);
|
|
635
560
|
}
|
|
636
561
|
const adminEntry = await this.#state.getAdminEntry();
|
|
637
562
|
|
|
638
563
|
if (!adminEntry) {
|
|
639
564
|
throw new Error(
|
|
640
|
-
`Can not ban writer with address: ${
|
|
565
|
+
`Can not ban writer with address: ${addresstToBan} - admin entry has not been initialized.`
|
|
641
566
|
);
|
|
642
567
|
}
|
|
643
568
|
|
|
644
|
-
if (!isAddressValid(
|
|
569
|
+
if (!isAddressValid(addresstToBan, this.#config.addressPrefix)) {
|
|
645
570
|
throw new Error(
|
|
646
|
-
`Can not ban writer with address: ${
|
|
571
|
+
`Can not ban writer with address: ${addresstToBan} - invalid address.`
|
|
647
572
|
);
|
|
648
573
|
}
|
|
649
574
|
|
|
650
575
|
if (!this.#isAdmin(adminEntry)) {
|
|
651
576
|
throw new Error(
|
|
652
|
-
`Can not ban writer with address: ${
|
|
577
|
+
`Can not ban writer with address: ${addresstToBan} - You are not an admin.`
|
|
653
578
|
);
|
|
654
579
|
}
|
|
655
580
|
|
|
656
|
-
const isWhitelisted = await this.#state.isAddressWhitelisted(
|
|
657
|
-
const nodeEntry = await this.#state.getNodeEntry(
|
|
581
|
+
const isWhitelisted = await this.#state.isAddressWhitelisted(addresstToBan);
|
|
582
|
+
const nodeEntry = await this.#state.getNodeEntry(addresstToBan);
|
|
658
583
|
|
|
659
584
|
if (!isWhitelisted || null === nodeEntry || nodeEntry.isIndexer === true) {
|
|
660
585
|
throw new Error(
|
|
661
|
-
`Can not ban writer with address: ${
|
|
586
|
+
`Can not ban writer with address: ${addresstToBan} - node is not whitelisted or is an indexer.`
|
|
662
587
|
);
|
|
663
588
|
}
|
|
664
589
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
665
|
-
const assembledBanValidatorMessage = await
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
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);
|
|
671
598
|
}
|
|
672
599
|
|
|
673
600
|
async #deployBootstrap(externalBootstrap, channel) {
|
|
674
|
-
if (this.#
|
|
601
|
+
if (!this.#config.enableWallet) {
|
|
675
602
|
throw new Error(
|
|
676
603
|
"Can not perform bootstrap deployment - wallet is not enabled."
|
|
677
604
|
);
|
|
@@ -719,7 +646,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
719
646
|
);
|
|
720
647
|
}
|
|
721
648
|
|
|
722
|
-
if (externalBootstrap === this.bootstrap.toString("hex")) {
|
|
649
|
+
if (externalBootstrap === this.#config.bootstrap.toString("hex")) {
|
|
723
650
|
throw new Error(
|
|
724
651
|
`Can not perform bootstrap deployment - bootstrap ${externalBootstrap} is equal to MSB bootstrap!`
|
|
725
652
|
);
|
|
@@ -740,14 +667,22 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
740
667
|
}
|
|
741
668
|
|
|
742
669
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
743
|
-
const payload = await PartialStateMessageOperations.assembleBootstrapDeploymentMessage(
|
|
744
|
-
this.#wallet,
|
|
745
|
-
externalBootstrap,
|
|
746
|
-
channel,
|
|
747
|
-
txValidity.toString('hex')
|
|
748
|
-
);
|
|
749
670
|
|
|
750
|
-
await this
|
|
671
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
672
|
+
.buildPartialBootstrapDeploymentMessage(
|
|
673
|
+
this.#wallet.address,
|
|
674
|
+
externalBootstrap,
|
|
675
|
+
channel,
|
|
676
|
+
txValidity,
|
|
677
|
+
"json"
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
const success = await this.broadcastPartialTransaction(payload);
|
|
681
|
+
|
|
682
|
+
if (!success) {
|
|
683
|
+
throw new Error("Failed to broadcast transaction after multiple attempts.");
|
|
684
|
+
}
|
|
685
|
+
|
|
751
686
|
console.info(`Transaction hash: ${payload.bdo.tx}`);
|
|
752
687
|
console.log(`Bootstrap ${externalBootstrap} deployment requested on channel ${channel}`);
|
|
753
688
|
console.log('Bootstrap Deployment Fee Details:');
|
|
@@ -756,32 +691,8 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
756
691
|
|
|
757
692
|
}
|
|
758
693
|
|
|
759
|
-
async #
|
|
760
|
-
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
async #handleRemoveIndexerOperation(address) {
|
|
764
|
-
await this.#updateIndexerRole(address, false);
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
async #handleAddWriterOperation() {
|
|
768
|
-
await this.#requestWriterRole(true);
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
async #handleRemoveWriterOperation() {
|
|
772
|
-
await this.#requestWriterRole(false);
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
async #handleBanValidatorOperation(address) {
|
|
776
|
-
await this.#banValidator(address);
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
async #handleBootstrapDeploymentOperation(bootstrapHex, channel) {
|
|
780
|
-
await this.#deployBootstrap(bootstrapHex, channel);
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
async #handleTransferOperation(address, amount) {
|
|
784
|
-
if (this.#enable_wallet === false) {
|
|
694
|
+
async #handleTransferOperation(recipientAddress, amount) {
|
|
695
|
+
if (!this.#config.enableWallet) {
|
|
785
696
|
throw new Error(
|
|
786
697
|
"Can not perform transfer - wallet is not enabled."
|
|
787
698
|
);
|
|
@@ -793,7 +704,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
793
704
|
);
|
|
794
705
|
}
|
|
795
706
|
|
|
796
|
-
if (!isAddressValid(
|
|
707
|
+
if (!isAddressValid(recipientAddress, this.#config.addressPrefix)) {
|
|
797
708
|
throw new Error("Invalid recipient address");
|
|
798
709
|
}
|
|
799
710
|
|
|
@@ -818,7 +729,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
818
729
|
const fee = this.#state.getFee();
|
|
819
730
|
const feeBigInt = bufferToBigInt(fee);
|
|
820
731
|
const senderBalance = bufferToBigInt(senderEntry.balance);
|
|
821
|
-
const isSelfTransfer =
|
|
732
|
+
const isSelfTransfer = recipientAddress === this.#wallet.address;
|
|
822
733
|
const totalDeductedAmount = isSelfTransfer ? feeBigInt : amountBigInt + feeBigInt;
|
|
823
734
|
|
|
824
735
|
if (!(senderBalance >= totalDeductedAmount)) {
|
|
@@ -826,15 +737,15 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
826
737
|
}
|
|
827
738
|
|
|
828
739
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
829
|
-
const payload = await
|
|
830
|
-
|
|
831
|
-
address,
|
|
832
|
-
|
|
833
|
-
|
|
740
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
741
|
+
.buildPartialTransferOperationMessage(
|
|
742
|
+
this.#wallet.address,
|
|
743
|
+
recipientAddress,
|
|
744
|
+
amountBuffer,
|
|
745
|
+
txValidity,
|
|
746
|
+
"json"
|
|
834
747
|
)
|
|
835
748
|
|
|
836
|
-
await this.broadcastPartialTransaction(payload);
|
|
837
|
-
|
|
838
749
|
const expectedNewBalance = senderBalance - totalDeductedAmount;
|
|
839
750
|
console.info('Transfer Details:');
|
|
840
751
|
console.info(`Transaction hash ${payload.tro.tx}`)
|
|
@@ -848,9 +759,16 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
848
759
|
console.info(`Total: ${bigIntToDecimalString(totalDeductedAmount)}`);
|
|
849
760
|
}
|
|
850
761
|
console.log(`Expected Balance After Transfer: ${bigIntToDecimalString(expectedNewBalance)}`);
|
|
762
|
+
const success = await this.broadcastPartialTransaction(payload);
|
|
763
|
+
if (!success) {
|
|
764
|
+
throw new Error("Failed to broadcast transfer transaction after multiple attempts.");
|
|
765
|
+
} else {
|
|
766
|
+
console.log(`Transfer transaction broadcasted successfully. Tx hash: ${payload.tro.tx}`);
|
|
767
|
+
}
|
|
768
|
+
|
|
851
769
|
}
|
|
852
770
|
|
|
853
|
-
async #
|
|
771
|
+
async #balanceMigrationOperation() {
|
|
854
772
|
|
|
855
773
|
const isInitDisabled = await this.#state.isInitalizationDisabled()
|
|
856
774
|
|
|
@@ -858,7 +776,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
858
776
|
throw new Error("Can not initialize balance - balance initialization is disabled.");
|
|
859
777
|
}
|
|
860
778
|
|
|
861
|
-
if (this.#
|
|
779
|
+
if (!this.#config.enableWallet) {
|
|
862
780
|
throw new Error("Can not initialize an admin - wallet is not enabled.");
|
|
863
781
|
}
|
|
864
782
|
|
|
@@ -880,14 +798,14 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
880
798
|
throw new Error("Can not initialize an admin - writing key is not initialized.");
|
|
881
799
|
}
|
|
882
800
|
|
|
883
|
-
if (!b4a.equals(this.#state.writingKey, this.#bootstrap)) {
|
|
801
|
+
if (!b4a.equals(this.#state.writingKey, this.#config.bootstrap)) {
|
|
884
802
|
throw new Error("Can not initialize an admin - bootstrap is not equal to writing key.");
|
|
885
803
|
}
|
|
886
804
|
|
|
887
805
|
const { addressBalancePair, totalBalance, totalAddresses, addresses } = await fileUtils.readBalanceMigrationFile();
|
|
888
806
|
|
|
889
807
|
for (let i = 0; i < addresses.length; i++) {
|
|
890
|
-
await migrationUtils.validateAddressFromIncomingFile(this.#state, addresses[i].address, adminEntry);
|
|
808
|
+
await migrationUtils.validateAddressFromIncomingFile(this.#state, this.#config, addresses[i].address, adminEntry);
|
|
891
809
|
}
|
|
892
810
|
|
|
893
811
|
await fileUtils.validateBalanceMigrationData(addresses);
|
|
@@ -895,11 +813,18 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
895
813
|
await fileUtils.createMigrationEntryFile(addressBalancePair, migrationNumber);
|
|
896
814
|
|
|
897
815
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
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,
|
|
824
|
+
txValidity,
|
|
825
|
+
)
|
|
826
|
+
messages.push(safeEncodeApplyOperation(payload));
|
|
827
|
+
}
|
|
903
828
|
|
|
904
829
|
console.log(`Total balance to migrate: ${bigIntToDecimalString(totalBalance)} across ${totalAddresses} addresses.`);
|
|
905
830
|
|
|
@@ -946,9 +871,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
946
871
|
}
|
|
947
872
|
|
|
948
873
|
async #disableInitialization() {
|
|
949
|
-
if (this.#
|
|
874
|
+
if (!this.#config.enableWallet) {
|
|
950
875
|
throw new Error("Can not initialize an admin - wallet is not enabled.");
|
|
951
876
|
}
|
|
877
|
+
const isInitDisabled = await this.#state.isInitalizationDisabled();
|
|
878
|
+
if (isInitDisabled) {
|
|
879
|
+
throw new Error("Can not disable initialization - it is already disabled.");
|
|
880
|
+
}
|
|
952
881
|
const adminEntry = await this.#state.getAdminEntry();
|
|
953
882
|
|
|
954
883
|
if (!adminEntry) {
|
|
@@ -958,22 +887,31 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
958
887
|
if (!this.#isAdmin(adminEntry)) {
|
|
959
888
|
throw new Error('Cannot perform whitelisting - you are not the admin!.');
|
|
960
889
|
}
|
|
961
|
-
|
|
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
|
+
}
|
|
962
896
|
const txValidity = await this.#state.getIndexerSequenceState();
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
const payload = await applyStateMessageFactory(this.#wallet, this.#config)
|
|
900
|
+
.buildCompleteDisableInitializationMessage(
|
|
901
|
+
this.#wallet.address,
|
|
902
|
+
this.#state.writingKey,
|
|
903
|
+
txValidity,
|
|
904
|
+
)
|
|
968
905
|
console.log('Disabling initialization...');
|
|
969
|
-
|
|
906
|
+
const encodedPayload = safeEncodeApplyOperation(payload);
|
|
907
|
+
await this.#state.append(encodedPayload);
|
|
970
908
|
}
|
|
971
909
|
|
|
972
910
|
async interactiveMode() {
|
|
973
911
|
if (this.#readline_instance === null) return;
|
|
974
912
|
const rl = this.#readline_instance;
|
|
975
913
|
|
|
976
|
-
printHelp(this.#
|
|
914
|
+
printHelp(this.#config.isAdminMode);
|
|
977
915
|
|
|
978
916
|
rl.on("line", async (input) => {
|
|
979
917
|
try {
|
|
@@ -989,35 +927,30 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
989
927
|
|
|
990
928
|
async handleCommand(input, rl = null, payload = null) {
|
|
991
929
|
const [command, ...parts] = input.split(" ");
|
|
992
|
-
|
|
993
930
|
const exactHandlers = {
|
|
994
931
|
"/help": async () => {
|
|
995
|
-
printHelp(this.#
|
|
932
|
+
printHelp(this.#config.isAdminMode);
|
|
996
933
|
},
|
|
997
934
|
"/exit": async () => {
|
|
998
935
|
if (rl) rl.close();
|
|
999
936
|
await this.close();
|
|
1000
937
|
},
|
|
1001
|
-
"/add_admin": () => this.#handleAdminCreation(),
|
|
1002
|
-
"/add_admin --recovery": () => this.#handleAdminRecovery(),
|
|
1003
|
-
"/add_whitelist": () => this.#handleWhitelistOperations(),
|
|
1004
|
-
"/add_writer": () => this.#
|
|
1005
|
-
"/remove_writer": () => this.#
|
|
1006
|
-
"/core": () => coreInfoCommand(this.#state),
|
|
1007
|
-
"/indexers_list": async () =>
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
"/validator_pool": () => {
|
|
1011
|
-
this.network.validatorConnectionManager.prettyPrint();
|
|
1012
|
-
},
|
|
1013
|
-
"/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(
|
|
1014
947
|
this.#state,
|
|
1015
948
|
this.#network,
|
|
1016
949
|
this.#wallet,
|
|
1017
950
|
this.#state.writingKey
|
|
1018
951
|
),
|
|
1019
|
-
"/balance_migration": () => this.#
|
|
1020
|
-
"/disable_initialization": () => this.#disableInitialization()
|
|
952
|
+
"/balance_migration": async () => await this.#balanceMigrationOperation(),
|
|
953
|
+
"/disable_initialization": async () => await this.#disableInitialization()
|
|
1021
954
|
};
|
|
1022
955
|
|
|
1023
956
|
if (exactHandlers[command]) {
|
|
@@ -1035,26 +968,26 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
1035
968
|
|
|
1036
969
|
if (input.startsWith("/add_indexer")) {
|
|
1037
970
|
const address = parts[0];
|
|
1038
|
-
await this.#
|
|
971
|
+
await this.#updateWriterToIndexerRole(address, true);
|
|
1039
972
|
} else if (input.startsWith("/remove_indexer")) {
|
|
1040
973
|
const address = parts[0];
|
|
1041
|
-
await this.#
|
|
974
|
+
await this.#updateWriterToIndexerRole(address, false);
|
|
1042
975
|
} else if (input.startsWith("/ban_writer")) {
|
|
1043
976
|
const address = parts[0];
|
|
1044
|
-
await this.#
|
|
977
|
+
await this.#banValidator(address);
|
|
1045
978
|
} else if (input.startsWith("/deployment")) {
|
|
1046
979
|
const bootstrapToDeploy = parts[0];
|
|
1047
980
|
const channel = parts[1] || randomBytes(32).toString("hex");
|
|
1048
981
|
if (channel.length !== 64 || !isHexString(channel)) {
|
|
1049
982
|
throw new Error("Channel must be a 32-byte hex string");
|
|
1050
983
|
}
|
|
1051
|
-
await this.#
|
|
984
|
+
await this.#deployBootstrap(bootstrapToDeploy, channel);
|
|
1052
985
|
} else if (input.startsWith("/get_validator_addr")) {
|
|
1053
986
|
const wkHexString = parts[0];
|
|
1054
|
-
await getValidatorAddressCommand(this.#state, wkHexString);
|
|
987
|
+
await getValidatorAddressCommand(this.#state, wkHexString, this.#config.addressPrefix);
|
|
1055
988
|
} else if (input.startsWith("/get_deployment")) {
|
|
1056
989
|
const bootstrapHex = parts[0];
|
|
1057
|
-
await getDeploymentCommand(this.#state, bootstrapHex);
|
|
990
|
+
await getDeploymentCommand(this.#state, bootstrapHex, this.#config.addressLength);
|
|
1058
991
|
} else if (input.startsWith("/get_tx_info")) {
|
|
1059
992
|
const txHash = parts[0];
|
|
1060
993
|
await getTxInfoCommand(this.#state, txHash);
|
|
@@ -1092,19 +1025,11 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
1092
1025
|
const result = getUnconfirmedLengthCommand(this.#state);
|
|
1093
1026
|
if (rl) rl.prompt();
|
|
1094
1027
|
return result;
|
|
1095
|
-
} else if (input.startsWith("/broadcast_transaction")) {
|
|
1096
|
-
if (!payload) {
|
|
1097
|
-
throw new Error("Transaction payload is required for broadcast_transaction command.");
|
|
1098
|
-
}
|
|
1099
|
-
const result = await this.broadcastTransactionCommand(payload);
|
|
1100
|
-
if (rl) rl.prompt();
|
|
1101
|
-
return result;
|
|
1102
1028
|
} else if (input.startsWith("/get_tx_payloads_bulk")) {
|
|
1103
1029
|
if (!payload) {
|
|
1104
1030
|
throw new Error("Missing payload for fetching tx payloads.");
|
|
1105
1031
|
}
|
|
1106
|
-
const
|
|
1107
|
-
const result = await getTxPayloadsBulkCommand(this.#state, hashes);
|
|
1032
|
+
const result = await getTxPayloadsBulkCommand(this.#state, payload, this.#config);
|
|
1108
1033
|
if (rl) rl.prompt();
|
|
1109
1034
|
return result;
|
|
1110
1035
|
} else if (input.startsWith("/get_txs_hashes")) {
|
|
@@ -1115,13 +1040,13 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
1115
1040
|
return result;
|
|
1116
1041
|
} else if (input.startsWith("/get_tx_details")) {
|
|
1117
1042
|
const hash = parts[0];
|
|
1118
|
-
const result = await getTxDetailsCommand(this.#state, hash);
|
|
1043
|
+
const result = await getTxDetailsCommand(this.#state, hash, this.#config);
|
|
1119
1044
|
if (rl) rl.prompt();
|
|
1120
1045
|
return result;
|
|
1121
1046
|
} else if (input.startsWith("/get_extended_tx_details")) {
|
|
1122
1047
|
const hash = parts[0];
|
|
1123
1048
|
const confirmed = parts[1] === "true";
|
|
1124
|
-
const result = await getExtendedTxDetailsCommand(this.#state, hash, confirmed);
|
|
1049
|
+
const result = await getExtendedTxDetailsCommand(this.#state, hash, confirmed, this.#config);
|
|
1125
1050
|
if (rl) rl.prompt();
|
|
1126
1051
|
return result;
|
|
1127
1052
|
}
|