trac-msb 0.2.7 → 0.2.9
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 +8 -16
- package/msb.mjs +13 -25
- package/package.json +8 -4
- package/proto/network.proto +74 -0
- package/rpc/{create_server.mjs → create_server.js} +4 -4
- package/rpc/{handlers.mjs → handlers.js} +7 -7
- package/rpc/routes/{index.mjs → index.js} +1 -1
- package/rpc/routes/{v1.mjs → v1.js} +1 -1
- package/rpc/rpc_server.js +10 -0
- package/rpc/rpc_services.js +48 -7
- package/rpc/utils/{helpers.mjs → helpers.js} +1 -1
- package/src/config/config.js +137 -0
- package/src/config/env.js +63 -0
- package/src/core/network/Network.js +133 -119
- package/src/core/network/identity/NetworkWalletFactory.js +5 -6
- package/src/core/network/protocols/LegacyProtocol.js +67 -0
- package/src/core/network/protocols/NetworkMessages.js +48 -0
- package/src/core/network/protocols/ProtocolInterface.js +31 -0
- package/src/core/network/protocols/ProtocolSession.js +59 -0
- package/src/core/network/protocols/V1Protocol.js +64 -0
- package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
- package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
- package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
- package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +2 -2
- package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +13 -6
- package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
- package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
- package/src/core/network/protocols/shared/handlers/TransferOperationHandler.js +57 -0
- package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +21 -26
- package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +3 -3
- package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +15 -12
- package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +10 -11
- package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +10 -7
- package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +40 -22
- package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
- package/src/core/network/services/ConnectionManager.js +13 -19
- package/src/core/network/services/MessageOrchestrator.js +10 -22
- package/src/core/network/services/TransactionPoolService.js +10 -10
- package/src/core/network/services/TransactionRateLimiterService.js +5 -3
- package/src/core/network/services/ValidatorObserverService.js +46 -21
- package/src/core/state/State.js +137 -141
- 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 +250 -325
- package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
- package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
- package/src/messages/network/v1/networkMessageFactory.js +12 -0
- package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
- package/src/messages/state/ApplyStateMessageDirector.js +516 -0
- package/src/messages/state/applyStateMessageFactory.js +12 -0
- package/src/utils/buffer.js +53 -1
- package/src/utils/check.js +21 -17
- package/src/utils/cli.js +0 -8
- package/src/utils/cliCommands.js +11 -11
- package/src/utils/constants.js +36 -24
- 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 +94 -11
- package/src/utils/protobuf/network.cjs +840 -0
- package/src/utils/protobuf/operationHelpers.js +10 -0
- 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 +10 -10
- 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/networkV1.fixtures.js +84 -0
- package/tests/fixtures/protobuf.fixtures.js +110 -26
- package/tests/helpers/StateNetworkFactory.js +3 -5
- package/tests/helpers/autobaseTestHelpers.js +1 -2
- package/tests/helpers/config.js +3 -0
- package/tests/helpers/setupApplyTests.js +113 -99
- package/tests/helpers/transactionPayloads.mjs +26 -12
- package/tests/unit/messages/messages.test.js +12 -0
- package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
- package/tests/unit/messages/network/NetworkMessageDirector.test.js +203 -0
- package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
- package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
- package/tests/unit/network/ConnectionManager.test.js +10 -7
- package/tests/unit/network/NetworkWalletFactory.test.js +14 -14
- package/tests/unit/network/networkModule.test.js +3 -2
- package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
- package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +11 -8
- package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +11 -7
- package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -20
- package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +57 -48
- package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +2 -1
- package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +72 -57
- package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +3 -7
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +12 -14
- package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +18 -13
- 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 +27 -30
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +2 -1
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +24 -21
- 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 +16 -16
- package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +10 -5
- 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 +16 -9
- package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +6 -5
- package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +23 -19
- package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +45 -36
- package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +48 -45
- package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +32 -29
- 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/unit.test.js +1 -1
- package/tests/unit/utils/buffer/buffer.test.js +62 -1
- 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/normalizers/normalizers.test.js +469 -0
- package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
- package/tests/unit/utils/utils.test.js +0 -1
- package/rpc/rpc_server.mjs +0 -10
- package/src/core/network/messaging/NetworkMessages.js +0 -63
- package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -112
- package/src/core/network/messaging/handlers/ResponseHandler.js +0 -108
- package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -116
- package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -143
- package/src/core/network/messaging/handlers/TransferOperationHandler.js +0 -52
- package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -94
- package/src/core/network/messaging/validators/AdminResponse.js +0 -58
- package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
- package/src/core/state/utils/indexerEntry.js +0 -105
- package/src/messages/base/StateBuilder.js +0 -25
- package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -421
- package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
- package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -299
- package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
- package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
- package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -131
- package/src/utils/crypto.js +0 -11
- package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -68
- package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -125
- package/tests/integration/apply/addIndexer.test.js +0 -237
- package/tests/integration/apply/addWhitelist.test.js +0 -53
- package/tests/integration/apply/addWriter.test.js +0 -244
- package/tests/integration/apply/apply.test.js +0 -19
- package/tests/integration/apply/banValidator.test.js +0 -109
- package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
- package/tests/integration/apply/postTx/postTx.test.js +0 -222
- package/tests/integration/apply/removeIndexer.test.js +0 -128
- package/tests/integration/apply/removeWriter.test.js +0 -167
- package/tests/integration/apply/transfer.test.js +0 -81
- package/tests/integration/integration.test.js +0 -9
- package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
- package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -16
- package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -69
- package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -16
- package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -442
- package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
- package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
- package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -58
- package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -277
- package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
- 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/{url.mjs → url.js} +0 -0
- /package/src/utils/{operations.js → applyOperations.js} +0 -0
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import {test, hook} from '../../../helpers/wrapper.js';
|
|
2
|
-
import {
|
|
3
|
-
initTemporaryDirectory, removeTemporaryDirectory, setupMsbPeer, setupMsbWriter, setupMsbIndexer,
|
|
4
|
-
tryToSyncWriters, waitForAdminEntry, setupMsbAdmin
|
|
5
|
-
} from '../../../helpers/setupApplyTests.js';
|
|
6
|
-
|
|
7
|
-
import {randomBytes} from '../../../helpers/setupApplyTests.js';
|
|
8
|
-
import CompleteStateMessageOperations from '../../../../src/messages/completeStateMessages/CompleteStateMessageOperations.js';
|
|
9
|
-
import PartialStateMessageOperations from '../../../../src/messages/partialStateMessages/PartialStateMessageOperations.js'
|
|
10
|
-
import {testKeyPair1, testKeyPair2, testKeyPair3, testKeyPair4} from '../../../fixtures/apply.fixtures.js';
|
|
11
|
-
import b4a from 'b4a';
|
|
12
|
-
import { decode as decodeAdmin } from '../../../../src/core/state/utils/adminEntry.js';
|
|
13
|
-
import { EntryType } from '../../../../src/utils/constants.js';
|
|
14
|
-
//TODO: ADD TEST WHEN NON-ADMIN NODE FORGES ADD ADMIN OPERATION AND BROADCASTS IT TO THE STATE - SHOULD BE REJECTED
|
|
15
|
-
|
|
16
|
-
let admin, newAdmin;
|
|
17
|
-
let indexer1, indexer2, writer;
|
|
18
|
-
let tmpDirectory;
|
|
19
|
-
let randomChannel;
|
|
20
|
-
|
|
21
|
-
hook('Initialize admin for addAdmin tests', async () => {
|
|
22
|
-
randomChannel = randomBytes(32).toString('hex');
|
|
23
|
-
const baseOptions = {
|
|
24
|
-
enable_tx_apply_logs: false,
|
|
25
|
-
enable_interactive_mode: false,
|
|
26
|
-
enable_role_requester: false,
|
|
27
|
-
channel: randomChannel,
|
|
28
|
-
enable_validator_observer: false,
|
|
29
|
-
}
|
|
30
|
-
tmpDirectory = await initTemporaryDirectory()
|
|
31
|
-
admin = await setupMsbAdmin(testKeyPair1, tmpDirectory, baseOptions);
|
|
32
|
-
|
|
33
|
-
// Setup nodes
|
|
34
|
-
writer = await setupMsbWriter(admin, 'writer', testKeyPair2, tmpDirectory, admin.options);
|
|
35
|
-
indexer1 = await setupMsbWriter(admin, 'indexer1', testKeyPair3, tmpDirectory, admin.options);
|
|
36
|
-
indexer2 = await setupMsbWriter(admin, 'indexer2', testKeyPair4, tmpDirectory, admin.options);
|
|
37
|
-
|
|
38
|
-
// Setup indexers after network is stable
|
|
39
|
-
indexer1 = await setupMsbIndexer(indexer1, admin);
|
|
40
|
-
indexer2 = await setupMsbIndexer(indexer2, admin);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('Apply function addAdmin for recovery - happy path', async (k) => {
|
|
44
|
-
const formerBootstrap = admin.options.bootstrap
|
|
45
|
-
await tryToSyncWriters(admin, writer, indexer1, indexer2);
|
|
46
|
-
|
|
47
|
-
const adminEntryBefore = await admin.msb.state.getAdminEntry();
|
|
48
|
-
const admI1 = await indexer1.msb.state.getAdminEntry();
|
|
49
|
-
const admI2 = await indexer2.msb.state.getAdminEntry();
|
|
50
|
-
const admW = await writer.msb.state.getAdminEntry();
|
|
51
|
-
|
|
52
|
-
await waitForAdminEntry(admin, {
|
|
53
|
-
address: admin.wallet.address,
|
|
54
|
-
wk: admin.msb.state.writingKey
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
await waitForAdminEntry(indexer1, {
|
|
58
|
-
address: admin.wallet.address,
|
|
59
|
-
wk: admin.msb.state.writingKey
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
await waitForAdminEntry(indexer2, {
|
|
63
|
-
address: admin.wallet.address,
|
|
64
|
-
wk: admin.msb.state.writingKey
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
await waitForAdminEntry(writer, {
|
|
68
|
-
address: admin.wallet.address,
|
|
69
|
-
wk: admin.msb.state.writingKey
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
// waitForIndexersConnection
|
|
73
|
-
|
|
74
|
-
k.ok(adminEntryBefore !== null, 'Admin entry should not be null before recovery');
|
|
75
|
-
k.ok(b4a.equals(adminEntryBefore.wk, admin.options.bootstrap), 'Admin writing key in base should match bootstrap key');
|
|
76
|
-
k.ok(b4a.equals(adminEntryBefore.wk, admI1.wk), 'Admin entry writer key the same as indexer');
|
|
77
|
-
k.ok(b4a.equals(admI1.wk, admI2.wk), 'Admin entry should be the same for both indexers');
|
|
78
|
-
k.ok(b4a.equals(admI1.wk, admW.wk), 'Admin entry should be the same for writer');
|
|
79
|
-
k.ok(adminEntryBefore.address === admI1.address, 'Admin entry address the same as indexer');
|
|
80
|
-
k.ok(admI1.address === admI2.address, 'Admin address should be the same for both indexers');
|
|
81
|
-
k.ok(admI1.address === admW.address, 'Admin address should be the same for writer');
|
|
82
|
-
const adminAddressBeforeRecovery = admin.wallet.address
|
|
83
|
-
|
|
84
|
-
// Simulate recovery by creating a new admin instance
|
|
85
|
-
newAdmin = await setupMsbPeer('newAdmin', testKeyPair1, tmpDirectory, admin.options);
|
|
86
|
-
await admin.msb.close(); // close the admin instance to simulate recovery
|
|
87
|
-
await newAdmin.msb.ready();
|
|
88
|
-
await newAdmin.msb.state.append(null);
|
|
89
|
-
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
|
-
);
|
|
95
|
-
|
|
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
|
-
)
|
|
105
|
-
await writer.msb.state.append(rawTx)
|
|
106
|
-
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
|
-
k.ok(adminEntryAfter, 'Result should not be null');
|
|
109
|
-
k.ok(adminEntryAfter.address === newAdmin.wallet.address, 'New Admin address in base should match new admin wallet address');
|
|
110
|
-
k.ok(adminAddressBeforeRecovery === newAdmin.wallet.address, 'New Admin wallet address should be the same as old admin wallet address');
|
|
111
|
-
k.ok(b4a.equals(adminEntryAfter.wk, newAdmin.msb.state.writingKey), 'New Admin writing key in base should match new admin MSB writing key');
|
|
112
|
-
k.ok(!b4a.equals(adminEntryBefore.wk, adminEntryAfter.wk), 'New Admin writing key in base should have changed');
|
|
113
|
-
k.ok(!b4a.equals(adminEntryAfter.wk, formerBootstrap), 'New Admin should not be bootstrap anymore');
|
|
114
|
-
//k.ok(newAdmin.msb.state.isWritable(), 'New Admin should be a writer');
|
|
115
|
-
// k.ok(newAdmin.msb.state.isIndexer(), 'New Admin should be an indexer'); // wait until holepunch team will fix bug with rotation.
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
hook('Clean up addAdmin recovery setup', async () => {
|
|
119
|
-
if (admin && admin.msb) await admin.msb.close();
|
|
120
|
-
if (newAdmin && newAdmin.msb) await newAdmin.msb.close();
|
|
121
|
-
if (indexer1 && indexer1.msb) await indexer1.msb.close();
|
|
122
|
-
if (indexer2 && indexer2.msb) await indexer2.msb.close();
|
|
123
|
-
if (writer && writer.msb) await writer.msb.close();
|
|
124
|
-
if (tmpDirectory) await removeTemporaryDirectory(tmpDirectory);
|
|
125
|
-
});
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import {test, hook, solo} from 'brittle';
|
|
2
|
-
import CompleteStateMessageOperations from '../../../src/messages/completeStateMessages/CompleteStateMessageOperations.js';
|
|
3
|
-
import {
|
|
4
|
-
initTemporaryDirectory,
|
|
5
|
-
removeTemporaryDirectory,
|
|
6
|
-
setupMsbAdmin,
|
|
7
|
-
setupMsbWriter,
|
|
8
|
-
randomBytes,
|
|
9
|
-
setupMsbPeer,
|
|
10
|
-
setupWhitelist, waitForNodeState, tryToSyncWriters, waitIndexer
|
|
11
|
-
} from '../../helpers/setupApplyTests.js';
|
|
12
|
-
import {
|
|
13
|
-
testKeyPair1,
|
|
14
|
-
testKeyPair2,
|
|
15
|
-
testKeyPair3,
|
|
16
|
-
testKeyPair4,
|
|
17
|
-
testKeyPair5,
|
|
18
|
-
testKeyPair6,
|
|
19
|
-
testKeyPair7
|
|
20
|
-
} from '../../fixtures/apply.fixtures.js';
|
|
21
|
-
import b4a from 'b4a';
|
|
22
|
-
|
|
23
|
-
let tmpDirectory, admin, indexer1, indexer2, reader1, reader2, indexer3, writer;
|
|
24
|
-
|
|
25
|
-
hook('Initialize nodes for addIndexer tests', async t => {
|
|
26
|
-
const randomChannel = randomBytes(32).toString('hex');
|
|
27
|
-
const baseOptions = {
|
|
28
|
-
enable_tx_apply_logs: false,
|
|
29
|
-
enable_interactive_mode: false,
|
|
30
|
-
enable_role_requester: false,
|
|
31
|
-
enable_validator_observer: false,
|
|
32
|
-
channel: randomChannel,
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
tmpDirectory = await initTemporaryDirectory()
|
|
36
|
-
admin = await setupMsbAdmin(testKeyPair1, tmpDirectory, baseOptions);
|
|
37
|
-
|
|
38
|
-
indexer1 = await setupMsbWriter(admin, 'indexer1', testKeyPair2, tmpDirectory, admin.options);
|
|
39
|
-
indexer2 = await setupMsbWriter(admin, 'indexer2', testKeyPair3, tmpDirectory, admin.options);
|
|
40
|
-
indexer3 = await setupMsbWriter(admin, 'indexer3', testKeyPair4, tmpDirectory, admin.options);
|
|
41
|
-
|
|
42
|
-
reader1 = await setupMsbPeer('reader1', testKeyPair5, tmpDirectory, admin.options);
|
|
43
|
-
reader2 = await setupMsbPeer('reader2', testKeyPair6, tmpDirectory, admin.options);
|
|
44
|
-
await setupWhitelist(admin, [reader2.wallet.address]);
|
|
45
|
-
|
|
46
|
-
writer = await setupMsbWriter(admin, 'writer', testKeyPair7, tmpDirectory, admin.options);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test('handleApplyAddIndexerOperation (apply) - Append addIndexer payload into the base - happy path', async t => {
|
|
50
|
-
// indexer1 is already a writer -> this writer will become an indexer
|
|
51
|
-
// indexer2 is already a writer.
|
|
52
|
-
// reader1 is just a reading node.
|
|
53
|
-
// reader2 is just a reading node.
|
|
54
|
-
// indexer3 is just a writer.
|
|
55
|
-
const oldIndexersEntry = await admin.msb.state.getIndexersEntry();
|
|
56
|
-
const validity = await admin.msb.state.getIndexerSequenceState()
|
|
57
|
-
const assembledAddIndexerMessage = await CompleteStateMessageOperations.assembleAddIndexerMessage(admin.wallet, indexer1.wallet.address, validity);
|
|
58
|
-
await waitIndexer(indexer1, async () => await admin.msb.state.append(assembledAddIndexerMessage))
|
|
59
|
-
|
|
60
|
-
await waitForNodeState(admin, indexer1.wallet.address, {
|
|
61
|
-
wk: indexer1.msb.state.writingKey,
|
|
62
|
-
isWhitelisted: true,
|
|
63
|
-
isWriter: true,
|
|
64
|
-
isIndexer: true,
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
const nodeInfo = await admin.msb.state.getNodeEntry(indexer1.wallet.address);
|
|
68
|
-
const indexersEntry = await admin.msb.state.getIndexersEntry();
|
|
69
|
-
|
|
70
|
-
t.is(indexersEntry.length, oldIndexersEntry.length + 1, 'Indexers entry count should be 2');
|
|
71
|
-
t.is(!!indexersEntry.find(({ key }) => b4a.equals(key, indexer1.msb.state.writingKey)), true, 'Indexer address should not be included in the indexers entry');
|
|
72
|
-
t.is(nodeInfo.isIndexer, true, 'Node info should indicate that the node is an indexer');
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test('handleApplyAddIndexerOperation (apply) - Append addIndexer payload into the base - idempotence', async t => {
|
|
76
|
-
// indexer1 is already an indexer.
|
|
77
|
-
// indexer2 is already a writer -> this writer will become an indexer
|
|
78
|
-
// writer is already a writer.
|
|
79
|
-
// reader1 is just a reading node.
|
|
80
|
-
// reader2 is just a reading node.
|
|
81
|
-
// indexer3 is just a writer.
|
|
82
|
-
const indexersEntryBefore = await admin.msb.state.getIndexersEntry();
|
|
83
|
-
const assembledAddIndexerMessage = await CompleteStateMessageOperations.assembleAddIndexerMessage(
|
|
84
|
-
admin.wallet,
|
|
85
|
-
indexer2.wallet.address,
|
|
86
|
-
await admin.msb.state.getIndexerSequenceState()
|
|
87
|
-
);
|
|
88
|
-
await waitIndexer(indexer2, async () => await admin.msb.state.append(assembledAddIndexerMessage))
|
|
89
|
-
|
|
90
|
-
await waitForNodeState(admin, indexer2.wallet.address, {
|
|
91
|
-
wk: indexer2.msb.state.writingKey,
|
|
92
|
-
isWhitelisted: true,
|
|
93
|
-
isWriter: true,
|
|
94
|
-
isIndexer: true,
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
await tryToSyncWriters(admin, indexer1, indexer2);
|
|
98
|
-
|
|
99
|
-
const adminSignedLengthBefore = admin.msb.state.getSignedLength();
|
|
100
|
-
const reqAddIndexerMessageAgain = await CompleteStateMessageOperations.assembleAddIndexerMessage(
|
|
101
|
-
admin.wallet,
|
|
102
|
-
indexer2.wallet.address,
|
|
103
|
-
await admin.msb.state.getIndexerSequenceState()
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
await admin.msb.state.append(reqAddIndexerMessageAgain);
|
|
107
|
-
|
|
108
|
-
await waitForNodeState(admin, indexer2.wallet.address, {
|
|
109
|
-
wk: indexer2.msb.state.writingKey,
|
|
110
|
-
isWhitelisted: true,
|
|
111
|
-
isWriter: true,
|
|
112
|
-
isIndexer: true,
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
await waitForNodeState(indexer2, indexer2.wallet.address, {
|
|
116
|
-
wk: indexer2.msb.state.writingKey,
|
|
117
|
-
isWhitelisted: true,
|
|
118
|
-
isWriter: true,
|
|
119
|
-
isIndexer: true,
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
const adminSignedLengthAfter = admin.msb.state.getSignedLength();
|
|
123
|
-
const indexersEntry = await admin.msb.state.getIndexersEntry();
|
|
124
|
-
|
|
125
|
-
t.is(indexersEntry.length, indexersEntryBefore.length + 1, `Indexers entry count should be ${indexersEntry.length}`);
|
|
126
|
-
t.is(adminSignedLengthBefore, adminSignedLengthAfter, 'Admin signed length should not change');
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
test('handleApplyAddIndexerOperation (apply) - Append addIndexer payload into the base - candidate is not a writer', async t => {
|
|
130
|
-
// indexer1 is already an indexer.
|
|
131
|
-
// indexer2 is already an indexer.
|
|
132
|
-
// reader1 is just a reading node -> will not become an indexer it will still a reader.
|
|
133
|
-
// reader2 is just a reading node.
|
|
134
|
-
// indexer3 is just a writer.
|
|
135
|
-
const indexersEntryBefore = await indexer1.msb.state.getIndexersEntry();
|
|
136
|
-
const validity = await admin.msb.state.getIndexerSequenceState()
|
|
137
|
-
const reqAddReader = await CompleteStateMessageOperations.assembleAddIndexerMessage(admin.wallet, reader1.wallet.address, validity);
|
|
138
|
-
|
|
139
|
-
const adminSignedLengthBefore = admin.msb.state.getSignedLength()
|
|
140
|
-
const indexer1SignedLengthBefore = indexer1.msb.state.getSignedLength();
|
|
141
|
-
const indexer2SignedLengthBefore = indexer2.msb.state.getSignedLength();
|
|
142
|
-
|
|
143
|
-
await admin.msb.state.append(reqAddReader);
|
|
144
|
-
await tryToSyncWriters(admin, indexer1, indexer2);
|
|
145
|
-
const adminSignedLengthAfter = admin.msb.state.getSignedLength();
|
|
146
|
-
const indexer1SignedLengthAfter = indexer1.msb.state.getSignedLength();
|
|
147
|
-
const indexer2SignedLengthAfter = indexer2.msb.state.getSignedLength();
|
|
148
|
-
|
|
149
|
-
const indexersEntry = await admin.msb.state.getIndexersEntry();
|
|
150
|
-
const nodeInfo = await admin.msb.state.getNodeEntry(reader1.wallet.address);
|
|
151
|
-
|
|
152
|
-
t.is(indexersEntry.length, indexersEntryBefore.length, `Indexers entry count should be ${indexersEntry.length}`);
|
|
153
|
-
t.is(!!indexersEntry.find(({ key }) => b4a.equals(key, reader1.msb.state.writingKey)), false, 'Reader address should not be included in the indexers entry');
|
|
154
|
-
t.is(nodeInfo, null, 'Node info should be null for reader');
|
|
155
|
-
t.is(adminSignedLengthBefore, adminSignedLengthAfter, 'Admin signed length should not change');
|
|
156
|
-
t.is(indexer1SignedLengthBefore, indexer1SignedLengthAfter, 'Indexer1 signed length should not change');
|
|
157
|
-
t.is(indexer2SignedLengthBefore, indexer2SignedLengthAfter, 'Indexer2 signed length should not change');
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
test('handleApplyAddIndexerOperation (apply) - Append addIndexer payload into the base - candidate is not a writer, but whitelisted', async t => {
|
|
161
|
-
// indexer1 is already an indexer.
|
|
162
|
-
// indexer2 is already an indexer.
|
|
163
|
-
// reader1 is just a reading node.
|
|
164
|
-
// reader2 is just a reading node -> will be whitelisted -> wil try to become an indexer but will not be able to.
|
|
165
|
-
// indexer3 is just a writer.
|
|
166
|
-
|
|
167
|
-
const indexersEntryBeforeWhitelist = await admin.msb.state.getIndexersEntry();
|
|
168
|
-
const adminSignedLengthBefore = admin.msb.state.getSignedLength();
|
|
169
|
-
const validity = await admin.msb.state.getIndexerSequenceState()
|
|
170
|
-
const reqAddIndexer2 = await CompleteStateMessageOperations.assembleAddIndexerMessage(
|
|
171
|
-
admin.wallet,
|
|
172
|
-
reader2.wallet.address,
|
|
173
|
-
validity);
|
|
174
|
-
|
|
175
|
-
await admin.msb.state.append(reqAddIndexer2);
|
|
176
|
-
await tryToSyncWriters(admin, indexer1, indexer2);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const adminSignedLengthAfter = admin.msb.state.getSignedLength();
|
|
180
|
-
|
|
181
|
-
const indexersEntryAfterWhitelist = await admin.msb.state.getIndexersEntry();
|
|
182
|
-
const nodeEntry = await admin.msb.state.getNodeEntry(reader2.wallet.address);
|
|
183
|
-
|
|
184
|
-
t.is(indexersEntryAfterWhitelist.length, indexersEntryBeforeWhitelist.length, `Indexers entry count should be ${indexersEntryAfterWhitelist.length}`);
|
|
185
|
-
t.is(!!indexersEntryAfterWhitelist.find(({ key }) => b4a.equals(key, reader2.msb.state.writingKey)), false, 'Reader address should not be included in the indexers entry');
|
|
186
|
-
t.is(nodeEntry.isIndexer, false, 'Node info should not indicate that the node is an indexer');
|
|
187
|
-
t.is(adminSignedLengthBefore, adminSignedLengthAfter, 'Admin signed length should not change');
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
test('handleApplyAddIndexerOperation (apply) - Append addIndexer payload into the base by non admin node (writer)', async t => {
|
|
191
|
-
// indexer1 is already an indexer.
|
|
192
|
-
// indexer2 is already an indexer.
|
|
193
|
-
// reader1 is just a reading node.
|
|
194
|
-
// reader2 is just a reading node.
|
|
195
|
-
// indexer3 is just a writer -> writer will try to add indexer3 as an indexer, however it won't be able to because it is not an admin.
|
|
196
|
-
// writer is just a writer.
|
|
197
|
-
const indexersEntryBefore = await writer.msb.state.getIndexersEntry();
|
|
198
|
-
const adminSignedLengthBefore = admin.msb.state.getSignedLength();
|
|
199
|
-
|
|
200
|
-
const validity = await admin.msb.state.getIndexerSequenceState()
|
|
201
|
-
const assembledAddIndexerMessage = await CompleteStateMessageOperations.assembleAddIndexerMessage(
|
|
202
|
-
admin.wallet,
|
|
203
|
-
indexer3.wallet.address,
|
|
204
|
-
validity);
|
|
205
|
-
|
|
206
|
-
await writer.msb.state.append(assembledAddIndexerMessage);
|
|
207
|
-
await tryToSyncWriters(admin, writer, indexer1, indexer2);
|
|
208
|
-
|
|
209
|
-
await waitForNodeState(writer, indexer3.wallet.address, {
|
|
210
|
-
wk: indexer3.msb.state.writingKey,
|
|
211
|
-
isWhitelisted: true,
|
|
212
|
-
isWriter: true,
|
|
213
|
-
isIndexer: false,
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
const adminSignedLengthAfter = admin.msb.state.getSignedLength();
|
|
217
|
-
const indexersEntry = await writer.msb.state.getIndexersEntry();
|
|
218
|
-
const nodeEntry = await writer.msb.state.getNodeEntry(indexer3.wallet.address);
|
|
219
|
-
|
|
220
|
-
t.is(indexersEntry.length, indexersEntryBefore.length, `Indexers entry count should be ${indexersEntry.length}`);
|
|
221
|
-
t.is(!!indexersEntry.find(({ key }) => b4a.equals(key, indexer3.msb.state.writingKey)), false, 'Indexer address should not be included in the indexers entry');
|
|
222
|
-
t.is(nodeEntry.isIndexer, false, 'Node info should indicate that the node is not an indexer');
|
|
223
|
-
t.is(adminSignedLengthBefore, adminSignedLengthAfter, 'Admin signed length should not change');
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
hook('Clean up addIndexer setup', async t => {
|
|
228
|
-
const toClose = []
|
|
229
|
-
if (admin?.msb) toClose.push(admin.msb.close());
|
|
230
|
-
if (indexer1?.msb) toClose.push(indexer1.msb.close());
|
|
231
|
-
if (indexer2?.msb) toClose.push(indexer2.msb.close());
|
|
232
|
-
if (reader2?.msb) toClose.push(reader2.msb.close());
|
|
233
|
-
if (reader1?.msb) toClose.push(reader1.msb.close());
|
|
234
|
-
if (indexer3?.msb) toClose.push(indexer3.msb.close());
|
|
235
|
-
await Promise.all(toClose)
|
|
236
|
-
if (tmpDirectory) await removeTemporaryDirectory(tmpDirectory);
|
|
237
|
-
});
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { test, hook } from '../../helpers/wrapper.js';
|
|
2
|
-
import b4a from 'b4a';
|
|
3
|
-
import { setupMsbAdmin, initTemporaryDirectory, removeTemporaryDirectory, randomBytes } from '../../helpers/setupApplyTests.js';
|
|
4
|
-
import { testKeyPair1, testKeyPair2 } from '../../fixtures/apply.fixtures.js';
|
|
5
|
-
import fileUtils from '../../../src/utils/fileUtils.js';
|
|
6
|
-
import CompleteStateMessageOperations from '../../../src/messages/completeStateMessages/CompleteStateMessageOperations.js';
|
|
7
|
-
import { address as addressApi } from 'trac-crypto-api';
|
|
8
|
-
import { TRAC_NETWORK_MSB_MAINNET_PREFIX } from 'trac-wallet/constants.js';
|
|
9
|
-
|
|
10
|
-
let admin, whitelistKeys, tmpDirectory, originalReadAddressesFromWhitelistFile;
|
|
11
|
-
const address = addressApi.encode(TRAC_NETWORK_MSB_MAINNET_PREFIX, b4a.from(testKeyPair2.publicKey, 'hex'))
|
|
12
|
-
hook('Initialize admin node for addWhitelist tests', async () => {
|
|
13
|
-
const randomChannel = randomBytes(32).toString('hex');
|
|
14
|
-
const baseOptions = {
|
|
15
|
-
enable_txchannels: false,
|
|
16
|
-
enable_tx_apply_logs: false,
|
|
17
|
-
enable_interactive_mode: false,
|
|
18
|
-
enable_role_requester: false,
|
|
19
|
-
channel: randomChannel,
|
|
20
|
-
}
|
|
21
|
-
tmpDirectory = await initTemporaryDirectory();
|
|
22
|
-
|
|
23
|
-
// Configure admin
|
|
24
|
-
admin = await setupMsbAdmin(testKeyPair1, tmpDirectory, baseOptions);
|
|
25
|
-
await admin.msb.ready();
|
|
26
|
-
|
|
27
|
-
// Configure whitelist
|
|
28
|
-
whitelistKeys = [address];
|
|
29
|
-
originalReadAddressesFromWhitelistFile = fileUtils.readAddressesFromWhitelistFile;
|
|
30
|
-
fileUtils.readAddressesFromWhitelistFile = async () => whitelistKeys;
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test('Apply function addWhitelist - happy path', async (t) => {
|
|
34
|
-
const validity = b4a.from(await admin.msb.state.getIndexerSequenceState(), 'hex')
|
|
35
|
-
const assembledWhitelistMessages = await CompleteStateMessageOperations.assembleAppendWhitelistMessages(admin.wallet, validity);
|
|
36
|
-
const payload = assembledWhitelistMessages.get(address);
|
|
37
|
-
|
|
38
|
-
await admin.msb.state.append(payload);
|
|
39
|
-
const isWhitelisted = await admin.msb.state.isAddressWhitelisted(address);
|
|
40
|
-
t.is(isWhitelisted, true, 'Whitelist entry should be created and true');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
//TODO: ADD TEST TO APPEND ADDRESS WHICH IS ALREADY WHITELISTED - SIGNED LENGTH SHOULD NOT CHANGE
|
|
44
|
-
|
|
45
|
-
hook('Cleanup after addWhitelist tests', async () => {
|
|
46
|
-
if (admin && admin.msb) {
|
|
47
|
-
await admin.msb.close();
|
|
48
|
-
}
|
|
49
|
-
if (tmpDirectory) {
|
|
50
|
-
await removeTemporaryDirectory(tmpDirectory);
|
|
51
|
-
}
|
|
52
|
-
fileUtils.readAddressesFromWhitelistFile = originalReadAddressesFromWhitelistFile;
|
|
53
|
-
});
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import b4a from 'b4a';
|
|
2
|
-
import { test, hook } from '../../helpers/wrapper.js';
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
setupMsbAdmin,
|
|
6
|
-
setupMsbPeer,
|
|
7
|
-
setupWhitelist,
|
|
8
|
-
fundPeer,
|
|
9
|
-
initTemporaryDirectory,
|
|
10
|
-
removeTemporaryDirectory,
|
|
11
|
-
randomBytes,
|
|
12
|
-
setupMsbIndexer,
|
|
13
|
-
setupMsbWriter,
|
|
14
|
-
tryToSyncWriters,
|
|
15
|
-
waitForNodeState,
|
|
16
|
-
waitWritable
|
|
17
|
-
} from '../../helpers/setupApplyTests.js';
|
|
18
|
-
import {
|
|
19
|
-
testKeyPair1,
|
|
20
|
-
testKeyPair2,
|
|
21
|
-
testKeyPair3,
|
|
22
|
-
testKeyPair4,
|
|
23
|
-
testKeyPair5,
|
|
24
|
-
testKeyPair6
|
|
25
|
-
} from '../../fixtures/apply.fixtures.js';
|
|
26
|
-
import PartialStateMessageOperations from "../../../src/messages/partialStateMessages/PartialStateMessageOperations.js";
|
|
27
|
-
import CompleteStateMessageOperations from '../../../src/messages/completeStateMessages/CompleteStateMessageOperations.js';
|
|
28
|
-
import {ZERO_WK} from '../../../src/utils/buffer.js';
|
|
29
|
-
import { $TNK } from '../../../src/core/state/utils/balance.js';
|
|
30
|
-
|
|
31
|
-
const sendAddWriter = async (invoker, broadcaster) => {
|
|
32
|
-
const validity = await invoker.msb.state.getIndexerSequenceState()
|
|
33
|
-
const req = await PartialStateMessageOperations.assembleAddWriterMessage(
|
|
34
|
-
invoker.wallet,
|
|
35
|
-
b4a.toString(invoker.msb.state.writingKey, 'hex'),
|
|
36
|
-
b4a.toString(validity, 'hex'));
|
|
37
|
-
|
|
38
|
-
const raw = await CompleteStateMessageOperations.assembleAddWriterMessage(
|
|
39
|
-
broadcaster.wallet,
|
|
40
|
-
req.address,
|
|
41
|
-
b4a.from(req.rao.tx, 'hex'),
|
|
42
|
-
b4a.from(req.rao.txv, 'hex'),
|
|
43
|
-
b4a.from(req.rao.iw, 'hex'),
|
|
44
|
-
b4a.from(req.rao.in, 'hex'),
|
|
45
|
-
b4a.from(req.rao.is, 'hex')
|
|
46
|
-
)
|
|
47
|
-
return await broadcaster.msb.state.append(raw)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
let admin, writer1, writer2, writer3, writer4, indexer1, tmpDirectory;
|
|
51
|
-
|
|
52
|
-
hook('Initialize nodes for addWriter tests', async t => {
|
|
53
|
-
const randomChannel = randomBytes(32).toString('hex');
|
|
54
|
-
const baseOptions = {
|
|
55
|
-
enable_tx_apply_logs: false,
|
|
56
|
-
enable_interactive_mode: false,
|
|
57
|
-
enable_role_requester: false,
|
|
58
|
-
channel: randomChannel,
|
|
59
|
-
enable_validator_observer: false
|
|
60
|
-
}
|
|
61
|
-
tmpDirectory = await initTemporaryDirectory();
|
|
62
|
-
admin = await setupMsbAdmin(testKeyPair1, tmpDirectory, baseOptions);
|
|
63
|
-
writer1 = await setupMsbPeer('writer1', testKeyPair2, tmpDirectory, admin.options); // just a peer, not a writer yet
|
|
64
|
-
await fundPeer(admin, writer1, $TNK(10n))
|
|
65
|
-
writer2 = await setupMsbPeer('writer2', testKeyPair3, tmpDirectory, admin.options); // just a peer, not a writer yet
|
|
66
|
-
await fundPeer(admin, writer2, $TNK(10n))
|
|
67
|
-
writer3 = await setupMsbPeer('writer3', testKeyPair4, tmpDirectory, admin.options); // just a peer, not a writer yet
|
|
68
|
-
await fundPeer(admin, writer3, $TNK(10n))
|
|
69
|
-
writer4 = await setupMsbPeer('writer4', testKeyPair5, tmpDirectory, admin.options); // just a peer, not a writer yet
|
|
70
|
-
indexer1 = await setupMsbWriter(admin, 'indexer1', testKeyPair6, tmpDirectory, admin.options); // writer and cannot be funded
|
|
71
|
-
|
|
72
|
-
const whitelistKeys = [writer1.wallet.address, writer2.wallet.address, writer3.wallet.address, indexer1.wallet.address];
|
|
73
|
-
await setupWhitelist(admin, whitelistKeys);
|
|
74
|
-
indexer1 = await setupMsbIndexer(indexer1, admin);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test('handleApplyAddWriterOperation (apply) - Append addWriter payload into the base - happy path for peer', async (t) => {
|
|
78
|
-
// writer1 is not a writer yet, but it is whitelisted -> It will become a writer after the operation.
|
|
79
|
-
// writer2 is not a writer yet, but it is whitelisted.
|
|
80
|
-
// writer3 is not a writer yet, but it is whitelisted.
|
|
81
|
-
// writer4 is reader
|
|
82
|
-
// indexer1 is already an indexer.
|
|
83
|
-
await admin.msb.state.append(null);
|
|
84
|
-
await waitWritable(admin, writer1, async () => await sendAddWriter(writer1, admin))
|
|
85
|
-
await waitForNodeState(admin, writer1.wallet.address, {
|
|
86
|
-
wk: writer1.msb.state.writingKey,
|
|
87
|
-
isWhitelisted: true,
|
|
88
|
-
isWriter: true,
|
|
89
|
-
isIndexer: false
|
|
90
|
-
});
|
|
91
|
-
await tryToSyncWriters(writer1, indexer1);
|
|
92
|
-
|
|
93
|
-
const result = await admin.msb.state.getNodeEntry(writer1.wallet.address); // check if the writer entry was added successfully in the base
|
|
94
|
-
|
|
95
|
-
t.ok(result, 'Result should not be null');
|
|
96
|
-
t.ok(b4a.equals(result.wk, writer1.msb.state.writingKey), 'Result writing key should match writer writing key');
|
|
97
|
-
t.ok(result.isWriter, 'Result should indicate that the peer is a valid writer');
|
|
98
|
-
t.is(result.isIndexer, false, 'Result should not indicate that the peer is an indexer');
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
test('handleApplyAddWriterOperation (apply) - Append addWriter payload into the base - doesnt change the signed length', async (t) => {
|
|
102
|
-
// writer1 is already a writer.
|
|
103
|
-
// writer2 is not a writer yet, but it is whitelisted -> It will become a writer after the operation.
|
|
104
|
-
// writer3 is not a writer yet, but it is whitelisted.
|
|
105
|
-
// writer4 is reader
|
|
106
|
-
// indexer1 is already an indexer.
|
|
107
|
-
await admin.msb.state.append(null);
|
|
108
|
-
await waitWritable(admin, writer2, async () => await sendAddWriter(writer2, admin))
|
|
109
|
-
await tryToSyncWriters(writer2, admin, indexer1);
|
|
110
|
-
|
|
111
|
-
await waitForNodeState(writer2, writer2.wallet.address, {
|
|
112
|
-
wk: writer2.msb.state.writingKey,
|
|
113
|
-
isWhitelisted: true,
|
|
114
|
-
isWriter: true,
|
|
115
|
-
isIndexer: false
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
const signedLengthAdminBefore = admin.msb.state.getSignedLength();
|
|
119
|
-
const signedLengthWriter2Before = writer2.msb.state.getSignedLength();
|
|
120
|
-
|
|
121
|
-
await sendAddWriter(writer2, admin)
|
|
122
|
-
|
|
123
|
-
await tryToSyncWriters(admin, writer2, indexer1);
|
|
124
|
-
await waitForNodeState(writer2, writer2.wallet.address, {
|
|
125
|
-
wk: writer2.msb.state.writingKey,
|
|
126
|
-
isWhitelisted: true,
|
|
127
|
-
isWriter: true,
|
|
128
|
-
isIndexer: false
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
const signedLengthAdminAfter = admin.msb.state.getSignedLength();
|
|
132
|
-
const signedLengthWriter2After = writer2.msb.state.getSignedLength();
|
|
133
|
-
|
|
134
|
-
t.is(signedLengthAdminBefore, signedLengthAdminAfter, 'Admin signed length should not change');
|
|
135
|
-
t.is(signedLengthWriter2Before, signedLengthWriter2After, 'Writer2 signed length should not change');
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
test('handleApplyAddWriterOperation (apply) - Append addWriter payload into the base - ZERO_WK', async (t) => {
|
|
139
|
-
// writer1 is already a writer.
|
|
140
|
-
// writer2 is already a writer.
|
|
141
|
-
// writer3 is not a writer yet, but it is whitelisted and won't become a writer.
|
|
142
|
-
// writer4 is reader
|
|
143
|
-
// indexer1 is already an indexer.
|
|
144
|
-
const signedLengthAdminBefore = admin.msb.state.getSignedLength();
|
|
145
|
-
const signedLengthWriter1Before = writer1.msb.state.getSignedLength();
|
|
146
|
-
|
|
147
|
-
const validity = await writer3.msb.state.getIndexerSequenceState()
|
|
148
|
-
const req = await PartialStateMessageOperations.assembleAddWriterMessage(
|
|
149
|
-
writer3.wallet,
|
|
150
|
-
b4a.toString(ZERO_WK, 'hex'),
|
|
151
|
-
b4a.toString(validity, 'hex'));
|
|
152
|
-
|
|
153
|
-
const raw = await CompleteStateMessageOperations.assembleAddWriterMessage(
|
|
154
|
-
admin.wallet,
|
|
155
|
-
req.address,
|
|
156
|
-
b4a.from(req.rao.tx, 'hex'),
|
|
157
|
-
b4a.from(req.rao.txv, 'hex'),
|
|
158
|
-
b4a.from(req.rao.iw, 'hex'),
|
|
159
|
-
b4a.from(req.rao.in, 'hex'),
|
|
160
|
-
b4a.from(req.rao.is, 'hex')
|
|
161
|
-
)
|
|
162
|
-
await admin.msb.state.append(raw)
|
|
163
|
-
await tryToSyncWriters(writer3, admin, writer1, writer2, indexer1);
|
|
164
|
-
|
|
165
|
-
const result = await writer1.msb.state.getNodeEntry(writer3.wallet.address);
|
|
166
|
-
const signedLengthAdminAfter = admin.msb.state.getSignedLength();
|
|
167
|
-
const signedLengthWriter1After = writer1.msb.state.getSignedLength();
|
|
168
|
-
|
|
169
|
-
t.is(signedLengthAdminBefore, signedLengthAdminAfter, 'admin signed length should not change');
|
|
170
|
-
t.is(signedLengthWriter1Before, signedLengthWriter1After, 'Writer1 signed length should not change');
|
|
171
|
-
t.ok(result, 'Result should not be null');
|
|
172
|
-
t.ok(!b4a.equals(result.wk, writer3.msb.state.writingKey), 'Result writing key should not match writer writing key');
|
|
173
|
-
t.ok(b4a.equals(result.wk, ZERO_WK), 'Result writing key should be ZERO_WK');
|
|
174
|
-
t.is(result.isWriter, false, 'Result should indicate that the peer is not a writer');
|
|
175
|
-
//t.is(writer3.msb.state.isWritable(), false, 'peer should not be writable');
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
test('handleApplyAddWriterOperation (apply) - Append addWriter payload into the base - node is already an indexer', async (t) => {
|
|
179
|
-
// writer1 is already a writer.
|
|
180
|
-
// writer2 is already a writer.
|
|
181
|
-
// writer3 is not a writer, but it is whitelisted.
|
|
182
|
-
// writer4 is reader
|
|
183
|
-
// indexer1 is already an indexer.
|
|
184
|
-
const resultBefore = await admin.msb.state.getNodeEntry(indexer1.wallet.address);
|
|
185
|
-
await indexer1.msb.state.append(null);
|
|
186
|
-
const signedLengthAdminBefore = admin.msb.state.getSignedLength();
|
|
187
|
-
const signedLengthIndexer1Before = indexer1.msb.state.getSignedLength();
|
|
188
|
-
|
|
189
|
-
await sendAddWriter(indexer1, admin)
|
|
190
|
-
await tryToSyncWriters(indexer1, admin, writer1, writer2);
|
|
191
|
-
|
|
192
|
-
const result = await admin.msb.state.getNodeEntry(indexer1.wallet.address); // check if the writer entry was added successfully in the base
|
|
193
|
-
const signedLengthAdminAfter = admin.msb.state.getSignedLength();
|
|
194
|
-
const signedLengthIndexer1After = indexer1.msb.state.getSignedLength();
|
|
195
|
-
|
|
196
|
-
t.is(signedLengthAdminBefore, signedLengthAdminAfter, 'Admin signed length should not change');
|
|
197
|
-
t.is(signedLengthIndexer1Before, signedLengthIndexer1After, 'Indexer1 signed length should not change');
|
|
198
|
-
t.ok(result, 'Result should not be null');
|
|
199
|
-
t.ok(b4a.equals(result.wk, indexer1.msb.state.writingKey), 'Result writing key should match writer writing key');
|
|
200
|
-
t.is(result.isWriter, true, 'Result should indicate that the peer is a writer');
|
|
201
|
-
t.is(result.isIndexer, true, 'Result should indicate that the peer is an indexer');
|
|
202
|
-
t.is(indexer1.msb.state.isWritable(), true, 'peer should still be writable');
|
|
203
|
-
t.is(indexer1.msb.state.isIndexer(), true, 'peer should still be an indexer');
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
test('handleApplyAddWriterOperation (apply) - Append addWriter payload into the base - non-whitelisted peer', async (t) => {
|
|
207
|
-
// writer1 is already a writer
|
|
208
|
-
// writer2 is already a writer
|
|
209
|
-
// writer3 is already a writer
|
|
210
|
-
// writer4 is reader -> this node will not become a writer.
|
|
211
|
-
// indexer1 is already an indexer
|
|
212
|
-
await writer4.msb.state.append(null);
|
|
213
|
-
const signedLengthAdminBefore = admin.msb.state.getSignedLength();
|
|
214
|
-
|
|
215
|
-
await sendAddWriter(writer4, admin)
|
|
216
|
-
await tryToSyncWriters(writer4, writer1, writer2, writer3, indexer1);
|
|
217
|
-
|
|
218
|
-
const result = await writer2.msb.state.getNodeEntry(writer4.wallet.address); // check if the writer entry was added successfully in the base
|
|
219
|
-
const signedLengthAdminAfter = admin.msb.state.getSignedLength();
|
|
220
|
-
|
|
221
|
-
t.is(signedLengthAdminBefore, signedLengthAdminAfter, 'Admin signed length should not change');
|
|
222
|
-
t.is(writer4.msb.state.isWritable(), false, 'peer should not be writable');
|
|
223
|
-
t.is(writer4.msb.state.isIndexer(), false, 'peer should not be an indexer');
|
|
224
|
-
t.is(result, null, 'Result should be null');
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
test('handleApplyAddWriterOperation (apply) - validator and invoker are the same', async (t) => {
|
|
228
|
-
// TODO: Implement when apply tests are fixed
|
|
229
|
-
t.pass('Skipping test: Placeholder. To be implemented later.');
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
hook('Clean up addWriter setup', async t => {
|
|
233
|
-
const toClose = []
|
|
234
|
-
// close msb instances and remove temp directory
|
|
235
|
-
if (admin?.msb) toClose.push(admin.msb.close());
|
|
236
|
-
if (writer1?.msb) toClose.push(writer1.msb.close());
|
|
237
|
-
if (writer2?.msb) toClose.push(writer2.msb.close());
|
|
238
|
-
if (writer3?.msb) toClose.push(writer3.msb.close());
|
|
239
|
-
if (writer4?.msb) toClose.push(writer4.msb.close());
|
|
240
|
-
if (indexer1?.msb) toClose.push(indexer1.msb.close());
|
|
241
|
-
|
|
242
|
-
await Promise.all(toClose)
|
|
243
|
-
if (tmpDirectory) await removeTemporaryDirectory(tmpDirectory);
|
|
244
|
-
})
|