trac-msb 0.2.13 → 0.2.15
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/acceptance-tests.yml +38 -0
- package/.github/workflows/lint-pr-title.yml +26 -0
- package/.github/workflows/publish.yml +33 -0
- package/.github/workflows/unit-tests.yml +34 -0
- package/package.json +7 -12
- package/proto/network.proto +74 -0
- package/rpc/rpc_services.js +4 -22
- package/scripts/generate-protobufs.js +12 -37
- package/src/config/config.js +9 -26
- package/src/config/env.js +17 -27
- package/src/core/network/Network.js +36 -73
- package/src/core/network/protocols/LegacyProtocol.js +11 -21
- package/src/core/network/protocols/NetworkMessages.js +17 -38
- package/src/core/network/protocols/ProtocolInterface.js +2 -14
- package/src/core/network/protocols/ProtocolSession.js +17 -144
- package/src/core/network/protocols/V1Protocol.js +18 -37
- package/src/core/network/protocols/legacy/NetworkMessageRouter.js +19 -25
- package/src/core/network/protocols/legacy/handlers/{LegacyGetRequestHandler.js → GetRequestHandler.js} +6 -6
- package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
- package/src/core/network/protocols/{legacy/handlers/LegacyRoleOperationHandler.js → shared/handlers/RoleOperationHandler.js} +11 -18
- package/src/core/network/protocols/{legacy/handlers/LegacySubnetworkOperationHandler.js → shared/handlers/SubnetworkOperationHandler.js} +17 -28
- package/src/core/network/protocols/{legacy/handlers/LegacyTransferOperationHandler.js → shared/handlers/TransferOperationHandler.js} +11 -17
- package/src/core/network/protocols/{legacy/handlers/BaseStateOperationHandler.js → shared/handlers/base/BaseOperationHandler.js} +12 -23
- package/src/core/network/protocols/shared/validators/{PartialBootstrapDeploymentValidator.js → PartialBootstrapDeployment.js} +4 -9
- package/src/core/network/protocols/shared/validators/{PartialRoleAccessValidator.js → PartialRoleAccess.js} +17 -51
- package/src/core/network/protocols/shared/validators/{PartialTransactionValidator.js → PartialTransaction.js} +7 -21
- package/src/core/network/protocols/shared/validators/{PartialTransferValidator.js → PartialTransfer.js} +9 -26
- package/src/core/network/protocols/shared/validators/{PartialOperationValidator.js → base/PartialOperation.js} +25 -47
- package/src/core/network/protocols/v1/NetworkMessageRouter.js +7 -91
- package/src/core/network/services/ConnectionManager.js +94 -146
- package/src/core/network/services/MessageOrchestrator.js +27 -151
- package/src/core/network/services/TransactionPoolService.js +18 -129
- package/src/core/network/services/TransactionRateLimiterService.js +34 -52
- package/src/core/network/services/ValidatorObserverService.js +26 -18
- package/src/core/state/State.js +19 -70
- package/src/index.js +8 -6
- package/src/messages/network/v1/NetworkMessageBuilder.js +79 -59
- package/src/messages/network/v1/NetworkMessageDirector.js +50 -16
- package/src/utils/Scheduler.js +8 -0
- package/src/utils/constants.js +5 -71
- package/src/utils/helpers.js +1 -10
- package/src/utils/normalizers.js +0 -38
- package/src/utils/protobuf/network.cjs +840 -0
- package/src/utils/protobuf/operationHelpers.js +3 -24
- package/tests/acceptance/v1/account/account.test.mjs +2 -8
- package/tests/acceptance/v1/tx/tx.test.mjs +1 -23
- package/tests/acceptance/v1/tx-details/tx-details.test.mjs +6 -34
- package/tests/fixtures/assembleMessage.fixtures.js +8 -7
- package/tests/fixtures/networkV1.fixtures.js +28 -2
- package/tests/helpers/autobaseTestHelpers.js +5 -2
- package/tests/helpers/createTestSignature.js +3 -2
- package/tests/helpers/transactionPayloads.mjs +2 -2
- package/tests/unit/messages/network/NetworkMessageBuilder.test.js +79 -239
- package/tests/unit/messages/network/NetworkMessageDirector.test.js +77 -223
- package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +5 -1
- package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +5 -1
- package/tests/unit/network/ConnectionManager.test.js +191 -0
- package/tests/unit/network/networkModule.test.js +1 -4
- package/tests/unit/unit.test.js +2 -2
- package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +2 -2
- package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +2 -2
- package/tests/unit/utils/protobuf/operationHelpers.test.js +4 -2
- package/tests/unit/utils/utils.test.js +0 -1
- package/proto/network/v1/enums/message_type.proto +0 -16
- package/proto/network/v1/enums/result_code.proto +0 -84
- package/proto/network/v1/messages/broadcast_transaction_request.proto +0 -9
- package/proto/network/v1/messages/broadcast_transaction_response.proto +0 -13
- package/proto/network/v1/messages/liveness_request.proto +0 -8
- package/proto/network/v1/messages/liveness_response.proto +0 -11
- package/proto/network/v1/network_message.proto +0 -22
- package/src/core/network/protocols/connectionPolicies.js +0 -88
- package/src/core/network/protocols/legacy/handlers/LegacyResponseHandler.js +0 -23
- package/src/core/network/protocols/shared/errors/SharedValidatorRejectionError.js +0 -27
- package/src/core/network/protocols/v1/V1ProtocolError.js +0 -91
- package/src/core/network/protocols/v1/handlers/V1BaseOperationHandler.js +0 -65
- package/src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js +0 -389
- package/src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js +0 -87
- package/src/core/network/protocols/v1/validators/V1BaseOperation.js +0 -211
- package/src/core/network/protocols/v1/validators/V1BroadcastTransactionRequest.js +0 -26
- package/src/core/network/protocols/v1/validators/V1BroadcastTransactionResponse.js +0 -276
- package/src/core/network/protocols/v1/validators/V1LivenessRequest.js +0 -15
- package/src/core/network/protocols/v1/validators/V1LivenessResponse.js +0 -17
- package/src/core/network/protocols/v1/validators/V1ValidationSchema.js +0 -210
- package/src/core/network/services/PendingRequestService.js +0 -172
- package/src/core/network/services/TransactionCommitService.js +0 -149
- package/src/core/network/services/ValidatorHealthCheckService.js +0 -127
- package/src/utils/deepEqualApplyPayload.js +0 -40
- package/src/utils/logger.js +0 -25
- package/src/utils/protobuf/networkV1.generated.cjs +0 -2460
- package/tests/unit/network/LegacyNetworkMessageRouter.test.js +0 -54
- package/tests/unit/network/ProtocolSession.test.js +0 -127
- package/tests/unit/network/services/ConnectionManager.test.js +0 -450
- package/tests/unit/network/services/MessageOrchestrator.test.js +0 -445
- package/tests/unit/network/services/PendingRequestService.test.js +0 -431
- package/tests/unit/network/services/TransactionCommitService.test.js +0 -246
- package/tests/unit/network/services/TransactionPoolService.test.js +0 -489
- package/tests/unit/network/services/TransactionRateLimiterService.test.js +0 -139
- package/tests/unit/network/services/ValidatorHealthCheckService.test.js +0 -115
- package/tests/unit/network/services/services.test.js +0 -17
- package/tests/unit/network/utils/v1TestUtils.js +0 -153
- package/tests/unit/network/v1/NetworkMessageRouterV1.test.js +0 -151
- package/tests/unit/network/v1/V1BaseOperation.test.js +0 -356
- package/tests/unit/network/v1/V1BroadcastTransactionOperationHandler.test.js +0 -129
- package/tests/unit/network/v1/V1BroadcastTransactionRequest.test.js +0 -53
- package/tests/unit/network/v1/V1BroadcastTransactionResponse.test.js +0 -512
- package/tests/unit/network/v1/V1LivenessRequest.test.js +0 -32
- package/tests/unit/network/v1/V1LivenessResponse.test.js +0 -45
- package/tests/unit/network/v1/V1ResultCode.test.js +0 -84
- package/tests/unit/network/v1/V1ValidationSchema.test.js +0 -13
- package/tests/unit/network/v1/connectionPolicies.test.js +0 -49
- package/tests/unit/network/v1/handlers/V1BaseOperationHandler.test.js +0 -284
- package/tests/unit/network/v1/handlers/V1BroadcastTransactionOperationHandler.test.js +0 -794
- package/tests/unit/network/v1/handlers/V1LivenessOperationHandler.test.js +0 -193
- package/tests/unit/network/v1/v1.handlers.test.js +0 -15
- package/tests/unit/network/v1/v1.test.js +0 -19
- package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionRequest.test.js +0 -119
- package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionResponse.test.js +0 -136
- package/tests/unit/network/v1/v1ValidationSchema/common.test.js +0 -308
- package/tests/unit/network/v1/v1ValidationSchema/livenessRequest.test.js +0 -90
- package/tests/unit/network/v1/v1ValidationSchema/livenessResponse.test.js +0 -133
- package/tests/unit/utils/deepEqualApplyPayload/deepEqualApplyPayload.test.js +0 -102
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import sinon from 'sinon';
|
|
2
|
-
import { test } from 'brittle';
|
|
3
|
-
import ValidatorHealthCheckService from '../../../../src/core/network/services/ValidatorHealthCheckService.js';
|
|
4
|
-
import { createConfig, ENV } from '../../../../src/config/env.js';
|
|
5
|
-
import { EventType } from '../../../../src/utils/constants.js';
|
|
6
|
-
import { testKeyPair1, testKeyPair2 } from '../../../fixtures/apply.fixtures.js';
|
|
7
|
-
|
|
8
|
-
test('ValidatorHealthCheckService', () => {
|
|
9
|
-
test('throws when start is called before ready', async (t) => {
|
|
10
|
-
const config = createConfig(ENV.MAINNET, { validatorHealthCheckInterval: 1000 });
|
|
11
|
-
const service = new ValidatorHealthCheckService(config);
|
|
12
|
-
|
|
13
|
-
await t.exception(() => service.start(testKeyPair1.publicKey));
|
|
14
|
-
await service.close();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
test('constructor rejects invalid interval', async (t) => {
|
|
18
|
-
const badConfig = createConfig(ENV.MAINNET, { validatorHealthCheckInterval: -1 });
|
|
19
|
-
|
|
20
|
-
await t.exception.all(() => new ValidatorHealthCheckService(badConfig));
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test('constructor defaults interval when missing', async (t) => {
|
|
24
|
-
const config = createConfig(ENV.MAINNET, {});
|
|
25
|
-
const service = new ValidatorHealthCheckService(config);
|
|
26
|
-
await service.ready();
|
|
27
|
-
|
|
28
|
-
t.is(service.start(testKeyPair1.publicKey), true);
|
|
29
|
-
t.is(service.start(testKeyPair1.publicKey), false);
|
|
30
|
-
await service.close();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test('stop returns false when no schedule exists', async (t) => {
|
|
34
|
-
const config = createConfig(ENV.MAINNET, { validatorHealthCheckInterval: 1000 });
|
|
35
|
-
const service = new ValidatorHealthCheckService(config);
|
|
36
|
-
await service.ready();
|
|
37
|
-
|
|
38
|
-
t.is(service.stop(testKeyPair1.publicKey), false);
|
|
39
|
-
await service.close();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('has throws on invalid public key type', async (t) => {
|
|
43
|
-
const config = createConfig(ENV.MAINNET, { validatorHealthCheckInterval: 1000 });
|
|
44
|
-
const service = new ValidatorHealthCheckService(config);
|
|
45
|
-
await service.ready();
|
|
46
|
-
|
|
47
|
-
await t.exception.all(() => service.has(123));
|
|
48
|
-
await service.close();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test('start returns false when already scheduled', async (t) => {
|
|
52
|
-
const config = createConfig(ENV.MAINNET, { validatorHealthCheckInterval: 1000 });
|
|
53
|
-
const service = new ValidatorHealthCheckService(config);
|
|
54
|
-
await service.ready();
|
|
55
|
-
|
|
56
|
-
t.ok(service.start(testKeyPair1.publicKey));
|
|
57
|
-
t.is(service.start(testKeyPair1.publicKey), false);
|
|
58
|
-
await service.close();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test('emits health check on interval', async (t) => {
|
|
62
|
-
const clock = sinon.useFakeTimers({ now: 0 });
|
|
63
|
-
try {
|
|
64
|
-
const config = createConfig(ENV.MAINNET, { validatorHealthCheckInterval: 1000 });
|
|
65
|
-
const service = new ValidatorHealthCheckService(config);
|
|
66
|
-
await service.ready();
|
|
67
|
-
|
|
68
|
-
const emitted = new Promise(resolve => {
|
|
69
|
-
service.once(EventType.VALIDATOR_HEALTH_CHECK, (publicKey, requestId) => {
|
|
70
|
-
resolve({ publicKey, requestId });
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
t.ok(service.start(testKeyPair1.publicKey));
|
|
74
|
-
|
|
75
|
-
await clock.tickAsync(1000);
|
|
76
|
-
const { publicKey, requestId } = await emitted;
|
|
77
|
-
t.is(publicKey, testKeyPair1.publicKey.toLowerCase());
|
|
78
|
-
t.ok(requestId);
|
|
79
|
-
await service.close();
|
|
80
|
-
} finally {
|
|
81
|
-
clock.restore();
|
|
82
|
-
sinon.restore();
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test('stopAll cancels scheduled checks', async (t) => {
|
|
87
|
-
const clock = sinon.useFakeTimers({ now: 0 });
|
|
88
|
-
try {
|
|
89
|
-
const config = createConfig(ENV.MAINNET, { validatorHealthCheckInterval: 1000 });
|
|
90
|
-
const service = new ValidatorHealthCheckService(config);
|
|
91
|
-
await service.ready();
|
|
92
|
-
const emitted = [];
|
|
93
|
-
const waitForTwo = new Promise(resolve => {
|
|
94
|
-
service.on(EventType.VALIDATOR_HEALTH_CHECK, (publicKey, requestId) => {
|
|
95
|
-
emitted.push({ publicKey, requestId });
|
|
96
|
-
if (emitted.length === 2) resolve();
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
t.ok(service.start(testKeyPair1.publicKey));
|
|
100
|
-
t.ok(service.start(testKeyPair2.publicKey));
|
|
101
|
-
|
|
102
|
-
await clock.tickAsync(1000);
|
|
103
|
-
await waitForTwo;
|
|
104
|
-
t.is(emitted.length, 2);
|
|
105
|
-
|
|
106
|
-
await service.close();
|
|
107
|
-
|
|
108
|
-
await clock.tickAsync(1000);
|
|
109
|
-
t.is(emitted.length, 2);
|
|
110
|
-
} finally {
|
|
111
|
-
clock.restore();
|
|
112
|
-
sinon.restore();
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// This runner is auto-generated by Brittle
|
|
2
|
-
|
|
3
|
-
import { default as test } from 'brittle';
|
|
4
|
-
|
|
5
|
-
async function runTests() {
|
|
6
|
-
test.pause();
|
|
7
|
-
await import('./ValidatorHealthCheckService.test.js');
|
|
8
|
-
await import('./TransactionRateLimiterService.test.js');
|
|
9
|
-
await import('./ConnectionManager.test.js');
|
|
10
|
-
await import('./MessageOrchestrator.test.js');
|
|
11
|
-
await import('./PendingRequestService.test.js');
|
|
12
|
-
await import('./TransactionCommitService.test.js');
|
|
13
|
-
await import('./TransactionPoolService.test.js');
|
|
14
|
-
test.resume();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
await runTests();
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import b4a from 'b4a';
|
|
2
|
-
import sinon from 'sinon';
|
|
3
|
-
import { config } from '../../../helpers/config.js';
|
|
4
|
-
import { NetworkOperationType, V1_PROTOCOL_PAYLOAD_MAX_SIZE } from '../../../../src/utils/constants.js';
|
|
5
|
-
import { encodeV1networkOperation } from '../../../../src/utils/protobuf/operationHelpers.js';
|
|
6
|
-
import NetworkMessageRouterV1 from '../../../../src/core/network/protocols/v1/NetworkMessageRouter.js';
|
|
7
|
-
import V1LivenessOperationHandler from '../../../../src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js';
|
|
8
|
-
import V1BroadcastTransactionOperationHandler from '../../../../src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js';
|
|
9
|
-
|
|
10
|
-
const resolveStub = (stubSource) => {
|
|
11
|
-
if (typeof stubSource === 'function') {
|
|
12
|
-
return stubSource;
|
|
13
|
-
}
|
|
14
|
-
if (stubSource && typeof stubSource.stub === 'function') {
|
|
15
|
-
return stubSource.stub.bind(stubSource);
|
|
16
|
-
}
|
|
17
|
-
throw new Error('Stub source must provide a stub function');
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const makeConnection = (stubSource) => {
|
|
21
|
-
const stub = resolveStub(stubSource);
|
|
22
|
-
return {
|
|
23
|
-
remotePublicKey: b4a.alloc(32, 0x01),
|
|
24
|
-
protocolSession: {
|
|
25
|
-
setV1AsPreferredProtocol: stub()
|
|
26
|
-
},
|
|
27
|
-
end: stub()
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const makeHandlers = (sandbox) => ({
|
|
32
|
-
livenessRequest: sandbox.stub(V1LivenessOperationHandler.prototype, 'handleRequest').resolves(),
|
|
33
|
-
livenessResponse: sandbox.stub(V1LivenessOperationHandler.prototype, 'handleResponse').resolves(),
|
|
34
|
-
broadcastRequest: sandbox.stub(V1BroadcastTransactionOperationHandler.prototype, 'handleRequest').resolves(),
|
|
35
|
-
broadcastResponse: sandbox.stub(V1BroadcastTransactionOperationHandler.prototype, 'handleResponse').resolves()
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
export const makeRouter = (t, { walletAddress = 'test-wallet' } = {}) => {
|
|
39
|
-
const sandbox = sinon.createSandbox();
|
|
40
|
-
if (t && typeof t.teardown === 'function') {
|
|
41
|
-
t.teardown(() => sandbox.restore());
|
|
42
|
-
}
|
|
43
|
-
sandbox.stub(console, 'error');
|
|
44
|
-
|
|
45
|
-
const handlerStubs = makeHandlers(sandbox);
|
|
46
|
-
const router = new NetworkMessageRouterV1(
|
|
47
|
-
{},
|
|
48
|
-
{ address: walletAddress },
|
|
49
|
-
{},
|
|
50
|
-
{},
|
|
51
|
-
{},
|
|
52
|
-
{},
|
|
53
|
-
config
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
return { router, handlerStubs, sandbox };
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export const makeRouterContext = (t, options) => {
|
|
60
|
-
const { router, handlerStubs, sandbox } = makeRouter(t, options);
|
|
61
|
-
const connection = makeConnection(sandbox);
|
|
62
|
-
return { router, handlerStubs, sandbox, connection };
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const buildMessage = (type, extra = {}) => encodeV1networkOperation({
|
|
66
|
-
type,
|
|
67
|
-
id: '1',
|
|
68
|
-
...extra
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
export const buildEmptyMessage = () => b4a.alloc(0);
|
|
72
|
-
|
|
73
|
-
export const buildOversizedMessage = () => b4a.alloc(V1_PROTOCOL_PAYLOAD_MAX_SIZE + 1, 0x01);
|
|
74
|
-
|
|
75
|
-
export const buildMalformedMessage = () => b4a.from([0x07]);
|
|
76
|
-
|
|
77
|
-
export const buildMaxSizeMessage = () => {
|
|
78
|
-
const basePayload = {
|
|
79
|
-
type: NetworkOperationType.LIVENESS_REQUEST,
|
|
80
|
-
id: '1',
|
|
81
|
-
capabilities: ['']
|
|
82
|
-
};
|
|
83
|
-
const baseLength = encodeV1networkOperation(basePayload).length;
|
|
84
|
-
let fillerLength = Math.max(0, V1_PROTOCOL_PAYLOAD_MAX_SIZE - baseLength - 1);
|
|
85
|
-
let buffer = encodeV1networkOperation({
|
|
86
|
-
...basePayload,
|
|
87
|
-
capabilities: ['a'.repeat(fillerLength)]
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
if (buffer.length !== V1_PROTOCOL_PAYLOAD_MAX_SIZE) {
|
|
91
|
-
const delta = V1_PROTOCOL_PAYLOAD_MAX_SIZE - buffer.length;
|
|
92
|
-
fillerLength = Math.max(0, fillerLength + delta);
|
|
93
|
-
buffer = encodeV1networkOperation({
|
|
94
|
-
...basePayload,
|
|
95
|
-
capabilities: ['a'.repeat(fillerLength)]
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (buffer.length !== V1_PROTOCOL_PAYLOAD_MAX_SIZE) {
|
|
100
|
-
throw new Error(
|
|
101
|
-
`Failed to build payload of size ${V1_PROTOCOL_PAYLOAD_MAX_SIZE}, got ${buffer.length}`
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return buffer;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export const getUnsupportedType = () => {
|
|
109
|
-
const values = Object.values(NetworkOperationType).map(Number);
|
|
110
|
-
return Math.max(...values) + 1;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
export const assertDisconnected = (t, connection, message = 'should end connection') => {
|
|
114
|
-
t.ok(connection.end.calledOnce, message);
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export const assertPreferredSet = (t, connection, message = 'should set preferred protocol') => {
|
|
118
|
-
t.ok(connection.protocolSession.setV1AsPreferredProtocol.calledOnce, message);
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
export const assertPreferredNotSet = (t, connection, message = 'should not set preferred protocol') => {
|
|
122
|
-
t.ok(connection.protocolSession.setV1AsPreferredProtocol.notCalled, message);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
export const assertNoHandlersCalled = (t, handlerStubs) => {
|
|
126
|
-
for (const [key, stub] of Object.entries(handlerStubs)) {
|
|
127
|
-
t.ok(stub.notCalled, `${key} not called`);
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
export const assertOnlyHandlerCalled = (t, handlerStubs, expectedKey) => {
|
|
132
|
-
for (const [key, stub] of Object.entries(handlerStubs)) {
|
|
133
|
-
if (key === expectedKey) {
|
|
134
|
-
t.ok(stub.calledOnce, `${key} called`);
|
|
135
|
-
} else {
|
|
136
|
-
t.ok(stub.notCalled, `${key} not called`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
export const assertRejected = (
|
|
142
|
-
t,
|
|
143
|
-
{ connection, handlerStubs, preferred = 'not', disconnectMessage } = {}
|
|
144
|
-
) => {
|
|
145
|
-
if (preferred === 'set') {
|
|
146
|
-
assertPreferredSet(t, connection);
|
|
147
|
-
} else {
|
|
148
|
-
assertPreferredNotSet(t, connection);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
assertDisconnected(t, connection, disconnectMessage);
|
|
152
|
-
assertNoHandlersCalled(t, handlerStubs);
|
|
153
|
-
};
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { test } from 'brittle';
|
|
2
|
-
import { NetworkOperationType } from '../../../../src/utils/constants.js';
|
|
3
|
-
import {
|
|
4
|
-
assertDisconnected,
|
|
5
|
-
assertOnlyHandlerCalled,
|
|
6
|
-
assertPreferredSet,
|
|
7
|
-
assertRejected,
|
|
8
|
-
buildEmptyMessage,
|
|
9
|
-
buildMalformedMessage,
|
|
10
|
-
buildMaxSizeMessage,
|
|
11
|
-
buildMessage,
|
|
12
|
-
buildOversizedMessage,
|
|
13
|
-
getUnsupportedType,
|
|
14
|
-
makeRouterContext
|
|
15
|
-
} from '../utils/v1TestUtils.js';
|
|
16
|
-
|
|
17
|
-
const SUPPORTED_OPERATION_CASES = [
|
|
18
|
-
{
|
|
19
|
-
name: 'LIVENESS_REQUEST -> liveness.handleRequest',
|
|
20
|
-
type: NetworkOperationType.LIVENESS_REQUEST,
|
|
21
|
-
handlerKey: 'livenessRequest'
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: 'LIVENESS_RESPONSE -> liveness.handleResponse',
|
|
25
|
-
type: NetworkOperationType.LIVENESS_RESPONSE,
|
|
26
|
-
handlerKey: 'livenessResponse'
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
name: 'BROADCAST_TRANSACTION_REQUEST -> broadcast.handleRequest',
|
|
30
|
-
type: NetworkOperationType.BROADCAST_TRANSACTION_REQUEST,
|
|
31
|
-
handlerKey: 'broadcastRequest'
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
name: 'BROADCAST_TRANSACTION_RESPONSE -> broadcast.handleResponse',
|
|
35
|
-
type: NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE,
|
|
36
|
-
handlerKey: 'broadcastResponse'
|
|
37
|
-
}
|
|
38
|
-
];
|
|
39
|
-
|
|
40
|
-
const runRejectionCase = async (t, message, { preferred = 'not' } = {}) => {
|
|
41
|
-
const { router, handlerStubs, connection } = makeRouterContext(t);
|
|
42
|
-
await router.route(message, connection);
|
|
43
|
-
assertRejected(t, { connection, handlerStubs, preferred });
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
test('NetworkMessageRouterV1', async (t) => {
|
|
47
|
-
await t.test('pre-validation', async (t) => {
|
|
48
|
-
const cases = [
|
|
49
|
-
{ name: 'rejects null message', message: null },
|
|
50
|
-
{ name: 'rejects non-buffer message', message: 'not-a-buffer' },
|
|
51
|
-
{ name: 'rejects empty buffer', message: buildEmptyMessage() },
|
|
52
|
-
{ name: 'rejects oversized buffer', message: buildOversizedMessage() }
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
for (const { name, message } of cases) {
|
|
56
|
-
await t.test(name, async (t) => {
|
|
57
|
-
await runRejectionCase(t, message);
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
await t.test('accepts max size payload', async (t) => {
|
|
62
|
-
const { router, handlerStubs, connection } = makeRouterContext(t);
|
|
63
|
-
const maxSizePayload = buildMaxSizeMessage();
|
|
64
|
-
|
|
65
|
-
await router.route(maxSizePayload, connection);
|
|
66
|
-
|
|
67
|
-
assertPreferredSet(t, connection);
|
|
68
|
-
t.ok(connection.end.notCalled, 'should not end connection');
|
|
69
|
-
t.ok(handlerStubs.livenessRequest.calledOnce, 'liveness handler called');
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
await t.test('decode failures', async (t) => {
|
|
74
|
-
await t.test('disconnects on decode error', async (t) => {
|
|
75
|
-
await runRejectionCase(t, buildMalformedMessage());
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
await t.test('type validation', async (t) => {
|
|
80
|
-
const invalidTypeCases = [
|
|
81
|
-
{ name: 'rejects type 0', message: buildMessage(0) },
|
|
82
|
-
{
|
|
83
|
-
name: 'rejects missing type (defaults to 0)',
|
|
84
|
-
message: buildMessage(NetworkOperationType.LIVENESS_REQUEST, { type: undefined })
|
|
85
|
-
}
|
|
86
|
-
];
|
|
87
|
-
|
|
88
|
-
for (const { name, message } of invalidTypeCases) {
|
|
89
|
-
await t.test(name, async (t) => {
|
|
90
|
-
await runRejectionCase(t, message);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
await t.test('unsupported type disconnects after setting preferred protocol', async (t) => {
|
|
95
|
-
await runRejectionCase(t, buildMessage(getUnsupportedType()), { preferred: 'set' });
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
await t.test('routing', async (t) => {
|
|
100
|
-
for (const { name, type, handlerKey } of SUPPORTED_OPERATION_CASES) {
|
|
101
|
-
await t.test(name, async (t) => {
|
|
102
|
-
const { router, handlerStubs, connection } = makeRouterContext(t);
|
|
103
|
-
|
|
104
|
-
await router.route(buildMessage(type), connection);
|
|
105
|
-
|
|
106
|
-
assertPreferredSet(t, connection);
|
|
107
|
-
t.ok(connection.end.notCalled, 'should not end connection');
|
|
108
|
-
assertOnlyHandlerCalled(t, handlerStubs, handlerKey);
|
|
109
|
-
|
|
110
|
-
const handler = handlerStubs[handlerKey];
|
|
111
|
-
t.is(handler.firstCall.args[0].type, type, 'passes decoded message');
|
|
112
|
-
t.is(handler.firstCall.args[1], connection, 'passes connection');
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const handlerErrorCases = [
|
|
117
|
-
{
|
|
118
|
-
name: 'liveness handler throws',
|
|
119
|
-
type: NetworkOperationType.LIVENESS_REQUEST,
|
|
120
|
-
handlerKey: 'livenessRequest',
|
|
121
|
-
error: new Error('handler-fail')
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
name: 'broadcast request handler throws',
|
|
125
|
-
type: NetworkOperationType.BROADCAST_TRANSACTION_REQUEST,
|
|
126
|
-
handlerKey: 'broadcastRequest',
|
|
127
|
-
error: new Error('broadcast-request-fail')
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'broadcast response handler throws',
|
|
131
|
-
type: NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE,
|
|
132
|
-
handlerKey: 'broadcastResponse',
|
|
133
|
-
error: new Error('broadcast-response-fail')
|
|
134
|
-
}
|
|
135
|
-
];
|
|
136
|
-
|
|
137
|
-
for (const { name, type, handlerKey, error } of handlerErrorCases) {
|
|
138
|
-
await t.test(name, async (t) => {
|
|
139
|
-
const { router, handlerStubs, connection } = makeRouterContext(t);
|
|
140
|
-
|
|
141
|
-
handlerStubs[handlerKey].rejects(error);
|
|
142
|
-
|
|
143
|
-
await router.route(buildMessage(type), connection);
|
|
144
|
-
|
|
145
|
-
assertPreferredSet(t, connection);
|
|
146
|
-
t.ok(handlerStubs[handlerKey].calledOnce, 'handler called');
|
|
147
|
-
assertDisconnected(t, connection);
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
});
|