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
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import { test } from 'brittle';
|
|
2
|
+
import b4a from 'b4a';
|
|
3
|
+
|
|
4
|
+
import { config } from '../../../helpers/config.js';
|
|
5
|
+
import { randomAddress } from '../../state/stateTestUtils.js';
|
|
6
|
+
import { errorMessageIncludes } from '../../../helpers/regexHelper.js';
|
|
7
|
+
import { OperationType } from '../../../../src/utils/constants.js';
|
|
8
|
+
import {
|
|
9
|
+
normalizeBootstrapDeploymentOperation,
|
|
10
|
+
normalizeDecodedPayloadForJson,
|
|
11
|
+
normalizeRoleAccessOperation,
|
|
12
|
+
normalizeTransactionOperation,
|
|
13
|
+
normalizeTransferOperation
|
|
14
|
+
} from '../../../../src/utils/normalizers.js';
|
|
15
|
+
import { addressToBuffer } from '../../../../src/core/state/utils/address.js';
|
|
16
|
+
import { bigIntTo16ByteBuffer } from '../../../../src/utils/amountSerialization.js';
|
|
17
|
+
|
|
18
|
+
const hex = (value, bytes) => value.repeat(bytes);
|
|
19
|
+
const toBuffer = value => b4a.from(value, 'hex');
|
|
20
|
+
|
|
21
|
+
test('normalizeTransferOperation normalizes hex strings and addresses', t => {
|
|
22
|
+
const sender = randomAddress(config.addressPrefix);
|
|
23
|
+
const recipient = randomAddress(config.addressPrefix);
|
|
24
|
+
const tx = hex('11', 32);
|
|
25
|
+
const txv = hex('22', 32);
|
|
26
|
+
const nonce = hex('33', 32);
|
|
27
|
+
const amount = hex('44', 16);
|
|
28
|
+
const signature = hex('55', 64);
|
|
29
|
+
|
|
30
|
+
const payload = {
|
|
31
|
+
type: OperationType.TRANSFER,
|
|
32
|
+
address: sender,
|
|
33
|
+
tro: {
|
|
34
|
+
tx,
|
|
35
|
+
txv,
|
|
36
|
+
in: nonce,
|
|
37
|
+
to: recipient,
|
|
38
|
+
am: amount,
|
|
39
|
+
is: signature
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const normalized = normalizeTransferOperation(payload, config);
|
|
44
|
+
|
|
45
|
+
t.is(normalized.type, OperationType.TRANSFER);
|
|
46
|
+
t.ok(b4a.equals(normalized.address, addressToBuffer(sender, config.addressPrefix)));
|
|
47
|
+
t.ok(b4a.equals(normalized.tro.tx, toBuffer(tx)));
|
|
48
|
+
t.ok(b4a.equals(normalized.tro.txv, toBuffer(txv)));
|
|
49
|
+
t.ok(b4a.equals(normalized.tro.in, toBuffer(nonce)));
|
|
50
|
+
t.ok(b4a.equals(normalized.tro.to, addressToBuffer(recipient, config.addressPrefix)));
|
|
51
|
+
t.ok(b4a.equals(normalized.tro.am, toBuffer(amount)));
|
|
52
|
+
t.ok(b4a.equals(normalized.tro.is, toBuffer(signature)));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('normalizeTransferOperation accepts buffer inputs', t => {
|
|
56
|
+
const sender = randomAddress(config.addressPrefix);
|
|
57
|
+
const recipient = randomAddress(config.addressPrefix);
|
|
58
|
+
const tx = toBuffer(hex('aa', 32));
|
|
59
|
+
const txv = toBuffer(hex('bb', 32));
|
|
60
|
+
const nonce = toBuffer(hex('cc', 32));
|
|
61
|
+
const amount = toBuffer(hex('dd', 16));
|
|
62
|
+
const signature = toBuffer(hex('ee', 64));
|
|
63
|
+
|
|
64
|
+
const payload = {
|
|
65
|
+
type: OperationType.TRANSFER,
|
|
66
|
+
address: sender,
|
|
67
|
+
tro: {
|
|
68
|
+
tx,
|
|
69
|
+
txv,
|
|
70
|
+
in: nonce,
|
|
71
|
+
to: recipient,
|
|
72
|
+
am: amount,
|
|
73
|
+
is: signature
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const normalized = normalizeTransferOperation(payload, config);
|
|
78
|
+
t.ok(b4a.equals(normalized.tro.tx, tx));
|
|
79
|
+
t.ok(b4a.equals(normalized.tro.txv, txv));
|
|
80
|
+
t.ok(b4a.equals(normalized.tro.in, nonce));
|
|
81
|
+
t.ok(b4a.equals(normalized.tro.am, amount));
|
|
82
|
+
t.ok(b4a.equals(normalized.tro.is, signature));
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('normalizeTransferOperation throws on missing payload fields', t => {
|
|
86
|
+
t.exception(
|
|
87
|
+
() => normalizeTransferOperation({ type: OperationType.TRANSFER }, config),
|
|
88
|
+
errorMessageIncludes('Invalid payload for transfer operation normalization.')
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
t.exception(
|
|
92
|
+
() => normalizeTransferOperation({ type: OperationType.TX, address: 'x', tro: {} }, config),
|
|
93
|
+
errorMessageIncludes('Missing required fields in transfer operation payload.')
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const sender = randomAddress(config.addressPrefix);
|
|
97
|
+
const payload = {
|
|
98
|
+
type: OperationType.TRANSFER,
|
|
99
|
+
address: sender,
|
|
100
|
+
tro: {
|
|
101
|
+
tx: hex('11', 32),
|
|
102
|
+
txv: hex('22', 32),
|
|
103
|
+
in: hex('33', 32),
|
|
104
|
+
to: randomAddress(config.addressPrefix),
|
|
105
|
+
am: hex('44', 16)
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
t.exception(
|
|
109
|
+
() => normalizeTransferOperation(payload, config),
|
|
110
|
+
errorMessageIncludes('Missing required fields in transfer operation payload.')
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('normalizeTransferOperation throws on invalid hex string', t => {
|
|
115
|
+
const sender = randomAddress(config.addressPrefix);
|
|
116
|
+
const payload = {
|
|
117
|
+
type: OperationType.TRANSFER,
|
|
118
|
+
address: sender,
|
|
119
|
+
tro: {
|
|
120
|
+
tx: 'zz',
|
|
121
|
+
txv: hex('22', 32),
|
|
122
|
+
in: hex('33', 32),
|
|
123
|
+
to: randomAddress(config.addressPrefix),
|
|
124
|
+
am: hex('44', 16),
|
|
125
|
+
is: hex('55', 64)
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
t.exception(
|
|
129
|
+
() => normalizeTransferOperation(payload, config),
|
|
130
|
+
errorMessageIncludes('Invalid hex string')
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('normalizeTransactionOperation normalizes hex strings and addresses', t => {
|
|
135
|
+
const sender = randomAddress(config.addressPrefix);
|
|
136
|
+
const tx = hex('11', 32);
|
|
137
|
+
const txv = hex('22', 32);
|
|
138
|
+
const writerKey = hex('33', 32);
|
|
139
|
+
const contentHash = hex('44', 32);
|
|
140
|
+
const bootstrap = hex('55', 32);
|
|
141
|
+
const msbBootstrap = hex('66', 32);
|
|
142
|
+
const nonce = hex('77', 32);
|
|
143
|
+
const signature = hex('88', 64);
|
|
144
|
+
|
|
145
|
+
const payload = {
|
|
146
|
+
type: OperationType.TX,
|
|
147
|
+
address: sender,
|
|
148
|
+
txo: {
|
|
149
|
+
tx,
|
|
150
|
+
txv,
|
|
151
|
+
iw: writerKey,
|
|
152
|
+
ch: contentHash,
|
|
153
|
+
bs: bootstrap,
|
|
154
|
+
mbs: msbBootstrap,
|
|
155
|
+
in: nonce,
|
|
156
|
+
is: signature
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const normalized = normalizeTransactionOperation(payload, config);
|
|
161
|
+
t.is(normalized.type, OperationType.TX);
|
|
162
|
+
t.ok(b4a.equals(normalized.address, addressToBuffer(sender, config.addressPrefix)));
|
|
163
|
+
t.ok(b4a.equals(normalized.txo.tx, toBuffer(tx)));
|
|
164
|
+
t.ok(b4a.equals(normalized.txo.txv, toBuffer(txv)));
|
|
165
|
+
t.ok(b4a.equals(normalized.txo.iw, toBuffer(writerKey)));
|
|
166
|
+
t.ok(b4a.equals(normalized.txo.ch, toBuffer(contentHash)));
|
|
167
|
+
t.ok(b4a.equals(normalized.txo.bs, toBuffer(bootstrap)));
|
|
168
|
+
t.ok(b4a.equals(normalized.txo.mbs, toBuffer(msbBootstrap)));
|
|
169
|
+
t.ok(b4a.equals(normalized.txo.in, toBuffer(nonce)));
|
|
170
|
+
t.ok(b4a.equals(normalized.txo.is, toBuffer(signature)));
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('normalizeTransactionOperation accepts buffer inputs', t => {
|
|
174
|
+
const sender = randomAddress(config.addressPrefix);
|
|
175
|
+
const tx = toBuffer(hex('aa', 32));
|
|
176
|
+
const txv = toBuffer(hex('bb', 32));
|
|
177
|
+
const writerKey = toBuffer(hex('cc', 32));
|
|
178
|
+
const contentHash = toBuffer(hex('dd', 32));
|
|
179
|
+
const bootstrap = toBuffer(hex('ee', 32));
|
|
180
|
+
const msbBootstrap = toBuffer(hex('ff', 32));
|
|
181
|
+
const nonce = toBuffer(hex('12', 32));
|
|
182
|
+
const signature = toBuffer(hex('34', 64));
|
|
183
|
+
|
|
184
|
+
const payload = {
|
|
185
|
+
type: OperationType.TX,
|
|
186
|
+
address: sender,
|
|
187
|
+
txo: {
|
|
188
|
+
tx,
|
|
189
|
+
txv,
|
|
190
|
+
iw: writerKey,
|
|
191
|
+
ch: contentHash,
|
|
192
|
+
bs: bootstrap,
|
|
193
|
+
mbs: msbBootstrap,
|
|
194
|
+
in: nonce,
|
|
195
|
+
is: signature
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const normalized = normalizeTransactionOperation(payload, config);
|
|
200
|
+
t.ok(b4a.equals(normalized.txo.tx, tx));
|
|
201
|
+
t.ok(b4a.equals(normalized.txo.txv, txv));
|
|
202
|
+
t.ok(b4a.equals(normalized.txo.iw, writerKey));
|
|
203
|
+
t.ok(b4a.equals(normalized.txo.ch, contentHash));
|
|
204
|
+
t.ok(b4a.equals(normalized.txo.bs, bootstrap));
|
|
205
|
+
t.ok(b4a.equals(normalized.txo.mbs, msbBootstrap));
|
|
206
|
+
t.ok(b4a.equals(normalized.txo.in, nonce));
|
|
207
|
+
t.ok(b4a.equals(normalized.txo.is, signature));
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test('normalizeTransactionOperation throws on missing payload fields', t => {
|
|
211
|
+
t.exception(
|
|
212
|
+
() => normalizeTransactionOperation({ type: OperationType.TX }, config),
|
|
213
|
+
errorMessageIncludes('Invalid payload for transaction operation normalization.')
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
t.exception(
|
|
217
|
+
() => normalizeTransactionOperation({ type: OperationType.TRANSFER, address: 'x', txo: {} }, config),
|
|
218
|
+
errorMessageIncludes('Missing required fields in transaction operation payload.')
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
const sender = randomAddress(config.addressPrefix);
|
|
222
|
+
const payload = {
|
|
223
|
+
type: OperationType.TX,
|
|
224
|
+
address: sender,
|
|
225
|
+
txo: {
|
|
226
|
+
tx: hex('11', 32),
|
|
227
|
+
txv: hex('22', 32),
|
|
228
|
+
iw: hex('33', 32),
|
|
229
|
+
ch: hex('44', 32),
|
|
230
|
+
bs: hex('55', 32),
|
|
231
|
+
mbs: hex('66', 32),
|
|
232
|
+
in: hex('77', 32)
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
t.exception(
|
|
236
|
+
() => normalizeTransactionOperation(payload, config),
|
|
237
|
+
errorMessageIncludes('Missing required fields in transaction operation payload.')
|
|
238
|
+
);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test('normalizeTransactionOperation throws on invalid hex string', t => {
|
|
242
|
+
const sender = randomAddress(config.addressPrefix);
|
|
243
|
+
const payload = {
|
|
244
|
+
type: OperationType.TX,
|
|
245
|
+
address: sender,
|
|
246
|
+
txo: {
|
|
247
|
+
tx: 'zz',
|
|
248
|
+
txv: hex('22', 32),
|
|
249
|
+
iw: hex('33', 32),
|
|
250
|
+
ch: hex('44', 32),
|
|
251
|
+
bs: hex('55', 32),
|
|
252
|
+
mbs: hex('66', 32),
|
|
253
|
+
in: hex('77', 32),
|
|
254
|
+
is: hex('88', 64)
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
t.exception(
|
|
258
|
+
() => normalizeTransactionOperation(payload, config),
|
|
259
|
+
errorMessageIncludes('Invalid hex string')
|
|
260
|
+
);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
test('normalizeRoleAccessOperation normalizes hex strings and addresses', t => {
|
|
264
|
+
const sender = randomAddress(config.addressPrefix);
|
|
265
|
+
const payload = {
|
|
266
|
+
type: OperationType.ADD_WRITER,
|
|
267
|
+
address: sender,
|
|
268
|
+
rao: {
|
|
269
|
+
tx: hex('11', 32),
|
|
270
|
+
txv: hex('22', 32),
|
|
271
|
+
iw: hex('33', 32),
|
|
272
|
+
in: hex('44', 32),
|
|
273
|
+
is: hex('55', 64)
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const normalized = normalizeRoleAccessOperation(payload, config);
|
|
278
|
+
t.is(normalized.type, OperationType.ADD_WRITER);
|
|
279
|
+
t.ok(b4a.equals(normalized.address, addressToBuffer(sender, config.addressPrefix)));
|
|
280
|
+
t.ok(b4a.equals(normalized.rao.tx, toBuffer(hex('11', 32))));
|
|
281
|
+
t.ok(b4a.equals(normalized.rao.txv, toBuffer(hex('22', 32))));
|
|
282
|
+
t.ok(b4a.equals(normalized.rao.iw, toBuffer(hex('33', 32))));
|
|
283
|
+
t.ok(b4a.equals(normalized.rao.in, toBuffer(hex('44', 32))));
|
|
284
|
+
t.ok(b4a.equals(normalized.rao.is, toBuffer(hex('55', 64))));
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test('normalizeRoleAccessOperation accepts buffer inputs', t => {
|
|
288
|
+
const sender = randomAddress(config.addressPrefix);
|
|
289
|
+
const tx = toBuffer(hex('aa', 32));
|
|
290
|
+
const txv = toBuffer(hex('bb', 32));
|
|
291
|
+
const writerKey = toBuffer(hex('cc', 32));
|
|
292
|
+
const nonce = toBuffer(hex('dd', 32));
|
|
293
|
+
const signature = toBuffer(hex('ee', 64));
|
|
294
|
+
|
|
295
|
+
const payload = {
|
|
296
|
+
type: OperationType.REMOVE_WRITER,
|
|
297
|
+
address: sender,
|
|
298
|
+
rao: {
|
|
299
|
+
tx,
|
|
300
|
+
txv,
|
|
301
|
+
iw: writerKey,
|
|
302
|
+
in: nonce,
|
|
303
|
+
is: signature
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const normalized = normalizeRoleAccessOperation(payload, config);
|
|
308
|
+
t.ok(b4a.equals(normalized.rao.tx, tx));
|
|
309
|
+
t.ok(b4a.equals(normalized.rao.txv, txv));
|
|
310
|
+
t.ok(b4a.equals(normalized.rao.iw, writerKey));
|
|
311
|
+
t.ok(b4a.equals(normalized.rao.in, nonce));
|
|
312
|
+
t.ok(b4a.equals(normalized.rao.is, signature));
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
test('normalizeRoleAccessOperation throws on missing payload fields', t => {
|
|
316
|
+
t.exception(
|
|
317
|
+
() => normalizeRoleAccessOperation({ type: OperationType.ADD_WRITER }, config),
|
|
318
|
+
errorMessageIncludes('Invalid payload for role access normalization.')
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
t.exception(
|
|
322
|
+
() => normalizeRoleAccessOperation({ type: OperationType.ADD_WRITER, address: 'x', rao: {} }, config),
|
|
323
|
+
errorMessageIncludes('Missing required fields in role access payload.')
|
|
324
|
+
);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
test('normalizeRoleAccessOperation throws on invalid hex string', t => {
|
|
328
|
+
const sender = randomAddress(config.addressPrefix);
|
|
329
|
+
const payload = {
|
|
330
|
+
type: OperationType.ADD_WRITER,
|
|
331
|
+
address: sender,
|
|
332
|
+
rao: {
|
|
333
|
+
tx: 'zz',
|
|
334
|
+
txv: hex('22', 32),
|
|
335
|
+
iw: hex('33', 32),
|
|
336
|
+
in: hex('44', 32),
|
|
337
|
+
is: hex('55', 64)
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
t.exception(
|
|
341
|
+
() => normalizeRoleAccessOperation(payload, config),
|
|
342
|
+
errorMessageIncludes('Invalid hex string')
|
|
343
|
+
);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
test('normalizeBootstrapDeploymentOperation normalizes hex strings and addresses', t => {
|
|
347
|
+
const sender = randomAddress(config.addressPrefix);
|
|
348
|
+
const payload = {
|
|
349
|
+
type: OperationType.BOOTSTRAP_DEPLOYMENT,
|
|
350
|
+
address: sender,
|
|
351
|
+
bdo: {
|
|
352
|
+
tx: hex('11', 32),
|
|
353
|
+
txv: hex('22', 32),
|
|
354
|
+
bs: hex('33', 32),
|
|
355
|
+
ic: hex('44', 32),
|
|
356
|
+
in: hex('55', 32),
|
|
357
|
+
is: hex('66', 64)
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const normalized = normalizeBootstrapDeploymentOperation(payload, config);
|
|
362
|
+
t.is(normalized.type, OperationType.BOOTSTRAP_DEPLOYMENT);
|
|
363
|
+
t.ok(b4a.equals(normalized.address, addressToBuffer(sender, config.addressPrefix)));
|
|
364
|
+
t.ok(b4a.equals(normalized.bdo.tx, toBuffer(hex('11', 32))));
|
|
365
|
+
t.ok(b4a.equals(normalized.bdo.txv, toBuffer(hex('22', 32))));
|
|
366
|
+
t.ok(b4a.equals(normalized.bdo.bs, toBuffer(hex('33', 32))));
|
|
367
|
+
t.ok(b4a.equals(normalized.bdo.ic, toBuffer(hex('44', 32))));
|
|
368
|
+
t.ok(b4a.equals(normalized.bdo.in, toBuffer(hex('55', 32))));
|
|
369
|
+
t.ok(b4a.equals(normalized.bdo.is, toBuffer(hex('66', 64))));
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
test('normalizeBootstrapDeploymentOperation accepts buffer inputs', t => {
|
|
373
|
+
const sender = randomAddress(config.addressPrefix);
|
|
374
|
+
const tx = toBuffer(hex('aa', 32));
|
|
375
|
+
const txv = toBuffer(hex('bb', 32));
|
|
376
|
+
const bootstrap = toBuffer(hex('cc', 32));
|
|
377
|
+
const channel = toBuffer(hex('dd', 32));
|
|
378
|
+
const nonce = toBuffer(hex('ee', 32));
|
|
379
|
+
const signature = toBuffer(hex('ff', 64));
|
|
380
|
+
|
|
381
|
+
const payload = {
|
|
382
|
+
type: OperationType.BOOTSTRAP_DEPLOYMENT,
|
|
383
|
+
address: sender,
|
|
384
|
+
bdo: {
|
|
385
|
+
tx,
|
|
386
|
+
txv,
|
|
387
|
+
bs: bootstrap,
|
|
388
|
+
ic: channel,
|
|
389
|
+
in: nonce,
|
|
390
|
+
is: signature
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
const normalized = normalizeBootstrapDeploymentOperation(payload, config);
|
|
395
|
+
t.ok(b4a.equals(normalized.bdo.tx, tx));
|
|
396
|
+
t.ok(b4a.equals(normalized.bdo.txv, txv));
|
|
397
|
+
t.ok(b4a.equals(normalized.bdo.bs, bootstrap));
|
|
398
|
+
t.ok(b4a.equals(normalized.bdo.ic, channel));
|
|
399
|
+
t.ok(b4a.equals(normalized.bdo.in, nonce));
|
|
400
|
+
t.ok(b4a.equals(normalized.bdo.is, signature));
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
test('normalizeBootstrapDeploymentOperation throws on missing payload fields', t => {
|
|
404
|
+
t.exception(
|
|
405
|
+
() => normalizeBootstrapDeploymentOperation({ type: OperationType.BOOTSTRAP_DEPLOYMENT }, config),
|
|
406
|
+
errorMessageIncludes('Invalid payload for bootstrap deployment normalization.')
|
|
407
|
+
);
|
|
408
|
+
|
|
409
|
+
t.exception(
|
|
410
|
+
() => normalizeBootstrapDeploymentOperation({ type: OperationType.TX, address: 'x', bdo: {} }, config),
|
|
411
|
+
errorMessageIncludes('Missing required fields in bootstrap deployment payload.')
|
|
412
|
+
);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
test('normalizeBootstrapDeploymentOperation throws on invalid hex string', t => {
|
|
416
|
+
const sender = randomAddress(config.addressPrefix);
|
|
417
|
+
const payload = {
|
|
418
|
+
type: OperationType.BOOTSTRAP_DEPLOYMENT,
|
|
419
|
+
address: sender,
|
|
420
|
+
bdo: {
|
|
421
|
+
tx: 'zz',
|
|
422
|
+
txv: hex('22', 32),
|
|
423
|
+
bs: hex('33', 32),
|
|
424
|
+
ic: hex('44', 32),
|
|
425
|
+
in: hex('55', 32),
|
|
426
|
+
is: hex('66', 64)
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
t.exception(
|
|
430
|
+
() => normalizeBootstrapDeploymentOperation(payload, config),
|
|
431
|
+
errorMessageIncludes('Invalid hex string')
|
|
432
|
+
);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
test('normalizeDecodedPayloadForJson converts buffers to strings', t => {
|
|
436
|
+
const address = randomAddress(config.addressPrefix);
|
|
437
|
+
const addressBuf = addressToBuffer(address, config.addressPrefix);
|
|
438
|
+
const amountBuf = bigIntTo16ByteBuffer(1234n);
|
|
439
|
+
const otherBuf = b4a.from('abcd', 'hex');
|
|
440
|
+
|
|
441
|
+
const payload = {
|
|
442
|
+
address: addressBuf,
|
|
443
|
+
am: amountBuf,
|
|
444
|
+
nested: {
|
|
445
|
+
to: addressBuf,
|
|
446
|
+
amount: amountBuf,
|
|
447
|
+
other: otherBuf
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
const normalized = normalizeDecodedPayloadForJson(payload, config);
|
|
452
|
+
t.is(normalized.address, address);
|
|
453
|
+
t.is(normalized.am, '1234');
|
|
454
|
+
t.is(normalized.nested.to, address);
|
|
455
|
+
t.is(normalized.nested.amount, '1234');
|
|
456
|
+
t.is(normalized.nested.other, 'abcd');
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
test('normalizeDecodedPayloadForJson falls back to hex for invalid address buffers', t => {
|
|
460
|
+
const bad = b4a.from('deadbeef', 'hex');
|
|
461
|
+
const payload = { address: bad };
|
|
462
|
+
const normalized = normalizeDecodedPayloadForJson(payload, config);
|
|
463
|
+
t.is(normalized.address, b4a.toString(bad, 'hex'));
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
test('normalizeDecodedPayloadForJson returns input for non-objects', t => {
|
|
467
|
+
t.is(normalizeDecodedPayloadForJson(null, config), null);
|
|
468
|
+
t.is(normalizeDecodedPayloadForJson('value', config), 'value');
|
|
469
|
+
});
|
|
@@ -2,12 +2,20 @@ import test from 'brittle';
|
|
|
2
2
|
import b4a from 'b4a';
|
|
3
3
|
|
|
4
4
|
import applyOperations from '../../../../src/utils/protobuf/applyOperations.cjs';
|
|
5
|
+
import {
|
|
6
|
+
decodeV1networkOperation,
|
|
7
|
+
encodeV1networkOperation,
|
|
8
|
+
normalizeIncomingMessage,
|
|
9
|
+
safeDecodeApplyOperation,
|
|
10
|
+
safeEncodeApplyOperation,
|
|
11
|
+
} from '../../../../src/utils/protobuf/operationHelpers.js';
|
|
5
12
|
import fixtures from '../../../fixtures/protobuf.fixtures.js';
|
|
13
|
+
import networkV1Fixtures from '../../../fixtures/networkV1.fixtures.js';
|
|
6
14
|
|
|
7
|
-
//TODO add missing operations tests and fill fixtures with them
|
|
8
15
|
test('Happy path encode/decode roundtrip for protobuf applyOperation payloads', t => {
|
|
9
16
|
const payloadsHashMap = new Map([
|
|
10
17
|
["txComplete", fixtures.validTransactionOperation],
|
|
18
|
+
["txPartial", fixtures.validPartialTransactionOperation],
|
|
11
19
|
["addIndexer", fixtures.validAddIndexer],
|
|
12
20
|
["removeIndexer", fixtures.validRemoveIndexer],
|
|
13
21
|
["appendWhitelist", fixtures.validAppendWhitelist],
|
|
@@ -19,8 +27,12 @@ test('Happy path encode/decode roundtrip for protobuf applyOperation payloads',
|
|
|
19
27
|
["removeWriterPartial", fixtures.validPartialRemoveWriter],
|
|
20
28
|
["adminRecoveryComplete", fixtures.validCompleteAdminRecovery],
|
|
21
29
|
["adminRecoveryPartial", fixtures.validPartialAdminRecovery],
|
|
30
|
+
["bootstrapDeploymentComplete", fixtures.validCompleteBootstrapDeployment],
|
|
31
|
+
["bootstrapDeploymentPartial", fixtures.validPartialBootstrapDeployment],
|
|
22
32
|
["transferComplete", fixtures.validTransferOperation],
|
|
23
|
-
["
|
|
33
|
+
["transferPartial", fixtures.validPartialTransferOperation],
|
|
34
|
+
["balanceInitialization", fixtures.validBalanceInitOperation],
|
|
35
|
+
["disableInitialization", fixtures.validDisableInitialization],
|
|
24
36
|
]);
|
|
25
37
|
|
|
26
38
|
for (const [key, value] of payloadsHashMap) {
|
|
@@ -101,6 +113,13 @@ test('Protobuf encode/decode is order-independent for all operation types', t =>
|
|
|
101
113
|
let decoded = applyOperations.Operation.decode(encoded);
|
|
102
114
|
t.ok(JSON.stringify(decoded) === JSON.stringify(fixtures.validTransactionOperation), 'TX operation encodes/decodes correctly with shuffled fields');
|
|
103
115
|
|
|
116
|
+
// Test TX operation (partial)
|
|
117
|
+
const shuffledPartialTxo = shuffleObject(fixtures.validPartialTransactionOperation.txo);
|
|
118
|
+
const shuffledPartialTx = { ...fixtures.validPartialTransactionOperation, txo: shuffledPartialTxo };
|
|
119
|
+
encoded = applyOperations.Operation.encode(shuffledPartialTx);
|
|
120
|
+
decoded = applyOperations.Operation.decode(encoded);
|
|
121
|
+
t.ok(JSON.stringify(decoded) === JSON.stringify(fixtures.validPartialTransactionOperation), 'Partial TX operation encodes/decodes correctly with shuffled fields');
|
|
122
|
+
|
|
104
123
|
// Test TRANSFER operation
|
|
105
124
|
const shuffledTro = shuffleObject(fixtures.validTransferOperation.tro);
|
|
106
125
|
const shuffledTransfer = { ...fixtures.validTransferOperation, tro: shuffledTro };
|
|
@@ -108,6 +127,13 @@ test('Protobuf encode/decode is order-independent for all operation types', t =>
|
|
|
108
127
|
decoded = applyOperations.Operation.decode(encoded);
|
|
109
128
|
t.ok(JSON.stringify(decoded) === JSON.stringify(fixtures.validTransferOperation), 'TRANSFER operation encodes/decodes correctly with shuffled fields');
|
|
110
129
|
|
|
130
|
+
// Test TRANSFER operation (partial)
|
|
131
|
+
const shuffledPartialTro = shuffleObject(fixtures.validPartialTransferOperation.tro);
|
|
132
|
+
const shuffledPartialTransfer = { ...fixtures.validPartialTransferOperation, tro: shuffledPartialTro };
|
|
133
|
+
encoded = applyOperations.Operation.encode(shuffledPartialTransfer);
|
|
134
|
+
decoded = applyOperations.Operation.decode(encoded);
|
|
135
|
+
t.ok(JSON.stringify(decoded) === JSON.stringify(fixtures.validPartialTransferOperation), 'Partial TRANSFER operation encodes/decodes correctly with shuffled fields');
|
|
136
|
+
|
|
111
137
|
// Test ADD_INDEXER operation
|
|
112
138
|
const shuffledAco = shuffleObject(fixtures.validAddIndexer.aco);
|
|
113
139
|
const shuffledAddIndexer = { ...fixtures.validAddIndexer, aco: shuffledAco };
|
|
@@ -184,4 +210,96 @@ test('Protobuf encode/decode is order-independent for all operation types', t =>
|
|
|
184
210
|
encoded = applyOperations.Operation.encode(shuffledPartialAdminRecovery);
|
|
185
211
|
decoded = applyOperations.Operation.decode(encoded);
|
|
186
212
|
t.ok(JSON.stringify(decoded) === JSON.stringify(fixtures.validPartialAdminRecovery), 'Partial ADMIN_RECOVERY operation encodes/decodes correctly with shuffled fields');
|
|
213
|
+
|
|
214
|
+
// Test BOOTSTRAP_DEPLOYMENT (complete) operation
|
|
215
|
+
const shuffledCompleteBootstrapBdo = shuffleObject(fixtures.validCompleteBootstrapDeployment.bdo);
|
|
216
|
+
const shuffledCompleteBootstrap = { ...fixtures.validCompleteBootstrapDeployment, bdo: shuffledCompleteBootstrapBdo };
|
|
217
|
+
encoded = applyOperations.Operation.encode(shuffledCompleteBootstrap);
|
|
218
|
+
decoded = applyOperations.Operation.decode(encoded);
|
|
219
|
+
t.ok(JSON.stringify(decoded) === JSON.stringify(fixtures.validCompleteBootstrapDeployment), 'Complete BOOTSTRAP_DEPLOYMENT operation encodes/decodes correctly with shuffled fields');
|
|
220
|
+
|
|
221
|
+
// Test BOOTSTRAP_DEPLOYMENT (partial) operation
|
|
222
|
+
const shuffledPartialBootstrapBdo = shuffleObject(fixtures.validPartialBootstrapDeployment.bdo);
|
|
223
|
+
const shuffledPartialBootstrap = { ...fixtures.validPartialBootstrapDeployment, bdo: shuffledPartialBootstrapBdo };
|
|
224
|
+
encoded = applyOperations.Operation.encode(shuffledPartialBootstrap);
|
|
225
|
+
decoded = applyOperations.Operation.decode(encoded);
|
|
226
|
+
t.ok(JSON.stringify(decoded) === JSON.stringify(fixtures.validPartialBootstrapDeployment), 'Partial BOOTSTRAP_DEPLOYMENT operation encodes/decodes correctly with shuffled fields');
|
|
227
|
+
|
|
228
|
+
// Test BALANCE_INITIALIZATION operation
|
|
229
|
+
const shuffledBio = shuffleObject(fixtures.validBalanceInitOperation.bio);
|
|
230
|
+
const shuffledBalanceInit = { ...fixtures.validBalanceInitOperation, bio: shuffledBio };
|
|
231
|
+
encoded = applyOperations.Operation.encode(shuffledBalanceInit);
|
|
232
|
+
decoded = applyOperations.Operation.decode(encoded);
|
|
233
|
+
t.ok(JSON.stringify(decoded) === JSON.stringify(fixtures.validBalanceInitOperation), 'BALANCE_INITIALIZATION operation encodes/decodes correctly with shuffled fields');
|
|
234
|
+
|
|
235
|
+
// Test DISABLE_INITIALIZATION operation
|
|
236
|
+
const shuffledDisableCao = shuffleObject(fixtures.validDisableInitialization.cao);
|
|
237
|
+
const shuffledDisableInitialization = { ...fixtures.validDisableInitialization, cao: shuffledDisableCao };
|
|
238
|
+
encoded = applyOperations.Operation.encode(shuffledDisableInitialization);
|
|
239
|
+
decoded = applyOperations.Operation.decode(encoded);
|
|
240
|
+
t.ok(JSON.stringify(decoded) === JSON.stringify(fixtures.validDisableInitialization), 'DISABLE_INITIALIZATION operation encodes/decodes correctly with shuffled fields');
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
test('encodeV1networkOperation/decodeV1networkOperation roundtrip for network v1 payloads', t => {
|
|
244
|
+
const payloadsHashMap = new Map([
|
|
245
|
+
['validatorConnectionRequest', networkV1Fixtures.payloadValidatorConnectionRequest],
|
|
246
|
+
['validatorConnectionResponse', networkV1Fixtures.payloadValidatorConnectionResponse],
|
|
247
|
+
['livenessRequest', networkV1Fixtures.payloadLivenessRequest],
|
|
248
|
+
['livenessResponse', networkV1Fixtures.payloadLivenessResponse],
|
|
249
|
+
['broadcastTransactionRequest', networkV1Fixtures.payloadBroadcastTransactionRequest],
|
|
250
|
+
['broadcastTransactionResponse', networkV1Fixtures.payloadBroadcastTransactionResponse],
|
|
251
|
+
]);
|
|
252
|
+
|
|
253
|
+
for (const [key, payload] of payloadsHashMap) {
|
|
254
|
+
const encoded = encodeV1networkOperation(payload);
|
|
255
|
+
const decoded = decodeV1networkOperation(encoded);
|
|
256
|
+
t.ok(b4a.isBuffer(encoded) && encoded.length > 0, `Payload ${key} encodes to a non-empty buffer`);
|
|
257
|
+
t.ok(JSON.stringify(decoded) === JSON.stringify(payload), `Payload ${key} decodes back correctly`);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test('safeEncodeApplyOperation returns an empty buffer on encode errors (and does not throw)', t => {
|
|
262
|
+
const originalLog = console.log;
|
|
263
|
+
console.log = () => {};
|
|
264
|
+
try {
|
|
265
|
+
const encoded = safeEncodeApplyOperation(fixtures.invalidPayloadWithMultipleOneOfKeys);
|
|
266
|
+
t.ok(b4a.isBuffer(encoded));
|
|
267
|
+
t.is(encoded.length, 0);
|
|
268
|
+
} finally {
|
|
269
|
+
console.log = originalLog;
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test('safeEncodeApplyOperation encodes valid payloads to a non-empty buffer', t => {
|
|
274
|
+
const encoded = safeEncodeApplyOperation(fixtures.validTransactionOperation);
|
|
275
|
+
t.ok(b4a.isBuffer(encoded));
|
|
276
|
+
t.ok(encoded.length > 0);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
test('safeDecodeApplyOperation returns null for invalid input (and does not throw)', t => {
|
|
280
|
+
t.is(safeDecodeApplyOperation(null), null);
|
|
281
|
+
t.is(safeDecodeApplyOperation({}), null);
|
|
282
|
+
t.is(safeDecodeApplyOperation('not-a-buffer'), null);
|
|
283
|
+
|
|
284
|
+
const originalLog = console.log;
|
|
285
|
+
console.log = () => {};
|
|
286
|
+
try {
|
|
287
|
+
t.is(safeDecodeApplyOperation(b4a.from([0x0F])), null);
|
|
288
|
+
} finally {
|
|
289
|
+
console.log = originalLog;
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
test('normalizeIncomingMessage decodes buffers and JSON buffers', t => {
|
|
294
|
+
const payload = fixtures.validTransactionOperation;
|
|
295
|
+
const encoded = applyOperations.Operation.encode(payload);
|
|
296
|
+
|
|
297
|
+
const decodedFromBuffer = normalizeIncomingMessage(encoded);
|
|
298
|
+
t.ok(JSON.stringify(decodedFromBuffer) === JSON.stringify(payload));
|
|
299
|
+
|
|
300
|
+
const decodedFromJsonBuffer = normalizeIncomingMessage({ type: 'Buffer', data: Array.from(encoded) });
|
|
301
|
+
t.ok(JSON.stringify(decodedFromJsonBuffer) === JSON.stringify(payload));
|
|
302
|
+
|
|
303
|
+
t.is(normalizeIncomingMessage(null), null);
|
|
304
|
+
t.is(normalizeIncomingMessage({ type: 'nope', data: [] }), null);
|
|
187
305
|
});
|
|
@@ -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
|
|
package/rpc/rpc_server.mjs
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { createServer } from "./create_server.mjs";
|
|
2
|
-
|
|
3
|
-
// Called by msb.mjs file
|
|
4
|
-
export function startRpcServer(msbInstance, host, port) {
|
|
5
|
-
const server = createServer(msbInstance)
|
|
6
|
-
|
|
7
|
-
return server.listen(port, host, () => {
|
|
8
|
-
console.log(`Running RPC with http at http://${host}:${port}`);
|
|
9
|
-
});
|
|
10
|
-
}
|