trac-msb 0.2.8 → 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.
Files changed (123) hide show
  1. package/msb.mjs +3 -3
  2. package/package.json +8 -3
  3. package/proto/network.proto +74 -0
  4. package/rpc/create_server.js +2 -2
  5. package/rpc/handlers.js +2 -2
  6. package/rpc/rpc_server.js +2 -2
  7. package/rpc/rpc_services.js +44 -3
  8. package/rpc/utils/helpers.js +1 -1
  9. package/src/config/env.js +2 -0
  10. package/src/core/network/Network.js +29 -61
  11. package/src/core/network/identity/NetworkWalletFactory.js +2 -2
  12. package/src/core/network/protocols/LegacyProtocol.js +67 -0
  13. package/src/core/network/protocols/NetworkMessages.js +48 -0
  14. package/src/core/network/protocols/ProtocolInterface.js +31 -0
  15. package/src/core/network/protocols/ProtocolSession.js +59 -0
  16. package/src/core/network/protocols/V1Protocol.js +64 -0
  17. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
  18. package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
  19. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
  20. package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +1 -2
  21. package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
  22. package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
  23. package/src/core/network/{messaging → protocols/shared}/handlers/TransferOperationHandler.js +16 -15
  24. package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +7 -11
  25. package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +2 -2
  26. package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +5 -5
  27. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +4 -4
  28. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +4 -4
  29. package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +14 -12
  30. package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
  31. package/src/core/network/services/ConnectionManager.js +4 -4
  32. package/src/core/network/services/MessageOrchestrator.js +1 -1
  33. package/src/core/network/services/TransactionPoolService.js +1 -2
  34. package/src/core/network/services/TransactionRateLimiterService.js +5 -3
  35. package/src/core/state/State.js +1 -2
  36. package/src/index.js +153 -180
  37. package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
  38. package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
  39. package/src/messages/network/v1/networkMessageFactory.js +12 -0
  40. package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
  41. package/src/messages/state/ApplyStateMessageDirector.js +516 -0
  42. package/src/messages/state/applyStateMessageFactory.js +12 -0
  43. package/src/utils/buffer.js +53 -1
  44. package/src/utils/cli.js +0 -8
  45. package/src/utils/constants.js +34 -14
  46. package/src/utils/normalizers.js +84 -2
  47. package/src/utils/protobuf/network.cjs +840 -0
  48. package/src/utils/protobuf/operationHelpers.js +10 -0
  49. package/tests/acceptance/v1/rpc.test.mjs +1 -1
  50. package/tests/fixtures/networkV1.fixtures.js +84 -0
  51. package/tests/fixtures/protobuf.fixtures.js +83 -0
  52. package/tests/helpers/config.js +1 -1
  53. package/tests/helpers/setupApplyTests.js +53 -46
  54. package/tests/unit/messages/messages.test.js +12 -0
  55. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
  56. package/tests/unit/messages/network/NetworkMessageDirector.test.js +203 -0
  57. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
  58. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
  59. package/tests/unit/network/ConnectionManager.test.js +6 -5
  60. package/tests/unit/network/networkModule.test.js +3 -2
  61. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
  62. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +9 -6
  63. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +10 -7
  64. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -21
  65. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +53 -38
  66. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +46 -35
  67. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +13 -16
  68. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +17 -11
  69. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +11 -12
  70. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +9 -7
  71. package/tests/unit/state/apply/common/commonScenarioHelper.js +15 -14
  72. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +9 -4
  73. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +17 -11
  74. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +19 -14
  75. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +37 -29
  76. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +9 -7
  77. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +11 -9
  78. package/tests/unit/unit.test.js +1 -1
  79. package/tests/unit/utils/buffer/buffer.test.js +62 -1
  80. package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
  81. package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
  82. package/docs/networking-dualstack-plan.md +0 -75
  83. package/docs/networking-layer-redesign.md +0 -155
  84. package/src/core/network/messaging/NetworkMessages.js +0 -64
  85. package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -113
  86. package/src/core/network/messaging/handlers/ResponseHandler.js +0 -107
  87. package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -114
  88. package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -149
  89. package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -98
  90. package/src/core/network/messaging/validators/AdminResponse.js +0 -58
  91. package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
  92. package/src/messages/base/StateBuilder.js +0 -25
  93. package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -425
  94. package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
  95. package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -296
  96. package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
  97. package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
  98. package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -138
  99. package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -69
  100. package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -126
  101. package/tests/integration/apply/addIndexer.test.js +0 -239
  102. package/tests/integration/apply/addWhitelist.test.js +0 -53
  103. package/tests/integration/apply/addWriter.test.js +0 -245
  104. package/tests/integration/apply/apply.test.js +0 -19
  105. package/tests/integration/apply/banValidator.test.js +0 -116
  106. package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
  107. package/tests/integration/apply/postTx/postTx.test.js +0 -196
  108. package/tests/integration/apply/removeIndexer.test.js +0 -132
  109. package/tests/integration/apply/removeWriter.test.js +0 -168
  110. package/tests/integration/apply/transfer.test.js +0 -83
  111. package/tests/integration/integration.test.js +0 -9
  112. package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
  113. package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -17
  114. package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -68
  115. package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -17
  116. package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -424
  117. package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
  118. package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
  119. package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -59
  120. package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -278
  121. package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
  122. /package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +0 -0
  123. /package/src/utils/{operations.js → applyOperations.js} +0 -0
@@ -0,0 +1,521 @@
1
+ import { test } from 'brittle';
2
+ import b4a from 'b4a';
3
+ import PeerWallet from 'trac-wallet';
4
+
5
+ import ApplyStateMessageBuilder from '../../../../src/messages/state/ApplyStateMessageBuilder.js';
6
+ import { OperationType } from '../../../../src/utils/constants.js';
7
+ import { config } from '../../../helpers/config.js';
8
+ import { testKeyPair1, testKeyPair2 } from '../../../fixtures/apply.fixtures.js';
9
+ import { addressToBuffer } from '../../../../src/core/state/utils/address.js';
10
+
11
+ const hex = (value, bytes) => value.repeat(bytes);
12
+ const toBuf = value => b4a.from(value, 'hex');
13
+
14
+ async function createWallet(mnemonic) {
15
+ const wallet = new PeerWallet({ mnemonic, networkPrefix: config.addressPrefix });
16
+ await wallet.ready;
17
+ return wallet;
18
+ }
19
+
20
+ function expectBufferField(t, value, bytes, label) {
21
+ t.ok(b4a.isBuffer(value), `${label} type`);
22
+ t.is(value.length, bytes, `${label} length`);
23
+ }
24
+
25
+ function expectAddressBuffer(t, value, label) {
26
+ expectBufferField(t, value, config.addressLength, label);
27
+ }
28
+
29
+ function expectKeys(t, value, keys, label) {
30
+ t.alike(Object.keys(value).sort(), keys.slice().sort(), `${label} keys`);
31
+ }
32
+
33
+ function expectPayloadKeys(t, payload, bodyKey) {
34
+ expectKeys(t, payload, ['type', 'address', bodyKey], 'payload');
35
+ }
36
+
37
+ test('ApplyStateMessageBuilder complete add admin (cao)', async t => {
38
+ const wallet = await createWallet(testKeyPair1.mnemonic);
39
+ const txValidity = toBuf(hex('11', 32));
40
+ const writingKey = toBuf(hex('22', 32));
41
+
42
+ const builder = new ApplyStateMessageBuilder(wallet, config);
43
+ await builder
44
+ .setPhase('complete')
45
+ .setOutput('buffer')
46
+ .setOperationType(OperationType.ADD_ADMIN)
47
+ .setAddress(wallet.address)
48
+ .setWriterKey(writingKey)
49
+ .setTxValidity(txValidity)
50
+ .build();
51
+
52
+ const payload = builder.getPayload();
53
+ t.is(payload.type, OperationType.ADD_ADMIN);
54
+ expectAddressBuffer(t, payload.address, 'address');
55
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
56
+ expectPayloadKeys(t, payload, 'cao');
57
+ expectKeys(t, payload.cao, ['tx', 'txv', 'iw', 'in', 'is'], 'cao');
58
+ expectBufferField(t, payload.cao.tx, 32, 'cao.tx');
59
+ expectBufferField(t, payload.cao.txv, 32, 'cao.txv');
60
+ expectBufferField(t, payload.cao.iw, 32, 'cao.iw');
61
+ t.ok(b4a.equals(payload.cao.txv, txValidity));
62
+ t.ok(b4a.equals(payload.cao.iw, writingKey));
63
+ expectBufferField(t, payload.cao.in, 32, 'cao.in');
64
+ expectBufferField(t, payload.cao.is, 64, 'cao.is');
65
+ });
66
+
67
+ test('ApplyStateMessageBuilder complete disable initialization (cao)', async t => {
68
+ const wallet = await createWallet(testKeyPair1.mnemonic);
69
+ const txValidity = toBuf(hex('33', 32));
70
+ const writingKey = toBuf(hex('44', 32));
71
+
72
+ const builder = new ApplyStateMessageBuilder(wallet, config);
73
+ await builder
74
+ .setPhase('complete')
75
+ .setOutput('buffer')
76
+ .setOperationType(OperationType.DISABLE_INITIALIZATION)
77
+ .setAddress(wallet.address)
78
+ .setWriterKey(writingKey)
79
+ .setTxValidity(txValidity)
80
+ .build();
81
+
82
+ const payload = builder.getPayload();
83
+ t.is(payload.type, OperationType.DISABLE_INITIALIZATION);
84
+ expectAddressBuffer(t, payload.address, 'address');
85
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
86
+ expectPayloadKeys(t, payload, 'cao');
87
+ expectKeys(t, payload.cao, ['tx', 'txv', 'iw', 'in', 'is'], 'cao');
88
+ expectBufferField(t, payload.cao.tx, 32, 'cao.tx');
89
+ expectBufferField(t, payload.cao.txv, 32, 'cao.txv');
90
+ expectBufferField(t, payload.cao.iw, 32, 'cao.iw');
91
+ t.ok(b4a.equals(payload.cao.txv, txValidity));
92
+ t.ok(b4a.equals(payload.cao.iw, writingKey));
93
+ expectBufferField(t, payload.cao.in, 32, 'cao.in');
94
+ expectBufferField(t, payload.cao.is, 64, 'cao.is');
95
+ });
96
+
97
+ test('ApplyStateMessageBuilder complete balance initialization (bio)', async t => {
98
+ const wallet = await createWallet(testKeyPair1.mnemonic);
99
+ const otherWallet = await createWallet(testKeyPair2.mnemonic);
100
+ const txValidity = toBuf(hex('55', 32));
101
+ const amount = toBuf(hex('66', 16));
102
+
103
+ const builder = new ApplyStateMessageBuilder(wallet, config);
104
+ await builder
105
+ .setPhase('complete')
106
+ .setOutput('buffer')
107
+ .setOperationType(OperationType.BALANCE_INITIALIZATION)
108
+ .setAddress(wallet.address)
109
+ .setIncomingAddress(otherWallet.address)
110
+ .setAmount(amount)
111
+ .setTxValidity(txValidity)
112
+ .build();
113
+
114
+ const payload = builder.getPayload();
115
+ t.is(payload.type, OperationType.BALANCE_INITIALIZATION);
116
+ expectAddressBuffer(t, payload.address, 'address');
117
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
118
+ expectPayloadKeys(t, payload, 'bio');
119
+ expectKeys(t, payload.bio, ['tx', 'txv', 'ia', 'am', 'in', 'is'], 'bio');
120
+ expectBufferField(t, payload.bio.tx, 32, 'bio.tx');
121
+ expectBufferField(t, payload.bio.txv, 32, 'bio.txv');
122
+ expectAddressBuffer(t, payload.bio.ia, 'bio.ia');
123
+ expectBufferField(t, payload.bio.am, 16, 'bio.am');
124
+ t.ok(b4a.equals(payload.bio.txv, txValidity));
125
+ t.ok(b4a.equals(payload.bio.ia, addressToBuffer(otherWallet.address, config.addressPrefix)));
126
+ t.ok(b4a.equals(payload.bio.am, amount));
127
+ expectBufferField(t, payload.bio.in, 32, 'bio.in');
128
+ expectBufferField(t, payload.bio.is, 64, 'bio.is');
129
+ });
130
+
131
+ test('ApplyStateMessageBuilder complete append whitelist (aco)', async t => {
132
+ const wallet = await createWallet(testKeyPair1.mnemonic);
133
+ const otherWallet = await createWallet(testKeyPair2.mnemonic);
134
+ const txValidity = toBuf(hex('77', 32));
135
+
136
+ const builder = new ApplyStateMessageBuilder(wallet, config);
137
+ await builder
138
+ .setPhase('complete')
139
+ .setOutput('buffer')
140
+ .setOperationType(OperationType.APPEND_WHITELIST)
141
+ .setAddress(wallet.address)
142
+ .setIncomingAddress(otherWallet.address)
143
+ .setTxValidity(txValidity)
144
+ .build();
145
+
146
+ const payload = builder.getPayload();
147
+ t.is(payload.type, OperationType.APPEND_WHITELIST);
148
+ expectAddressBuffer(t, payload.address, 'address');
149
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
150
+ expectPayloadKeys(t, payload, 'aco');
151
+ expectKeys(t, payload.aco, ['tx', 'txv', 'ia', 'in', 'is'], 'aco');
152
+ expectBufferField(t, payload.aco.tx, 32, 'aco.tx');
153
+ expectBufferField(t, payload.aco.txv, 32, 'aco.txv');
154
+ expectAddressBuffer(t, payload.aco.ia, 'aco.ia');
155
+ t.ok(b4a.equals(payload.aco.txv, txValidity));
156
+ t.ok(b4a.equals(payload.aco.ia, addressToBuffer(otherWallet.address, config.addressPrefix)));
157
+ expectBufferField(t, payload.aco.in, 32, 'aco.in');
158
+ expectBufferField(t, payload.aco.is, 64, 'aco.is');
159
+ });
160
+
161
+ test('ApplyStateMessageBuilder complete add indexer (aco)', async t => {
162
+ const wallet = await createWallet(testKeyPair1.mnemonic);
163
+ const otherWallet = await createWallet(testKeyPair2.mnemonic);
164
+ const txValidity = toBuf(hex('88', 32));
165
+
166
+ const builder = new ApplyStateMessageBuilder(wallet, config);
167
+ await builder
168
+ .setPhase('complete')
169
+ .setOutput('buffer')
170
+ .setOperationType(OperationType.ADD_INDEXER)
171
+ .setAddress(wallet.address)
172
+ .setIncomingAddress(otherWallet.address)
173
+ .setTxValidity(txValidity)
174
+ .build();
175
+
176
+ const payload = builder.getPayload();
177
+ t.is(payload.type, OperationType.ADD_INDEXER);
178
+ expectAddressBuffer(t, payload.address, 'address');
179
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
180
+ expectPayloadKeys(t, payload, 'aco');
181
+ expectKeys(t, payload.aco, ['tx', 'txv', 'ia', 'in', 'is'], 'aco');
182
+ expectBufferField(t, payload.aco.tx, 32, 'aco.tx');
183
+ expectBufferField(t, payload.aco.txv, 32, 'aco.txv');
184
+ expectAddressBuffer(t, payload.aco.ia, 'aco.ia');
185
+ t.ok(b4a.equals(payload.aco.txv, txValidity));
186
+ t.ok(b4a.equals(payload.aco.ia, addressToBuffer(otherWallet.address, config.addressPrefix)));
187
+ expectBufferField(t, payload.aco.in, 32, 'aco.in');
188
+ expectBufferField(t, payload.aco.is, 64, 'aco.is');
189
+ });
190
+
191
+ test('ApplyStateMessageBuilder complete remove indexer (aco)', async t => {
192
+ const wallet = await createWallet(testKeyPair1.mnemonic);
193
+ const otherWallet = await createWallet(testKeyPair2.mnemonic);
194
+ const txValidity = toBuf(hex('99', 32));
195
+
196
+ const builder = new ApplyStateMessageBuilder(wallet, config);
197
+ await builder
198
+ .setPhase('complete')
199
+ .setOutput('buffer')
200
+ .setOperationType(OperationType.REMOVE_INDEXER)
201
+ .setAddress(wallet.address)
202
+ .setIncomingAddress(otherWallet.address)
203
+ .setTxValidity(txValidity)
204
+ .build();
205
+
206
+ const payload = builder.getPayload();
207
+ t.is(payload.type, OperationType.REMOVE_INDEXER);
208
+ expectAddressBuffer(t, payload.address, 'address');
209
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
210
+ expectPayloadKeys(t, payload, 'aco');
211
+ expectKeys(t, payload.aco, ['tx', 'txv', 'ia', 'in', 'is'], 'aco');
212
+ expectBufferField(t, payload.aco.tx, 32, 'aco.tx');
213
+ expectBufferField(t, payload.aco.txv, 32, 'aco.txv');
214
+ expectAddressBuffer(t, payload.aco.ia, 'aco.ia');
215
+ t.ok(b4a.equals(payload.aco.txv, txValidity));
216
+ t.ok(b4a.equals(payload.aco.ia, addressToBuffer(otherWallet.address, config.addressPrefix)));
217
+ expectBufferField(t, payload.aco.in, 32, 'aco.in');
218
+ expectBufferField(t, payload.aco.is, 64, 'aco.is');
219
+ });
220
+
221
+ test('ApplyStateMessageBuilder complete ban validator (aco)', async t => {
222
+ const wallet = await createWallet(testKeyPair1.mnemonic);
223
+ const otherWallet = await createWallet(testKeyPair2.mnemonic);
224
+ const txValidity = toBuf(hex('aa', 32));
225
+
226
+ const builder = new ApplyStateMessageBuilder(wallet, config);
227
+ await builder
228
+ .setPhase('complete')
229
+ .setOutput('buffer')
230
+ .setOperationType(OperationType.BAN_VALIDATOR)
231
+ .setAddress(wallet.address)
232
+ .setIncomingAddress(otherWallet.address)
233
+ .setTxValidity(txValidity)
234
+ .build();
235
+
236
+ const payload = builder.getPayload();
237
+ t.is(payload.type, OperationType.BAN_VALIDATOR);
238
+ expectAddressBuffer(t, payload.address, 'address');
239
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
240
+ expectPayloadKeys(t, payload, 'aco');
241
+ expectKeys(t, payload.aco, ['tx', 'txv', 'ia', 'in', 'is'], 'aco');
242
+ expectBufferField(t, payload.aco.tx, 32, 'aco.tx');
243
+ expectBufferField(t, payload.aco.txv, 32, 'aco.txv');
244
+ expectAddressBuffer(t, payload.aco.ia, 'aco.ia');
245
+ t.ok(b4a.equals(payload.aco.txv, txValidity));
246
+ t.ok(b4a.equals(payload.aco.ia, addressToBuffer(otherWallet.address, config.addressPrefix)));
247
+ expectBufferField(t, payload.aco.in, 32, 'aco.in');
248
+ expectBufferField(t, payload.aco.is, 64, 'aco.is');
249
+ });
250
+
251
+ test('ApplyStateMessageBuilder complete add writer (rao)', async t => {
252
+ const wallet = await createWallet(testKeyPair1.mnemonic);
253
+ const txHash = toBuf(hex('bb', 32));
254
+ const txValidity = toBuf(hex('cc', 32));
255
+ const incomingWriterKey = toBuf(hex('dd', 32));
256
+ const incomingNonce = toBuf(hex('ee', 32));
257
+ const incomingSignature = toBuf(hex('ff', 64));
258
+
259
+ const builder = new ApplyStateMessageBuilder(wallet, config);
260
+ await builder
261
+ .setPhase('complete')
262
+ .setOutput('buffer')
263
+ .setOperationType(OperationType.ADD_WRITER)
264
+ .setAddress(wallet.address)
265
+ .setTxHash(txHash)
266
+ .setTxValidity(txValidity)
267
+ .setIncomingWriterKey(incomingWriterKey)
268
+ .setIncomingNonce(incomingNonce)
269
+ .setIncomingSignature(incomingSignature)
270
+ .build();
271
+
272
+ const payload = builder.getPayload();
273
+ t.is(payload.type, OperationType.ADD_WRITER);
274
+ expectAddressBuffer(t, payload.address, 'address');
275
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
276
+ expectPayloadKeys(t, payload, 'rao');
277
+ expectKeys(t, payload.rao, ['tx', 'txv', 'iw', 'in', 'is', 'va', 'vn', 'vs'], 'rao');
278
+ expectBufferField(t, payload.rao.tx, 32, 'rao.tx');
279
+ expectBufferField(t, payload.rao.txv, 32, 'rao.txv');
280
+ expectBufferField(t, payload.rao.iw, 32, 'rao.iw');
281
+ expectBufferField(t, payload.rao.in, 32, 'rao.in');
282
+ expectBufferField(t, payload.rao.is, 64, 'rao.is');
283
+ expectAddressBuffer(t, payload.rao.va, 'rao.va');
284
+ expectBufferField(t, payload.rao.vn, 32, 'rao.vn');
285
+ expectBufferField(t, payload.rao.vs, 64, 'rao.vs');
286
+ t.ok(b4a.equals(payload.rao.tx, txHash));
287
+ t.ok(b4a.equals(payload.rao.txv, txValidity));
288
+ t.ok(b4a.equals(payload.rao.iw, incomingWriterKey));
289
+ t.ok(b4a.equals(payload.rao.in, incomingNonce));
290
+ t.ok(b4a.equals(payload.rao.is, incomingSignature));
291
+ });
292
+
293
+ test('ApplyStateMessageBuilder complete remove writer (rao)', async t => {
294
+ const wallet = await createWallet(testKeyPair1.mnemonic);
295
+ const txHash = toBuf(hex('01', 32));
296
+ const txValidity = toBuf(hex('02', 32));
297
+ const incomingWriterKey = toBuf(hex('03', 32));
298
+ const incomingNonce = toBuf(hex('04', 32));
299
+ const incomingSignature = toBuf(hex('05', 64));
300
+
301
+ const builder = new ApplyStateMessageBuilder(wallet, config);
302
+ await builder
303
+ .setPhase('complete')
304
+ .setOutput('buffer')
305
+ .setOperationType(OperationType.REMOVE_WRITER)
306
+ .setAddress(wallet.address)
307
+ .setTxHash(txHash)
308
+ .setTxValidity(txValidity)
309
+ .setIncomingWriterKey(incomingWriterKey)
310
+ .setIncomingNonce(incomingNonce)
311
+ .setIncomingSignature(incomingSignature)
312
+ .build();
313
+
314
+ const payload = builder.getPayload();
315
+ t.is(payload.type, OperationType.REMOVE_WRITER);
316
+ expectAddressBuffer(t, payload.address, 'address');
317
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
318
+ expectPayloadKeys(t, payload, 'rao');
319
+ expectKeys(t, payload.rao, ['tx', 'txv', 'iw', 'in', 'is', 'va', 'vn', 'vs'], 'rao');
320
+ expectBufferField(t, payload.rao.tx, 32, 'rao.tx');
321
+ expectBufferField(t, payload.rao.txv, 32, 'rao.txv');
322
+ expectBufferField(t, payload.rao.iw, 32, 'rao.iw');
323
+ expectBufferField(t, payload.rao.in, 32, 'rao.in');
324
+ expectBufferField(t, payload.rao.is, 64, 'rao.is');
325
+ expectAddressBuffer(t, payload.rao.va, 'rao.va');
326
+ expectBufferField(t, payload.rao.vn, 32, 'rao.vn');
327
+ expectBufferField(t, payload.rao.vs, 64, 'rao.vs');
328
+ t.ok(b4a.equals(payload.rao.tx, txHash));
329
+ t.ok(b4a.equals(payload.rao.txv, txValidity));
330
+ t.ok(b4a.equals(payload.rao.iw, incomingWriterKey));
331
+ t.ok(b4a.equals(payload.rao.in, incomingNonce));
332
+ t.ok(b4a.equals(payload.rao.is, incomingSignature));
333
+ });
334
+
335
+ test('ApplyStateMessageBuilder complete admin recovery (rao)', async t => {
336
+ const wallet = await createWallet(testKeyPair1.mnemonic);
337
+ const txHash = toBuf(hex('10', 32));
338
+ const txValidity = toBuf(hex('20', 32));
339
+ const incomingWriterKey = toBuf(hex('30', 32));
340
+ const incomingNonce = toBuf(hex('40', 32));
341
+ const incomingSignature = toBuf(hex('50', 64));
342
+
343
+ const builder = new ApplyStateMessageBuilder(wallet, config);
344
+ await builder
345
+ .setPhase('complete')
346
+ .setOutput('buffer')
347
+ .setOperationType(OperationType.ADMIN_RECOVERY)
348
+ .setAddress(wallet.address)
349
+ .setTxHash(txHash)
350
+ .setTxValidity(txValidity)
351
+ .setIncomingWriterKey(incomingWriterKey)
352
+ .setIncomingNonce(incomingNonce)
353
+ .setIncomingSignature(incomingSignature)
354
+ .build();
355
+
356
+ const payload = builder.getPayload();
357
+ t.is(payload.type, OperationType.ADMIN_RECOVERY);
358
+ expectAddressBuffer(t, payload.address, 'address');
359
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
360
+ expectPayloadKeys(t, payload, 'rao');
361
+ expectKeys(t, payload.rao, ['tx', 'txv', 'iw', 'in', 'is', 'va', 'vn', 'vs'], 'rao');
362
+ expectBufferField(t, payload.rao.tx, 32, 'rao.tx');
363
+ expectBufferField(t, payload.rao.txv, 32, 'rao.txv');
364
+ expectBufferField(t, payload.rao.iw, 32, 'rao.iw');
365
+ expectBufferField(t, payload.rao.in, 32, 'rao.in');
366
+ expectBufferField(t, payload.rao.is, 64, 'rao.is');
367
+ expectAddressBuffer(t, payload.rao.va, 'rao.va');
368
+ expectBufferField(t, payload.rao.vn, 32, 'rao.vn');
369
+ expectBufferField(t, payload.rao.vs, 64, 'rao.vs');
370
+ t.ok(b4a.equals(payload.rao.tx, txHash));
371
+ t.ok(b4a.equals(payload.rao.txv, txValidity));
372
+ t.ok(b4a.equals(payload.rao.iw, incomingWriterKey));
373
+ t.ok(b4a.equals(payload.rao.in, incomingNonce));
374
+ t.ok(b4a.equals(payload.rao.is, incomingSignature));
375
+ });
376
+
377
+ test('ApplyStateMessageBuilder complete bootstrap deployment (bdo)', async t => {
378
+ const wallet = await createWallet(testKeyPair1.mnemonic);
379
+ const txHash = toBuf(hex('60', 32));
380
+ const txValidity = toBuf(hex('70', 32));
381
+ const externalBootstrap = toBuf(hex('80', 32));
382
+ const channel = toBuf(hex('90', 32));
383
+ const incomingNonce = toBuf(hex('a0', 32));
384
+ const incomingSignature = toBuf(hex('b0', 64));
385
+
386
+ const builder = new ApplyStateMessageBuilder(wallet, config);
387
+ await builder
388
+ .setPhase('complete')
389
+ .setOutput('buffer')
390
+ .setOperationType(OperationType.BOOTSTRAP_DEPLOYMENT)
391
+ .setAddress(wallet.address)
392
+ .setTxHash(txHash)
393
+ .setTxValidity(txValidity)
394
+ .setExternalBootstrap(externalBootstrap)
395
+ .setChannel(channel)
396
+ .setIncomingNonce(incomingNonce)
397
+ .setIncomingSignature(incomingSignature)
398
+ .build();
399
+
400
+ const payload = builder.getPayload();
401
+ t.is(payload.type, OperationType.BOOTSTRAP_DEPLOYMENT);
402
+ expectAddressBuffer(t, payload.address, 'address');
403
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
404
+ expectPayloadKeys(t, payload, 'bdo');
405
+ expectKeys(t, payload.bdo, ['tx', 'txv', 'bs', 'ic', 'in', 'is', 'va', 'vn', 'vs'], 'bdo');
406
+ expectBufferField(t, payload.bdo.tx, 32, 'bdo.tx');
407
+ expectBufferField(t, payload.bdo.txv, 32, 'bdo.txv');
408
+ expectBufferField(t, payload.bdo.bs, 32, 'bdo.bs');
409
+ expectBufferField(t, payload.bdo.ic, 32, 'bdo.ic');
410
+ expectBufferField(t, payload.bdo.in, 32, 'bdo.in');
411
+ expectBufferField(t, payload.bdo.is, 64, 'bdo.is');
412
+ expectAddressBuffer(t, payload.bdo.va, 'bdo.va');
413
+ expectBufferField(t, payload.bdo.vn, 32, 'bdo.vn');
414
+ expectBufferField(t, payload.bdo.vs, 64, 'bdo.vs');
415
+ t.ok(b4a.equals(payload.bdo.tx, txHash));
416
+ t.ok(b4a.equals(payload.bdo.txv, txValidity));
417
+ t.ok(b4a.equals(payload.bdo.bs, externalBootstrap));
418
+ t.ok(b4a.equals(payload.bdo.ic, channel));
419
+ t.ok(b4a.equals(payload.bdo.in, incomingNonce));
420
+ t.ok(b4a.equals(payload.bdo.is, incomingSignature));
421
+ });
422
+
423
+ test('ApplyStateMessageBuilder complete transaction operation (txo)', async t => {
424
+ const wallet = await createWallet(testKeyPair1.mnemonic);
425
+ const txHash = toBuf(hex('c0', 32));
426
+ const txValidity = toBuf(hex('d0', 32));
427
+ const incomingWriterKey = toBuf(hex('e0', 32));
428
+ const incomingNonce = toBuf(hex('f0', 32));
429
+ const incomingSignature = toBuf(hex('01', 64));
430
+ const contentHash = toBuf(hex('02', 32));
431
+ const externalBootstrap = toBuf(hex('03', 32));
432
+ const msbBootstrap = toBuf(hex('04', 32));
433
+
434
+ const builder = new ApplyStateMessageBuilder(wallet, config);
435
+ await builder
436
+ .setPhase('complete')
437
+ .setOutput('buffer')
438
+ .setOperationType(OperationType.TX)
439
+ .setAddress(wallet.address)
440
+ .setTxHash(txHash)
441
+ .setTxValidity(txValidity)
442
+ .setIncomingWriterKey(incomingWriterKey)
443
+ .setIncomingNonce(incomingNonce)
444
+ .setIncomingSignature(incomingSignature)
445
+ .setContentHash(contentHash)
446
+ .setExternalBootstrap(externalBootstrap)
447
+ .setMsbBootstrap(msbBootstrap)
448
+ .build();
449
+
450
+ const payload = builder.getPayload();
451
+ t.is(payload.type, OperationType.TX);
452
+ expectAddressBuffer(t, payload.address, 'address');
453
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
454
+ expectPayloadKeys(t, payload, 'txo');
455
+ expectKeys(t, payload.txo, ['tx', 'txv', 'iw', 'ch', 'bs', 'mbs', 'in', 'is', 'va', 'vn', 'vs'], 'txo');
456
+ expectBufferField(t, payload.txo.tx, 32, 'txo.tx');
457
+ expectBufferField(t, payload.txo.txv, 32, 'txo.txv');
458
+ expectBufferField(t, payload.txo.iw, 32, 'txo.iw');
459
+ expectBufferField(t, payload.txo.in, 32, 'txo.in');
460
+ expectBufferField(t, payload.txo.is, 64, 'txo.is');
461
+ expectBufferField(t, payload.txo.ch, 32, 'txo.ch');
462
+ expectBufferField(t, payload.txo.bs, 32, 'txo.bs');
463
+ expectBufferField(t, payload.txo.mbs, 32, 'txo.mbs');
464
+ expectAddressBuffer(t, payload.txo.va, 'txo.va');
465
+ expectBufferField(t, payload.txo.vn, 32, 'txo.vn');
466
+ expectBufferField(t, payload.txo.vs, 64, 'txo.vs');
467
+ t.ok(b4a.equals(payload.txo.tx, txHash));
468
+ t.ok(b4a.equals(payload.txo.txv, txValidity));
469
+ t.ok(b4a.equals(payload.txo.iw, incomingWriterKey));
470
+ t.ok(b4a.equals(payload.txo.in, incomingNonce));
471
+ t.ok(b4a.equals(payload.txo.is, incomingSignature));
472
+ t.ok(b4a.equals(payload.txo.ch, contentHash));
473
+ t.ok(b4a.equals(payload.txo.bs, externalBootstrap));
474
+ t.ok(b4a.equals(payload.txo.mbs, msbBootstrap));
475
+ });
476
+
477
+ test('ApplyStateMessageBuilder complete transfer operation (tro)', async t => {
478
+ const wallet = await createWallet(testKeyPair1.mnemonic);
479
+ const otherWallet = await createWallet(testKeyPair2.mnemonic);
480
+ const txHash = toBuf(hex('05', 32));
481
+ const txValidity = toBuf(hex('06', 32));
482
+ const incomingNonce = toBuf(hex('07', 32));
483
+ const incomingSignature = toBuf(hex('08', 64));
484
+ const amount = toBuf(hex('09', 16));
485
+
486
+ const builder = new ApplyStateMessageBuilder(wallet, config);
487
+ await builder
488
+ .setPhase('complete')
489
+ .setOutput('buffer')
490
+ .setOperationType(OperationType.TRANSFER)
491
+ .setAddress(wallet.address)
492
+ .setTxHash(txHash)
493
+ .setTxValidity(txValidity)
494
+ .setIncomingNonce(incomingNonce)
495
+ .setIncomingAddress(otherWallet.address)
496
+ .setAmount(amount)
497
+ .setIncomingSignature(incomingSignature)
498
+ .build();
499
+
500
+ const payload = builder.getPayload();
501
+ t.is(payload.type, OperationType.TRANSFER);
502
+ expectAddressBuffer(t, payload.address, 'address');
503
+ t.ok(b4a.equals(payload.address, addressToBuffer(wallet.address, config.addressPrefix)));
504
+ expectPayloadKeys(t, payload, 'tro');
505
+ expectKeys(t, payload.tro, ['tx', 'txv', 'to', 'am', 'in', 'is', 'va', 'vn', 'vs'], 'tro');
506
+ expectBufferField(t, payload.tro.tx, 32, 'tro.tx');
507
+ expectBufferField(t, payload.tro.txv, 32, 'tro.txv');
508
+ expectAddressBuffer(t, payload.tro.to, 'tro.to');
509
+ expectBufferField(t, payload.tro.am, 16, 'tro.am');
510
+ expectBufferField(t, payload.tro.in, 32, 'tro.in');
511
+ expectBufferField(t, payload.tro.is, 64, 'tro.is');
512
+ expectAddressBuffer(t, payload.tro.va, 'tro.va');
513
+ expectBufferField(t, payload.tro.vn, 32, 'tro.vn');
514
+ expectBufferField(t, payload.tro.vs, 64, 'tro.vs');
515
+ t.ok(b4a.equals(payload.tro.tx, txHash));
516
+ t.ok(b4a.equals(payload.tro.txv, txValidity));
517
+ t.ok(b4a.equals(payload.tro.to, addressToBuffer(otherWallet.address, config.addressPrefix)));
518
+ t.ok(b4a.equals(payload.tro.am, amount));
519
+ t.ok(b4a.equals(payload.tro.in, incomingNonce));
520
+ t.ok(b4a.equals(payload.tro.is, incomingSignature));
521
+ });