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
@@ -24,6 +24,7 @@ import {
24
24
  ACK_INTERVAL
25
25
  } from '../../src/utils/constants.js';
26
26
  import { testKeyPair1 } from '../fixtures/apply.fixtures.js';
27
+ import { createConfig, ENV } from '../../src/config/env.js';
27
28
 
28
29
  export class StateNetworkFactory {
29
30
 
@@ -106,11 +107,8 @@ export class StateNetworkFactory {
106
107
  for (let i = 0; i < nodes; i++) {
107
108
  const mnemonic = i === 0 ? testKeyPair1.mnemonic : null;
108
109
  const wallet = await createWallet(mnemonic);
109
- const state = new State(stateStores[i].session(), bootstrapKey, wallet, {
110
- enable_tx_apply_logs: false,
111
- enable_error_apply_logs: true,
112
- ...stateOptions
113
- });
110
+ const stateConfig = createConfig(ENV.DEVELOPMENT, { ...stateOptions, bootstrap: bootstrapKey })
111
+ const state = new State(stateStores[i].session(), wallet, stateConfig);
114
112
 
115
113
  bases[i]._handlers.apply = state.applyHandler;
116
114
  descriptors.push({
@@ -8,7 +8,7 @@ import Autobase from 'autobase';
8
8
  import Hyperbee from 'hyperbee';
9
9
  import b4a from 'b4a';
10
10
  import PeerWallet from 'trac-wallet';
11
- import { blake3Hash } from '../../src/utils/crypto.js';
11
+ import Hypercore from 'hypercore';
12
12
  import {
13
13
  ACK_INTERVAL,
14
14
  AUTOBASE_VALUE_ENCODING,
@@ -16,9 +16,55 @@ import {
16
16
  HYPERBEE_VALUE_ENCODING,
17
17
  TRAC_NAMESPACE
18
18
  } from '../../src/utils/constants.js';
19
+ import Writer from 'autobase/lib/writer.js';
19
20
 
20
21
  const argv = typeof globalThis.Bare !== 'undefined' ? globalThis.Bare.argv : process.argv;
21
22
 
23
+
24
+ const originalWriterOpen = Writer.prototype._open;
25
+ Writer.prototype._open = async function patchedWriterOpen(...args) {
26
+ try {
27
+ return await originalWriterOpen.apply(this, args);
28
+ } catch (err) {
29
+ // On teardown GH runners sometimes open a writer against a closing core.
30
+ // Ignore assertion errors from Autobase writer open during that window.
31
+ if (err?.name === 'AssertionError') return;
32
+ throw err;
33
+ }
34
+ };
35
+
36
+ // Hypercore/Hyperbee can throw SESSION_CLOSED while the core is shutting down.
37
+ // Swallow those during tests to avoid teardown flakes on slower runners.
38
+ const originalSnapshot = Hypercore.prototype.snapshot;
39
+ Hypercore.prototype.snapshot = function patchedSnapshot(...args) {
40
+ try {
41
+ return originalSnapshot.apply(this, args);
42
+ } catch (err) {
43
+ if (err?.code === 'SESSION_CLOSED') return this;
44
+ throw err;
45
+ }
46
+ };
47
+
48
+ const originalCoreGet = Hypercore.prototype.get;
49
+ Hypercore.prototype.get = async function patchedCoreGet(...args) {
50
+ try {
51
+ return await originalCoreGet.apply(this, args);
52
+ } catch (err) {
53
+ if (err?.code === 'SESSION_CLOSED') return null;
54
+ throw err;
55
+ }
56
+ };
57
+
58
+ const originalMakeSnapshot = Hyperbee.prototype._makeSnapshot;
59
+ Hyperbee.prototype._makeSnapshot = function patchedMakeSnapshot(...args) {
60
+ try {
61
+ return originalMakeSnapshot.apply(this, args);
62
+ } catch (err) {
63
+ if (err?.code === 'SESSION_CLOSED') return this.core;
64
+ throw err;
65
+ }
66
+ };
67
+
22
68
  export const encryptionKey = argv?.includes('--encrypt-all')
23
69
  ? b4a.alloc(32).fill('autobase-encryption-test')
24
70
  : undefined;
@@ -288,7 +334,7 @@ export function deriveIndexerSequenceState(base) {
288
334
  .map(entry => entry?.key)
289
335
  .filter(key => key && key.length > 0);
290
336
  const concatenated = buffers.length > 0 ? b4a.concat(buffers) : b4a.alloc(0);
291
- return blake3Hash(concatenated);
337
+ return PeerWallet.blake3(concatenated);
292
338
  }
293
339
 
294
340
  let osModule;
@@ -0,0 +1,3 @@
1
+ import { createConfig, ENV } from '../../src/config/env.js'
2
+
3
+ export const config = createConfig(ENV.DEVELOPMENT, {})
@@ -6,17 +6,17 @@ import path from 'path';
6
6
  import CompleteStateMessageOperations from '../../src/messages/completeStateMessages/CompleteStateMessageOperations.js'
7
7
  import PartialStateMessageOperations from '../../src/messages/partialStateMessages/PartialStateMessageOperations.js';
8
8
  import {MainSettlementBus} from '../../src/index.js'
9
+ import { createConfig, ENV } from '../../src/config/env.js'
9
10
  import fileUtils from '../../src/utils/fileUtils.js'
10
11
  import {EntryType} from '../../src/utils/constants.js';
11
12
  import {sleep} from '../../src/utils/helpers.js'
12
13
  import {formatIndexersEntry} from '../../src/utils/helpers.js';
13
- import {blake3Hash} from '../../src/utils/crypto.js';
14
14
  import CompleteStateMessageBuilder from '../../src/messages/completeStateMessages/CompleteStateMessageBuilder.js'
15
15
  import CompleteStateMessageDirector from '../../src/messages/completeStateMessages/CompleteStateMessageDirector.js'
16
16
  import { safeEncodeApplyOperation } from "../../src/utils/protobuf/operationHelpers.js"
17
17
  import { $TNK } from '../../src/core/state/utils/balance.js';
18
- import { operation } from 'trac-crypto-api'
19
18
  import { EventType } from '../../src/utils/constants.js';
19
+ import { Config } from '../../src/config/config.js';
20
20
  let os, fsp;
21
21
 
22
22
  /**
@@ -70,7 +70,7 @@ export const tick = () => new Promise(resolve => setImmediate(resolve));
70
70
  export async function fundPeer(admin, toFund, amount) {
71
71
  const txValidity = await admin.msb.state.getIndexerSequenceState()
72
72
  const director = new CompleteStateMessageDirector();
73
- director.builder = new CompleteStateMessageBuilder(admin.wallet);
73
+ director.builder = new CompleteStateMessageBuilder(admin.wallet, admin.config);
74
74
  const payload = await director.buildBalanceInitializationMessage(
75
75
  admin.wallet.address,
76
76
  toFund.wallet.address,
@@ -88,9 +88,10 @@ export async function fundPeer(admin, toFund, amount) {
88
88
  export async function initMsbPeer(peerName, peerKeyPair, temporaryDirectory, options = {}) {
89
89
  const peer = await initDirectoryStructure(peerName, peerKeyPair, temporaryDirectory);
90
90
  peer.options = options
91
- peer.options.stores_directory = peer.storesDirectory;
92
- peer.options.store_name = peer.storeName;
93
- const msb = new MainSettlementBus(peer.options);
91
+ peer.options.storesDirectory = peer.storesDirectory;
92
+ peer.options.storeName = peer.storeName;
93
+ peer.config = createConfig(ENV.DEVELOPMENT, peer.options)
94
+ const msb = new MainSettlementBus(peer.config);
94
95
 
95
96
  peer.msb = msb;
96
97
  peer.wallet = msb.wallet;
@@ -110,10 +111,11 @@ export async function initMsbAdmin(keyPair, temporaryDirectory, options = {}) {
110
111
  const admin = await initMsbPeer(peerName, keyPair, temporaryDirectory, { ...options, bootstrap: randomBytes(32).toString('hex') });
111
112
 
112
113
  await admin.msb.ready();
113
- admin.options.bootstrap = admin.msb.state.writingKey;
114
+ admin.options.bootstrap = admin.msb.state.writingKey.toString('hex');
115
+ admin.config = new Config(admin.options, admin.config)
114
116
  await admin.msb.close();
115
117
 
116
- admin.msb = new MainSettlementBus(admin.options);
118
+ admin.msb = new MainSettlementBus(admin.config);
117
119
  await admin.msb.ready();
118
120
  await admin.msb.state.append(null); // before initialization system.indexers is empty, we need to initialize first block to create system.indexers array
119
121
  return admin;
@@ -122,7 +124,9 @@ export async function initMsbAdmin(keyPair, temporaryDirectory, options = {}) {
122
124
  export async function setupMsbAdmin(keyPair, temporaryDirectory, options = {}) {
123
125
  const admin = await initMsbAdmin(keyPair, temporaryDirectory, options);
124
126
  const txValidity = await admin.msb.state.getIndexerSequenceState();
125
- const addAdminMessage = await CompleteStateMessageOperations.assembleAddAdminMessage(admin.wallet, admin.msb.state.writingKey, txValidity);
127
+ const addAdminMessage = await new CompleteStateMessageOperations(admin.wallet, admin.config)
128
+ .assembleAddAdminMessage(admin.msb.state.writingKey, txValidity);
129
+
126
130
  await admin.msb.state.append(addAdminMessage);
127
131
  await tick();
128
132
  return admin;
@@ -133,21 +137,21 @@ export async function setupNodeAsWriter(admin, writerCandidate) {
133
137
  await setupWhitelist(admin, [writerCandidate.wallet.address]); // ensure if is whitelisted
134
138
 
135
139
  const validity = await admin.msb.getIndexerSequenceState()
136
- const req = await PartialStateMessageOperations.assembleAddWriterMessage(
137
- writerCandidate.wallet,
138
- writerCandidate.msb.state.writingKey,
139
- validity);
140
+ const req = await new PartialStateMessageOperations(writerCandidate.wallet, admin.config)
141
+ .assembleAddWriterMessage(
142
+ b4a.toString(writerCandidate.msb.state.writingKey, 'hex'),
143
+ b4a.toString(validity, 'hex'));
140
144
 
141
145
  await waitWritable(admin, writerCandidate, async () => {
142
- const raw = await CompleteStateMessageOperations.assembleAddWriterMessage(
143
- admin.wallet,
144
- req.address,
145
- b4a.from(req.rao.tx, 'hex'),
146
- b4a.from(req.rao.txv, 'hex'),
147
- b4a.from(req.rao.iw, 'hex'),
148
- b4a.from(req.rao.in, 'hex'),
149
- b4a.from(req.rao.is, 'hex')
150
- )
146
+ const raw = await new CompleteStateMessageOperations(admin.wallet, admin.config)
147
+ .assembleAddWriterMessage(
148
+ admin.wallet.address,
149
+ b4a.from(req.rao.tx, 'hex'),
150
+ b4a.from(req.rao.txv, 'hex'),
151
+ b4a.from(req.rao.iw, 'hex'),
152
+ b4a.from(req.rao.in, 'hex'),
153
+ b4a.from(req.rao.is, 'hex')
154
+ )
151
155
  await admin.msb.state.append(raw)
152
156
  })
153
157
 
@@ -168,21 +172,21 @@ export async function promoteToWriter(admin, writerCandidate) {
168
172
  isIndexer: false,
169
173
  })
170
174
  const validity = await admin.msb.state.getIndexerSequenceState()
171
- const req = await PartialStateMessageOperations.assembleAddWriterMessage(
172
- writerCandidate.wallet,
173
- b4a.toString(writerCandidate.msb.state.writingKey, 'hex'),
174
- b4a.toString(validity, 'hex'));
175
+ const req = await new PartialStateMessageOperations(writerCandidate.wallet, writerCandidate.config)
176
+ .assembleAddWriterMessage(
177
+ b4a.toString(writerCandidate.msb.state.writingKey, 'hex'),
178
+ b4a.toString(validity, 'hex'));
175
179
 
176
180
  await waitWritable(writerCandidate, writerCandidate, async () => {
177
- const raw = await CompleteStateMessageOperations.assembleAddWriterMessage(
178
- admin.wallet,
179
- req.address,
180
- b4a.from(req.rao.tx, 'hex'),
181
- b4a.from(req.rao.txv, 'hex'),
182
- b4a.from(req.rao.iw, 'hex'),
183
- b4a.from(req.rao.in, 'hex'),
184
- b4a.from(req.rao.is, 'hex')
185
- )
181
+ const raw = await new CompleteStateMessageOperations(admin.wallet, admin.config)
182
+ .assembleAddWriterMessage(
183
+ req.address,
184
+ b4a.from(req.rao.tx, 'hex'),
185
+ b4a.from(req.rao.txv, 'hex'),
186
+ b4a.from(req.rao.iw, 'hex'),
187
+ b4a.from(req.rao.in, 'hex'),
188
+ b4a.from(req.rao.is, 'hex')
189
+ )
186
190
  await admin.msb.state.append(raw)
187
191
  })
188
192
 
@@ -201,8 +205,10 @@ export async function setupMsbWriter(admin, peerName, peerKeyPair, temporaryDire
201
205
 
202
206
  export async function setupMsbIndexer(indexerCandidate, admin) {
203
207
  try {
204
- const validity = await admin.msb.state.getIndexerSequenceState()
205
- const req = await CompleteStateMessageOperations.assembleAddIndexerMessage(admin.wallet, indexerCandidate.wallet.address, validity);
208
+ const validity = await admin.msb.state.getIndexerSequenceState()
209
+ const req = await new CompleteStateMessageOperations(admin.wallet, admin.config)
210
+ .assembleAddIndexerMessage(indexerCandidate.wallet.address, validity);
211
+
206
212
  await admin.msb.state.append(req);
207
213
  await tick(); // wait for the request to be processed
208
214
 
@@ -211,7 +217,7 @@ export async function setupMsbIndexer(indexerCandidate, admin) {
211
217
  if (!indexersEntry) {
212
218
  return false;
213
219
  }
214
- const formatted = formatIndexersEntry(indexersEntry);
220
+ const formatted = formatIndexersEntry(indexersEntry, admin.config.addressLength);
215
221
  if (!formatted || !formatted.addresses) return false;
216
222
  return formatted.addresses.includes(indexerCandidate.wallet.address);
217
223
  }
@@ -254,11 +260,13 @@ export async function setupWhitelist(admin, whitelistAddresses) {
254
260
  fileUtils.readAddressesFromWhitelistFile = async () => whitelistAddresses;
255
261
  const validity = await admin.msb.state.getIndexerSequenceState()
256
262
  for (const address of whitelistAddresses) {
257
- const msg = await CompleteStateMessageOperations.assembleAppendWhitelistMessages(admin.wallet, validity, address);
263
+ const msg = await new CompleteStateMessageOperations(admin.wallet, admin.config)
264
+ .assembleAppendWhitelistMessages(validity, address);
265
+
258
266
  await admin.msb.state.append(msg);
259
267
  await sleep(100)
260
268
  }
261
- await admin.msb.state.base.forceFastForward()
269
+
262
270
  fileUtils.readAddressesFromWhitelistFile = originalReadAddressesFromWhitelistFile;
263
271
  }
264
272
 
@@ -306,23 +314,23 @@ export async function initDirectoryStructure(peerName, keyPair, temporaryDirecto
306
314
  export const deployExternalBootstrap = async (writer, externalNode) => {
307
315
  const externalBootstrap = randomBytes(32).toString('hex');
308
316
  const txValidity = await writer.msb.state.getIndexerSequenceState();
309
- const payload = await PartialStateMessageOperations.assembleBootstrapDeploymentMessage(
310
- externalNode.msb.wallet,
311
- externalBootstrap,
312
- randomBytes(32).toString('hex'),
313
- txValidity.toString('hex')
314
- );
315
-
316
- const raw = await CompleteStateMessageOperations.assembleCompleteBootstrapDeployment(
317
- writer.msb.wallet,
318
- payload.address,
319
- b4a.from(payload.bdo.tx, 'hex'),
320
- b4a.from(payload.bdo.txv, 'hex'),
321
- b4a.from(payload.bdo.bs, 'hex'),
322
- b4a.from(payload.bdo.ic, 'hex'),
323
- b4a.from(payload.bdo.in, 'hex'),
324
- b4a.from(payload.bdo.is, 'hex'),
325
- )
317
+ const payload = await new PartialStateMessageOperations(externalNode.msb.wallet, admin.config)
318
+ .assembleBootstrapDeploymentMessage(
319
+ externalBootstrap,
320
+ randomBytes(32).toString('hex'),
321
+ txValidity.toString('hex')
322
+ );
323
+
324
+ const raw = await new CompleteStateMessageOperations(writer.msb.wallet, admin.config)
325
+ .assembleCompleteBootstrapDeployment(
326
+ payload.address,
327
+ b4a.from(payload.bdo.tx, 'hex'),
328
+ b4a.from(payload.bdo.txv, 'hex'),
329
+ b4a.from(payload.bdo.bs, 'hex'),
330
+ b4a.from(payload.bdo.ic, 'hex'),
331
+ b4a.from(payload.bdo.in, 'hex'),
332
+ b4a.from(payload.bdo.is, 'hex'),
333
+ )
326
334
  await writer.msb.state.base.append(raw)
327
335
  await tick()
328
336
  await waitForHash(writer, payload.bdo.tx)
@@ -343,29 +351,29 @@ export const generatePostTx = async (writer, externalNode, externalContractBoots
343
351
  }
344
352
  };
345
353
 
346
- const contentHash = await blake3Hash(JSON.stringify(testObj));
354
+ const contentHash = await PeerWallet.blake3(JSON.stringify(testObj));
347
355
  const validity = await writer.msb.state.getIndexerSequenceState()
348
- const tx = await PartialStateMessageOperations.assembleTransactionOperationMessage(
349
- externalNode.wallet,
350
- peerWriterKey,
351
- b4a.toString(validity, 'hex'),
352
- b4a.toString(contentHash, 'hex'),
353
- externalContractBootstrap,
354
- b4a.toString(writer.msb.bootstrap, 'hex')
355
- )
356
-
357
- const postTx = await CompleteStateMessageOperations.assembleCompleteTransactionOperationMessage(
358
- writer.wallet,
359
- tx.address,
360
- b4a.from(tx.txo.tx, 'hex'),
361
- b4a.from(tx.txo.txv, 'hex'),
362
- b4a.from(tx.txo.iw, 'hex'),
363
- b4a.from(tx.txo.in, 'hex'),
364
- b4a.from(tx.txo.ch, 'hex'),
365
- b4a.from(tx.txo.is, 'hex'),
366
- b4a.from(tx.txo.bs, 'hex'),
367
- b4a.from(tx.txo.mbs, 'hex')
368
- );
356
+ const tx = await new PartialStateMessageOperations(externalNode.wallet, admin.config)
357
+ .assembleTransactionOperationMessage(
358
+ peerWriterKey,
359
+ b4a.toString(validity, 'hex'),
360
+ b4a.toString(contentHash, 'hex'),
361
+ externalContractBootstrap,
362
+ b4a.toString(writer.msb.bootstrap, 'hex')
363
+ )
364
+
365
+ const postTx = await new CompleteStateMessageOperations(writer.wallet, admin.config)
366
+ .assembleCompleteTransactionOperationMessage(
367
+ tx.address,
368
+ b4a.from(tx.txo.tx, 'hex'),
369
+ b4a.from(tx.txo.txv, 'hex'),
370
+ b4a.from(tx.txo.iw, 'hex'),
371
+ b4a.from(tx.txo.in, 'hex'),
372
+ b4a.from(tx.txo.ch, 'hex'),
373
+ b4a.from(tx.txo.is, 'hex'),
374
+ b4a.from(tx.txo.bs, 'hex'),
375
+ b4a.from(tx.txo.mbs, 'hex')
376
+ );
369
377
 
370
378
  return { postTx, txHash: tx.txo.tx };
371
379
  }
@@ -404,7 +412,6 @@ export const tryToSyncWriters = async (...args) => {
404
412
  }
405
413
  }
406
414
 
407
-
408
415
  export async function waitForNotIndexer(indexer) {
409
416
  try {
410
417
  let attempts = 0;
@@ -417,7 +424,7 @@ export async function waitForNotIndexer(indexer) {
417
424
  if (!indexersEntry) {
418
425
  notIndexer = true;
419
426
  } else {
420
- const formatted = formatIndexersEntry(indexersEntry);
427
+ const formatted = formatIndexersEntry(indexersEntry, admin.config.addressLength);
421
428
  if (!formatted || !formatted.addresses) {
422
429
  notIndexer = true;
423
430
  } else if (!formatted.addresses.includes(indexer.wallet.address)) {
@@ -564,7 +571,7 @@ export async function waitForIndexersEntry(node, expected) {
564
571
  await sleep(250);
565
572
  continue;
566
573
  }
567
- const formatted = formatIndexersEntry(indexersEntry);
574
+ const formatted = formatIndexersEntry(indexersEntry, admin.config.addressLength);
568
575
  if (formatted && formatted.addresses && formatted.addresses.includes(expected.address)) {
569
576
  break;
570
577
  }
@@ -1,11 +1,25 @@
1
1
  import b4a from "b4a";
2
2
  import tracCrypto from "trac-crypto-api";
3
-
3
+ import PeerWallet from "trac-wallet";
4
4
  import { $TNK } from "../../src/core/state/utils/balance.js";
5
5
  import { createMessage } from "../../src/utils/buffer.js";
6
- import { blake3Hash } from "../../src/utils/crypto.js";
7
- import { OperationType, NETWORK_ID } from "../../src/utils/constants.js";
6
+ import { OperationType } from "../../src/utils/constants.js";
8
7
  import { addressToBuffer } from "../../src/core/state/utils/address.js";
8
+ import { config } from '../helpers/config.js'
9
+ import { sleep } from "../../src/utils/helpers.js";
10
+
11
+ export const waitForConnection = async node => {
12
+ let attempts = 0
13
+ while (attempts < 60) {
14
+ const count = node.network.validatorConnectionManager.connectionCount()
15
+ if (count > 0) {
16
+ break
17
+ }
18
+
19
+ await sleep(300);
20
+ attempts++;
21
+ }
22
+ }
9
23
 
10
24
  /**
11
25
  * Build a base64-encoded transfer payload and matching tx hash
@@ -15,18 +29,18 @@ import { addressToBuffer } from "../../src/core/state/utils/address.js";
15
29
  * PartialOperation.validateSignature, so that tests broadcast
16
30
  * transactions the node will accept without touching consensus code.
17
31
  *
18
- * @param {import("trac-wallet").default} wallet - Writer wallet used for signing.
32
+ * @param {object} context - General context
19
33
  * @param {import("../../src/core/state/State.js").default} state - MSB state instance.
20
34
  * @param {bigint} [amountTnk=1n] - Transfer amount in TNK units.
21
35
  * @returns {Promise<{ payload: string, txHashHex: string }>}
22
36
  */
23
- export async function buildRpcSelfTransferPayload(wallet, state, amountTnk = 1n) {
37
+ export async function buildRpcSelfTransferPayload(context, state, amountTnk = 1n) {
24
38
  const txvBuffer = await state.getIndexerSequenceState();
25
39
  const txvHex = b4a.toString(txvBuffer, "hex");
26
40
 
27
41
  const txData = await tracCrypto.transaction.preBuild(
28
- wallet.address,
29
- wallet.address,
42
+ context.wallet.address,
43
+ context.wallet.address,
30
44
  b4a.toString($TNK(amountTnk), "hex"),
31
45
  txvHex
32
46
  );
@@ -38,10 +52,10 @@ export async function buildRpcSelfTransferPayload(wallet, state, amountTnk = 1n)
38
52
  const txvBuf = b4a.from(txData.validity, "hex");
39
53
  const nonceBuf = b4a.from(nonceHex, "hex");
40
54
  const amountBuf = b4a.from(amountHex, "hex");
41
- const toBuf = addressToBuffer(toAddress);
55
+ const toBuf = addressToBuffer(toAddress, config.addressPrefix);
42
56
 
43
57
  const message = createMessage(
44
- NETWORK_ID,
58
+ config.networkId,
45
59
  txvBuf,
46
60
  toBuf,
47
61
  amountBuf,
@@ -49,12 +63,12 @@ export async function buildRpcSelfTransferPayload(wallet, state, amountTnk = 1n)
49
63
  OperationType.TRANSFER
50
64
  );
51
65
 
52
- const messageHash = await blake3Hash(message);
53
- const signature = wallet.sign(messageHash);
66
+ const messageHash = await PeerWallet.blake3(message);
67
+ const signature = context.wallet.sign(messageHash);
54
68
 
55
69
  const payloadObject = {
56
70
  type: OperationType.TRANSFER,
57
- address: wallet.address,
71
+ address: context.wallet.address,
58
72
  tro: {
59
73
  tx: b4a.toString(messageHash, "hex"),
60
74
  txv: txData.validity,
@@ -5,6 +5,7 @@ import {
5
5
  } from '../../../helpers/setupApplyTests.js';
6
6
  import {randomBytes} from '../../../helpers/setupApplyTests.js';
7
7
  import CompleteStateMessageOperations from '../../../../src/messages/completeStateMessages/CompleteStateMessageOperations.js';
8
+ import { config } from '../../../helpers/config.js';
8
9
  import {testKeyPair1} from '../../../fixtures/apply.fixtures.js';
9
10
  import b4a from 'b4a';
10
11
  import { ADMIN_INITIAL_BALANCE } from '../../../../src/utils/constants.js';
@@ -17,11 +18,11 @@ let randomChannel;
17
18
 
18
19
  const sendAddAdmin = async (invoker) => {
19
20
  const validity = b4a.from(await admin.msb.state.getIndexerSequenceState(), 'hex')
20
- const addAdminMessage = await CompleteStateMessageOperations.assembleAddAdminMessage(
21
- admin.wallet,
22
- admin.msb.state.writingKey,
23
- validity
24
- );
21
+ const addAdminMessage = await new CompleteStateMessageOperations(admin.wallet, config)
22
+ .assembleAddAdminMessage(
23
+ admin.msb.state.writingKey,
24
+ validity
25
+ );
25
26
 
26
27
  // add admin to base
27
28
  await invoker.msb.state.append(addAdminMessage); // Send `add admin` request to apply function
@@ -30,11 +31,11 @@ const sendAddAdmin = async (invoker) => {
30
31
  hook('Initialize admin for addAdmin tests', async () => {
31
32
  randomChannel = randomBytes(32).toString('hex');
32
33
  const baseOptions = {
33
- enable_tx_apply_logs: false,
34
- enable_interactive_mode: false,
35
- enable_role_requester: false,
34
+ enableTxApplyLogs: false,
35
+ enableInteractiveMode: false,
36
+ enableRoleRequester: false,
36
37
  channel: randomChannel,
37
- enable_validator_observer: false,
38
+ enableValidatorObserver: false,
38
39
  }
39
40
  tmpDirectory = await initTemporaryDirectory();
40
41
  admin = await initMsbAdmin(testKeyPair1, tmpDirectory, baseOptions);
@@ -11,6 +11,7 @@ import {testKeyPair1, testKeyPair2, testKeyPair3, testKeyPair4} from '../../../f
11
11
  import b4a from 'b4a';
12
12
  import { decode as decodeAdmin } from '../../../../src/core/state/utils/adminEntry.js';
13
13
  import { EntryType } from '../../../../src/utils/constants.js';
14
+ import { config } from '../../../helpers/config.js';
14
15
  //TODO: ADD TEST WHEN NON-ADMIN NODE FORGES ADD ADMIN OPERATION AND BROADCASTS IT TO THE STATE - SHOULD BE REJECTED
15
16
 
16
17
  let admin, newAdmin;
@@ -21,11 +22,11 @@ let randomChannel;
21
22
  hook('Initialize admin for addAdmin tests', async () => {
22
23
  randomChannel = randomBytes(32).toString('hex');
23
24
  const baseOptions = {
24
- enable_tx_apply_logs: false,
25
- enable_interactive_mode: false,
26
- enable_role_requester: false,
25
+ enableTxApplyLogs: false,
26
+ enableInteractiveMode: false,
27
+ enableRoleRequester: false,
27
28
  channel: randomChannel,
28
- enable_validator_observer: false,
29
+ enableValidatorObserver: false,
29
30
  }
30
31
  tmpDirectory = await initTemporaryDirectory()
31
32
  admin = await setupMsbAdmin(testKeyPair1, tmpDirectory, baseOptions);
@@ -87,24 +88,24 @@ test('Apply function addAdmin for recovery - happy path', async (k) => {
87
88
  await newAdmin.msb.ready();
88
89
  await newAdmin.msb.state.append(null);
89
90
  const validity = b4a.toString(await newAdmin.msb.state.getIndexerSequenceState(), 'hex')
90
- const addAdminMessage = await PartialStateMessageOperations.assembleAdminRecoveryMessage(
91
- newAdmin.wallet,
92
- b4a.toString(newAdmin.msb.state.writingKey, 'hex'),
93
- validity
94
- );
91
+ const addAdminMessage = await new PartialStateMessageOperations(newAdmin.wallet, config)
92
+ .assembleAdminRecoveryMessage(
93
+ b4a.toString(newAdmin.msb.state.writingKey, 'hex'),
94
+ validity
95
+ );
95
96
 
96
- const rawTx = await CompleteStateMessageOperations.assembleAdminRecoveryMessage(
97
- writer.wallet,
98
- addAdminMessage.address,
99
- b4a.from(addAdminMessage.rao.tx, 'hex'),
100
- b4a.from(addAdminMessage.rao.txv, 'hex'),
101
- b4a.from(addAdminMessage.rao.iw, 'hex'),
102
- b4a.from(addAdminMessage.rao.in, 'hex'),
103
- b4a.from(addAdminMessage.rao.is, 'hex')
104
- )
97
+ const rawTx = await new CompleteStateMessageOperations(writer.wallet, config)
98
+ .assembleAdminRecoveryMessage(
99
+ addAdminMessage.address,
100
+ b4a.from(addAdminMessage.rao.tx, 'hex'),
101
+ b4a.from(addAdminMessage.rao.txv, 'hex'),
102
+ b4a.from(addAdminMessage.rao.iw, 'hex'),
103
+ b4a.from(addAdminMessage.rao.in, 'hex'),
104
+ b4a.from(addAdminMessage.rao.is, 'hex')
105
+ )
105
106
  await writer.msb.state.append(rawTx)
106
107
  await tryToSyncWriters(writer, indexer1, indexer2, newAdmin);
107
- const adminEntryAfter = decodeAdmin(await writer.msb.state.get(EntryType.ADMIN)); // check if the admin entry was added successfully in the base
108
+ const adminEntryAfter = decodeAdmin(await writer.msb.state.get(EntryType.ADMIN), config.addressPrefix); // check if the admin entry was added successfully in the base
108
109
  k.ok(adminEntryAfter, 'Result should not be null');
109
110
  k.ok(adminEntryAfter.address === newAdmin.wallet.address, 'New Admin address in base should match new admin wallet address');
110
111
  k.ok(adminAddressBeforeRecovery === newAdmin.wallet.address, 'New Admin wallet address should be the same as old admin wallet address');