trac-msb 0.2.8 → 0.2.10

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 (151) hide show
  1. package/.github/workflows/acceptance-tests.yml +7 -11
  2. package/.github/workflows/lint-pr-title.yml +26 -0
  3. package/.github/workflows/unit-tests.yml +2 -8
  4. package/CODE_OF_CONDUCT.md +128 -0
  5. package/README.md +33 -18
  6. package/docker-compose.yml +1 -0
  7. package/docs/trac_network_http_api.openapi.yaml +889 -0
  8. package/msb.mjs +5 -22
  9. package/package.json +14 -10
  10. package/proto/network.proto +74 -0
  11. package/rpc/create_server.js +2 -2
  12. package/rpc/handlers.js +165 -92
  13. package/rpc/routes/v1.js +3 -1
  14. package/rpc/rpc_server.js +4 -4
  15. package/rpc/rpc_services.js +62 -25
  16. package/rpc/utils/helpers.js +83 -52
  17. package/src/config/args.js +46 -0
  18. package/src/config/config.js +78 -5
  19. package/src/config/env.js +70 -3
  20. package/src/core/network/Network.js +34 -70
  21. package/src/core/network/identity/NetworkWalletFactory.js +2 -2
  22. package/src/core/network/protocols/LegacyProtocol.js +67 -0
  23. package/src/core/network/protocols/NetworkMessages.js +48 -0
  24. package/src/core/network/protocols/ProtocolInterface.js +31 -0
  25. package/src/core/network/protocols/ProtocolSession.js +59 -0
  26. package/src/core/network/protocols/V1Protocol.js +64 -0
  27. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
  28. package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
  29. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
  30. package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +2 -3
  31. package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
  32. package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
  33. package/src/core/network/{messaging → protocols/shared}/handlers/TransferOperationHandler.js +17 -16
  34. package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +10 -15
  35. package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +2 -2
  36. package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +5 -5
  37. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +4 -4
  38. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +4 -4
  39. package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +14 -12
  40. package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
  41. package/src/core/network/services/ConnectionManager.js +5 -5
  42. package/src/core/network/services/MessageOrchestrator.js +2 -2
  43. package/src/core/network/services/TransactionPoolService.js +5 -6
  44. package/src/core/network/services/TransactionRateLimiterService.js +12 -13
  45. package/src/core/network/services/ValidatorObserverService.js +5 -6
  46. package/src/core/state/State.js +3 -5
  47. package/src/index.js +156 -181
  48. package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
  49. package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
  50. package/src/messages/network/v1/networkMessageFactory.js +12 -0
  51. package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
  52. package/src/messages/state/ApplyStateMessageDirector.js +516 -0
  53. package/src/messages/state/applyStateMessageFactory.js +12 -0
  54. package/src/utils/buffer.js +53 -1
  55. package/src/utils/check.js +1 -1
  56. package/src/utils/cli.js +0 -8
  57. package/src/utils/constants.js +33 -30
  58. package/src/utils/fileUtils.js +13 -0
  59. package/src/utils/normalizers.js +84 -2
  60. package/src/utils/protobuf/network.cjs +840 -0
  61. package/src/utils/protobuf/operationHelpers.js +10 -0
  62. package/src/utils/type.js +26 -0
  63. package/tests/acceptance/v1/balance/balance.test.mjs +1 -2
  64. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +26 -30
  65. package/tests/acceptance/v1/health/health.test.mjs +33 -0
  66. package/tests/acceptance/v1/rpc.test.mjs +4 -3
  67. package/tests/acceptance/v1/tx/tx.test.mjs +27 -16
  68. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +26 -12
  69. package/tests/fixtures/check.fixtures.js +33 -32
  70. package/tests/fixtures/networkV1.fixtures.js +85 -0
  71. package/tests/fixtures/protobuf.fixtures.js +109 -25
  72. package/tests/helpers/StateNetworkFactory.js +2 -2
  73. package/tests/helpers/address.js +6 -0
  74. package/tests/helpers/autobaseTestHelpers.js +2 -1
  75. package/tests/helpers/config.js +2 -1
  76. package/tests/helpers/setupApplyTests.js +59 -56
  77. package/tests/unit/messages/messages.test.js +12 -0
  78. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
  79. package/tests/unit/messages/network/NetworkMessageDirector.test.js +201 -0
  80. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
  81. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
  82. package/tests/unit/network/ConnectionManager.test.js +6 -5
  83. package/tests/unit/network/networkModule.test.js +3 -2
  84. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
  85. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +9 -6
  86. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +10 -7
  87. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -21
  88. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +53 -38
  89. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +46 -35
  90. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +13 -16
  91. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +17 -11
  92. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +11 -12
  93. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +9 -7
  94. package/tests/unit/state/apply/common/commonScenarioHelper.js +15 -14
  95. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +9 -4
  96. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +17 -11
  97. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +19 -14
  98. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +37 -29
  99. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +9 -7
  100. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +11 -9
  101. package/tests/unit/unit.test.js +1 -1
  102. package/tests/unit/utils/buffer/buffer.test.js +62 -1
  103. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +4 -3
  104. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +3 -2
  105. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +3 -2
  106. package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
  107. package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
  108. package/tests/unit/utils/type/type.test.js +25 -0
  109. package/tests/unit/utils/utils.test.js +1 -0
  110. package/docs/networking-dualstack-plan.md +0 -75
  111. package/docs/networking-layer-redesign.md +0 -155
  112. package/src/core/network/messaging/NetworkMessages.js +0 -64
  113. package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -113
  114. package/src/core/network/messaging/handlers/ResponseHandler.js +0 -107
  115. package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -114
  116. package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -149
  117. package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -98
  118. package/src/core/network/messaging/validators/AdminResponse.js +0 -58
  119. package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
  120. package/src/messages/base/StateBuilder.js +0 -25
  121. package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -425
  122. package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
  123. package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -296
  124. package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
  125. package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
  126. package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -138
  127. package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -69
  128. package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -126
  129. package/tests/integration/apply/addIndexer.test.js +0 -239
  130. package/tests/integration/apply/addWhitelist.test.js +0 -53
  131. package/tests/integration/apply/addWriter.test.js +0 -245
  132. package/tests/integration/apply/apply.test.js +0 -19
  133. package/tests/integration/apply/banValidator.test.js +0 -116
  134. package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
  135. package/tests/integration/apply/postTx/postTx.test.js +0 -196
  136. package/tests/integration/apply/removeIndexer.test.js +0 -132
  137. package/tests/integration/apply/removeWriter.test.js +0 -168
  138. package/tests/integration/apply/transfer.test.js +0 -83
  139. package/tests/integration/integration.test.js +0 -9
  140. package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
  141. package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -17
  142. package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -68
  143. package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -17
  144. package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -424
  145. package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
  146. package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
  147. package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -59
  148. package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -278
  149. package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
  150. /package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +0 -0
  151. /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
+ });