trac-msb 0.2.7 → 0.2.8

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.
Files changed (146) hide show
  1. package/.github/workflows/publish.yml +8 -16
  2. package/docs/networking-dualstack-plan.md +75 -0
  3. package/docs/networking-layer-redesign.md +155 -0
  4. package/msb.mjs +11 -23
  5. package/package.json +2 -3
  6. package/rpc/{create_server.mjs → create_server.js} +2 -2
  7. package/rpc/{handlers.mjs → handlers.js} +5 -5
  8. package/rpc/routes/{index.mjs → index.js} +1 -1
  9. package/rpc/routes/{v1.mjs → v1.js} +1 -1
  10. package/rpc/{rpc_server.mjs → rpc_server.js} +1 -1
  11. package/rpc/rpc_services.js +4 -4
  12. package/src/config/config.js +137 -0
  13. package/src/config/env.js +61 -0
  14. package/src/core/network/Network.js +119 -73
  15. package/src/core/network/identity/NetworkWalletFactory.js +3 -4
  16. package/src/core/network/messaging/NetworkMessages.js +12 -11
  17. package/src/core/network/messaging/handlers/GetRequestHandler.js +5 -4
  18. package/src/core/network/messaging/handlers/ResponseHandler.js +4 -5
  19. package/src/core/network/messaging/handlers/RoleOperationHandler.js +17 -19
  20. package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +44 -38
  21. package/src/core/network/messaging/handlers/TransferOperationHandler.js +29 -25
  22. package/src/core/network/messaging/handlers/base/BaseOperationHandler.js +20 -21
  23. package/src/core/network/messaging/routes/NetworkMessageRouter.js +24 -20
  24. package/src/core/network/messaging/validators/AdminResponse.js +2 -2
  25. package/src/core/network/messaging/validators/CustomNodeResponse.js +2 -2
  26. package/src/core/network/messaging/validators/PartialBootstrapDeployment.js +3 -3
  27. package/src/core/network/messaging/validators/PartialRoleAccess.js +15 -12
  28. package/src/core/network/messaging/validators/PartialTransaction.js +9 -10
  29. package/src/core/network/messaging/validators/PartialTransfer.js +10 -7
  30. package/src/core/network/messaging/validators/ValidatorResponse.js +2 -2
  31. package/src/core/network/messaging/validators/base/BaseResponse.js +13 -5
  32. package/src/core/network/messaging/validators/base/PartialOperation.js +37 -21
  33. package/src/core/network/services/ConnectionManager.js +9 -15
  34. package/src/core/network/services/MessageOrchestrator.js +10 -22
  35. package/src/core/network/services/TransactionPoolService.js +9 -8
  36. package/src/core/network/services/ValidatorObserverService.js +46 -21
  37. package/src/core/state/State.js +136 -139
  38. package/src/core/state/utils/address.js +18 -16
  39. package/src/core/state/utils/adminEntry.js +17 -16
  40. package/src/core/state/utils/deploymentEntry.js +15 -15
  41. package/src/core/state/utils/transaction.js +3 -95
  42. package/src/index.js +153 -201
  43. package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +36 -32
  44. package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +39 -42
  45. package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +20 -20
  46. package/src/messages/partialStateMessages/PartialStateMessageOperations.js +29 -22
  47. package/src/utils/check.js +21 -17
  48. package/src/utils/cliCommands.js +11 -11
  49. package/src/utils/constants.js +2 -10
  50. package/src/utils/fileUtils.js +1 -4
  51. package/src/utils/helpers.js +9 -20
  52. package/src/utils/migrationUtils.js +2 -2
  53. package/src/utils/normalizers.js +10 -9
  54. package/tests/acceptance/v1/account/account.test.mjs +2 -2
  55. package/tests/acceptance/v1/balance/balance.test.mjs +1 -1
  56. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +11 -2
  57. package/tests/acceptance/v1/rpc.test.mjs +9 -9
  58. package/tests/acceptance/v1/tx/tx.test.mjs +4 -2
  59. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +7 -3
  60. package/tests/fixtures/check.fixtures.js +42 -42
  61. package/tests/fixtures/protobuf.fixtures.js +27 -26
  62. package/tests/helpers/StateNetworkFactory.js +3 -5
  63. package/tests/helpers/autobaseTestHelpers.js +1 -2
  64. package/tests/helpers/config.js +3 -0
  65. package/tests/helpers/setupApplyTests.js +89 -82
  66. package/tests/helpers/transactionPayloads.mjs +26 -12
  67. package/tests/integration/apply/addAdmin/addAdminBasic.test.js +10 -9
  68. package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +20 -19
  69. package/tests/integration/apply/addIndexer.test.js +23 -21
  70. package/tests/integration/apply/addWhitelist.test.js +9 -9
  71. package/tests/integration/apply/addWriter.test.js +33 -32
  72. package/tests/integration/apply/banValidator.test.js +16 -9
  73. package/tests/integration/apply/postTx/invalidSubValues.test.js +4 -4
  74. package/tests/integration/apply/postTx/postTx.test.js +7 -33
  75. package/tests/integration/apply/removeIndexer.test.js +11 -7
  76. package/tests/integration/apply/removeWriter.test.js +20 -19
  77. package/tests/integration/apply/transfer.test.js +18 -16
  78. package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +2 -2
  79. package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +2 -1
  80. package/tests/unit/messageOperations/assembleAdminMessage.test.js +9 -10
  81. package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +3 -2
  82. package/tests/unit/messageOperations/assemblePostTransaction.test.js +25 -43
  83. package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +2 -2
  84. package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +2 -2
  85. package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +5 -4
  86. package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +4 -3
  87. package/tests/unit/network/ConnectionManager.test.js +4 -2
  88. package/tests/unit/network/NetworkWalletFactory.test.js +14 -14
  89. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +6 -6
  90. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +8 -8
  91. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +6 -5
  92. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +24 -23
  93. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +10 -16
  94. package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +2 -1
  95. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +45 -41
  96. package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +3 -7
  97. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +17 -16
  98. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +3 -4
  99. package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +2 -1
  100. package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +2 -1
  101. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +23 -25
  102. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +2 -1
  103. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +19 -18
  104. package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +5 -4
  105. package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +4 -3
  106. package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +2 -1
  107. package/tests/unit/state/apply/common/commonScenarioHelper.js +3 -4
  108. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +2 -2
  109. package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +2 -2
  110. package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +2 -1
  111. package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +2 -1
  112. package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +2 -1
  113. package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +2 -1
  114. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +11 -10
  115. package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +6 -5
  116. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +6 -7
  117. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +35 -34
  118. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +44 -43
  119. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +26 -25
  120. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +2 -1
  121. package/tests/unit/state/stateModule.test.js +0 -1
  122. package/tests/unit/state/stateTestUtils.js +7 -3
  123. package/tests/unit/state/utils/address.test.js +3 -3
  124. package/tests/unit/state/utils/adminEntry.test.js +10 -9
  125. package/tests/unit/utils/check/adminControlOperation.test.js +3 -3
  126. package/tests/unit/utils/check/balanceInitializationOperation.test.js +2 -2
  127. package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +2 -3
  128. package/tests/unit/utils/check/common.test.js +7 -6
  129. package/tests/unit/utils/check/coreAdminOperation.test.js +3 -3
  130. package/tests/unit/utils/check/roleAccessOperation.test.js +3 -2
  131. package/tests/unit/utils/check/transactionOperation.test.js +3 -3
  132. package/tests/unit/utils/check/transferOperation.test.js +3 -3
  133. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +2 -1
  134. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +2 -1
  135. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +7 -0
  136. package/tests/unit/utils/utils.test.js +0 -1
  137. package/src/core/state/utils/indexerEntry.js +0 -105
  138. package/src/utils/crypto.js +0 -11
  139. package/tests/unit/state/utils/indexerEntry.test.js +0 -83
  140. package/tests/unit/state/utils/transaction.test.js +0 -97
  141. package/tests/unit/utils/crypto/createHash.test.js +0 -15
  142. /package/rpc/{constants.mjs → constants.js} +0 -0
  143. /package/rpc/{cors.mjs → cors.js} +0 -0
  144. /package/rpc/utils/{confirmedParameter.mjs → confirmedParameter.js} +0 -0
  145. /package/rpc/utils/{helpers.mjs → helpers.js} +0 -0
  146. /package/rpc/utils/{url.mjs → url.js} +0 -0
package/src/index.js CHANGED
@@ -6,12 +6,10 @@ import PeerWallet from "trac-wallet";
6
6
  import b4a from "b4a";
7
7
  import readline from "readline";
8
8
  import tty from "tty";
9
-
10
- import { sleep, getFormattedIndexersWithAddresses, isHexString, convertAdminCoreOperationPayloadToHex } from "./utils/helpers.js";
11
- import { verifyDag, printHelp, printWalletInfo, get_confirmed_tx_info, printBalance, get_unconfirmed_tx_info } from "./utils/cli.js";
9
+ import { sleep, isHexString } from "./utils/helpers.js";
10
+ import { verifyDag, printHelp, printWalletInfo, printBalance } from "./utils/cli.js";
12
11
  import CompleteStateMessageOperations from "./messages/completeStateMessages/CompleteStateMessageOperations.js";
13
- import { safeDecodeApplyOperation } from "./utils/protobuf/operationHelpers.js";
14
- import { bufferToAddress, isAddressValid } from "./core/state/utils/address.js";
12
+ import { isAddressValid } from "./core/state/utils/address.js";
15
13
  import Network from "./core/network/Network.js";
16
14
  import Check from "./utils/check.js";
17
15
  import State from "./core/state/State.js";
@@ -20,21 +18,15 @@ import {
20
18
  EventType,
21
19
  WHITELIST_SLEEP_INTERVAL,
22
20
  BOOTSTRAP_HEXSTRING_LENGTH,
23
- EntryType,
24
21
  OperationType,
25
- MAX_MESSAGE_SEND_ATTEMPTS,
26
22
  CustomEventType,
27
23
  BALANCE_MIGRATION_SLEEP_INTERVAL,
28
24
  WHITELIST_MIGRATION_DIR
29
25
  } from "./utils/constants.js";
30
- import partialStateMessageOperations from "./messages/partialStateMessages/PartialStateMessageOperations.js";
31
26
  import { randomBytes } from "hypercore-crypto";
32
- import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString, licenseBufferToBigInt } from "./utils/amountSerialization.js"
33
- import { ZERO_WK } from "./utils/buffer.js";
34
- import { normalizeDecodedPayloadForJson, normalizeTransferOperation, normalizeTransactionOperation } from "./utils/normalizers.js"
27
+ import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString } from "./utils/amountSerialization.js"
28
+ import { normalizeTransferOperation, normalizeTransactionOperation } from "./utils/normalizers.js"
35
29
  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
30
  import PartialTransaction from "./core/network/messaging/validators/PartialTransaction.js";
39
31
  import fileUtils from './utils/fileUtils.js';
40
32
  import migrationUtils from './utils/migrationUtils.js';
@@ -59,94 +51,47 @@ import {
59
51
  } from "./utils/cliCommands.js";
60
52
  export class MainSettlementBus extends ReadyResource {
61
53
  // internal attributes
62
- #options;
63
- #stores_directory;
64
- #key_pair_path;
65
- #bootstrap;
66
- #channel;
67
54
  #store;
68
- #enable_wallet;
69
55
  #wallet;
70
56
  #network;
71
57
  #readline_instance;
72
- #enable_validator_observer;
73
- #enable_role_requester;
74
58
  #state;
75
59
  #isClosing = false;
76
- #is_admin_mode;
77
60
  #partialTransferValidator;
78
61
  #partialTransactionValidator;
79
- #maxRetries
62
+ #config
80
63
 
81
- constructor(options = {}) {
64
+ /**
65
+ * @param {object} config
66
+ **/
67
+ constructor(config) {
82
68
  super();
83
- this.#options = options;
84
- this.#stores_directory = options.stores_directory;
85
- this.#key_pair_path = `${this.#stores_directory}${options.store_name}/db/keypair.json`;
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
- }
69
+ this.#config = config
106
70
 
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);
71
+ this.#store = new Corestore(this.#config.storesFullPath);
72
+ this.#wallet = new PeerWallet({ networkPrefix: this.#config.addressPrefix });
110
73
  this.#readline_instance = null;
111
- this.#maxRetries = Number(options.max_retries) ? options.max_retries : MAX_MESSAGE_SEND_ATTEMPTS
112
74
 
113
- if (this.enable_interactive_mode !== false) {
75
+ if (this.#config.enableInteractiveMode) {
114
76
  try {
115
77
  this.#readline_instance = readline.createInterface({
116
78
  input: new tty.ReadStream(0),
117
79
  output: new tty.WriteStream(1),
118
80
  });
119
- } catch (e) {
120
- }
81
+ } catch (_ignored) {}
121
82
  }
122
83
 
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;
84
+ this.check = new Check(this.#config);
136
85
  }
137
86
 
138
- get bootstrap() {
139
- return this.#bootstrap;
87
+ get config() {
88
+ return this.#config
140
89
  }
141
90
 
142
91
  get state() {
143
92
  return this.#state;
144
93
  }
145
94
 
146
- get channel() {
147
- return this.#channel;
148
- }
149
-
150
95
  get network() {
151
96
  return this.#network;
152
97
  }
@@ -156,31 +101,26 @@ export class MainSettlementBus extends ReadyResource {
156
101
  return this.#wallet;
157
102
  }
158
103
 
159
- get tracPublicKey() {
160
- if (!this.#wallet) return null;
161
- return this.#wallet.publicKey;
162
- }
163
-
164
104
  async _open() {
165
- if (this.#enable_wallet) {
105
+ if (this.#config.enableWallet) {
166
106
  await this.#wallet.initKeyPair(
167
- this.key_pair_path,
107
+ this.#config.keyPairPath,
168
108
  this.#readline_instance
169
109
  );
170
110
  }
171
- this.#state = new State(this.#store, this.bootstrap, this.#wallet, this.options);
172
- this.#network = new Network(this.#state, this.#channel, this.#wallet.address, this.options);
111
+ this.#state = new State(this.#store, this.#wallet, this.#config);
112
+ this.#network = new Network(this.#state, this.#config, this.#wallet.address);
173
113
 
174
114
  await this.#state.ready();
175
115
  await this.#network.ready();
176
116
  this.#stateEventsListener();
177
117
 
178
- if (this.#enable_wallet) {
179
- printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#enable_wallet);
118
+ if (this.#config.enableWallet) {
119
+ printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#config.enableWallet);
180
120
  }
181
121
 
182
- this.#partialTransferValidator = new PartialTransfer(this.state);
183
- this.#partialTransactionValidator = new PartialTransaction(this.state);
122
+ this.#partialTransferValidator = new PartialTransfer(this.state, this.#wallet, this.#config);
123
+ this.#partialTransactionValidator = new PartialTransaction(this.state, this.#wallet ,this.#config);
184
124
 
185
125
  await this.#network.replicate(
186
126
  this.#state,
@@ -196,7 +136,7 @@ export class MainSettlementBus extends ReadyResource {
196
136
  console.log("MSB Unsigned Length:", this.#state.getUnsignedLength());
197
137
  console.log("MSB Signed Length:", this.#state.getSignedLength());
198
138
 
199
- await printBalance(this.#wallet.address, this.#state, this.#enable_wallet);
139
+ await printBalance(this.#wallet.address, this.#state, this.#config.enableWallet);
200
140
  }
201
141
 
202
142
  async _close() {
@@ -239,7 +179,7 @@ export class MainSettlementBus extends ReadyResource {
239
179
  }
240
180
 
241
181
  async broadcastPartialTransaction(partialTransactionPayload) {
242
- await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
182
+ return await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
243
183
  }
244
184
 
245
185
  async broadcastTransactionCommand(payload) {
@@ -252,11 +192,11 @@ export class MainSettlementBus extends ReadyResource {
252
192
  let hash;
253
193
 
254
194
  if (payload.type === OperationType.TRANSFER) {
255
- normalizedPayload = normalizeTransferOperation(payload);
195
+ normalizedPayload = normalizeTransferOperation(payload, this.#config);
256
196
  isValid = await this.#partialTransferValidator.validate(normalizedPayload);
257
197
  hash = b4a.toString(normalizedPayload.tro.tx, "hex");
258
198
  } else if (payload.type === OperationType.TX) {
259
- normalizedPayload = normalizeTransactionOperation(payload);
199
+ normalizedPayload = normalizeTransactionOperation(payload, this.#config);
260
200
  isValid = await this.#partialTransactionValidator.validate(normalizedPayload);
261
201
  hash = b4a.toString(normalizedPayload.txo.tx, "hex");
262
202
  }
@@ -268,19 +208,9 @@ export class MainSettlementBus extends ReadyResource {
268
208
  const signedLength = this.#state.getSignedLength();
269
209
  const unsignedLength = this.#state.getUnsignedLength();
270
210
 
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);
211
+ const success = await this.broadcastPartialTransaction(payload);
275
212
 
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) {
213
+ if (!success) {
284
214
  throw new Error("Failed to broadcast transaction after multiple attempts.");
285
215
  }
286
216
 
@@ -288,7 +218,7 @@ export class MainSettlementBus extends ReadyResource {
288
218
  }
289
219
 
290
220
  async #setUpRoleAutomatically() {
291
- if (!this.#state.isWritable() && this.#enable_role_requester) {
221
+ if (!this.#state.isWritable() && this.#config.enableRoleRequester) {
292
222
  console.log("Requesting writer role... This may take a moment.");
293
223
  await this.#requestWriterRole(false);
294
224
  setTimeout(async () => {
@@ -299,15 +229,12 @@ export class MainSettlementBus extends ReadyResource {
299
229
  }
300
230
 
301
231
  #isAdmin(adminEntry) {
302
- if (!adminEntry || this.#enable_wallet === false) return false;
303
- return !!(
304
- this.#wallet.address === adminEntry.address &&
305
- b4a.equals(adminEntry.wk, this.#state.writingKey)
306
- );
232
+ if (!adminEntry || !this.#config.enableWallet) return false;
233
+ return this.#wallet.address === adminEntry.address && b4a.equals(adminEntry.wk, this.#state.writingKey)
307
234
  }
308
235
 
309
236
  async #isAllowedToRequestRole(adminEntry, nodeEntry) {
310
- return nodeEntry && nodeEntry.isWhitelisted && !this.#isAdmin(adminEntry);
237
+ return nodeEntry?.isWhitelisted && !this.#isAdmin(adminEntry);
311
238
  }
312
239
 
313
240
  async #stateEventsListener() {
@@ -338,18 +265,15 @@ export class MainSettlementBus extends ReadyResource {
338
265
  });
339
266
 
340
267
  this.#state.base.on(EventType.UNWRITABLE, async () => {
341
- if (this.#enable_wallet === false) {
342
- console.log("Current node is unwritable");
343
- return;
344
- }
345
268
  console.log("Current node is unwritable");
346
269
  });
347
270
  }
348
271
 
349
272
  async #handleAdminCreation() {
350
- if (this.#enable_wallet === false) {
273
+ if (!this.#config.enableWallet) {
351
274
  throw new Error("Can not initialize an admin - wallet is not enabled.");
352
275
  }
276
+
353
277
  const adminEntry = await this.#state.getAdminEntry();
354
278
 
355
279
  if (adminEntry) {
@@ -365,25 +289,26 @@ export class MainSettlementBus extends ReadyResource {
365
289
  "Can not initialize an admin - writing key is not initialized."
366
290
  );
367
291
  }
368
- if (!b4a.equals(this.#state.writingKey, this.#bootstrap)) {
292
+ if (!b4a.equals(this.#state.writingKey, this.#config.bootstrap)) {
369
293
  throw new Error(
370
294
  "Can not initialize an admin - bootstrap is not equal to writing key."
371
295
  );
372
296
  }
373
297
 
374
- const txValidity = await blake3Hash(this.bootstrap);
375
- const addAdminMessage = await CompleteStateMessageOperations.assembleAddAdminMessage(
376
- this.#wallet,
377
- this.#state.writingKey,
378
- txValidity
379
- );
298
+ const txValidity = await PeerWallet.blake3(this.#config.bootstrap);
299
+ const addAdminMessage = await new CompleteStateMessageOperations(this.#wallet, this.#config)
300
+ .assembleAddAdminMessage(
301
+ this.#state.writingKey,
302
+ txValidity
303
+ );
380
304
 
381
305
  await this.#state.append(addAdminMessage);
382
306
  }
383
307
  async #handleAdminRecovery() {
384
- if (this.#enable_wallet === false) {
308
+ if (!this.#config.enableWallet) {
385
309
  throw new Error("Can not initialize an admin - wallet is not enabled.");
386
310
  }
311
+
387
312
  const adminEntry = await this.#state.getAdminEntry();
388
313
 
389
314
  if (!adminEntry) {
@@ -404,22 +329,25 @@ export class MainSettlementBus extends ReadyResource {
404
329
  }
405
330
 
406
331
  const txValidity = await this.#state.getIndexerSequenceState();
407
- const adminRecoveryMessage = await partialStateMessageOperations.assembleAdminRecoveryMessage(
408
- this.#wallet,
332
+ const adminRecoveryMessage = await new PartialStateMessageOperations(this.#wallet, this.#config).assembleAdminRecoveryMessage(
409
333
  this.#state.writingKey.toString('hex'),
410
334
  txValidity.toString('hex')
411
335
  );
412
336
 
413
- await this.broadcastPartialTransaction(adminRecoveryMessage);
337
+ const success = await this.broadcastPartialTransaction(adminRecoveryMessage);
338
+
339
+ if (!success) {
340
+ throw new Error("Failed to broadcast transaction after multiple attempts.");
341
+ }
342
+
414
343
  console.info(`Transaction hash: ${adminRecoveryMessage.rao.tx}`);
415
344
  }
416
345
 
417
346
  async #handleWhitelistOperations() {
418
- if (this.#enable_wallet === false) {
347
+ if (!this.#config.enableWallet) {
419
348
  throw new Error("Cannot perform whitelisting - wallet is not enabled.");
420
349
  }
421
350
 
422
- if (this.#enable_wallet === false) return;
423
351
  const adminEntry = await this.#state.getAdminEntry();
424
352
 
425
353
  if (!this.#isAdmin(adminEntry)) {
@@ -430,7 +358,7 @@ export class MainSettlementBus extends ReadyResource {
430
358
  const addresses = await fileUtils.readAddressesFromWhitelistFile();
431
359
 
432
360
  for (const address of addresses) {
433
- await migrationUtils.validateAddressFromIncomingFile(this.#state, address, adminEntry);
361
+ await migrationUtils.validateAddressFromIncomingFile(this.#state, this.#config, address, adminEntry);
434
362
  }
435
363
  await fileUtils.validateWhitelistMigrationData(addresses, WHITELIST_MIGRATION_DIR);
436
364
  const migrationNumber = await fileUtils.getNextMigrationNumber(WHITELIST_MIGRATION_DIR);
@@ -438,11 +366,12 @@ export class MainSettlementBus extends ReadyResource {
438
366
 
439
367
  for (const addressToWhitelist of addresses) {
440
368
  const txValidity = await this.#state.getIndexerSequenceState();
441
- const encodedPayload = await CompleteStateMessageOperations.assembleAppendWhitelistMessages(
442
- this.#wallet,
443
- txValidity,
444
- addressToWhitelist
445
- );
369
+ const encodedPayload = await new CompleteStateMessageOperations(this.#wallet, this.#config)
370
+ .assembleAppendWhitelistMessages(
371
+ txValidity,
372
+ addressToWhitelist
373
+ );
374
+
446
375
  messages.set(addressToWhitelist, encodedPayload);
447
376
  }
448
377
 
@@ -476,12 +405,13 @@ export class MainSettlementBus extends ReadyResource {
476
405
  }
477
406
 
478
407
  async #requestWriterRole(toAdd) {
479
- if (this.#enable_wallet === false) {
408
+ if (!this.#config.enableWallet) {
480
409
  throw new Error("Cannot request writer role - wallet is not enabled");
481
410
  }
411
+
482
412
  const adminEntry = await this.#state.getAdminEntry();
483
413
  const nodeEntry = await this.#state.getNodeEntry(this.#wallet.address);
484
- const isAlreadyWriter = !!(nodeEntry && nodeEntry.isWriter === true);
414
+ const isAlreadyWriter = !!nodeEntry?.isWriter;
485
415
 
486
416
  if (toAdd) {
487
417
  if (isAlreadyWriter) {
@@ -515,13 +445,18 @@ export class MainSettlementBus extends ReadyResource {
515
445
  }
516
446
 
517
447
  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
- )
448
+ const assembledMessage = await new PartialStateMessageOperations(this.#wallet, { networkId: this.#config.networkId, addressPrefix: this.#config.addressPrefix })
449
+ .assembleAddWriterMessage(
450
+ this.#state.writingKey.toString('hex'),
451
+ txValidity.toString('hex')
452
+ )
453
+
454
+ const success = await this.broadcastPartialTransaction(assembledMessage);
455
+
456
+ if (!success) {
457
+ throw new Error("Failed to broadcast transaction after multiple attempts.");
458
+ }
523
459
 
524
- await this.broadcastPartialTransaction(assembledMessage);
525
460
  console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
526
461
  return;
527
462
  }
@@ -542,19 +477,23 @@ export class MainSettlementBus extends ReadyResource {
542
477
  }
543
478
 
544
479
  const txValidity = await this.#state.getIndexerSequenceState();
545
- const assembledMessage = await PartialStateMessageOperations.assembleRemoveWriterMessage(
546
- this.#wallet,
547
- nodeEntry.wk.toString('hex'),
548
- txValidity.toString('hex')
549
- )
480
+ const assembledMessage = await new PartialStateMessageOperations(this.#wallet, { networkId: this.#config.networkId, addressPrefix: this.#config.addressPrefix })
481
+ .assembleRemoveWriterMessage(
482
+ nodeEntry.wk.toString('hex'),
483
+ txValidity.toString('hex')
484
+ )
485
+
486
+ const success = await this.broadcastPartialTransaction(assembledMessage);
487
+
488
+ if (!success) {
489
+ throw new Error("Failed to broadcast transaction after multiple attempts.");
490
+ }
550
491
 
551
- await this.broadcastPartialTransaction(assembledMessage);
552
492
  console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
553
- return;
554
493
  }
555
494
 
556
495
  async #updateIndexerRole(address, toAdd) {
557
- if (this.#enable_wallet === false) {
496
+ if (!this.#config.enableWallet) {
558
497
  throw new Error(
559
498
  `Can not request indexer role for: ${address} - wallet is not enabled.`
560
499
  );
@@ -568,7 +507,7 @@ export class MainSettlementBus extends ReadyResource {
568
507
  );
569
508
  }
570
509
 
571
- if (!isAddressValid(address)) {
510
+ if (!isAddressValid(address, this.#config.addressPrefix)) {
572
511
  throw new Error(
573
512
  `Can not request indexer role for: ${address} - invalid address.`
574
513
  );
@@ -610,7 +549,8 @@ export class MainSettlementBus extends ReadyResource {
610
549
  );
611
550
  }
612
551
  const txValidity = await this.#state.getIndexerSequenceState();
613
- const assembledAddIndexerMessage = await CompleteStateMessageOperations.assembleAddIndexerMessage(this.#wallet, address, txValidity);
552
+ const assembledAddIndexerMessage = await new CompleteStateMessageOperations(this.#wallet, this.#config)
553
+ .assembleAddIndexerMessage(address, txValidity);
614
554
  await this.#state.append(assembledAddIndexerMessage);
615
555
  } else {
616
556
  const canRemoveIndexer =
@@ -622,13 +562,15 @@ export class MainSettlementBus extends ReadyResource {
622
562
  );
623
563
  }
624
564
  const txValidity = await this.#state.getIndexerSequenceState();
625
- const assembledRemoveIndexer = await CompleteStateMessageOperations.assembleRemoveIndexerMessage(this.#wallet, address, txValidity);
565
+ const assembledRemoveIndexer = await new CompleteStateMessageOperations(this.#wallet, this.#config)
566
+ .assembleRemoveIndexerMessage(address, txValidity);
567
+
626
568
  await this.#state.append(assembledRemoveIndexer);
627
569
  }
628
570
  }
629
571
 
630
572
  async #banValidator(address) {
631
- if (this.#enable_wallet === false) {
573
+ if (!this.#config.enableWallet) {
632
574
  throw new Error(
633
575
  `Can not ban writer with address: ${address} - wallet is not enabled.`
634
576
  );
@@ -641,7 +583,7 @@ export class MainSettlementBus extends ReadyResource {
641
583
  );
642
584
  }
643
585
 
644
- if (!isAddressValid(address)) {
586
+ if (!isAddressValid(address, this.#config.addressPrefix)) {
645
587
  throw new Error(
646
588
  `Can not ban writer with address: ${address} - invalid address.`
647
589
  );
@@ -662,16 +604,16 @@ export class MainSettlementBus extends ReadyResource {
662
604
  );
663
605
  }
664
606
  const txValidity = await this.#state.getIndexerSequenceState();
665
- const assembledBanValidatorMessage = await CompleteStateMessageOperations.assembleBanWriterMessage(
666
- this.#wallet,
667
- address,
668
- txValidity
669
- );
607
+ const assembledBanValidatorMessage = await new CompleteStateMessageOperations(this.#wallet, this.#config)
608
+ .assembleBanWriterMessage(
609
+ address,
610
+ txValidity
611
+ );
670
612
  await this.#state.append(assembledBanValidatorMessage);
671
613
  }
672
614
 
673
615
  async #deployBootstrap(externalBootstrap, channel) {
674
- if (this.#enable_wallet === false) {
616
+ if (!this.#config.enableWallet) {
675
617
  throw new Error(
676
618
  "Can not perform bootstrap deployment - wallet is not enabled."
677
619
  );
@@ -719,7 +661,7 @@ export class MainSettlementBus extends ReadyResource {
719
661
  );
720
662
  }
721
663
 
722
- if (externalBootstrap === this.bootstrap.toString("hex")) {
664
+ if (externalBootstrap === this.#config.bootstrap.toString("hex")) {
723
665
  throw new Error(
724
666
  `Can not perform bootstrap deployment - bootstrap ${externalBootstrap} is equal to MSB bootstrap!`
725
667
  );
@@ -740,14 +682,19 @@ export class MainSettlementBus extends ReadyResource {
740
682
  }
741
683
 
742
684
  const txValidity = await this.#state.getIndexerSequenceState();
743
- const payload = await PartialStateMessageOperations.assembleBootstrapDeploymentMessage(
744
- this.#wallet,
745
- externalBootstrap,
746
- channel,
747
- txValidity.toString('hex')
748
- );
685
+ const payload = await new PartialStateMessageOperations(this.#wallet, this.#config)
686
+ .assembleBootstrapDeploymentMessage(
687
+ externalBootstrap,
688
+ channel,
689
+ txValidity.toString('hex')
690
+ );
691
+
692
+ const success = await this.broadcastPartialTransaction(payload);
693
+
694
+ if (!success) {
695
+ throw new Error("Failed to broadcast transaction after multiple attempts.");
696
+ }
749
697
 
750
- await this.broadcastPartialTransaction(payload);
751
698
  console.info(`Transaction hash: ${payload.bdo.tx}`);
752
699
  console.log(`Bootstrap ${externalBootstrap} deployment requested on channel ${channel}`);
753
700
  console.log('Bootstrap Deployment Fee Details:');
@@ -781,7 +728,7 @@ export class MainSettlementBus extends ReadyResource {
781
728
  }
782
729
 
783
730
  async #handleTransferOperation(address, amount) {
784
- if (this.#enable_wallet === false) {
731
+ if (!this.#config.enableWallet) {
785
732
  throw new Error(
786
733
  "Can not perform transfer - wallet is not enabled."
787
734
  );
@@ -793,7 +740,7 @@ export class MainSettlementBus extends ReadyResource {
793
740
  );
794
741
  }
795
742
 
796
- if (!isAddressValid(address)) {
743
+ if (!isAddressValid(address, this.#config.addressPrefix)) {
797
744
  throw new Error("Invalid recipient address");
798
745
  }
799
746
 
@@ -826,14 +773,13 @@ export class MainSettlementBus extends ReadyResource {
826
773
  }
827
774
 
828
775
  const txValidity = await this.#state.getIndexerSequenceState();
829
- const payload = await PartialStateMessageOperations.assembleTransferOperationMessage(
830
- this.#wallet,
831
- address,
832
- amountBuffer.toString('hex'),
833
- txValidity.toString('hex'),
834
- )
776
+ const payload = await new PartialStateMessageOperations(this.#wallet, this.#config)
777
+ .assembleTransferOperationMessage(
778
+ address,
779
+ amountBuffer.toString('hex'),
780
+ txValidity.toString('hex'),
781
+ )
835
782
 
836
- await this.broadcastPartialTransaction(payload);
837
783
 
838
784
  const expectedNewBalance = senderBalance - totalDeductedAmount;
839
785
  console.info('Transfer Details:');
@@ -848,6 +794,14 @@ export class MainSettlementBus extends ReadyResource {
848
794
  console.info(`Total: ${bigIntToDecimalString(totalDeductedAmount)}`);
849
795
  }
850
796
  console.log(`Expected Balance After Transfer: ${bigIntToDecimalString(expectedNewBalance)}`);
797
+
798
+ const success = await this.broadcastPartialTransaction(payload);
799
+ if (!success) {
800
+ throw new Error("Failed to broadcast transfer transaction after multiple attempts.");
801
+ } else {
802
+ console.log(`Transfer transaction broadcasted successfully. Tx hash: ${payload.tro.tx}`);
803
+ }
804
+
851
805
  }
852
806
 
853
807
  async #handleBalanceMigrationOperation() {
@@ -858,7 +812,7 @@ export class MainSettlementBus extends ReadyResource {
858
812
  throw new Error("Can not initialize balance - balance initialization is disabled.");
859
813
  }
860
814
 
861
- if (this.#enable_wallet === false) {
815
+ if (!this.#config.enableWallet) {
862
816
  throw new Error("Can not initialize an admin - wallet is not enabled.");
863
817
  }
864
818
 
@@ -880,14 +834,14 @@ export class MainSettlementBus extends ReadyResource {
880
834
  throw new Error("Can not initialize an admin - writing key is not initialized.");
881
835
  }
882
836
 
883
- if (!b4a.equals(this.#state.writingKey, this.#bootstrap)) {
837
+ if (!b4a.equals(this.#state.writingKey, this.#config.bootstrap)) {
884
838
  throw new Error("Can not initialize an admin - bootstrap is not equal to writing key.");
885
839
  }
886
840
 
887
841
  const { addressBalancePair, totalBalance, totalAddresses, addresses } = await fileUtils.readBalanceMigrationFile();
888
842
 
889
843
  for (let i = 0; i < addresses.length; i++) {
890
- await migrationUtils.validateAddressFromIncomingFile(this.#state, addresses[i].address, adminEntry);
844
+ await migrationUtils.validateAddressFromIncomingFile(this.#state, this.#config, addresses[i].address, adminEntry);
891
845
  }
892
846
 
893
847
  await fileUtils.validateBalanceMigrationData(addresses);
@@ -895,11 +849,11 @@ export class MainSettlementBus extends ReadyResource {
895
849
  await fileUtils.createMigrationEntryFile(addressBalancePair, migrationNumber);
896
850
 
897
851
  const txValidity = await this.#state.getIndexerSequenceState();
898
- const messages = await CompleteStateMessageOperations.assembleBalanceInitializationMessages(
899
- this.#wallet,
900
- txValidity,
901
- addressBalancePair,
902
- );
852
+ const messages = await new CompleteStateMessageOperations(this.#wallet, this.#config)
853
+ .assembleBalanceInitializationMessages(
854
+ txValidity,
855
+ addressBalancePair,
856
+ );
903
857
 
904
858
  console.log(`Total balance to migrate: ${bigIntToDecimalString(totalBalance)} across ${totalAddresses} addresses.`);
905
859
 
@@ -946,7 +900,7 @@ export class MainSettlementBus extends ReadyResource {
946
900
  }
947
901
 
948
902
  async #disableInitialization() {
949
- if (this.#enable_wallet === false) {
903
+ if (!this.#config.enableWallet) {
950
904
  throw new Error("Can not initialize an admin - wallet is not enabled.");
951
905
  }
952
906
  const adminEntry = await this.#state.getAdminEntry();
@@ -960,11 +914,11 @@ export class MainSettlementBus extends ReadyResource {
960
914
  }
961
915
  // add more checks
962
916
  const txValidity = await this.#state.getIndexerSequenceState();
963
- const payload = await CompleteStateMessageOperations.assembleDisableInitializationMessage(
964
- this.#wallet,
965
- this.#state.writingKey,
966
- txValidity,
967
- )
917
+ const payload = await new CompleteStateMessageOperations(this.#wallet, this.#config)
918
+ .assembleDisableInitializationMessage(
919
+ this.#state.writingKey,
920
+ txValidity,
921
+ )
968
922
  console.log('Disabling initialization...');
969
923
  await this.#state.append(payload);
970
924
  }
@@ -973,7 +927,7 @@ export class MainSettlementBus extends ReadyResource {
973
927
  if (this.#readline_instance === null) return;
974
928
  const rl = this.#readline_instance;
975
929
 
976
- printHelp(this.#is_admin_mode);
930
+ printHelp(this.#config.isAdminMode);
977
931
 
978
932
  rl.on("line", async (input) => {
979
933
  try {
@@ -989,10 +943,9 @@ export class MainSettlementBus extends ReadyResource {
989
943
 
990
944
  async handleCommand(input, rl = null, payload = null) {
991
945
  const [command, ...parts] = input.split(" ");
992
-
993
946
  const exactHandlers = {
994
947
  "/help": async () => {
995
- printHelp(this.#is_admin_mode);
948
+ printHelp(this.#config.isAdminMode);
996
949
  },
997
950
  "/exit": async () => {
998
951
  if (rl) rl.close();
@@ -1008,7 +961,7 @@ export class MainSettlementBus extends ReadyResource {
1008
961
  console.log(await this.#state.getIndexersEntry());
1009
962
  },
1010
963
  "/validator_pool": () => {
1011
- this.network.validatorConnectionManager.prettyPrint();
964
+ this.#network.validatorConnectionManager.prettyPrint();
1012
965
  },
1013
966
  "/stats": () => verifyDag(
1014
967
  this.#state,
@@ -1051,10 +1004,10 @@ export class MainSettlementBus extends ReadyResource {
1051
1004
  await this.#handleBootstrapDeploymentOperation(bootstrapToDeploy, channel);
1052
1005
  } else if (input.startsWith("/get_validator_addr")) {
1053
1006
  const wkHexString = parts[0];
1054
- await getValidatorAddressCommand(this.#state, wkHexString);
1007
+ await getValidatorAddressCommand(this.#state, wkHexString, this.#config.addressPrefix);
1055
1008
  } else if (input.startsWith("/get_deployment")) {
1056
1009
  const bootstrapHex = parts[0];
1057
- await getDeploymentCommand(this.#state, bootstrapHex);
1010
+ await getDeploymentCommand(this.#state, bootstrapHex, this.#config.addressLength);
1058
1011
  } else if (input.startsWith("/get_tx_info")) {
1059
1012
  const txHash = parts[0];
1060
1013
  await getTxInfoCommand(this.#state, txHash);
@@ -1103,8 +1056,7 @@ export class MainSettlementBus extends ReadyResource {
1103
1056
  if (!payload) {
1104
1057
  throw new Error("Missing payload for fetching tx payloads.");
1105
1058
  }
1106
- const hashes = payload;
1107
- const result = await getTxPayloadsBulkCommand(this.#state, hashes);
1059
+ const result = await getTxPayloadsBulkCommand(this.#state, payload, this.#config);
1108
1060
  if (rl) rl.prompt();
1109
1061
  return result;
1110
1062
  } else if (input.startsWith("/get_txs_hashes")) {
@@ -1115,13 +1067,13 @@ export class MainSettlementBus extends ReadyResource {
1115
1067
  return result;
1116
1068
  } else if (input.startsWith("/get_tx_details")) {
1117
1069
  const hash = parts[0];
1118
- const result = await getTxDetailsCommand(this.#state, hash);
1070
+ const result = await getTxDetailsCommand(this.#state, hash, this.#config);
1119
1071
  if (rl) rl.prompt();
1120
1072
  return result;
1121
1073
  } else if (input.startsWith("/get_extended_tx_details")) {
1122
1074
  const hash = parts[0];
1123
1075
  const confirmed = parts[1] === "true";
1124
- const result = await getExtendedTxDetailsCommand(this.#state, hash, confirmed);
1076
+ const result = await getExtendedTxDetailsCommand(this.#state, hash, confirmed, this.#config);
1125
1077
  if (rl) rl.prompt();
1126
1078
  return result;
1127
1079
  }