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.
- package/.github/workflows/publish.yml +9 -16
- package/docs/networking-dualstack-plan.md +75 -0
- package/docs/networking-layer-redesign.md +155 -0
- package/msb.mjs +11 -23
- package/package.json +2 -3
- package/rpc/{create_server.mjs → create_server.js} +2 -2
- package/rpc/{handlers.mjs → handlers.js} +5 -5
- package/rpc/routes/{index.mjs → index.js} +1 -1
- package/rpc/routes/{v1.mjs → v1.js} +1 -1
- package/rpc/{rpc_server.mjs → rpc_server.js} +1 -1
- package/rpc/rpc_services.js +4 -4
- package/src/config/config.js +137 -0
- package/src/config/env.js +61 -0
- package/src/core/network/Network.js +131 -72
- package/src/core/network/identity/NetworkWalletFactory.js +3 -4
- package/src/core/network/messaging/NetworkMessages.js +12 -11
- package/src/core/network/messaging/handlers/GetRequestHandler.js +5 -4
- package/src/core/network/messaging/handlers/ResponseHandler.js +4 -5
- package/src/core/network/messaging/handlers/RoleOperationHandler.js +17 -19
- package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +44 -38
- package/src/core/network/messaging/handlers/TransferOperationHandler.js +29 -25
- package/src/core/network/messaging/handlers/base/BaseOperationHandler.js +20 -21
- package/src/core/network/messaging/routes/NetworkMessageRouter.js +24 -20
- package/src/core/network/messaging/validators/AdminResponse.js +2 -2
- package/src/core/network/messaging/validators/CustomNodeResponse.js +2 -2
- package/src/core/network/messaging/validators/PartialBootstrapDeployment.js +3 -3
- package/src/core/network/messaging/validators/PartialRoleAccess.js +15 -12
- package/src/core/network/messaging/validators/PartialTransaction.js +9 -10
- package/src/core/network/messaging/validators/PartialTransfer.js +10 -7
- package/src/core/network/messaging/validators/ValidatorResponse.js +2 -2
- package/src/core/network/messaging/validators/base/BaseResponse.js +13 -5
- package/src/core/network/messaging/validators/base/PartialOperation.js +37 -21
- package/src/core/network/services/ConnectionManager.js +248 -62
- package/src/core/network/services/MessageOrchestrator.js +83 -0
- package/src/core/network/services/TransactionPoolService.js +9 -8
- package/src/core/network/services/ValidatorObserverService.js +95 -34
- package/src/core/state/State.js +136 -139
- package/src/core/state/utils/address.js +18 -16
- package/src/core/state/utils/adminEntry.js +17 -16
- package/src/core/state/utils/deploymentEntry.js +15 -15
- package/src/core/state/utils/transaction.js +3 -95
- package/src/index.js +153 -201
- package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +36 -32
- package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +39 -42
- package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +20 -20
- package/src/messages/partialStateMessages/PartialStateMessageOperations.js +29 -22
- package/src/utils/check.js +21 -17
- package/src/utils/cliCommands.js +11 -11
- package/src/utils/constants.js +2 -9
- package/src/utils/fileUtils.js +1 -4
- package/src/utils/helpers.js +9 -20
- package/src/utils/migrationUtils.js +2 -2
- package/src/utils/normalizers.js +10 -9
- package/tests/acceptance/v1/account/account.test.mjs +2 -2
- package/tests/acceptance/v1/balance/balance.test.mjs +1 -1
- package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +11 -2
- package/tests/acceptance/v1/rpc.test.mjs +9 -9
- package/tests/acceptance/v1/tx/tx.test.mjs +4 -2
- package/tests/acceptance/v1/tx-details/tx-details.test.mjs +7 -3
- package/tests/fixtures/check.fixtures.js +42 -42
- package/tests/fixtures/protobuf.fixtures.js +27 -26
- package/tests/helpers/StateNetworkFactory.js +3 -5
- package/tests/helpers/autobaseTestHelpers.js +48 -2
- package/tests/helpers/config.js +3 -0
- package/tests/helpers/setupApplyTests.js +89 -82
- package/tests/helpers/transactionPayloads.mjs +26 -12
- package/tests/integration/apply/addAdmin/addAdminBasic.test.js +10 -9
- package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +20 -19
- package/tests/integration/apply/addIndexer.test.js +23 -21
- package/tests/integration/apply/addWhitelist.test.js +9 -9
- package/tests/integration/apply/addWriter.test.js +33 -32
- package/tests/integration/apply/banValidator.test.js +16 -9
- package/tests/integration/apply/postTx/invalidSubValues.test.js +4 -4
- package/tests/integration/apply/postTx/postTx.test.js +7 -33
- package/tests/integration/apply/removeIndexer.test.js +11 -7
- package/tests/integration/apply/removeWriter.test.js +20 -19
- package/tests/integration/apply/transfer.test.js +18 -16
- package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +2 -2
- package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +2 -1
- package/tests/unit/messageOperations/assembleAdminMessage.test.js +9 -10
- package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +3 -2
- package/tests/unit/messageOperations/assemblePostTransaction.test.js +25 -43
- package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +2 -2
- package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +2 -2
- package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +5 -4
- package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +4 -3
- package/tests/unit/network/ConnectionManager.test.js +41 -70
- package/tests/unit/network/NetworkWalletFactory.test.js +14 -14
- package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +6 -6
- package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +8 -8
- package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +6 -5
- package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +24 -23
- package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +10 -16
- package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +2 -1
- package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +45 -41
- package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +3 -7
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +17 -16
- package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +3 -4
- package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +2 -1
- package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +2 -1
- package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +23 -25
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +2 -1
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +19 -18
- package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +5 -4
- package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +4 -3
- package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +2 -1
- package/tests/unit/state/apply/common/commonScenarioHelper.js +3 -4
- package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +2 -2
- package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +2 -2
- package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +2 -1
- package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +2 -1
- package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +2 -1
- package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +2 -1
- package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +11 -10
- package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +6 -5
- package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +6 -7
- package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +35 -34
- package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +44 -43
- package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +26 -25
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +2 -1
- package/tests/unit/state/stateModule.test.js +0 -1
- package/tests/unit/state/stateTestUtils.js +7 -3
- package/tests/unit/state/utils/address.test.js +3 -3
- package/tests/unit/state/utils/adminEntry.test.js +10 -9
- package/tests/unit/utils/check/adminControlOperation.test.js +3 -3
- package/tests/unit/utils/check/balanceInitializationOperation.test.js +2 -2
- package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +2 -3
- package/tests/unit/utils/check/common.test.js +7 -6
- package/tests/unit/utils/check/coreAdminOperation.test.js +3 -3
- package/tests/unit/utils/check/roleAccessOperation.test.js +3 -2
- package/tests/unit/utils/check/transactionOperation.test.js +3 -3
- package/tests/unit/utils/check/transferOperation.test.js +3 -3
- package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +2 -1
- package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +2 -1
- package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +7 -0
- package/tests/unit/utils/utils.test.js +0 -1
- package/src/core/state/utils/indexerEntry.js +0 -105
- package/src/utils/crypto.js +0 -11
- package/tests/unit/state/utils/indexerEntry.test.js +0 -83
- package/tests/unit/state/utils/transaction.test.js +0 -97
- package/tests/unit/utils/crypto/createHash.test.js +0 -15
- /package/rpc/{constants.mjs → constants.js} +0 -0
- /package/rpc/{cors.mjs → cors.js} +0 -0
- /package/rpc/utils/{confirmedParameter.mjs → confirmedParameter.js} +0 -0
- /package/rpc/utils/{helpers.mjs → helpers.js} +0 -0
- /package/rpc/utils/{url.mjs → url.js} +0 -0
|
@@ -2,6 +2,17 @@ import PartialStateMessageBuilder from './PartialStateMessageBuilder.js';
|
|
|
2
2
|
import PartialStateMessageDirector from './PartialStateMessageDirector.js';
|
|
3
3
|
|
|
4
4
|
class PartialStateMessageOperations {
|
|
5
|
+
#wallet;
|
|
6
|
+
#config
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {PeerWallet} wallet - Wallet of the requester/invoker node that broadcasts the operation
|
|
10
|
+
* @param {object} config - A configuration object
|
|
11
|
+
*/
|
|
12
|
+
constructor(wallet, config) {
|
|
13
|
+
this.#wallet = wallet;
|
|
14
|
+
this.#config = config;
|
|
15
|
+
}
|
|
5
16
|
|
|
6
17
|
/**
|
|
7
18
|
* Assembles a PARTIAL bootstrap deployment operation, which can be sent to a validator.
|
|
@@ -9,8 +20,6 @@ class PartialStateMessageOperations {
|
|
|
9
20
|
* Bootstrap deployment is required to register a subnetwork. The network will reject
|
|
10
21
|
* TransactionOperation messages for external bootstraps that are not registered.
|
|
11
22
|
* Do NOT attempt to register the MSB bootstrap key.
|
|
12
|
-
*
|
|
13
|
-
* @param {Object} wallet - Wallet of the requester/invoker node that broadcasts the operation
|
|
14
23
|
* @param {String} externalBootstrap - Bootstrap key from the subnetwork to be registered.
|
|
15
24
|
* MUST be different from the MSB bootstrap key.
|
|
16
25
|
* BEFORE deploying ensure if the subnetwork bootstrap is not already deployed.
|
|
@@ -20,13 +29,13 @@ class PartialStateMessageOperations {
|
|
|
20
29
|
* @returns {Promise<Object>} The assembled bootstrap deployment operation message
|
|
21
30
|
* @throws {Error} If assembly of the bootstrap deployment operation message fails
|
|
22
31
|
*/
|
|
23
|
-
|
|
32
|
+
async assembleBootstrapDeploymentMessage(externalBootstrap, channel, txValidity) {
|
|
24
33
|
try {
|
|
25
|
-
const builder = new PartialStateMessageBuilder(wallet);
|
|
34
|
+
const builder = new PartialStateMessageBuilder(this.#wallet, this.#config);
|
|
26
35
|
const director = new PartialStateMessageDirector();
|
|
27
36
|
director.builder = builder;
|
|
28
37
|
return await director.buildPartialBootstrapDeploymentMessage(
|
|
29
|
-
wallet.address,
|
|
38
|
+
this.#wallet.address,
|
|
30
39
|
externalBootstrap,
|
|
31
40
|
channel,
|
|
32
41
|
txValidity
|
|
@@ -36,34 +45,34 @@ class PartialStateMessageOperations {
|
|
|
36
45
|
}
|
|
37
46
|
}
|
|
38
47
|
|
|
39
|
-
|
|
48
|
+
async assembleAddWriterMessage(writingKey, txValidity) {
|
|
40
49
|
try {
|
|
41
|
-
const builder = new PartialStateMessageBuilder(wallet);
|
|
50
|
+
const builder = new PartialStateMessageBuilder(this.#wallet, this.#config);
|
|
42
51
|
const director = new PartialStateMessageDirector();
|
|
43
52
|
director.builder = builder;
|
|
44
|
-
return await director.buildAddWriterMessage(wallet.address, writingKey, txValidity);
|
|
53
|
+
return await director.buildAddWriterMessage(this.#wallet.address, writingKey, txValidity);
|
|
45
54
|
} catch (error) {
|
|
46
55
|
throw new Error(`Failed to assemble add writer message: ${error.message}`);
|
|
47
56
|
}
|
|
48
57
|
}
|
|
49
58
|
|
|
50
|
-
|
|
59
|
+
async assembleRemoveWriterMessage(writerKey, txValidity) {
|
|
51
60
|
try {
|
|
52
|
-
const builder = new PartialStateMessageBuilder(wallet);
|
|
61
|
+
const builder = new PartialStateMessageBuilder(this.#wallet, this.#config);
|
|
53
62
|
const director = new PartialStateMessageDirector();
|
|
54
63
|
director.builder = builder;
|
|
55
|
-
return await director.buildRemoveWriterMessage(wallet.address, writerKey, txValidity);
|
|
64
|
+
return await director.buildRemoveWriterMessage(this.#wallet.address, writerKey, txValidity);
|
|
56
65
|
} catch (error) {
|
|
57
66
|
throw new Error(`Failed to assemble remove writer message: ${error.message}`);
|
|
58
67
|
}
|
|
59
68
|
}
|
|
60
69
|
|
|
61
|
-
|
|
70
|
+
async assembleAdminRecoveryMessage(writingKey, txValidity) {
|
|
62
71
|
try {
|
|
63
|
-
const builder = new PartialStateMessageBuilder(wallet);
|
|
72
|
+
const builder = new PartialStateMessageBuilder(this.#wallet, this.#config);
|
|
64
73
|
const director = new PartialStateMessageDirector();
|
|
65
74
|
director.builder = builder;
|
|
66
|
-
return await director.buildAdminRecoveryMessage(wallet.address, writingKey, txValidity);
|
|
75
|
+
return await director.buildAdminRecoveryMessage(this.#wallet.address, writingKey, txValidity);
|
|
67
76
|
} catch (error) {
|
|
68
77
|
throw new Error(`Failed to assemble admin recovery message: ${error.message}`);
|
|
69
78
|
}
|
|
@@ -73,8 +82,6 @@ class PartialStateMessageOperations {
|
|
|
73
82
|
/**
|
|
74
83
|
* Assembles a PARTIAL transaction operation, which can be sent to a validator, who can then
|
|
75
84
|
* sign the transaction to make it COMPLETE.
|
|
76
|
-
*
|
|
77
|
-
* @param {Object} wallet - Wallet of the requester/invoker node that broadcasts the transaction
|
|
78
85
|
* @param {String} incomingWritingKey - Writing key from the subnetwork, used for authentication of the requesting node
|
|
79
86
|
* @param {String} txValidity - Transaction validity hash representing current indexer combination.
|
|
80
87
|
* Transaction remains valid as long as indexer keys maintain their order.
|
|
@@ -91,13 +98,13 @@ class PartialStateMessageOperations {
|
|
|
91
98
|
* @returns {Promise<Object>} The assembled transaction operation message
|
|
92
99
|
* @throws {Error} If assembly of the transaction operation message fails
|
|
93
100
|
*/
|
|
94
|
-
|
|
101
|
+
async assembleTransactionOperationMessage(incomingWritingKey, txValidity, contentHash, externalBootstrap, msbBootstrap) {
|
|
95
102
|
try {
|
|
96
|
-
const builder = new PartialStateMessageBuilder(wallet);
|
|
103
|
+
const builder = new PartialStateMessageBuilder(this.#wallet, this.#config);
|
|
97
104
|
const director = new PartialStateMessageDirector();
|
|
98
105
|
director.builder = builder;
|
|
99
106
|
return await director.buildTransactionOperationMessage(
|
|
100
|
-
wallet.address,
|
|
107
|
+
this.#wallet.address,
|
|
101
108
|
incomingWritingKey,
|
|
102
109
|
txValidity,
|
|
103
110
|
contentHash,
|
|
@@ -109,13 +116,13 @@ class PartialStateMessageOperations {
|
|
|
109
116
|
}
|
|
110
117
|
}
|
|
111
118
|
|
|
112
|
-
|
|
119
|
+
async assembleTransferOperationMessage(recipientAddress, amount, txValidity) {
|
|
113
120
|
try {
|
|
114
|
-
const builder = new PartialStateMessageBuilder(wallet);
|
|
121
|
+
const builder = new PartialStateMessageBuilder(this.#wallet, this.#config);
|
|
115
122
|
const director = new PartialStateMessageDirector();
|
|
116
123
|
director.builder = builder;
|
|
117
124
|
return await director.buildTransferOperationMessage(
|
|
118
|
-
wallet.address,
|
|
125
|
+
this.#wallet.address,
|
|
119
126
|
recipientAddress,
|
|
120
127
|
amount,
|
|
121
128
|
txValidity
|
package/src/utils/check.js
CHANGED
|
@@ -10,9 +10,7 @@ import {
|
|
|
10
10
|
BOOTSTRAP_BYTE_LENGTH,
|
|
11
11
|
CHANNEL_BYTE_LENGTH,
|
|
12
12
|
AMOUNT_BYTE_LENGTH,
|
|
13
|
-
TRAC_ADDRESS_SIZE,
|
|
14
13
|
} from './constants.js';
|
|
15
|
-
|
|
16
14
|
//TODO: ATTENTION - CURRENT IMPLEMENTATION UTILIZES `custom` FOR MULTIPLE TIMES IN MANY SCHEMAS. IT SHOULD BE CLEANED UP
|
|
17
15
|
// TO UTILIZE ONLY ONE FUNCTION COMMON FOR ALL THE SCHEMAS. CREATE A TICKED P2/P3.
|
|
18
16
|
|
|
@@ -25,8 +23,13 @@ class Check {
|
|
|
25
23
|
#validateTransactionOperationSchema
|
|
26
24
|
#validateTransferOperationSchema
|
|
27
25
|
#validateBalanceInitializationSchema
|
|
26
|
+
#config
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @param {object} config
|
|
30
|
+
**/
|
|
31
|
+
constructor(config) {
|
|
32
|
+
this.#config = config
|
|
30
33
|
|
|
31
34
|
this.#validator = new Validator({
|
|
32
35
|
useNewCustomCheckerFunction: true,
|
|
@@ -101,6 +104,7 @@ class Check {
|
|
|
101
104
|
|
|
102
105
|
// Complete by default - no writer needed
|
|
103
106
|
#compileCoreAdminOperationSchema() {
|
|
107
|
+
const addressLength = this.#config.addressLength
|
|
104
108
|
const schema = {
|
|
105
109
|
$$strict: true,
|
|
106
110
|
type: {
|
|
@@ -124,7 +128,7 @@ class Check {
|
|
|
124
128
|
return value;
|
|
125
129
|
}
|
|
126
130
|
},
|
|
127
|
-
address: {
|
|
131
|
+
address: {type: 'buffer', length: addressLength, required: true}, // invoker adddress (admin)
|
|
128
132
|
cao: {
|
|
129
133
|
strict: true,
|
|
130
134
|
type: 'object',
|
|
@@ -163,14 +167,14 @@ class Check {
|
|
|
163
167
|
return value;
|
|
164
168
|
}
|
|
165
169
|
},
|
|
166
|
-
address: { type: 'buffer', length:
|
|
170
|
+
address: { type: 'buffer', length: this.#config.addressLength, required: true },
|
|
167
171
|
bio: {
|
|
168
172
|
strict: true,
|
|
169
173
|
type: 'object',
|
|
170
174
|
props: {
|
|
171
175
|
tx: { type: 'buffer', length: HASH_BYTE_LENGTH, required: true }, // tx hash
|
|
172
176
|
txv: { type: 'buffer', length: HASH_BYTE_LENGTH, required: true }, // tx validity
|
|
173
|
-
ia: { type: 'buffer', length:
|
|
177
|
+
ia: { type: 'buffer', length: this.#config.addressLength, required: true }, // selected address to specific operation.
|
|
174
178
|
am: { type: 'buffer', length: AMOUNT_BYTE_LENGTH, required: true }, // amount to transfer
|
|
175
179
|
in: { type: 'buffer', length: NONCE_BYTE_LENGTH, required: true }, // nonce of the invoker
|
|
176
180
|
is: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, required: true }, // signature of the invoker
|
|
@@ -211,14 +215,14 @@ class Check {
|
|
|
211
215
|
return value;
|
|
212
216
|
}
|
|
213
217
|
},
|
|
214
|
-
address: {
|
|
218
|
+
address: {type: 'buffer', length: this.#config.addressLength, required: true}, // invoker adddress (admin)
|
|
215
219
|
aco: {
|
|
216
220
|
strict: true,
|
|
217
221
|
type: 'object',
|
|
218
222
|
props: {
|
|
219
223
|
tx: { type: 'buffer', length: HASH_BYTE_LENGTH, required: true }, // tx hash
|
|
220
224
|
txv: { type: 'buffer', length: HASH_BYTE_LENGTH, required: true }, // tx validity
|
|
221
|
-
ia: { type: 'buffer', length:
|
|
225
|
+
ia: { type: 'buffer', length: this.#config.addressLength, required: true }, // incoming address - selected address for specific operation
|
|
222
226
|
in: { type: 'buffer', length: NONCE_BYTE_LENGTH, required: true }, // nonce
|
|
223
227
|
is: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, required: true }, // signature
|
|
224
228
|
}
|
|
@@ -256,7 +260,7 @@ class Check {
|
|
|
256
260
|
return value;
|
|
257
261
|
}
|
|
258
262
|
},
|
|
259
|
-
address: {
|
|
263
|
+
address: {type: 'buffer', length: this.#config.addressLength, required: true},
|
|
260
264
|
rao: {
|
|
261
265
|
strict: true,
|
|
262
266
|
type: 'object',
|
|
@@ -266,7 +270,7 @@ class Check {
|
|
|
266
270
|
iw: { type: 'buffer', length: WRITER_BYTE_LENGTH, required: true }, // writing key of the invoker
|
|
267
271
|
in: { type: 'buffer', length: NONCE_BYTE_LENGTH, required: true }, // nonce of the invoker
|
|
268
272
|
is: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, required: true }, // signature
|
|
269
|
-
va: { type: 'buffer', length:
|
|
273
|
+
va: { type: 'buffer', length: this.#config.addressLength, optional: true },
|
|
270
274
|
vn: { type: 'buffer', length: NONCE_BYTE_LENGTH, optional: true },
|
|
271
275
|
vs: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, optional: true }
|
|
272
276
|
|
|
@@ -325,7 +329,7 @@ class Check {
|
|
|
325
329
|
return value;
|
|
326
330
|
}
|
|
327
331
|
},
|
|
328
|
-
address: {
|
|
332
|
+
address: {type: 'buffer', length: this.#config.addressLength, required: true}, // invoker address
|
|
329
333
|
txo: {
|
|
330
334
|
strict: true,
|
|
331
335
|
type: 'object',
|
|
@@ -338,7 +342,7 @@ class Check {
|
|
|
338
342
|
mbs: { type: 'buffer', length: BOOTSTRAP_BYTE_LENGTH, required: true }, // MSB bootstrap key
|
|
339
343
|
in: { type: 'buffer', length: NONCE_BYTE_LENGTH, required: true }, // Nonce of the requesting node
|
|
340
344
|
is: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, required: true }, // Requester's signature
|
|
341
|
-
va: { type: 'buffer', length:
|
|
345
|
+
va: { type: 'buffer', length: this.#config.addressLength, optional: true }, //validator address
|
|
342
346
|
vn: { type: 'buffer', length: NONCE_BYTE_LENGTH, optional: true }, //validator nonce
|
|
343
347
|
vs: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, optional: true }, //validator signature
|
|
344
348
|
},
|
|
@@ -396,7 +400,7 @@ class Check {
|
|
|
396
400
|
return value;
|
|
397
401
|
}
|
|
398
402
|
},
|
|
399
|
-
address: {
|
|
403
|
+
address: {type: 'buffer', length: this.#config.addressLength, required: true},
|
|
400
404
|
bdo: {
|
|
401
405
|
|
|
402
406
|
strict: true,
|
|
@@ -408,7 +412,7 @@ class Check {
|
|
|
408
412
|
ic: { type: 'buffer', length: CHANNEL_BYTE_LENGTH, required: true },
|
|
409
413
|
in: { type: 'buffer', length: NONCE_BYTE_LENGTH, required: true },
|
|
410
414
|
is: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, required: true },
|
|
411
|
-
va: { type: 'buffer', length:
|
|
415
|
+
va: { type: 'buffer', length: this.#config.addressLength, optional: true },
|
|
412
416
|
vn: { type: 'buffer', length: NONCE_BYTE_LENGTH, optional: true },
|
|
413
417
|
vs: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, optional: true },
|
|
414
418
|
},
|
|
@@ -466,18 +470,18 @@ class Check {
|
|
|
466
470
|
return value;
|
|
467
471
|
}
|
|
468
472
|
},
|
|
469
|
-
address: {
|
|
473
|
+
address: {type: 'buffer', length: this.#config.addressLength, required: true},
|
|
470
474
|
tro: {
|
|
471
475
|
strict: true,
|
|
472
476
|
type: 'object',
|
|
473
477
|
props: {
|
|
474
478
|
tx: { type: 'buffer', length: HASH_BYTE_LENGTH, required: true }, // tx hash
|
|
475
479
|
txv: { type: 'buffer', length: HASH_BYTE_LENGTH, required: true }, // tx validity
|
|
476
|
-
to: { type: 'buffer', length:
|
|
480
|
+
to: { type: 'buffer', length: this.#config.addressLength, required: true }, // recipient address
|
|
477
481
|
am: { type: 'buffer_amount', length: AMOUNT_BYTE_LENGTH, required: true }, // amount to transfer
|
|
478
482
|
in: { type: 'buffer', length: NONCE_BYTE_LENGTH, required: true }, // nonce of the invoker
|
|
479
483
|
is: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, required: true }, // signature of the invoker
|
|
480
|
-
va: { type: 'buffer', length:
|
|
484
|
+
va: { type: 'buffer', length: this.#config.addressLength, optional: true }, // validator address
|
|
481
485
|
vn: { type: 'buffer', length: NONCE_BYTE_LENGTH, optional: true }, // validator nonce
|
|
482
486
|
vs: { type: 'buffer', length: SIGNATURE_BYTE_LENGTH, optional: true } // validator signature
|
|
483
487
|
|
package/src/utils/cliCommands.js
CHANGED
|
@@ -83,20 +83,20 @@ export async function coreInfoCommand(state) {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export async function getValidatorAddressCommand(state, wkHexString) {
|
|
86
|
+
export async function getValidatorAddressCommand(state, wkHexString, prefix) {
|
|
87
87
|
const payload = await state.getSigned(EntryType.WRITER_ADDRESS + wkHexString);
|
|
88
88
|
if (payload === null) {
|
|
89
89
|
console.log(`No address assigned to the writer key: ${wkHexString}`);
|
|
90
90
|
} else {
|
|
91
|
-
console.log(`Address assigned to the writer key: ${wkHexString} - ${bufferToAddress(payload)}`);
|
|
91
|
+
console.log(`Address assigned to the writer key: ${wkHexString} - ${bufferToAddress(payload, prefix)}`);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
export async function getDeploymentCommand(state, bootstrapHex) {
|
|
95
|
+
export async function getDeploymentCommand(state, bootstrapHex, addressLength) {
|
|
96
96
|
const deploymentEntry = await state.getRegisteredBootstrapEntry(bootstrapHex);
|
|
97
97
|
console.log(`Searching deployment for bootstrap: ${bootstrapHex}`);
|
|
98
98
|
if (deploymentEntry) {
|
|
99
|
-
const decodedDeploymentEntry = deploymentEntryUtils.decode(deploymentEntry);
|
|
99
|
+
const decodedDeploymentEntry = deploymentEntryUtils.decode(deploymentEntry, addressLength);
|
|
100
100
|
const txhash = decodedDeploymentEntry.txHash.toString("hex");
|
|
101
101
|
console.log(`Bootstrap deployed under transaction hash: ${txhash}`);
|
|
102
102
|
const payload = await state.getSigned(txhash);
|
|
@@ -189,7 +189,7 @@ export function getUnconfirmedLengthCommand(state) {
|
|
|
189
189
|
return unconfirmedLength;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
export async function getTxPayloadsBulkCommand(state, hashes) {
|
|
192
|
+
export async function getTxPayloadsBulkCommand(state, hashes, config) {
|
|
193
193
|
if (!Array.isArray(hashes) || hashes.length === 0) {
|
|
194
194
|
throw new Error("Missing hash list.");
|
|
195
195
|
}
|
|
@@ -208,7 +208,7 @@ export async function getTxPayloadsBulkCommand(state, hashes) {
|
|
|
208
208
|
if (result === null || result === undefined) {
|
|
209
209
|
res.missing.push(hash);
|
|
210
210
|
} else {
|
|
211
|
-
const decodedResult = normalizeDecodedPayloadForJson(result.decoded);
|
|
211
|
+
const decodedResult = normalizeDecodedPayloadForJson(result.decoded, config);
|
|
212
212
|
res.results.push({ hash, payload: decodedResult });
|
|
213
213
|
}
|
|
214
214
|
});
|
|
@@ -225,20 +225,20 @@ export async function getTxHashesCommand(state, start, end) {
|
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
export async function getTxDetailsCommand(state, hash) {
|
|
228
|
+
export async function getTxDetailsCommand(state, hash, config) {
|
|
229
229
|
try {
|
|
230
230
|
const rawPayload = await get_confirmed_tx_info(state, hash);
|
|
231
231
|
if (!rawPayload) {
|
|
232
232
|
console.log(`No payload found for tx hash: ${hash}`);
|
|
233
233
|
return null;
|
|
234
234
|
}
|
|
235
|
-
return normalizeDecodedPayloadForJson(rawPayload.decoded);
|
|
235
|
+
return normalizeDecodedPayloadForJson(rawPayload.decoded, config);
|
|
236
236
|
} catch (error) {
|
|
237
237
|
throw new Error("Invalid params to perform the request.", error.message);
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
export async function getExtendedTxDetailsCommand(state, hash, confirmed) {
|
|
241
|
+
export async function getExtendedTxDetailsCommand(state, hash, confirmed, config) {
|
|
242
242
|
if (confirmed) {
|
|
243
243
|
const rawPayload = await get_confirmed_tx_info(state, hash);
|
|
244
244
|
if (!rawPayload) {
|
|
@@ -248,7 +248,7 @@ export async function getExtendedTxDetailsCommand(state, hash, confirmed) {
|
|
|
248
248
|
if (confirmedLength === null) {
|
|
249
249
|
throw new Error(`No confirmed length found for tx hash: ${hash} in confirmed mode`);
|
|
250
250
|
}
|
|
251
|
-
const normalizedPayload = normalizeDecodedPayloadForJson(rawPayload.decoded,
|
|
251
|
+
const normalizedPayload = normalizeDecodedPayloadForJson(rawPayload.decoded, config);
|
|
252
252
|
const fee = state.getFee();
|
|
253
253
|
return {
|
|
254
254
|
txDetails: normalizedPayload,
|
|
@@ -261,7 +261,7 @@ export async function getExtendedTxDetailsCommand(state, hash, confirmed) {
|
|
|
261
261
|
if (!rawPayload) {
|
|
262
262
|
throw new Error(`No payload found for tx hash: ${hash}`);
|
|
263
263
|
}
|
|
264
|
-
const normalizedPayload = normalizeDecodedPayloadForJson(rawPayload.decoded,
|
|
264
|
+
const normalizedPayload = normalizeDecodedPayloadForJson(rawPayload.decoded, config);
|
|
265
265
|
const length = await state.getTransactionConfirmedLength(hash);
|
|
266
266
|
if (length === null) {
|
|
267
267
|
return {
|
package/src/utils/constants.js
CHANGED
|
@@ -40,6 +40,8 @@ export const EventType = Object.freeze({
|
|
|
40
40
|
WRITABLE: 'writable',
|
|
41
41
|
UNWRITABLE: 'unwritable',
|
|
42
42
|
WARNING: 'warning',
|
|
43
|
+
VALIDATOR_CONNECTION_READY: 'validator-connection-ready',
|
|
44
|
+
VALIDATOR_CONNECTION_TIMEOUT: 'validator-connection-timeout',
|
|
43
45
|
});
|
|
44
46
|
|
|
45
47
|
// Role managment constants
|
|
@@ -66,7 +68,6 @@ export const MAX_PEERS = 64;
|
|
|
66
68
|
export const MAX_PARALLEL = 64;
|
|
67
69
|
export const MAX_SERVER_CONNECTIONS = Infinity;
|
|
68
70
|
export const MAX_CLIENT_CONNECTIONS = Infinity;
|
|
69
|
-
export const DHT_BOOTSTRAPS = ['116.202.214.149:10001', '157.180.12.214:10001', 'node1.hyperdht.org:49737', 'node2.hyperdht.org:49737', 'node3.hyperdht.org:49737'];
|
|
70
71
|
export const MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION = 10;
|
|
71
72
|
// State
|
|
72
73
|
export const ACK_INTERVAL = 1_000;
|
|
@@ -119,11 +120,3 @@ export const NETWORK_MESSAGE_TYPES = Object.freeze({
|
|
|
119
120
|
NODE: 'nodeResponse'
|
|
120
121
|
},
|
|
121
122
|
});
|
|
122
|
-
|
|
123
|
-
export const TRAC_ADDRESS_SIZE = 63; // TODO: Change this to config().addressLength || 63
|
|
124
|
-
export const NETWORK_ID = 918; // TODO: Change this to config().network_id || 918
|
|
125
|
-
|
|
126
|
-
export const MAX_VALIDATORS = 50
|
|
127
|
-
export const MAX_RETRIES = 3
|
|
128
|
-
|
|
129
|
-
export const MAX_REQUEST_COUNT = 5;
|
package/src/utils/fileUtils.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import fs from 'fs'; // TODO: If we are using bare environment, we should use bare-fs instead
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { WHITELIST_FILEPATH, BALANCE_MIGRATION_FILEPATH, BALANCE_MIGRATED_DIR, WHITELIST_MIGRATION_DIR } from '../utils/constants.js';
|
|
4
|
-
import { isAddressValid } from '../core/state/utils/address.js';
|
|
5
4
|
import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString } from './amountSerialization.js';
|
|
6
|
-
|
|
7
|
-
import b4a from 'b4a';
|
|
8
|
-
import { ZERO_LICENSE } from '../core/state/utils/nodeEntry.js';
|
|
5
|
+
|
|
9
6
|
const MIGRATED_FILE_REGEX = /^migrated(\d+)\.csv$/;
|
|
10
7
|
|
|
11
8
|
/**
|
package/src/utils/helpers.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import b4a from "b4a";
|
|
2
2
|
import {bufferToAddress} from "../core/state/utils/address.js";
|
|
3
|
-
import { EntryType
|
|
3
|
+
import { EntryType } from "./constants.js";
|
|
4
4
|
|
|
5
5
|
//TODO: change file name or split functions below into multiple files (Remember to update imports and tests accordingly)
|
|
6
6
|
|
|
@@ -48,7 +48,7 @@ export const safeJsonParse = (str) => {
|
|
|
48
48
|
return undefined;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
export async function getFormattedIndexersWithAddresses(state) {
|
|
51
|
+
export async function getFormattedIndexersWithAddresses(state, config) {
|
|
52
52
|
const indexers = await state.getIndexersEntry();
|
|
53
53
|
const formatted = indexers.map((entry) => ({
|
|
54
54
|
writingKey: b4a.toString(entry.key, "hex"),
|
|
@@ -56,7 +56,10 @@ export async function getFormattedIndexersWithAddresses(state) {
|
|
|
56
56
|
|
|
57
57
|
const results = await Promise.all(
|
|
58
58
|
formatted.map(async (entry) => {
|
|
59
|
-
const address = bufferToAddress(
|
|
59
|
+
const address = bufferToAddress(
|
|
60
|
+
await state.getSigned(EntryType.WRITER_ADDRESS + entry.writingKey),
|
|
61
|
+
config.addressPrefix
|
|
62
|
+
);
|
|
60
63
|
|
|
61
64
|
return {
|
|
62
65
|
...entry,
|
|
@@ -68,14 +71,14 @@ export async function getFormattedIndexersWithAddresses(state) {
|
|
|
68
71
|
return results;
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
export function formatIndexersEntry(indexersEntry) {
|
|
74
|
+
export function formatIndexersEntry(indexersEntry, addressLength) {
|
|
72
75
|
|
|
73
76
|
const count = indexersEntry[0];
|
|
74
77
|
const indexers = [];
|
|
75
78
|
|
|
76
79
|
for (let i = 0; i < count; i++) {
|
|
77
|
-
const start = 1 + (i *
|
|
78
|
-
const end = start +
|
|
80
|
+
const start = 1 + (i * addressLength);
|
|
81
|
+
const end = start + addressLength;
|
|
79
82
|
const indexerAddr = indexersEntry.subarray(start, end);
|
|
80
83
|
indexers.push(indexerAddr.toString('ascii'));
|
|
81
84
|
}
|
|
@@ -86,20 +89,6 @@ export function formatIndexersEntry(indexersEntry) {
|
|
|
86
89
|
};
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
export function convertAdminCoreOperationPayloadToHex(payload) {
|
|
90
|
-
return {
|
|
91
|
-
...payload,
|
|
92
|
-
address: bufferToAddress(payload.address),
|
|
93
|
-
aco: {
|
|
94
|
-
tx: payload.aco.tx.toString('hex'),
|
|
95
|
-
txv: payload.aco.txv.toString('hex'),
|
|
96
|
-
in: payload.aco.in.toString('hex'),
|
|
97
|
-
ia: payload.aco.ia.toString('hex'),
|
|
98
|
-
is: payload.aco.is.toString('hex'),
|
|
99
|
-
},
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
92
|
export function isTransactionRecordPut(entry) {
|
|
104
93
|
const isPut = entry.type === "put";
|
|
105
94
|
const isHex = isHexString(entry.key);
|
|
@@ -4,8 +4,8 @@ import PeerWallet from 'trac-wallet';
|
|
|
4
4
|
import b4a from 'b4a';
|
|
5
5
|
import { ZERO_LICENSE } from '../core/state/utils/nodeEntry.js';
|
|
6
6
|
|
|
7
|
-
export async function validateAddressFromIncomingFile(stateInstance, address, adminEntry) {
|
|
8
|
-
if (!isAddressValid(address)) {
|
|
7
|
+
export async function validateAddressFromIncomingFile(stateInstance, config, address, adminEntry) {
|
|
8
|
+
if (!isAddressValid(address, config.addressPrefix)) {
|
|
9
9
|
throw new Error(`Invalid address format: '${address}'. Please ensure all addresses are valid.`);
|
|
10
10
|
}
|
|
11
11
|
|
package/src/utils/normalizers.js
CHANGED
|
@@ -10,10 +10,11 @@ import { bufferToBigInt } from './amountSerialization.js'
|
|
|
10
10
|
* to the correct buffer or hexadecimal string format for processing.
|
|
11
11
|
*
|
|
12
12
|
* @param {Object} payload The raw payload for the transfer operation.
|
|
13
|
+
* @param {object} config The environment configuration object.
|
|
13
14
|
* @returns {Object} A new object with addresses converted to buffers and hex values normalized.
|
|
14
15
|
* @throws {Error} If the payload is invalid or missing required fields.
|
|
15
16
|
*/
|
|
16
|
-
export function normalizeTransferOperation(payload) {
|
|
17
|
+
export function normalizeTransferOperation(payload, config) {
|
|
17
18
|
if (!payload || typeof payload !== 'object' || !payload.tro) {
|
|
18
19
|
throw new Error('Invalid payload for transfer operation normalization.');
|
|
19
20
|
}
|
|
@@ -31,19 +32,19 @@ export function normalizeTransferOperation(payload) {
|
|
|
31
32
|
tx: normalizeHex(tro.tx), // Transaction hash
|
|
32
33
|
txv: normalizeHex(tro.txv), // Transaction validity
|
|
33
34
|
in: normalizeHex(tro.in), // Nonce
|
|
34
|
-
to: addressToBuffer(tro.to), // Recipient address
|
|
35
|
+
to: addressToBuffer(tro.to, config.addressPrefix), // Recipient address
|
|
35
36
|
am: normalizeHex(tro.am), // Amount
|
|
36
37
|
is: normalizeHex(tro.is) // Signature
|
|
37
38
|
};
|
|
38
39
|
|
|
39
40
|
return {
|
|
40
41
|
type,
|
|
41
|
-
address: addressToBuffer(address),
|
|
42
|
+
address: addressToBuffer(address, config.addressPrefix),
|
|
42
43
|
tro: normalizedTro
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
export function normalizeTransactionOperation(payload) {
|
|
47
|
+
export function normalizeTransactionOperation(payload, config) {
|
|
47
48
|
if (!payload || typeof payload !== 'object' || !payload.txo) {
|
|
48
49
|
throw new Error('Invalid payload for transaction operation normalization.');
|
|
49
50
|
}
|
|
@@ -70,7 +71,7 @@ export function normalizeTransactionOperation(payload) {
|
|
|
70
71
|
|
|
71
72
|
return {
|
|
72
73
|
type,
|
|
73
|
-
address: addressToBuffer(address),
|
|
74
|
+
address: addressToBuffer(address, config.addressPrefix),
|
|
74
75
|
txo: normalizedTxo
|
|
75
76
|
};
|
|
76
77
|
}
|
|
@@ -82,7 +83,7 @@ export function normalizeTransactionOperation(payload) {
|
|
|
82
83
|
* @param {Object} payload The decoded transaction payload.
|
|
83
84
|
* @returns {Object} A new object with Buffer values converted to hex strings.
|
|
84
85
|
*/
|
|
85
|
-
export function normalizeDecodedPayloadForJson(payload) {
|
|
86
|
+
export function normalizeDecodedPayloadForJson(payload, config) {
|
|
86
87
|
if (!payload || typeof payload !== "object") {
|
|
87
88
|
return payload;
|
|
88
89
|
}
|
|
@@ -96,7 +97,7 @@ export function normalizeDecodedPayloadForJson(payload) {
|
|
|
96
97
|
if (b4a.isBuffer(value)) {
|
|
97
98
|
// 👇 intercept address buffers by key name (e.g. `address`)
|
|
98
99
|
if (addressKeys.some(k => key.toLowerCase().includes(k))) {
|
|
99
|
-
const addr = bufferToAddress(value);
|
|
100
|
+
const addr = bufferToAddress(value, config.addressPrefix);
|
|
100
101
|
newPayload[key] = addr ?? b4a.toString(value, "hex");
|
|
101
102
|
} else if (key.toLowerCase().includes("am")) {
|
|
102
103
|
const amount = bufferToBigInt(value)
|
|
@@ -107,7 +108,7 @@ export function normalizeDecodedPayloadForJson(payload) {
|
|
|
107
108
|
|
|
108
109
|
} else if (typeof value === "object" && value !== null) {
|
|
109
110
|
// recursively handle nested objects
|
|
110
|
-
newPayload[key] = normalizeDecodedPayloadForJson(value);
|
|
111
|
+
newPayload[key] = normalizeDecodedPayloadForJson(value, config);
|
|
111
112
|
|
|
112
113
|
} else {
|
|
113
114
|
newPayload[key] = value;
|
|
@@ -115,4 +116,4 @@ export function normalizeDecodedPayloadForJson(payload) {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
return newPayload;
|
|
118
|
-
}
|
|
119
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import request from "supertest"
|
|
2
2
|
import { bufferToBigInt, licenseBufferToBigInt } from "../../../../src/utils/amountSerialization.js"
|
|
3
|
-
import { ZERO_WK } from "../../../../rpc/constants.
|
|
3
|
+
import { ZERO_WK } from "../../../../rpc/constants.js"
|
|
4
4
|
import { ADMIN_INITIAL_STAKED_BALANCE } from "../../../../src/utils/constants.js"
|
|
5
5
|
import { BALANCE_TO_STAKE } from "../../../../src/core/state/utils/balance.js"
|
|
6
6
|
import { randomAddress } from "../../../unit/state/stateTestUtils.js"
|
|
@@ -72,7 +72,7 @@ export const registerAccountTests = (context) => {
|
|
|
72
72
|
})
|
|
73
73
|
|
|
74
74
|
it("returns default state for non-existent node", async () => {
|
|
75
|
-
const address = randomAddress()
|
|
75
|
+
const address = randomAddress(context.rpcMsb.config.addressPrefix)
|
|
76
76
|
|
|
77
77
|
const res = await request(context.server).get(`/v1/account/${address}`)
|
|
78
78
|
expect(res.statusCode).toBe(200)
|
|
@@ -37,7 +37,7 @@ export const registerBalanceTests = (context) => {
|
|
|
37
37
|
})
|
|
38
38
|
|
|
39
39
|
it("returns zero balance for an unknown address", async () => {
|
|
40
|
-
const address = randomAddress()
|
|
40
|
+
const address = randomAddress(context.rpcMsb.config.addressPrefix)
|
|
41
41
|
const res = await request(context.server).get(`/v1/balance/${address}`)
|
|
42
42
|
expect(res.statusCode).toBe(200)
|
|
43
43
|
expect(res.body.address).toBe(address)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import request from "supertest"
|
|
2
2
|
import b4a from "b4a"
|
|
3
3
|
import { $TNK } from "../../../../src/core/state/utils/balance.js"
|
|
4
|
-
import { buildRpcSelfTransferPayload } from "../../../helpers/transactionPayloads.mjs"
|
|
4
|
+
import { buildRpcSelfTransferPayload, waitForConnection } from "../../../helpers/transactionPayloads.mjs"
|
|
5
5
|
|
|
6
6
|
const toBase64 = (value) => b4a.toString(b4a.from(JSON.stringify(value)), "base64")
|
|
7
7
|
|
|
@@ -9,10 +9,11 @@ export const registerBroadcastTransactionTests = (context) => {
|
|
|
9
9
|
describe("POST /v1/broadcast-transaction", () => {
|
|
10
10
|
it("broadcasts transaction and returns lengths", async () => {
|
|
11
11
|
const { payload } = await buildRpcSelfTransferPayload(
|
|
12
|
-
context
|
|
12
|
+
context,
|
|
13
13
|
context.rpcMsb.state,
|
|
14
14
|
1n
|
|
15
15
|
);
|
|
16
|
+
await waitForConnection(context.rpcMsb)
|
|
16
17
|
const res = await request(context.server)
|
|
17
18
|
.post("/v1/broadcast-transaction")
|
|
18
19
|
.set("Accept", "application/json")
|
|
@@ -30,6 +31,7 @@ export const registerBroadcastTransactionTests = (context) => {
|
|
|
30
31
|
})
|
|
31
32
|
|
|
32
33
|
it("returns 400 when payload is missing", async () => {
|
|
34
|
+
await waitForConnection(context.rpcMsb)
|
|
33
35
|
const res = await request(context.server)
|
|
34
36
|
.post("/v1/broadcast-transaction")
|
|
35
37
|
.set("Accept", "application/json")
|
|
@@ -40,6 +42,7 @@ export const registerBroadcastTransactionTests = (context) => {
|
|
|
40
42
|
})
|
|
41
43
|
|
|
42
44
|
it("returns 400 when payload is not base64", async () => {
|
|
45
|
+
await waitForConnection(context.rpcMsb)
|
|
43
46
|
const res = await request(context.server)
|
|
44
47
|
.post("/v1/broadcast-transaction")
|
|
45
48
|
.set("Accept", "application/json")
|
|
@@ -52,6 +55,8 @@ export const registerBroadcastTransactionTests = (context) => {
|
|
|
52
55
|
// TODO: enable once handler returns 400 for client-side decode errors
|
|
53
56
|
it.skip("returns 400 when decoded payload is not valid JSON", async () => {
|
|
54
57
|
const invalidJsonBase64 = b4a.toString(b4a.from("{{invalid"), "base64")
|
|
58
|
+
|
|
59
|
+
await waitForConnection(context.rpcMsb)
|
|
55
60
|
const res = await request(context.server)
|
|
56
61
|
.post("/v1/broadcast-transaction")
|
|
57
62
|
.set("Accept", "application/json")
|
|
@@ -67,6 +72,8 @@ export const registerBroadcastTransactionTests = (context) => {
|
|
|
67
72
|
type: 1,
|
|
68
73
|
address: context.wallet.address,
|
|
69
74
|
}
|
|
75
|
+
|
|
76
|
+
await waitForConnection(context.rpcMsb)
|
|
70
77
|
const res = await request(context.server)
|
|
71
78
|
.post("/v1/broadcast-transaction")
|
|
72
79
|
.set("Accept", "application/json")
|
|
@@ -81,6 +88,7 @@ export const registerBroadcastTransactionTests = (context) => {
|
|
|
81
88
|
const largeString = "a".repeat(3_000_000)
|
|
82
89
|
const payload = toBase64({ type: 1, address: context.wallet.address, txo: { large: largeString } })
|
|
83
90
|
|
|
91
|
+
await waitForConnection(context.rpcMsb)
|
|
84
92
|
const res = await request(context.server)
|
|
85
93
|
.post("/v1/broadcast-transaction")
|
|
86
94
|
.set("Accept", "application/json")
|
|
@@ -99,6 +107,7 @@ export const registerBroadcastTransactionTests = (context) => {
|
|
|
99
107
|
)
|
|
100
108
|
|
|
101
109
|
const payload = tracCrypto.transaction.build(txData, b4a.from(context.wallet.secretKey, 'hex'))
|
|
110
|
+
await waitForConnection(context.rpcMsb)
|
|
102
111
|
const res = await request(context.server)
|
|
103
112
|
.post("/v1/broadcast-transaction")
|
|
104
113
|
.set("Accept", "application/json")
|