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
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import b4a from 'b4a';
|
|
2
2
|
|
|
3
|
-
import { MIN_SAFE_VALIDATION_INTEGER, MAX_SAFE_VALIDATION_INTEGER
|
|
3
|
+
import { MIN_SAFE_VALIDATION_INTEGER, MAX_SAFE_VALIDATION_INTEGER } from '../../../../src/utils/constants.js';
|
|
4
4
|
import { partial_operation_value_type } from "../../../fixtures/check.fixtures.js";
|
|
5
|
+
import { config } from '../../../helpers/config.js';
|
|
5
6
|
|
|
6
7
|
export function topLevelValidationTests(
|
|
7
8
|
t,
|
|
@@ -210,11 +211,11 @@ export function addressBufferLengthTest(
|
|
|
210
211
|
validFixture,
|
|
211
212
|
) {
|
|
212
213
|
const emptyBuffer = b4a.alloc(0);
|
|
213
|
-
const oneTooShort = b4a.alloc(
|
|
214
|
-
const tooShort = b4a.alloc(
|
|
215
|
-
const exact = b4a.alloc(
|
|
216
|
-
const oneTooLong = b4a.alloc(
|
|
217
|
-
const tooLong = b4a.alloc(
|
|
214
|
+
const oneTooShort = b4a.alloc(config.addressLength - 1, 0x01);
|
|
215
|
+
const tooShort = b4a.alloc(config.addressLength - 2, 0x01);
|
|
216
|
+
const exact = b4a.alloc(config.addressLength, 0x01);
|
|
217
|
+
const oneTooLong = b4a.alloc(config.addressLength + 1, 0x01);
|
|
218
|
+
const tooLong = b4a.alloc(config.addressLength + 2, 0x01);
|
|
218
219
|
|
|
219
220
|
const inputs = {
|
|
220
221
|
emptyBufferInput: { ...validFixture, address: emptyBuffer },
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import test from 'brittle'
|
|
2
|
-
|
|
3
2
|
import Check from '../../../../src/utils/check.js'
|
|
4
|
-
import {CAO, not_allowed_data_types} from '../../../fixtures/check.fixtures.js'
|
|
3
|
+
import { CAO, not_allowed_data_types } from '../../../fixtures/check.fixtures.js'
|
|
5
4
|
import { topLevelValidationTests, valueLevelValidationTest, addressBufferLengthTest, fieldsBufferLengthTest } from './common.test.js';
|
|
5
|
+
import { config } from '../../../helpers/config.js';
|
|
6
6
|
|
|
7
|
-
const check = new Check()
|
|
7
|
+
const check = new Check(config)
|
|
8
8
|
|
|
9
9
|
test('validateCoreAdminOperation- happy paths for all operation types', t => {
|
|
10
10
|
const validInputs = [
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import test from 'brittle'
|
|
2
2
|
|
|
3
3
|
import Check from '../../../../src/utils/check.js';
|
|
4
|
-
import {RAO, not_allowed_data_types} from '../../../fixtures/check.fixtures.js';
|
|
4
|
+
import { RAO, not_allowed_data_types } from '../../../fixtures/check.fixtures.js';
|
|
5
5
|
import { topLevelValidationTests, valueLevelValidationTest, addressBufferLengthTest, fieldsBufferLengthTest, partialTypeCommonTests } from './common.test.js';
|
|
6
|
+
import { config } from '../../../helpers/config.js';
|
|
6
7
|
|
|
7
|
-
const check = new Check()
|
|
8
|
+
const check = new Check(config)
|
|
8
9
|
|
|
9
10
|
test('validateRoleAccessOperation - happy-path case', t => {
|
|
10
11
|
// ADD_WRITER
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import test from 'brittle'
|
|
2
|
-
|
|
3
2
|
import Check from '../../../../src/utils/check.js';
|
|
4
|
-
import {TXO, not_allowed_data_types} from '../../../fixtures/check.fixtures.js';
|
|
3
|
+
import { TXO, not_allowed_data_types } from '../../../fixtures/check.fixtures.js';
|
|
5
4
|
import { topLevelValidationTests, valueLevelValidationTest, addressBufferLengthTest, fieldsBufferLengthTest, partialTypeCommonTests } from './common.test.js';
|
|
5
|
+
import { config } from '../../../helpers/config.js';
|
|
6
6
|
|
|
7
|
-
const check = new Check()
|
|
7
|
+
const check = new Check(config)
|
|
8
8
|
|
|
9
9
|
test('validateTransactionOperation - happy-path case', t => {
|
|
10
10
|
// ADD_WRITER
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import test from 'brittle'
|
|
2
|
-
|
|
3
2
|
import Check from '../../../../src/utils/check.js';
|
|
4
|
-
import {TRO, not_allowed_data_types
|
|
3
|
+
import { TRO, not_allowed_data_types } from '../../../fixtures/check.fixtures.js';
|
|
5
4
|
import { topLevelValidationTests, valueLevelValidationTest, addressBufferLengthTest, fieldsBufferLengthTest, partialTypeCommonTests } from './common.test.js';
|
|
5
|
+
import { config } from '../../../helpers/config.js';
|
|
6
6
|
|
|
7
|
-
const check = new Check()
|
|
7
|
+
const check = new Check(config)
|
|
8
8
|
|
|
9
9
|
test('validateTransferOperation - happy-path case', t => {
|
|
10
10
|
// ADD_WRITER
|
|
@@ -3,6 +3,7 @@ import fileUtils from '../../../../src/utils/fileUtils.js';
|
|
|
3
3
|
import { errorMessageIncludes } from "../../../helpers/regexHelper.js";
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import PeerWallet from 'trac-wallet';
|
|
6
|
+
import { config } from '../../../helpers/config.js';
|
|
6
7
|
|
|
7
8
|
const DUMMY_PATH_OK = './dummy_whitelist_ok.csv';
|
|
8
9
|
const DUMMY_PATH_DUP = './dummy_whitelist_dup.csv';
|
|
@@ -34,7 +35,7 @@ hook('Initialize dummy whitelist files', async t => {
|
|
|
34
35
|
return wallet.address;
|
|
35
36
|
};
|
|
36
37
|
for (let i = 0; i < 1000; i++) {
|
|
37
|
-
const rand = await randomAddress();
|
|
38
|
+
const rand = await randomAddress(config.addressPrefix);
|
|
38
39
|
large += `${rand}\n`;
|
|
39
40
|
}
|
|
40
41
|
fs.writeFileSync(DUMMY_PATH_LARGE, large);
|
|
@@ -3,6 +3,7 @@ import fileUtils from '../../../../src/utils/fileUtils.js';
|
|
|
3
3
|
import { errorMessageIncludes } from "../../../helpers/regexHelper.js";
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import PeerWallet from 'trac-wallet';
|
|
6
|
+
import { config } from '../../../helpers/config.js';
|
|
6
7
|
|
|
7
8
|
const DUMMY_PATH_OK = './dummy_balance_ok.csv';
|
|
8
9
|
const DUMMY_PATH_DUP = './dummy_balance_dup.csv';
|
|
@@ -51,7 +52,7 @@ hook('Initialize dummy balance files', async t => {
|
|
|
51
52
|
return wallet.address;
|
|
52
53
|
}
|
|
53
54
|
for (let i = 0; i < 1000; i++) {
|
|
54
|
-
const rand = await randomAddress();
|
|
55
|
+
const rand = await randomAddress(config.addressPrefix);
|
|
55
56
|
large += `${rand},1.0\n`;
|
|
56
57
|
}
|
|
57
58
|
fs.writeFileSync(DUMMY_PATH_LARGE, large);
|
|
@@ -3,6 +3,8 @@ import migrationUtils from '../../../../src/utils/migrationUtils.js';
|
|
|
3
3
|
import { errorMessageIncludes } from "../../../helpers/regexHelper.js";
|
|
4
4
|
import { ZERO_LICENSE } from '../../../../src/core/state/utils/nodeEntry.js';
|
|
5
5
|
import b4a from 'b4a';
|
|
6
|
+
import { config } from '../../../helpers/config.js';
|
|
7
|
+
|
|
6
8
|
const VALID_ADDRESS = 'trac1dguwzsvcsehslh6dgj2mqlsxdn7s5t5vhem56yd0xlg47aq6exzqymhr6u';
|
|
7
9
|
const ADMIN_ADDRESS = 'trac1yva2pduhz5yst8jgzmrc9ve0as5mx7tcw6le9srj6xcwqkx9hacqxxhsf9';
|
|
8
10
|
const INVALID_ADDRESS = 'notanaddress';
|
|
@@ -41,6 +43,7 @@ const mockStateInstanceBanned = {
|
|
|
41
43
|
test('validateAddressFromIncomingFile - valid address', async (t) => {
|
|
42
44
|
await migrationUtils.validateAddressFromIncomingFile(
|
|
43
45
|
mockStateInstance,
|
|
46
|
+
config,
|
|
44
47
|
VALID_ADDRESS,
|
|
45
48
|
{ address: ADMIN_ADDRESS }
|
|
46
49
|
);
|
|
@@ -51,6 +54,7 @@ test('validateAddressFromIncomingFile - invalid address format', async (t) => {
|
|
|
51
54
|
await t.exception(
|
|
52
55
|
() => migrationUtils.validateAddressFromIncomingFile(
|
|
53
56
|
mockStateInstance,
|
|
57
|
+
config,
|
|
54
58
|
INVALID_ADDRESS,
|
|
55
59
|
{ address: ADMIN_ADDRESS }
|
|
56
60
|
),
|
|
@@ -62,6 +66,7 @@ test('validateAddressFromIncomingFile - admin address', async (t) => {
|
|
|
62
66
|
await t.exception(
|
|
63
67
|
() => migrationUtils.validateAddressFromIncomingFile(
|
|
64
68
|
mockStateInstance,
|
|
69
|
+
config,
|
|
65
70
|
ADMIN_ADDRESS,
|
|
66
71
|
{ address: ADMIN_ADDRESS }
|
|
67
72
|
),
|
|
@@ -73,6 +78,7 @@ test('validateAddressFromIncomingFile - whitelisted node', async (t) => {
|
|
|
73
78
|
await t.exception(
|
|
74
79
|
() => migrationUtils.validateAddressFromIncomingFile(
|
|
75
80
|
mockStateInstanceWhitelisted,
|
|
81
|
+
config,
|
|
76
82
|
VALID_ADDRESS,
|
|
77
83
|
{ address: ADMIN_ADDRESS }
|
|
78
84
|
),
|
|
@@ -84,6 +90,7 @@ test('validateAddressFromIncomingFile - banned/previously whitelisted address',
|
|
|
84
90
|
await t.exception(
|
|
85
91
|
() => migrationUtils.validateAddressFromIncomingFile(
|
|
86
92
|
mockStateInstanceBanned,
|
|
93
|
+
config,
|
|
87
94
|
VALID_ADDRESS,
|
|
88
95
|
{ address: ADMIN_ADDRESS }
|
|
89
96
|
),
|
|
@@ -13,7 +13,6 @@ async function runTests() {
|
|
|
13
13
|
await import('./migrationUtils/validateAddressFromIncomingFile.test.js');
|
|
14
14
|
await import('./buffer/buffer.test.js')
|
|
15
15
|
await import('./amountSerialization/amountSerialization.test.js');
|
|
16
|
-
await import('./crypto/createHash.test.js');
|
|
17
16
|
test.resume();
|
|
18
17
|
}
|
|
19
18
|
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import b4a from 'b4a';
|
|
2
|
-
import { TRAC_ADDRESS_SIZE } from '../../../utils/constants.js';
|
|
3
|
-
import { isBufferValid } from '../../../utils/buffer.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Appends an indexer address to the indexers entry buffer.
|
|
7
|
-
* The buffer format is: [count(1)][indexerAddr1][indexerAddr2]...[indexerAddrN]
|
|
8
|
-
* Where count is the number of indexers.
|
|
9
|
-
* If indexersEntry is null or invalid, a new buffer is created.
|
|
10
|
-
* If indexerAddr is invalid, the original entry is returned unchanged.
|
|
11
|
-
*
|
|
12
|
-
* @param {Buffer} indexerAddr - The indexer address to append (must be TRAC_ADDRESS_SIZE bytes).
|
|
13
|
-
* @param {Buffer|null} indexersEntry - The current indexers entry buffer, or null to create a new one.
|
|
14
|
-
* @returns {Buffer} The updated indexers entry buffer or an empty buffer in case something goes wrong.
|
|
15
|
-
*/
|
|
16
|
-
export function append(indexerAddr, indexersEntry = null) {
|
|
17
|
-
if (!isBufferValid(indexerAddr, TRAC_ADDRESS_SIZE)) {
|
|
18
|
-
return b4a.alloc(0);
|
|
19
|
-
}
|
|
20
|
-
// Append the indexer address to the IndexersEntry buffer
|
|
21
|
-
try {
|
|
22
|
-
let newIndexersEntry;
|
|
23
|
-
if (!b4a.isBuffer(indexersEntry) || indexersEntry.length < TRAC_ADDRESS_SIZE + 1) {
|
|
24
|
-
newIndexersEntry = b4a.concat([b4a.from([1]), indexerAddr]);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
newIndexersEntry = b4a.concat([indexersEntry, indexerAddr]);
|
|
28
|
-
newIndexersEntry[0]++;
|
|
29
|
-
}
|
|
30
|
-
return newIndexersEntry;
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
console.error("Error appending indexer:", error);
|
|
34
|
-
return b4a.alloc(0); // If some error occurs, do nothing
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Finds the index of a given indexer address within the indexers entry buffer.
|
|
40
|
-
* The buffer format is: [count(1)][indexerAddr1][indexerAddr2]...[indexerAddrN]
|
|
41
|
-
* Returns the zero-based index of the address if found, or -1 if not found.
|
|
42
|
-
*
|
|
43
|
-
* @param {Buffer} indexersEntry - The current indexers entry buffer.
|
|
44
|
-
* @param {Buffer} indexerAddr - The indexer address to search for (must be TRAC_ADDRESS_SIZE bytes).
|
|
45
|
-
* @returns {number} The index of the address if found, or -1 if not found.
|
|
46
|
-
*/
|
|
47
|
-
export function getIndex(indexersEntry, indexerAddr) {
|
|
48
|
-
if (
|
|
49
|
-
!b4a.isBuffer(indexersEntry) ||
|
|
50
|
-
!isBufferValid(indexerAddr, TRAC_ADDRESS_SIZE) ||
|
|
51
|
-
indexersEntry.length < TRAC_ADDRESS_SIZE + 1 // it should ensure minimal length of the indexersEntry
|
|
52
|
-
) {
|
|
53
|
-
return -1;
|
|
54
|
-
}
|
|
55
|
-
// step through the indexersEntry until we find indexerAddr
|
|
56
|
-
for (let i = 0; i < indexersEntry[0]; i++) {
|
|
57
|
-
if (b4a.equals(indexersEntry.subarray(1 + i * TRAC_ADDRESS_SIZE, 1 + (i + 1) * TRAC_ADDRESS_SIZE), indexerAddr)) {
|
|
58
|
-
return i;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return -1; // Not found
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Removes an indexer address from the indexers entry buffer.
|
|
66
|
-
* The buffer format is: [count(1)][indexerAddr1][indexerAddr2]...[indexerAddrN]
|
|
67
|
-
* If the indexer address is not found or input is invalid, returns an empty buffer.
|
|
68
|
-
*
|
|
69
|
-
* @param {Buffer} indexerAddr - The indexer address to remove (must be TRAC_ADDRESS_SIZE bytes).
|
|
70
|
-
* @param {Buffer} indexersEntry - The current indexers entry buffer.
|
|
71
|
-
* @returns {Buffer} The updated indexers entry buffer with the address removed,
|
|
72
|
-
* or an empty buffer if the address is not found or input is invalid.
|
|
73
|
-
*/
|
|
74
|
-
export function remove(indexerAddr, indexersEntry) {
|
|
75
|
-
if (!b4a.isBuffer(indexersEntry) ||
|
|
76
|
-
indexersEntry.length < TRAC_ADDRESS_SIZE + 1 ||
|
|
77
|
-
!isBufferValid(indexerAddr, TRAC_ADDRESS_SIZE)) {
|
|
78
|
-
return b4a.alloc(0); // If the indexer address is invalid, do nothing
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
const index = getIndex(indexersEntry, indexerAddr);
|
|
83
|
-
if (index === -1) {
|
|
84
|
-
return b4a.alloc(0); // If the indexer is not found, do nothing
|
|
85
|
-
}
|
|
86
|
-
// Remove the indexer address from the entry
|
|
87
|
-
const newIndexersEntry = b4a.concat([
|
|
88
|
-
indexersEntry.subarray(0, 1 + index * TRAC_ADDRESS_SIZE),
|
|
89
|
-
indexersEntry.subarray(1 + (index + 1) * TRAC_ADDRESS_SIZE)
|
|
90
|
-
]);
|
|
91
|
-
|
|
92
|
-
newIndexersEntry[0]--; // Decrease the count of indexers
|
|
93
|
-
return newIndexersEntry;
|
|
94
|
-
}
|
|
95
|
-
catch (error) {
|
|
96
|
-
console.error("Error removing indexer:", error);
|
|
97
|
-
return b4a.alloc(0); // If some error occurs, do nothing
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export default {
|
|
102
|
-
append,
|
|
103
|
-
getIndex,
|
|
104
|
-
remove
|
|
105
|
-
};
|
package/src/utils/crypto.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import b4a from "b4a";
|
|
2
|
-
import { blake3 } from "@tracsystems/blake3";
|
|
3
|
-
|
|
4
|
-
export async function blake3Hash(input, hashLength = 32) {
|
|
5
|
-
if (typeof input === "string") {
|
|
6
|
-
input = b4a.from(input, "utf8");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const hashBytes = await blake3(input, hashLength);
|
|
10
|
-
return b4a.from(hashBytes);
|
|
11
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { test } from 'brittle';
|
|
2
|
-
import b4a from 'b4a';
|
|
3
|
-
import { TRAC_ADDRESS_SIZE } from '../../../../src/utils/constants.js';
|
|
4
|
-
import { randomBuffer } from '../stateTestUtils.js';
|
|
5
|
-
import indexerEntryUtils, { append } from '../../../../src/core/state/utils/indexerEntry.js';
|
|
6
|
-
|
|
7
|
-
const appendIndexer = indexerEntryUtils.append;
|
|
8
|
-
const removeIndexer = indexerEntryUtils.remove;
|
|
9
|
-
|
|
10
|
-
// Test append()
|
|
11
|
-
test('Indexer Entry - Append creates new entry if none exists', t => {
|
|
12
|
-
const addr = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
13
|
-
const entry = appendIndexer(addr, null);
|
|
14
|
-
t.is(entry[0], 1, 'count should be 1');
|
|
15
|
-
t.ok(b4a.equals(entry.subarray(1), addr), 'address should match');
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test('Indexer Entry - Append to existing entry', t => {
|
|
19
|
-
const addr1 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
20
|
-
const addr2 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
21
|
-
let entry = appendIndexer(addr1, null);
|
|
22
|
-
entry = appendIndexer(addr2, entry);
|
|
23
|
-
t.is(entry[0], 2, 'count should be 2');
|
|
24
|
-
t.ok(b4a.equals(entry.subarray(1, 1 + TRAC_ADDRESS_SIZE), addr1), 'first address matches');
|
|
25
|
-
t.ok(b4a.equals(entry.subarray(1 + TRAC_ADDRESS_SIZE), addr2), 'second address matches');
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test('Indexer Entry - Append returns empty buffer if address is invalid', t => {
|
|
29
|
-
const addr = b4a.alloc(5); // invalid size
|
|
30
|
-
const entry = appendIndexer(addr, null);
|
|
31
|
-
t.ok(b4a.equals(entry, b4a.alloc(0)), 'should return empty buffer if address is invalid');
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// Test remove()
|
|
35
|
-
test('Indexer Entry - Removes address from entry', t => {
|
|
36
|
-
const addr1 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
37
|
-
const addr2 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
38
|
-
let entry = appendIndexer(addr1, null);
|
|
39
|
-
entry = appendIndexer(addr2, entry);
|
|
40
|
-
|
|
41
|
-
const updated = removeIndexer(addr1, entry);
|
|
42
|
-
t.is(updated[0], 1, 'count should be 1 after removal');
|
|
43
|
-
t.ok(b4a.equals(updated.subarray(1), addr2), 'remaining address should be addr2');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test('Indexer Entry - Remove returns empty buffer if address not found', t => {
|
|
47
|
-
const addr1 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
48
|
-
const addr2 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
49
|
-
const addr3 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
50
|
-
let entry = appendIndexer(addr1, null);
|
|
51
|
-
entry = appendIndexer(addr2, entry);
|
|
52
|
-
|
|
53
|
-
const updated = removeIndexer(addr3, entry);
|
|
54
|
-
t.ok(b4a.equals(updated, b4a.alloc(0)), 'entry should be empty if address not found');
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test('Indexer Entry - Remove returns empty buffer on invalid entry', t => {
|
|
58
|
-
const addr = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
59
|
-
const invalidEntry = b4a.alloc(5); // too short
|
|
60
|
-
const updated = removeIndexer(addr, invalidEntry);
|
|
61
|
-
t.ok(b4a.equals(updated, b4a.alloc(0)), 'should return empty buffer if invalid');
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
test('Indexer Entry - Remove returns empty buffer on invalid address', t => {
|
|
65
|
-
const addr1 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
66
|
-
let entry = appendIndexer(addr1, null);
|
|
67
|
-
const invalidAddr = b4a.alloc(5);
|
|
68
|
-
const updated = removeIndexer(invalidAddr, entry);
|
|
69
|
-
t.ok(b4a.equals(updated, b4a.alloc(0)), 'should return empty buffer if address invalid');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('Indexer Entry - Remove doesn\'t throw an error when count is bigger than the number of indexers', t => {
|
|
73
|
-
const addr1 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
74
|
-
const addr2 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
75
|
-
const addr3 = randomBuffer(TRAC_ADDRESS_SIZE);
|
|
76
|
-
let entry = appendIndexer(addr1, null);
|
|
77
|
-
entry = appendIndexer(addr2, entry);
|
|
78
|
-
|
|
79
|
-
// Remove an indexer and set the count to a higher value
|
|
80
|
-
entry[0] = 3;
|
|
81
|
-
const updated = removeIndexer(addr3, entry);
|
|
82
|
-
t.ok(b4a.equals(updated, b4a.alloc(0)), 'entry should be unchanged if count is too high');
|
|
83
|
-
});
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import test from 'brittle';
|
|
2
|
-
import b4a from 'b4a';
|
|
3
|
-
import transaction from '../../../src/core/state/utils/transaction.js';
|
|
4
|
-
|
|
5
|
-
const { generateTxBuffer, TRANSACTION_TOTAL_SIZE, generateBootstrapDeploymentTxBuffer, BOOTSTRAP_DEPLOYMENT_SIZE } = transaction;
|
|
6
|
-
import { OperationType, BOOTSTRAP_BYTE_LENGTH, NONCE_BYTE_LENGTH } from '../../../src/utils/constants.js';
|
|
7
|
-
|
|
8
|
-
function buf(size, fill = 0) {
|
|
9
|
-
return b4a.alloc(size, fill);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
test('generateTxBuffer returns a 32-byte hash for valid input', async t => {
|
|
13
|
-
const bootstrap = buf(8, 0x01);
|
|
14
|
-
const msb_bootstrap = buf(8, 0x02);
|
|
15
|
-
const validator_address = buf(20, 0x03);
|
|
16
|
-
const local_writer_key = buf(32, 0x04);
|
|
17
|
-
const local_address = buf(20, 0x05);
|
|
18
|
-
const content_hash = buf(32, 0x06);
|
|
19
|
-
const nonce = buf(8, 0x07);
|
|
20
|
-
|
|
21
|
-
const total = bootstrap.length + msb_bootstrap.length + validator_address.length + local_writer_key.length + local_address.length + content_hash.length + nonce.length;
|
|
22
|
-
t.is(total, TRANSACTION_TOTAL_SIZE, 'sum of buffer sizes matches TRANSACTION_TOTAL_SIZE');
|
|
23
|
-
|
|
24
|
-
const hash = await generateTxBuffer(bootstrap, msb_bootstrap, validator_address, local_writer_key, local_address, content_hash, nonce);
|
|
25
|
-
t.ok(b4a.isBuffer(hash));
|
|
26
|
-
t.is(hash.length, 32, 'hash should be 32 bytes (sha256)');
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test('generateTxBuffer returns empty buffer on error', async t => {
|
|
30
|
-
const bootstrap = buf(1, 0x01); // too small
|
|
31
|
-
const msb_bootstrap = buf(8, 0x02);
|
|
32
|
-
const validator_address = buf(20, 0x03);
|
|
33
|
-
const local_writer_key = buf(32, 0x04);
|
|
34
|
-
const local_address = buf(20, 0x05);
|
|
35
|
-
const content_hash = buf(32, 0x06);
|
|
36
|
-
const nonce = buf(8, 0x07);
|
|
37
|
-
|
|
38
|
-
const hash = await generateTxBuffer(bootstrap, msb_bootstrap, validator_address, local_writer_key, local_address, content_hash, nonce);
|
|
39
|
-
t.ok(b4a.isBuffer(hash));
|
|
40
|
-
t.is(hash.length, 0, 'should return empty buffer on error');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('generateBootstrapDeploymentTxBuffer returns a 32-byte hash for valid input', async t => {
|
|
44
|
-
const bootstrap = buf(BOOTSTRAP_BYTE_LENGTH, 0x01);
|
|
45
|
-
const incoming_nonce = buf(NONCE_BYTE_LENGTH, 0x02);
|
|
46
|
-
const opType = OperationType.BOOTSTRAP_DEPLOYMENT;
|
|
47
|
-
|
|
48
|
-
const hash = await generateBootstrapDeploymentTxBuffer(bootstrap, incoming_nonce, opType);
|
|
49
|
-
t.ok(b4a.isBuffer(hash));
|
|
50
|
-
t.is(hash.length, 32, 'hash should be 32 bytes (sha256)');
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test('generateBootstrapDeploymentTxBuffer returns empty buffer on error (bad bootstrap size)', async t => {
|
|
54
|
-
const bootstrap = buf(1, 0x01); // too small
|
|
55
|
-
const incoming_nonce = buf(NONCE_BYTE_LENGTH, 0x02);
|
|
56
|
-
const opType = OperationType.BOOTSTRAP_DEPLOYMENT;
|
|
57
|
-
|
|
58
|
-
const hash = await generateBootstrapDeploymentTxBuffer(bootstrap, incoming_nonce, opType);
|
|
59
|
-
t.ok(b4a.isBuffer(hash));
|
|
60
|
-
t.is(hash.length, 0, 'should return empty buffer on error');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test('generateBootstrapDeploymentTxBuffer returns empty buffer on error (bad nonce size)', async t => {
|
|
64
|
-
const bootstrap = buf(BOOTSTRAP_BYTE_LENGTH, 0x01);
|
|
65
|
-
const incoming_nonce = buf(1, 0x02); // too small
|
|
66
|
-
const opType = OperationType.BOOTSTRAP_DEPLOYMENT;
|
|
67
|
-
|
|
68
|
-
const hash = await generateBootstrapDeploymentTxBuffer(bootstrap, incoming_nonce, opType);
|
|
69
|
-
t.ok(b4a.isBuffer(hash));
|
|
70
|
-
t.is(hash.length, 0, 'should return empty buffer on error');
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
test('generateBootstrapDeploymentTxBuffer returns empty buffer on error (bad opType buffer)', async t => {
|
|
74
|
-
const bootstrap = buf(BOOTSTRAP_BYTE_LENGTH, 0x01);
|
|
75
|
-
const incoming_nonce = buf(NONCE_BYTE_LENGTH, 0x02);
|
|
76
|
-
// simulate opTypeBuffer of wrong size by passing undefined (should fail internally)
|
|
77
|
-
const hash = await generateBootstrapDeploymentTxBuffer(bootstrap, incoming_nonce, undefined);
|
|
78
|
-
t.ok(b4a.isBuffer(hash));
|
|
79
|
-
t.is(hash.length, 0, 'should return empty buffer on error');
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test('generateBootstrapDeploymentTxBuffer output buffer size is correct before hashing', async t => {
|
|
83
|
-
const bootstrap = buf(BOOTSTRAP_BYTE_LENGTH, 0x01);
|
|
84
|
-
const incoming_nonce = buf(NONCE_BYTE_LENGTH, 0x02);
|
|
85
|
-
const opType = OperationType.BOOTSTRAP_DEPLOYMENT;
|
|
86
|
-
|
|
87
|
-
const opTypeBuffer = b4a.alloc(4);
|
|
88
|
-
opTypeBuffer.writeUInt32BE(opType, 0);
|
|
89
|
-
const tx = b4a.alloc(BOOTSTRAP_DEPLOYMENT_SIZE);
|
|
90
|
-
let offset = 0;
|
|
91
|
-
bootstrap.copy(tx, offset);
|
|
92
|
-
offset += bootstrap.length;
|
|
93
|
-
incoming_nonce.copy(tx, offset);
|
|
94
|
-
offset += incoming_nonce.length;
|
|
95
|
-
opTypeBuffer.copy(tx, offset);
|
|
96
|
-
t.is(tx.length, BOOTSTRAP_DEPLOYMENT_SIZE, 'buffer size should match BOOTSTRAP_DEPLOYMENT_SIZE');
|
|
97
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import test from 'brittle';
|
|
2
|
-
import b4a from 'b4a';
|
|
3
|
-
import { blake3Hash} from '../../../../src/utils/crypto.js';
|
|
4
|
-
|
|
5
|
-
test('blake3', async (t) => {
|
|
6
|
-
t.test('blake3Hash', async (k) => {
|
|
7
|
-
const hash = await blake3Hash('test');
|
|
8
|
-
const expectedResult = b4a.from("4878ca0425c739fa427f7eda20fe845f6b2e46ba5fe2a14df5b1e32f50603215", 'hex');
|
|
9
|
-
k.ok(b4a.isBuffer(hash), 'Hash should be a buffer');
|
|
10
|
-
k.ok(hash.length === 32, 'Hash should be 32 bytes long');
|
|
11
|
-
k.ok(hash.equals(expectedResult), 'Hash result should be the expected one');
|
|
12
|
-
k.ok(hash.equals(await blake3Hash('test')), 'Hash should be the same for the same input');
|
|
13
|
-
k.ok(!hash.equals(await blake3Hash('Test')), 'Hash should be different for different inputs');
|
|
14
|
-
});
|
|
15
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|