trac-msb 0.2.6 → 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 +9 -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 +131 -72
  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 +248 -62
  34. package/src/core/network/services/MessageOrchestrator.js +83 -0
  35. package/src/core/network/services/TransactionPoolService.js +9 -8
  36. package/src/core/network/services/ValidatorObserverService.js +95 -34
  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 -9
  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 +48 -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 +41 -70
  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
@@ -1,27 +1,50 @@
1
1
  import PeerWallet from "trac-wallet";
2
2
  import b4a from "b4a";
3
- import { MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION, TRAC_ADDRESS_SIZE } from '../../../utils/constants.js';
3
+ import { MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION } from '../../../utils/constants.js';
4
4
  import { bufferToAddress } from '../../state/utils/address.js';
5
5
  import { sleep } from '../../../utils/helpers.js';
6
6
  import Scheduler from "../../../utils/Scheduler.js";
7
-
8
- const POLL_INTERVAL = 3500 // This was increase since the iterations dont wait for the execution its about 10 * DELAY_INTERVAL
9
- const DELAY_INTERVAL = 250
7
+ import Network from "../Network.js";
8
+
9
+ const DELAY_INTERVAL = 50
10
+ const VALIDATOR_CANDIDATES_PER_CYCLE = 10
11
+ const POLL_INTERVAL = (VALIDATOR_CANDIDATES_PER_CYCLE + 1) * DELAY_INTERVAL // This is to avoid more than one instance of the worker running at the same time
12
+
13
+ // -- Debug Mode --
14
+ // TODO: Implement a better debug system in the future. This is just temporary.
15
+ const DEBUG = false;
16
+ const debugLog = (...args) => {
17
+ if (DEBUG) {
18
+ console.log('DEBUG [ValidatorObserverService] ==> ', ...args);
19
+ }
20
+ };
10
21
 
11
22
  class ValidatorObserverService {
12
- #enable_validator_observer;
23
+ #config;
13
24
  #state;
14
25
  #network;
15
26
  #scheduler;
16
27
  #address;
17
28
  #isInterrupted
18
29
 
19
- constructor(network, state, address, options = {}) {
20
- this.#enable_validator_observer = options.enable_validator_observer !== false;
30
+ /**
31
+ * @param {Network} network
32
+ * @param {State} state
33
+ * @param {string} address
34
+ * @param {object} config
35
+ **/
36
+ constructor(network, state, address, config) {
37
+ this.#config = config
21
38
  this.#network = network;
22
39
  this.#state = state;
23
40
  this.#address = address;
24
41
  this.#isInterrupted = false;
42
+ if (DEBUG) {
43
+ this.initTimestamp = Date.now();
44
+ this.reachedMax = false;
45
+ this.end = 0;
46
+ this.begin = 0;
47
+ }
25
48
  }
26
49
 
27
50
  get state() {
@@ -55,36 +78,80 @@ class ValidatorObserverService {
55
78
  }
56
79
 
57
80
  async #worker(next) {
58
- if (!this.#network.validatorConnectionManager.maxConnections()) {
81
+ if (!this.#network.validatorConnectionManager.maxConnectionsReached()) {
82
+ if (DEBUG) this.begin = Date.now();
59
83
  const length = await this.#lengthEntry()
60
84
 
61
85
  const promises = [];
62
- for (let i = 0; i < 10; i++) {
63
- promises.push(this.#findValidator(this.#address, length));
86
+ for (let i = 0; i < VALIDATOR_CANDIDATES_PER_CYCLE; i++) {
87
+ promises.push(this.#findValidator(this.#address, length + 1));
64
88
  await sleep(DELAY_INTERVAL); // Low key dangerous as the network progresses
65
89
  }
66
90
  await Promise.all(promises);
91
+
92
+ if (DEBUG) this.end = Date.now();
93
+ debugLog('Worker cycle completed in (ms):', this.end - this.begin, '| Validator Connections:', this.#network.validatorConnectionManager.connectionCount(), " | Pending: ", this.#network.pendingConnectionsCount());
67
94
  }
68
- next(POLL_INTERVAL)
95
+ else if (DEBUG) {
96
+ if (!this.reachedMax) {
97
+ this.reachedMax = true;
98
+ debugLog('Max validator connections reached. Skipping this cycle.');
99
+ const now = Date.now();
100
+ const elapsed = now - this.initTimestamp;
101
+ debugLog('>>> Time elapsed since start (ms):', elapsed);
102
+ }
103
+ }
104
+ next(POLL_INTERVAL);
69
105
  }
70
106
 
71
- async #findValidator(address, length) {
72
- if (this.#network.validatorConnectionManager.maxConnections() || !this.#shouldRun()) return;
107
+ async #findValidator(address, validatorListLength) {
108
+ if (!this.#shouldRun()) return;
109
+ const maxAttempts = 50; // TODO: make configurable
110
+ let attempts = 0;
111
+ let isValidatorValid = false;
112
+ let validatorAddressBuffer = b4a.alloc(0);
113
+
114
+ while (attempts < maxAttempts && !isValidatorValid) {
115
+ const rndIndex = Math.floor(Math.random() * validatorListLength);
116
+ validatorAddressBuffer = await this.state.getWriterIndex(rndIndex);
117
+ isValidatorValid = await this.#isValidatorValid(address, validatorAddressBuffer, validatorListLength);
118
+ attempts++;
119
+ }
120
+
121
+ if (attempts >= maxAttempts) {
122
+ debugLog('Max attempts reached without finding a valid validator.');
123
+ }
124
+ else {
125
+ debugLog(`Found valid validator to connect after ${attempts} attempts.`);
126
+ }
127
+
128
+ if (!isValidatorValid) return;
73
129
 
74
- const rndIndex = Math.floor(Math.random() * length);
75
- const validatorAddressBuffer = await this.state.getWriterIndex(rndIndex);
130
+ const validatorAddress = bufferToAddress(validatorAddressBuffer, this.#config.addressPrefix);
131
+ const validatorPubKeyBuffer = PeerWallet.decodeBech32m(validatorAddress);
132
+ const validatorPubKeyHex = validatorPubKeyBuffer.toString('hex');
133
+ const adminEntry = await this.state.getAdminEntry();
134
+
135
+ if (validatorAddress !== adminEntry?.address || validatorListLength < MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION) {
136
+ this.#network.tryConnect(validatorPubKeyHex, 'validator');
137
+ }
138
+ };
76
139
 
77
- if (validatorAddressBuffer === null || b4a.byteLength(validatorAddressBuffer) !== TRAC_ADDRESS_SIZE) return;
140
+ async #isValidatorValid(forbiddenAddress, validatorAddressBuffer, validatorListLength) {
141
+ if (validatorAddressBuffer === null || b4a.byteLength(validatorAddressBuffer) !== this.#config.addressLength) return false;
78
142
 
79
- const validatorAddress = bufferToAddress(validatorAddressBuffer);
80
- if (validatorAddress === address) return;
143
+ const validatorAddress = bufferToAddress(validatorAddressBuffer, this.#config.addressPrefix);
144
+ if (validatorAddress === forbiddenAddress) return false;
81
145
 
82
- const validatorPubKey = PeerWallet.decodeBech32m(validatorAddress).toString('hex');
146
+ const validatorPubKeyBuffer = PeerWallet.decodeBech32m(validatorAddress);
83
147
  const validatorEntry = await this.state.getNodeEntry(validatorAddress);
84
148
  const adminEntry = await this.state.getAdminEntry();
85
149
 
86
- if (validatorAddress === adminEntry?.address && length >= MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION) {
87
- const validatorPubKeyBuffer = b4a.from(validatorPubKey, 'hex')
150
+ if (this.#network.isConnectionPending(validatorPubKeyBuffer.toString('hex'))) {
151
+ return false;
152
+ }
153
+
154
+ if (validatorAddress === adminEntry?.address && validatorListLength >= MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION) {
88
155
  if (this.#network.validatorConnectionManager.exists(validatorPubKeyBuffer)) {
89
156
  this.#network.validatorConnectionManager.remove(validatorPubKeyBuffer)
90
157
  }
@@ -95,28 +162,22 @@ class ValidatorObserverService {
95
162
  // - Validator must exist and be a writer
96
163
  // - Cannot connect to indexers, except for admin-indexer
97
164
  // - Admin-indexer connection is allowed only when writers length has less than 10 writers
98
- if (
99
- this.#network.validatorConnectionManager.connected(validatorPubKey) ||
165
+ if (this.#network.validatorConnectionManager.connected(validatorPubKeyBuffer) ||
166
+ this.#network.validatorConnectionManager.maxConnectionsReached() ||
100
167
  validatorEntry === null ||
101
168
  !validatorEntry.isWriter ||
102
- (validatorEntry.isIndexer && (validatorAddress !== adminEntry?.address || length >= MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION))
169
+ (validatorEntry.isIndexer && (validatorAddress !== adminEntry?.address || validatorListLength >= MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION))
103
170
  ) {
104
- return;
105
- }
106
-
107
- if (validatorAddress !== adminEntry?.address || length < MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION) {
108
- await this.#network.tryConnect(validatorPubKey, 'validator');
109
- }
110
- };
111
-
112
- #shouldRun() {
113
- if (!this.#enable_validator_observer || this.#isInterrupted) {
114
171
  return false;
115
172
  }
116
173
 
117
174
  return true;
118
175
  }
119
176
 
177
+ #shouldRun() {
178
+ return this.#config.enableValidatorObserver && !this.#isInterrupted
179
+ }
180
+
120
181
  async #lengthEntry() {
121
182
  const lengthEntry = await this.state.getWriterLength();
122
183
  return Number.isInteger(lengthEntry) && lengthEntry > 0 ? lengthEntry : 0;