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.
Files changed (121) hide show
  1. package/.github/workflows/acceptance-tests.yml +38 -0
  2. package/.github/workflows/lint-pr-title.yml +26 -0
  3. package/.github/workflows/publish.yml +33 -0
  4. package/.github/workflows/unit-tests.yml +34 -0
  5. package/package.json +7 -12
  6. package/proto/network.proto +74 -0
  7. package/rpc/rpc_services.js +4 -22
  8. package/scripts/generate-protobufs.js +12 -37
  9. package/src/config/config.js +9 -26
  10. package/src/config/env.js +17 -27
  11. package/src/core/network/Network.js +36 -73
  12. package/src/core/network/protocols/LegacyProtocol.js +11 -21
  13. package/src/core/network/protocols/NetworkMessages.js +17 -38
  14. package/src/core/network/protocols/ProtocolInterface.js +2 -14
  15. package/src/core/network/protocols/ProtocolSession.js +17 -144
  16. package/src/core/network/protocols/V1Protocol.js +18 -37
  17. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +19 -25
  18. package/src/core/network/protocols/legacy/handlers/{LegacyGetRequestHandler.js → GetRequestHandler.js} +6 -6
  19. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
  20. package/src/core/network/protocols/{legacy/handlers/LegacyRoleOperationHandler.js → shared/handlers/RoleOperationHandler.js} +11 -18
  21. package/src/core/network/protocols/{legacy/handlers/LegacySubnetworkOperationHandler.js → shared/handlers/SubnetworkOperationHandler.js} +17 -28
  22. package/src/core/network/protocols/{legacy/handlers/LegacyTransferOperationHandler.js → shared/handlers/TransferOperationHandler.js} +11 -17
  23. package/src/core/network/protocols/{legacy/handlers/BaseStateOperationHandler.js → shared/handlers/base/BaseOperationHandler.js} +12 -23
  24. package/src/core/network/protocols/shared/validators/{PartialBootstrapDeploymentValidator.js → PartialBootstrapDeployment.js} +4 -9
  25. package/src/core/network/protocols/shared/validators/{PartialRoleAccessValidator.js → PartialRoleAccess.js} +17 -51
  26. package/src/core/network/protocols/shared/validators/{PartialTransactionValidator.js → PartialTransaction.js} +7 -21
  27. package/src/core/network/protocols/shared/validators/{PartialTransferValidator.js → PartialTransfer.js} +9 -26
  28. package/src/core/network/protocols/shared/validators/{PartialOperationValidator.js → base/PartialOperation.js} +25 -47
  29. package/src/core/network/protocols/v1/NetworkMessageRouter.js +7 -91
  30. package/src/core/network/services/ConnectionManager.js +94 -146
  31. package/src/core/network/services/MessageOrchestrator.js +27 -151
  32. package/src/core/network/services/TransactionPoolService.js +18 -129
  33. package/src/core/network/services/TransactionRateLimiterService.js +34 -52
  34. package/src/core/network/services/ValidatorObserverService.js +26 -18
  35. package/src/core/state/State.js +19 -70
  36. package/src/index.js +8 -6
  37. package/src/messages/network/v1/NetworkMessageBuilder.js +79 -59
  38. package/src/messages/network/v1/NetworkMessageDirector.js +50 -16
  39. package/src/utils/Scheduler.js +8 -0
  40. package/src/utils/constants.js +5 -71
  41. package/src/utils/helpers.js +1 -10
  42. package/src/utils/normalizers.js +0 -38
  43. package/src/utils/protobuf/network.cjs +840 -0
  44. package/src/utils/protobuf/operationHelpers.js +3 -24
  45. package/tests/acceptance/v1/account/account.test.mjs +2 -8
  46. package/tests/acceptance/v1/tx/tx.test.mjs +1 -23
  47. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +6 -34
  48. package/tests/fixtures/assembleMessage.fixtures.js +8 -7
  49. package/tests/fixtures/networkV1.fixtures.js +28 -2
  50. package/tests/helpers/autobaseTestHelpers.js +5 -2
  51. package/tests/helpers/createTestSignature.js +3 -2
  52. package/tests/helpers/transactionPayloads.mjs +2 -2
  53. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +79 -239
  54. package/tests/unit/messages/network/NetworkMessageDirector.test.js +77 -223
  55. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +5 -1
  56. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +5 -1
  57. package/tests/unit/network/ConnectionManager.test.js +191 -0
  58. package/tests/unit/network/networkModule.test.js +1 -4
  59. package/tests/unit/unit.test.js +2 -2
  60. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +2 -2
  61. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +2 -2
  62. package/tests/unit/utils/protobuf/operationHelpers.test.js +4 -2
  63. package/tests/unit/utils/utils.test.js +0 -1
  64. package/proto/network/v1/enums/message_type.proto +0 -16
  65. package/proto/network/v1/enums/result_code.proto +0 -84
  66. package/proto/network/v1/messages/broadcast_transaction_request.proto +0 -9
  67. package/proto/network/v1/messages/broadcast_transaction_response.proto +0 -13
  68. package/proto/network/v1/messages/liveness_request.proto +0 -8
  69. package/proto/network/v1/messages/liveness_response.proto +0 -11
  70. package/proto/network/v1/network_message.proto +0 -22
  71. package/src/core/network/protocols/connectionPolicies.js +0 -88
  72. package/src/core/network/protocols/legacy/handlers/LegacyResponseHandler.js +0 -23
  73. package/src/core/network/protocols/shared/errors/SharedValidatorRejectionError.js +0 -27
  74. package/src/core/network/protocols/v1/V1ProtocolError.js +0 -91
  75. package/src/core/network/protocols/v1/handlers/V1BaseOperationHandler.js +0 -65
  76. package/src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js +0 -389
  77. package/src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js +0 -87
  78. package/src/core/network/protocols/v1/validators/V1BaseOperation.js +0 -211
  79. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionRequest.js +0 -26
  80. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionResponse.js +0 -276
  81. package/src/core/network/protocols/v1/validators/V1LivenessRequest.js +0 -15
  82. package/src/core/network/protocols/v1/validators/V1LivenessResponse.js +0 -17
  83. package/src/core/network/protocols/v1/validators/V1ValidationSchema.js +0 -210
  84. package/src/core/network/services/PendingRequestService.js +0 -172
  85. package/src/core/network/services/TransactionCommitService.js +0 -149
  86. package/src/core/network/services/ValidatorHealthCheckService.js +0 -127
  87. package/src/utils/deepEqualApplyPayload.js +0 -40
  88. package/src/utils/logger.js +0 -25
  89. package/src/utils/protobuf/networkV1.generated.cjs +0 -2460
  90. package/tests/unit/network/LegacyNetworkMessageRouter.test.js +0 -54
  91. package/tests/unit/network/ProtocolSession.test.js +0 -127
  92. package/tests/unit/network/services/ConnectionManager.test.js +0 -450
  93. package/tests/unit/network/services/MessageOrchestrator.test.js +0 -445
  94. package/tests/unit/network/services/PendingRequestService.test.js +0 -431
  95. package/tests/unit/network/services/TransactionCommitService.test.js +0 -246
  96. package/tests/unit/network/services/TransactionPoolService.test.js +0 -489
  97. package/tests/unit/network/services/TransactionRateLimiterService.test.js +0 -139
  98. package/tests/unit/network/services/ValidatorHealthCheckService.test.js +0 -115
  99. package/tests/unit/network/services/services.test.js +0 -17
  100. package/tests/unit/network/utils/v1TestUtils.js +0 -153
  101. package/tests/unit/network/v1/NetworkMessageRouterV1.test.js +0 -151
  102. package/tests/unit/network/v1/V1BaseOperation.test.js +0 -356
  103. package/tests/unit/network/v1/V1BroadcastTransactionOperationHandler.test.js +0 -129
  104. package/tests/unit/network/v1/V1BroadcastTransactionRequest.test.js +0 -53
  105. package/tests/unit/network/v1/V1BroadcastTransactionResponse.test.js +0 -512
  106. package/tests/unit/network/v1/V1LivenessRequest.test.js +0 -32
  107. package/tests/unit/network/v1/V1LivenessResponse.test.js +0 -45
  108. package/tests/unit/network/v1/V1ResultCode.test.js +0 -84
  109. package/tests/unit/network/v1/V1ValidationSchema.test.js +0 -13
  110. package/tests/unit/network/v1/connectionPolicies.test.js +0 -49
  111. package/tests/unit/network/v1/handlers/V1BaseOperationHandler.test.js +0 -284
  112. package/tests/unit/network/v1/handlers/V1BroadcastTransactionOperationHandler.test.js +0 -794
  113. package/tests/unit/network/v1/handlers/V1LivenessOperationHandler.test.js +0 -193
  114. package/tests/unit/network/v1/v1.handlers.test.js +0 -15
  115. package/tests/unit/network/v1/v1.test.js +0 -19
  116. package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionRequest.test.js +0 -119
  117. package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionResponse.test.js +0 -136
  118. package/tests/unit/network/v1/v1ValidationSchema/common.test.js +0 -308
  119. package/tests/unit/network/v1/v1ValidationSchema/livenessRequest.test.js +0 -90
  120. package/tests/unit/network/v1/v1ValidationSchema/livenessResponse.test.js +0 -133
  121. 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
- });