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
@@ -17,6 +17,7 @@ import {
17
17
  idToBuffer,
18
18
  timestampToBuffer
19
19
  } from '../../../../src/utils/buffer.js';
20
+ import { addressToBuffer } from '../../../../src/core/state/utils/address.js';
20
21
  import { config } from '../../../helpers/config.js';
21
22
  import { asAddress } from '../../../helpers/address.js';
22
23
  import { testKeyPair1 } from '../../../fixtures/apply.fixtures.js';
@@ -37,6 +38,81 @@ function uniqueResultCodes() {
37
38
  return [...new Set(Object.values(NetworkResultCode))].sort((a, b) => a - b);
38
39
  }
39
40
 
41
+ test('NetworkMessageBuilder builds validator connection request and verifies signature', async t => {
42
+ const wallet = createWallet();
43
+ const builder = new NetworkMessageBuilder(wallet, config);
44
+
45
+ const id = uuidv7();
46
+ const caps = ['cap:b', 'cap:a'];
47
+
48
+ await builder
49
+ .setType(NetworkOperationType.VALIDATOR_CONNECTION_REQUEST)
50
+ .setId(id)
51
+ .setTimestamp()
52
+ .setIssuerAddress(wallet.address)
53
+ .setCapabilities(caps)
54
+ .buildPayload();
55
+
56
+ const payload = builder.getResult();
57
+ t.is(payload.type, NetworkOperationType.VALIDATOR_CONNECTION_REQUEST);
58
+ t.is(payload.id, id);
59
+ t.alike(payload.capabilities, caps);
60
+ t.ok(b4a.isBuffer(payload.validator_connection_request.nonce));
61
+ t.ok(b4a.isBuffer(payload.validator_connection_request.signature));
62
+
63
+ const message = createMessage(
64
+ payload.type,
65
+ idToBuffer(id),
66
+ timestampToBuffer(payload.timestamp),
67
+ addressToBuffer(wallet.address, config.addressPrefix),
68
+ payload.validator_connection_request.nonce,
69
+ encodeCapabilities(caps)
70
+ );
71
+ const hash = await PeerWallet.blake3(message);
72
+ t.ok(wallet.verify(payload.validator_connection_request.signature, hash, wallet.publicKey));
73
+
74
+ const roundTrip = decodeV1networkOperation(encodeV1networkOperation(payload));
75
+ t.is(roundTrip.type, NetworkOperationType.VALIDATOR_CONNECTION_REQUEST);
76
+ });
77
+
78
+ test('NetworkMessageBuilder iterates validator connection response ResultCode values', async t => {
79
+ const wallet = createWallet();
80
+ const builder = new NetworkMessageBuilder(wallet, config);
81
+ const id = uuidv7();
82
+ const otherAddress = asAddress('36fdaf941de4afe602cbb1e2f56dc582466ef23fad1da55c09fd6dd841cbd117');
83
+ const caps = ['cap:b', 'cap:a'];
84
+
85
+ for (const code of uniqueResultCodes()) {
86
+ await builder
87
+ .setType(NetworkOperationType.VALIDATOR_CONNECTION_RESPONSE)
88
+ .setId(id)
89
+ .setTimestamp()
90
+ .setIssuerAddress(otherAddress)
91
+ .setCapabilities(caps)
92
+ .setResultCode(code)
93
+ .buildPayload();
94
+
95
+ const payload = builder.getResult();
96
+ t.is(payload.type, NetworkOperationType.VALIDATOR_CONNECTION_RESPONSE);
97
+ t.is(payload.validator_connection_response.result, code);
98
+
99
+ const msg = createMessage(
100
+ payload.type,
101
+ idToBuffer(payload.id),
102
+ timestampToBuffer(payload.timestamp),
103
+ addressToBuffer(otherAddress, config.addressPrefix),
104
+ payload.validator_connection_response.nonce,
105
+ safeWriteUInt32BE(code, 0),
106
+ encodeCapabilities(caps)
107
+ );
108
+ const hash = await PeerWallet.blake3(msg);
109
+ t.ok(wallet.verify(payload.validator_connection_response.signature, hash, wallet.publicKey));
110
+
111
+ const decoded = decodeV1networkOperation(encodeV1networkOperation(payload));
112
+ t.is(decoded.validator_connection_response.result, code);
113
+ }
114
+ });
115
+
40
116
  test('NetworkMessageBuilder iterates liveness response ResultCode values', async t => {
41
117
  const wallet = createWallet();
42
118
  const builder = new NetworkMessageBuilder(wallet, config);
@@ -49,6 +125,7 @@ test('NetworkMessageBuilder iterates liveness response ResultCode values', async
49
125
  .setType(NetworkOperationType.LIVENESS_RESPONSE)
50
126
  .setId(id)
51
127
  .setTimestamp()
128
+ .setData(data)
52
129
  .setCapabilities(caps)
53
130
  .setResultCode(code)
54
131
  .buildPayload();
@@ -79,11 +156,13 @@ test('NetworkMessageBuilder builds liveness request and verifies signature (data
79
156
 
80
157
  const id = uuidv7();
81
158
  const caps = ['cap:b', 'cap:a'];
159
+ const data = b4a.from('ping', 'utf8');
82
160
 
83
161
  await builder
84
162
  .setType(NetworkOperationType.LIVENESS_REQUEST)
85
163
  .setId(id)
86
164
  .setTimestamp()
165
+ .setData(data)
87
166
  .setCapabilities(caps)
88
167
  .buildPayload();
89
168
 
@@ -108,275 +187,36 @@ test('NetworkMessageBuilder iterates broadcast transaction response ResultCode v
108
187
  const builder = new NetworkMessageBuilder(wallet, config);
109
188
  const id = uuidv7();
110
189
  const caps = ['cap:b', 'cap:a'];
111
- const proof = b4a.from('deadbeef', 'hex');
112
- const timestamp = Date.now();
113
- const emptyProof = b4a.alloc(0);
114
190
 
115
191
  for (const code of uniqueResultCodes()) {
116
- const includeProof = code === NetworkResultCode.OK;
117
- const proofUnavailable = code === NetworkResultCode.TX_ACCEPTED_PROOF_UNAVAILABLE;
118
- const responseProof = includeProof ? proof : emptyProof;
119
- const responseTimestampLedger = includeProof || proofUnavailable ? timestamp : 0;
120
192
  await builder
121
193
  .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
122
194
  .setId(id)
123
195
  .setTimestamp()
124
196
  .setCapabilities(caps)
125
- .setProof(responseProof)
126
- .setTimestampLedger(responseTimestampLedger)
127
197
  .setResultCode(code)
128
198
  .buildPayload();
129
199
 
130
200
  const payload = builder.getResult();
131
201
  t.is(payload.type, NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE);
132
202
  t.is(payload.broadcast_transaction_response.result, code);
133
- t.alike(payload.broadcast_transaction_response.proof, responseProof);
134
- t.is(payload.broadcast_transaction_response.timestamp, responseTimestampLedger);
135
203
 
136
204
  const msg = createMessage(
137
205
  payload.type,
138
206
  idToBuffer(payload.id),
139
207
  timestampToBuffer(payload.timestamp),
140
208
  payload.broadcast_transaction_response.nonce,
141
- responseProof,
142
- timestampToBuffer(responseTimestampLedger),
143
209
  safeWriteUInt32BE(code, 0),
144
210
  encodeCapabilities(caps)
145
211
  );
146
-
147
212
  const hash = await PeerWallet.blake3(msg);
148
213
  t.ok(wallet.verify(payload.broadcast_transaction_response.signature, hash, wallet.publicKey));
149
214
 
150
215
  const decoded = decodeV1networkOperation(encodeV1networkOperation(payload));
151
216
  t.is(decoded.broadcast_transaction_response.result, code);
152
- t.alike(decoded.broadcast_transaction_response.proof, responseProof);
153
- t.is(decoded.broadcast_transaction_response.timestamp, responseTimestampLedger);
154
217
  }
155
218
  });
156
219
 
157
- test('NetworkMessageBuilder builds broadcast transaction response with proof and timestamp', async t => {
158
- const wallet = createWallet();
159
- const builder = new NetworkMessageBuilder(wallet, config);
160
- const id = uuidv7();
161
- const caps = ['cap:b', 'cap:a'];
162
- const proof = b4a.from('deadbeef', 'hex');
163
- const timestamp = Date.now();
164
-
165
- await builder
166
- .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
167
- .setId(id)
168
- .setTimestamp()
169
- .setCapabilities(caps)
170
- .setProof(proof)
171
- .setTimestampLedger(timestamp)
172
- .setResultCode(NetworkResultCode.OK)
173
- .buildPayload();
174
-
175
- const payload = builder.getResult();
176
- t.alike(payload.broadcast_transaction_response.proof, proof);
177
- t.is(payload.broadcast_transaction_response.timestamp, timestamp);
178
-
179
- const msg = createMessage(
180
- payload.type,
181
- idToBuffer(payload.id),
182
- timestampToBuffer(payload.timestamp),
183
- payload.broadcast_transaction_response.nonce,
184
- proof,
185
- timestampToBuffer(timestamp),
186
- safeWriteUInt32BE(NetworkResultCode.OK, 0),
187
- encodeCapabilities(caps)
188
- );
189
- const hash = await PeerWallet.blake3(msg);
190
- t.ok(wallet.verify(payload.broadcast_transaction_response.signature, hash, wallet.publicKey));
191
-
192
- const decoded = decodeV1networkOperation(encodeV1networkOperation(payload));
193
- t.alike(decoded.broadcast_transaction_response.proof, proof);
194
- t.is(decoded.broadcast_transaction_response.timestamp, timestamp);
195
- });
196
-
197
- test('NetworkMessageBuilder rejects OK response when proof is provided without timestamp', async t => {
198
- const wallet = createWallet();
199
- const builder = new NetworkMessageBuilder(wallet, config);
200
- const id = uuidv7();
201
- const caps = ['cap:b', 'cap:a'];
202
- const proof = b4a.from('deadbeef', 'hex');
203
-
204
- await t.exception(
205
- () =>
206
- builder
207
- .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
208
- .setId(id)
209
- .setTimestamp()
210
- .setCapabilities(caps)
211
- .setProof(proof)
212
- .setResultCode(NetworkResultCode.OK)
213
- .buildPayload(),
214
- errorMessageIncludes('Result code OK requires non-empty proof and timestamp > 0.')
215
- );
216
- });
217
-
218
- test('NetworkMessageBuilder rejects OK response when timestamp is provided without proof', async t => {
219
- const wallet = createWallet();
220
- const builder = new NetworkMessageBuilder(wallet, config);
221
- const id = uuidv7();
222
- const caps = ['cap:b', 'cap:a'];
223
- const timestamp = Date.now();
224
-
225
- await t.exception(
226
- () =>
227
- builder
228
- .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
229
- .setId(id)
230
- .setTimestamp()
231
- .setCapabilities(caps)
232
- .setTimestampLedger(timestamp)
233
- .setResultCode(NetworkResultCode.OK)
234
- .buildPayload(),
235
- errorMessageIncludes('Result code OK requires non-empty proof and timestamp > 0.')
236
- );
237
- });
238
-
239
- test('NetworkMessageBuilder allows TX_ACCEPTED_PROOF_UNAVAILABLE response with timestamp and empty proof', async t => {
240
- const wallet = createWallet();
241
- const builder = new NetworkMessageBuilder(wallet, config);
242
- const id = uuidv7();
243
- const caps = ['cap:b', 'cap:a'];
244
- const timestamp = Date.now();
245
- const emptyProof = b4a.alloc(0);
246
-
247
- await builder
248
- .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
249
- .setId(id)
250
- .setTimestamp()
251
- .setCapabilities(caps)
252
- .setProof(emptyProof)
253
- .setTimestampLedger(timestamp)
254
- .setResultCode(NetworkResultCode.TX_ACCEPTED_PROOF_UNAVAILABLE)
255
- .buildPayload();
256
-
257
- const payload = builder.getResult();
258
- t.alike(payload.broadcast_transaction_response.proof, emptyProof);
259
- t.is(payload.broadcast_transaction_response.timestamp, timestamp);
260
- t.is(payload.broadcast_transaction_response.result, NetworkResultCode.TX_ACCEPTED_PROOF_UNAVAILABLE);
261
-
262
- const msg = createMessage(
263
- payload.type,
264
- idToBuffer(payload.id),
265
- timestampToBuffer(payload.timestamp),
266
- payload.broadcast_transaction_response.nonce,
267
- emptyProof,
268
- timestampToBuffer(timestamp),
269
- safeWriteUInt32BE(NetworkResultCode.TX_ACCEPTED_PROOF_UNAVAILABLE, 0),
270
- encodeCapabilities(caps)
271
- );
272
- const hash = await PeerWallet.blake3(msg);
273
- t.ok(wallet.verify(payload.broadcast_transaction_response.signature, hash, wallet.publicKey));
274
-
275
- const decoded = decodeV1networkOperation(encodeV1networkOperation(payload));
276
- t.is(decoded.broadcast_transaction_response.timestamp, timestamp);
277
- t.is(decoded.broadcast_transaction_response.result, NetworkResultCode.TX_ACCEPTED_PROOF_UNAVAILABLE);
278
- });
279
-
280
- test('NetworkMessageBuilder rejects OK response when proof and timestamp are both missing', async t => {
281
- const wallet = createWallet();
282
- const builder = new NetworkMessageBuilder(wallet, config);
283
- const id = uuidv7();
284
- const caps = ['cap:b', 'cap:a'];
285
-
286
- await t.exception(
287
- () =>
288
- builder
289
- .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
290
- .setId(id)
291
- .setTimestamp()
292
- .setCapabilities(caps)
293
- .setResultCode(NetworkResultCode.OK)
294
- .buildPayload(),
295
- errorMessageIncludes('Result code OK requires non-empty proof and timestamp > 0.')
296
- );
297
- });
298
-
299
- test('NetworkMessageBuilder rejects TX_ACCEPTED_PROOF_UNAVAILABLE response when timestamp is missing', async t => {
300
- const wallet = createWallet();
301
- const builder = new NetworkMessageBuilder(wallet, config);
302
- const id = uuidv7();
303
- const caps = ['cap:b', 'cap:a'];
304
-
305
- await t.exception(
306
- () =>
307
- builder
308
- .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
309
- .setId(id)
310
- .setTimestamp()
311
- .setCapabilities(caps)
312
- .setResultCode(NetworkResultCode.TX_ACCEPTED_PROOF_UNAVAILABLE)
313
- .buildPayload(),
314
- errorMessageIncludes('Result code TX_ACCEPTED_PROOF_UNAVAILABLE requires timestamp > 0.')
315
- );
316
- });
317
-
318
- test('NetworkMessageBuilder rejects TX_ACCEPTED_PROOF_UNAVAILABLE response when proof is non-empty', async t => {
319
- const wallet = createWallet();
320
- const builder = new NetworkMessageBuilder(wallet, config);
321
- const id = uuidv7();
322
- const caps = ['cap:b', 'cap:a'];
323
-
324
- await t.exception(
325
- () =>
326
- builder
327
- .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
328
- .setId(id)
329
- .setTimestamp()
330
- .setCapabilities(caps)
331
- .setProof(b4a.from('deadbeef', 'hex'))
332
- .setTimestampLedger(Date.now())
333
- .setResultCode(NetworkResultCode.TX_ACCEPTED_PROOF_UNAVAILABLE)
334
- .buildPayload(),
335
- errorMessageIncludes('Result code TX_ACCEPTED_PROOF_UNAVAILABLE requires empty proof.')
336
- );
337
- });
338
-
339
- test('NetworkMessageBuilder rejects non-OK response when proof is non-empty', async t => {
340
- const wallet = createWallet();
341
- const builder = new NetworkMessageBuilder(wallet, config);
342
- const id = uuidv7();
343
- const caps = ['cap:b', 'cap:a'];
344
-
345
- await t.exception(
346
- () =>
347
- builder
348
- .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
349
- .setId(id)
350
- .setTimestamp()
351
- .setCapabilities(caps)
352
- .setProof(b4a.from('deadbeef', 'hex'))
353
- .setTimestampLedger(0)
354
- .setResultCode(NetworkResultCode.INVALID_PAYLOAD)
355
- .buildPayload(),
356
- errorMessageIncludes('Non-OK result code requires empty proof.')
357
- );
358
- });
359
-
360
- test('NetworkMessageBuilder rejects non-OK response with timestamp > 0 unless proof is unavailable', async t => {
361
- const wallet = createWallet();
362
- const builder = new NetworkMessageBuilder(wallet, config);
363
- const id = uuidv7();
364
- const caps = ['cap:b', 'cap:a'];
365
-
366
- await t.exception(
367
- () =>
368
- builder
369
- .setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
370
- .setId(id)
371
- .setTimestamp()
372
- .setCapabilities(caps)
373
- .setTimestampLedger(Date.now())
374
- .setResultCode(NetworkResultCode.INVALID_PAYLOAD)
375
- .buildPayload(),
376
- errorMessageIncludes('Non-OK result code requires timestamp to be 0, except TX_ACCEPTED_PROOF_UNAVAILABLE.')
377
- );
378
- });
379
-
380
220
  test('NetworkMessageBuilder builds broadcast transaction request and verifies signature', async t => {
381
221
  const wallet = createWallet();
382
222
  const builder = new NetworkMessageBuilder(wallet, config);