@dashevo/wasm-dpp 0.23.0-dev.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 (110) hide show
  1. package/.babelrc +5 -0
  2. package/.editorconfig +13 -0
  3. package/.eslintignore +1 -0
  4. package/.eslintrc +15 -0
  5. package/.mocharc.yml +4 -0
  6. package/CHANGELOG.md +397 -0
  7. package/LICENSE +20 -0
  8. package/README.md +37 -0
  9. package/karma.conf.js +53 -0
  10. package/package.json +107 -0
  11. package/test/.eslintrc +12 -0
  12. package/test/integration/DashPlatformProtocol.spec.js +53 -0
  13. package/test/integration/ajv/keywords/byteArray/addByteArrayKeyword.spec.js +148 -0
  14. package/test/integration/dataContract/DataContractFacade.spec.js +84 -0
  15. package/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js +357 -0
  16. package/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js +444 -0
  17. package/test/integration/dataContract/validation/validateDataContractFactory.spec.js +2191 -0
  18. package/test/integration/document/Document.spec.js +90 -0
  19. package/test/integration/document/DocumentFacade.spec.js +155 -0
  20. package/test/integration/document/stateTransition/DocumentsBatchTransition/DocumentBatchTransition.spec.js +83 -0
  21. package/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js +1146 -0
  22. package/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js +294 -0
  23. package/test/integration/document/validation/validateDocumentFactory.spec.js +447 -0
  24. package/test/integration/error/consensus/createConsensusError.spec.js +21 -0
  25. package/test/integration/identity/IdentityFacade.spec.js +187 -0
  26. package/test/integration/identity/stateTransition/IdentityCreateTransition/validation/basic/validateIdentityCreateTransitionBasicFactory.spec.js +422 -0
  27. package/test/integration/identity/stateTransition/IdentityTopUpTransition/validation/basic/validateIdentityTopUpTransitionBasicFactory.spec.js +361 -0
  28. package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/basic/validateIdentityUpdateTransitionBasicFactory.spec.js +595 -0
  29. package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validateIdentityUpdateTransitionStateFactory.spec.js +299 -0
  30. package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validatePublicKeysState.spec.js +66 -0
  31. package/test/integration/identity/stateTransition/assetLockProof/chain/validateChainAssetLockProofStructureFactory.spec.js +415 -0
  32. package/test/integration/identity/stateTransition/assetLockProof/fetchAssetLockTransactionOutputFactory.spec.js +134 -0
  33. package/test/integration/identity/stateTransition/assetLockProof/instant/validateInstantAssetLockProofStructureFactory.spec.js +401 -0
  34. package/test/integration/identity/stateTransition/assetLockProof/validateAssetLockTransactionFactory.spec.js +205 -0
  35. package/test/integration/identity/stateTransition/validatePublicKeySignaturesFactory.spec.js +127 -0
  36. package/test/integration/identity/validation/validateIdentityFactory.spec.js +370 -0
  37. package/test/integration/identity/validation/validatePublicKeysFactory.spec.js +497 -0
  38. package/test/integration/stateTransition/AbstractStateTransitionIdentitySigned.spec.js +507 -0
  39. package/test/integration/stateTransition/StateTransitionFacade.spec.js +418 -0
  40. package/test/integration/stateTransition/calculateStateTransitionFee.spec.js +35 -0
  41. package/test/integration/util/generateEntropy.spec.js +17 -0
  42. package/test/integration/util/serializer.spec.js +24 -0
  43. package/test/unit/DashPlatformProtocol.spec.js +79 -0
  44. package/test/unit/Identifier.spec.js +123 -0
  45. package/test/unit/Metadata.spec.js +37 -0
  46. package/test/unit/dataContract/DataContract.spec.js +407 -0
  47. package/test/unit/dataContract/DataContractFactory.spec.js +178 -0
  48. package/test/unit/dataContract/createDataContract.spec.js +57 -0
  49. package/test/unit/dataContract/errors/InvalidDataContractError.spec.js +46 -0
  50. package/test/unit/dataContract/generateDataContractId.spec.js +19 -0
  51. package/test/unit/dataContract/getBinaryPropertiesFromSchema.spec.js +103 -0
  52. package/test/unit/dataContract/getPropertyDefinitionByPath.spec.js +84 -0
  53. package/test/unit/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition.spec.js +160 -0
  54. package/test/unit/dataContract/stateTransition/DataContractCreateTransition/applyDataContractCreateTransitionFactory.spec.js +48 -0
  55. package/test/unit/dataContract/stateTransition/DataContractCreateTransition/validation/state/validateDataContractCreateTransitionStateFactory.spec.js +85 -0
  56. package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/DataContractUpdateTransition.spec.js +158 -0
  57. package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/applyDataContractUpdateTransitionFactory.spec.js +47 -0
  58. package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateIndicesAreBackwardCompatible.spec.js +121 -0
  59. package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory.spec.js +111 -0
  60. package/test/unit/dataContract/validation/validateDataContractMaxDepthFactory.spec.js +93 -0
  61. package/test/unit/dataContract/validation/validateDataContractPatternsFactory.spec.js +64 -0
  62. package/test/unit/dataTrigger/DataTrigger.spec.js +132 -0
  63. package/test/unit/dataTrigger/DataTriggerExecutionContext.spec.js +29 -0
  64. package/test/unit/dataTrigger/dashpayDataTriggers/createContactRequestDataTrigger.spec.js +109 -0
  65. package/test/unit/dataTrigger/dpnsTriggers/createDomainDataTrigger.spec.js +382 -0
  66. package/test/unit/dataTrigger/featureFlagDataTriggers/createFeatureFlagDataTrigger.spec.js +101 -0
  67. package/test/unit/dataTrigger/getDataTriggersFactory.spec.js +113 -0
  68. package/test/unit/dataTrigger/rejectDataTrigger.spec.js +51 -0
  69. package/test/unit/dataTrigger/rewardShareDataTriggers/createMasternodeRewardSharesDataTrigger.spec.js +200 -0
  70. package/test/unit/decodeProtocolEntityFactory.spec.js +75 -0
  71. package/test/unit/document/Document.spec.js +444 -0
  72. package/test/unit/document/DocumentFactory.spec.js +376 -0
  73. package/test/unit/document/errors/InvalidDocumentError.spec.js +46 -0
  74. package/test/unit/document/fetchAndValidateDataContractFactory.spec.js +66 -0
  75. package/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js +168 -0
  76. package/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js +171 -0
  77. package/test/unit/document/stateTransition/DocumetsBatchTransition/documentTransition/DocumentCreateTransition.spec.js +25 -0
  78. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesById.spec.js +31 -0
  79. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js +122 -0
  80. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/validatePartialCompoundIndices.spec.js +75 -0
  81. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js +128 -0
  82. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js +811 -0
  83. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +279 -0
  84. package/test/unit/errors/consensus/codes.spec.js +102 -0
  85. package/test/unit/identity/Identity.spec.js +243 -0
  86. package/test/unit/identity/IdentityFactory.spec.js +274 -0
  87. package/test/unit/identity/IdentityPublicKey.spec.js +273 -0
  88. package/test/unit/identity/creditsConverter.spec.js +34 -0
  89. package/test/unit/identity/errors/InvalidIdentityError.spec.js +46 -0
  90. package/test/unit/identity/stateTransition/IdentityCreateTransition/IdentityCreateTransition.spec.js +184 -0
  91. package/test/unit/identity/stateTransition/IdentityCreateTransition/applyIdentityCreateTransitionFactory.spec.js +90 -0
  92. package/test/unit/identity/stateTransition/IdentityCreateTransition/validation/state/validateIdentityCreateTransitionStateFactory.spec.js +71 -0
  93. package/test/unit/identity/stateTransition/IdentityTopUpTransition/IdentityTopUpTransition.spec.js +137 -0
  94. package/test/unit/identity/stateTransition/IdentityTopUpTransition/applyIdentityTopUpTransitionFactory.spec.js +108 -0
  95. package/test/unit/identity/stateTransition/IdentityTopUpTransition/validation/state/validateIdentityTopUpTransitionStateFactory.spec.js +22 -0
  96. package/test/unit/identity/stateTransition/IdentityUpdateTransition/IdentityUpdateTransition.spec.js +219 -0
  97. package/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js +149 -0
  98. package/test/unit/identity/stateTransition/assetLockProof/createAssetLockProofInstance.spec.js +21 -0
  99. package/test/unit/identity/stateTransition/assetLockProof/fetchAssetLockPublicKeyHashFactory.spec.js +36 -0
  100. package/test/unit/identity/validation/validateRequiredPurposeAndSecurityLevelFactory.spec.js +47 -0
  101. package/test/unit/stateTransition/StateTransitionFactory.spec.js +160 -0
  102. package/test/unit/stateTransition/createStateTransitionFactory.spec.js +72 -0
  103. package/test/unit/stateTransition/errors/InvalidStateTransitionError.spec.js +51 -0
  104. package/test/unit/stateTransition/validation/validateStateTransitionBasicFactory.spec.js +138 -0
  105. package/test/unit/stateTransition/validation/validateStateTransitionFeeFactory.spec.js +372 -0
  106. package/test/unit/stateTransition/validation/validateStateTransitionIdentitySignatureFactory.spec.js +339 -0
  107. package/test/unit/stateTransition/validation/validateStateTransitionKeySignatureFactory.spec.js +86 -0
  108. package/test/unit/stateTransition/validation/validateStateTransitionStateFactory.spec.js +89 -0
  109. package/test/unit/version/validateProtocolVersionFactory.spec.js +80 -0
  110. package/webpack.config.js +49 -0
@@ -0,0 +1,401 @@
1
+ const { getRE2Class } = require('@dashevo/wasm-re2');
2
+
3
+ const DashCoreLib = require('@dashevo/dashcore-lib');
4
+
5
+ const createAjv = require('../../../../../../lib/ajv/createAjv');
6
+
7
+ const getInstantAssetLockFixture = require('../../../../../../lib/test/fixtures/getInstantAssetLockProofFixture');
8
+ const JsonSchemaValidator = require('../../../../../../lib/validation/JsonSchemaValidator');
9
+ const createStateRepositoryMock = require('../../../../../../lib/test/mocks/createStateRepositoryMock');
10
+ const InvalidIdentityAssetLockProofError = require('../../../../../../lib/errors/consensus/basic/identity/InvalidInstantAssetLockProofError');
11
+ const IdentityAssetLockProofLockedTransactionMismatchError = require('../../../../../../lib/errors/consensus/basic/identity/IdentityAssetLockProofLockedTransactionMismatchError');
12
+ const InvalidIdentityAssetLockProofSignatureError = require('../../../../../../lib/errors/consensus/basic/identity/InvalidInstantAssetLockProofSignatureError');
13
+
14
+ const { expectValidationError, expectJsonSchemaError } = require(
15
+ '../../../../../../lib/test/expect/expectError',
16
+ );
17
+
18
+ const ValidationResult = require('../../../../../../lib/validation/ValidationResult');
19
+ const InvalidIdentityAssetLockTransactionError = require('../../../../../../lib/errors/consensus/basic/identity/InvalidIdentityAssetLockTransactionError');
20
+ const validateInstantAssetLockProofStructureFactory = require('../../../../../../lib/identity/stateTransition/assetLockProof/instant/validateInstantAssetLockProofStructureFactory');
21
+
22
+ describe('validateInstantAssetLockProofStructureFactory', () => {
23
+ let rawProof;
24
+ let transaction;
25
+ let stateRepositoryMock;
26
+ let instantLockFromBufferMock;
27
+ let instantLockMock;
28
+ let validateInstantAssetLockProofStructure;
29
+ let jsonSchemaValidator;
30
+ let validateAssetLockTransactionResult;
31
+ let publicKeyHash;
32
+ let validateAssetLockTransactionMock;
33
+
34
+ beforeEach(async function beforeEach() {
35
+ const assetLock = getInstantAssetLockFixture();
36
+ transaction = assetLock.getTransaction();
37
+
38
+ rawProof = assetLock.toObject();
39
+
40
+ const RE2 = await getRE2Class();
41
+ const ajv = createAjv(RE2);
42
+
43
+ jsonSchemaValidator = new JsonSchemaValidator(ajv);
44
+
45
+ stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
46
+ stateRepositoryMock.verifyInstantLock.resolves(true);
47
+
48
+ instantLockMock = {
49
+ txid: transaction.id,
50
+ verify: this.sinonSandbox.stub().resolves(true),
51
+ };
52
+
53
+ instantLockFromBufferMock = this.sinonSandbox.stub(DashCoreLib.InstantLock, 'fromBuffer').returns(instantLockMock);
54
+
55
+ publicKeyHash = Buffer.from('152073ca2300a86b510fa2f123d3ea7da3af68dc', 'hex');
56
+
57
+ validateAssetLockTransactionResult = new ValidationResult();
58
+ validateAssetLockTransactionResult.setData({
59
+ publicKeyHash,
60
+ transaction,
61
+ });
62
+ validateAssetLockTransactionMock = this.sinonSandbox.stub().resolves(
63
+ validateAssetLockTransactionResult,
64
+ );
65
+
66
+ validateInstantAssetLockProofStructure = validateInstantAssetLockProofStructureFactory(
67
+ jsonSchemaValidator,
68
+ stateRepositoryMock,
69
+ validateAssetLockTransactionMock,
70
+ );
71
+ });
72
+
73
+ afterEach(() => {
74
+ instantLockFromBufferMock.restore();
75
+ });
76
+
77
+ describe('type', () => {
78
+ it('should be present', async () => {
79
+ delete rawProof.type;
80
+
81
+ const result = await validateInstantAssetLockProofStructure(rawProof);
82
+
83
+ expectJsonSchemaError(result);
84
+
85
+ const [error] = result.getErrors();
86
+
87
+ expect(error.getInstancePath()).to.equal('');
88
+ expect(error.getKeyword()).to.equal('required');
89
+ expect(error.getParams().missingProperty).to.equal('type');
90
+
91
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
92
+ expect(instantLockMock.verify).to.not.be.called();
93
+ expect(validateAssetLockTransactionMock).to.not.be.called();
94
+ });
95
+
96
+ it('should be equal to 0', async () => {
97
+ rawProof.type = -1;
98
+
99
+ const result = await validateInstantAssetLockProofStructure(rawProof);
100
+
101
+ expectJsonSchemaError(result);
102
+
103
+ const [error] = result.getErrors();
104
+
105
+ expect(error.getInstancePath()).to.equal('/type');
106
+ expect(error.getKeyword()).to.equal('const');
107
+
108
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
109
+ expect(instantLockMock.verify).to.not.be.called();
110
+ expect(validateAssetLockTransactionMock).to.not.be.called();
111
+ });
112
+ });
113
+
114
+ describe('instantLock', () => {
115
+ it('should be present', async () => {
116
+ delete rawProof.instantLock;
117
+
118
+ const result = await validateInstantAssetLockProofStructure(rawProof);
119
+
120
+ expectJsonSchemaError(result);
121
+
122
+ const [error] = result.getErrors();
123
+
124
+ expect(error.getInstancePath()).to.equal('');
125
+ expect(error.getKeyword()).to.equal('required');
126
+ expect(error.getParams().missingProperty).to.equal('instantLock');
127
+
128
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
129
+ expect(instantLockMock.verify).to.not.be.called();
130
+ expect(validateAssetLockTransactionMock).to.not.be.called();
131
+ });
132
+
133
+ it('should be a byte array', async () => {
134
+ rawProof.instantLock = new Array(165).fill('string');
135
+
136
+ const result = await validateInstantAssetLockProofStructure(rawProof);
137
+
138
+ expectJsonSchemaError(result, 2);
139
+
140
+ const [error, byteArrayError] = result.getErrors();
141
+
142
+ expect(error.getInstancePath()).to.equal('/instantLock/0');
143
+ expect(error.getKeyword()).to.equal('type');
144
+
145
+ expect(byteArrayError.getKeyword()).to.equal('byteArray');
146
+
147
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
148
+ expect(instantLockMock.verify).to.not.be.called();
149
+ expect(validateAssetLockTransactionMock).to.not.be.called();
150
+ });
151
+
152
+ it('should not be shorter than 160 bytes', async () => {
153
+ rawProof.instantLock = Buffer.alloc(159);
154
+
155
+ const result = await validateInstantAssetLockProofStructure(rawProof);
156
+
157
+ expectJsonSchemaError(result);
158
+
159
+ const [error] = result.getErrors();
160
+
161
+ expect(error.getInstancePath()).to.equal('/instantLock');
162
+ expect(error.getKeyword()).to.equal('minItems');
163
+
164
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
165
+ expect(instantLockMock.verify).to.not.be.called();
166
+ expect(validateAssetLockTransactionMock).to.not.be.called();
167
+ });
168
+
169
+ it('should not be longer than 100 Kb', async () => {
170
+ rawProof.instantLock = Buffer.alloc(100001);
171
+
172
+ const result = await validateInstantAssetLockProofStructure(rawProof);
173
+
174
+ expectJsonSchemaError(result);
175
+
176
+ const [error] = result.getErrors();
177
+
178
+ expect(error.getInstancePath()).to.equal('/instantLock');
179
+ expect(error.getKeyword()).to.equal('maxItems');
180
+
181
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
182
+ expect(instantLockMock.verify).to.not.be.called();
183
+ expect(validateAssetLockTransactionMock).to.not.be.called();
184
+ });
185
+
186
+ it('should be valid', async () => {
187
+ const instantLockError = new Error('something is wrong');
188
+
189
+ instantLockFromBufferMock.throws(instantLockError);
190
+
191
+ rawProof.instantLock = Buffer.alloc(200);
192
+
193
+ const result = await validateInstantAssetLockProofStructure(rawProof);
194
+ expectValidationError(result, InvalidIdentityAssetLockProofError);
195
+
196
+ const [error] = result.getErrors();
197
+
198
+ expect(error.getCode()).to.equal(1041);
199
+ expect(error.getValidationError()).to.equal(instantLockError);
200
+
201
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
202
+ expect(instantLockMock.verify).to.not.be.called();
203
+ expect(validateAssetLockTransactionMock).to.not.be.called();
204
+ });
205
+
206
+ it('should lock the same transaction', async () => {
207
+ const txId = Buffer.alloc(32);
208
+ instantLockMock.txid = txId.toString('hex');
209
+
210
+ const result = await validateInstantAssetLockProofStructure(rawProof);
211
+
212
+ expectValidationError(result, IdentityAssetLockProofLockedTransactionMismatchError);
213
+
214
+ const [error] = result.getErrors();
215
+
216
+ expect(error.getCode()).to.equal(1031);
217
+ expect(error.getInstantLockTransactionId()).to.deep.equal(txId);
218
+ expect(error.getAssetLockTransactionId()).to.deep.equal(Buffer.from(transaction.id, 'hex'));
219
+
220
+ // expect(stateRepositoryMock.verifyInstantLock).to.be.calledOnce();
221
+ expect(instantLockMock.verify).to.not.be.called();
222
+ expect(validateAssetLockTransactionMock).to.be.calledOnce();
223
+ });
224
+
225
+ it('should have valid signature', async () => {
226
+ stateRepositoryMock.verifyInstantLock.resolves(false);
227
+
228
+ const result = await validateInstantAssetLockProofStructure(rawProof);
229
+
230
+ expectValidationError(result, InvalidIdentityAssetLockProofSignatureError);
231
+
232
+ const [error] = result.getErrors();
233
+
234
+ expect(error.getCode()).to.equal(1042);
235
+
236
+ expect(stateRepositoryMock.verifyInstantLock).to.be.calledOnce();
237
+ expect(validateAssetLockTransactionMock).to.not.be.called();
238
+ });
239
+ });
240
+
241
+ describe('transaction', () => {
242
+ it('should be present', async () => {
243
+ delete rawProof.transaction;
244
+
245
+ const result = await validateInstantAssetLockProofStructure(rawProof);
246
+
247
+ expectJsonSchemaError(result);
248
+
249
+ const [error] = result.getErrors();
250
+
251
+ expect(error.getInstancePath()).to.equal('');
252
+ expect(error.getKeyword()).to.equal('required');
253
+ expect(error.getParams().missingProperty).to.equal('transaction');
254
+
255
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
256
+ expect(instantLockMock.verify).to.not.be.called();
257
+ expect(validateAssetLockTransactionMock).to.not.be.called();
258
+ });
259
+
260
+ it('should be a byte array', async () => {
261
+ rawProof.transaction = new Array(65).fill('string');
262
+
263
+ const result = await validateInstantAssetLockProofStructure(rawProof);
264
+
265
+ expectJsonSchemaError(result, 2);
266
+
267
+ const [error, byteArrayError] = result.getErrors();
268
+
269
+ expect(error.getInstancePath()).to.equal('/transaction/0');
270
+ expect(error.getKeyword()).to.equal('type');
271
+
272
+ expect(byteArrayError.getKeyword()).to.equal('byteArray');
273
+
274
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
275
+ expect(instantLockMock.verify).to.not.be.called();
276
+ expect(validateAssetLockTransactionMock).to.not.be.called();
277
+ });
278
+
279
+ it('should not be shorter than 1 byte', async () => {
280
+ rawProof.transaction = Buffer.alloc(0);
281
+
282
+ const result = await validateInstantAssetLockProofStructure(rawProof);
283
+
284
+ expectJsonSchemaError(result);
285
+
286
+ const [error] = result.getErrors();
287
+
288
+ expect(error.instancePath).to.equal('/transaction');
289
+ expect(error.getKeyword()).to.equal('minItems');
290
+
291
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
292
+ expect(instantLockMock.verify).to.not.be.called();
293
+ expect(validateAssetLockTransactionMock).to.not.be.called();
294
+ });
295
+
296
+ it('should not be longer than 100 Kb', async () => {
297
+ rawProof.transaction = Buffer.alloc(100001);
298
+
299
+ const result = await validateInstantAssetLockProofStructure(rawProof);
300
+
301
+ expectJsonSchemaError(result);
302
+
303
+ const [error] = result.getErrors();
304
+
305
+ expect(error.instancePath).to.equal('/transaction');
306
+ expect(error.getKeyword()).to.equal('maxItems');
307
+
308
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
309
+ expect(instantLockMock.verify).to.not.be.called();
310
+ expect(validateAssetLockTransactionMock).to.not.be.called();
311
+ });
312
+
313
+ it('should should be valid', async () => {
314
+ const validationError = new Error('parsing failed');
315
+
316
+ const consensusError = new InvalidIdentityAssetLockTransactionError(validationError.message);
317
+
318
+ consensusError.setValidationError(validationError);
319
+
320
+ validateAssetLockTransactionResult.addError(consensusError);
321
+ validateAssetLockTransactionMock.resolves(validateAssetLockTransactionResult);
322
+
323
+ const result = await validateInstantAssetLockProofStructure(rawProof);
324
+
325
+ expectValidationError(result, InvalidIdentityAssetLockTransactionError);
326
+
327
+ const [error] = result.getErrors();
328
+
329
+ expect(error.getCode()).to.equal(1038);
330
+
331
+ expect(error).to.equal(consensusError);
332
+
333
+ expect(error.getValidationError()).to.equal(validationError);
334
+
335
+ // expect(stateRepositoryMock.verifyInstantLock).to.be.calledOnce();
336
+ expect(instantLockMock.verify).to.not.be.called();
337
+ expect(validateAssetLockTransactionMock).to.be.calledOnce();
338
+ });
339
+ });
340
+
341
+ describe('outputIndex', () => {
342
+ it('should be present', async () => {
343
+ delete rawProof.outputIndex;
344
+
345
+ const result = await validateInstantAssetLockProofStructure(rawProof);
346
+
347
+ expectJsonSchemaError(result);
348
+
349
+ const [error] = result.getErrors();
350
+
351
+ expect(error.instancePath).to.equal('');
352
+ expect(error.getKeyword()).to.equal('required');
353
+ expect(error.getParams().missingProperty).to.equal('outputIndex');
354
+
355
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
356
+ expect(instantLockMock.verify).to.not.be.called();
357
+ });
358
+
359
+ it('should be an integer', async () => {
360
+ rawProof.outputIndex = 1.1;
361
+
362
+ const result = await validateInstantAssetLockProofStructure(rawProof);
363
+
364
+ expectJsonSchemaError(result, 1);
365
+
366
+ const [error] = result.getErrors();
367
+
368
+ expect(error.instancePath).to.equal('/outputIndex');
369
+ expect(error.getKeyword()).to.equal('type');
370
+
371
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
372
+ expect(instantLockMock.verify).to.not.be.called();
373
+ });
374
+
375
+ it('should not be less than 0', async () => {
376
+ rawProof.outputIndex = -1;
377
+
378
+ const result = await validateInstantAssetLockProofStructure(rawProof);
379
+
380
+ expectJsonSchemaError(result);
381
+
382
+ const [error] = result.getErrors();
383
+
384
+ expect(error.instancePath).to.equal('/outputIndex');
385
+ expect(error.getKeyword()).to.equal('minimum');
386
+
387
+ expect(stateRepositoryMock.verifyInstantLock).to.not.be.called();
388
+ expect(instantLockMock.verify).to.not.be.called();
389
+ });
390
+ });
391
+
392
+ it('should return valid result', async () => {
393
+ const result = await validateInstantAssetLockProofStructure(rawProof);
394
+
395
+ expect(result).to.be.an.instanceOf(ValidationResult);
396
+ expect(result.isValid()).to.be.true();
397
+ expect(result.getData()).to.deep.equal(publicKeyHash);
398
+
399
+ // expect(stateRepositoryMock.verifyInstantLock).to.be.calledOnce();
400
+ });
401
+ });
@@ -0,0 +1,205 @@
1
+ const { Transaction } = require('@dashevo/dashcore-lib');
2
+
3
+ const DashCoreLib = require('@dashevo/dashcore-lib');
4
+ const validateAssetLockTransactionFactory = require('../../../../../lib/identity/stateTransition/assetLockProof/validateAssetLockTransactionFactory');
5
+ const createStateRepositoryMock = require('../../../../../lib/test/mocks/createStateRepositoryMock');
6
+
7
+ const ValidationResult = require('../../../../../lib/validation/ValidationResult');
8
+
9
+ const { expectValidationError } = require('../../../../../lib/test/expect/expectError');
10
+
11
+ const InvalidIdentityAssetLockTransactionError = require('../../../../../lib/errors/consensus/basic/identity/InvalidIdentityAssetLockTransactionError');
12
+ const IdentityAssetLockTransactionOutputNotFoundError = require('../../../../../lib/errors/consensus/basic/identity/IdentityAssetLockTransactionOutputNotFoundError');
13
+ const IdentityAssetLockTransactionOutPointAlreadyExistsError = require('../../../../../lib/errors/consensus/basic/identity/IdentityAssetLockTransactionOutPointAlreadyExistsError');
14
+ const InvalidIdentityAssetLockTransactionOutputError = require('../../../../../lib/errors/consensus/basic/identity/InvalidIdentityAssetLockTransactionOutputError');
15
+ const InvalidAssetLockTransactionOutputReturnSizeError = require('../../../../../lib/errors/consensus/basic/identity/InvalidAssetLockTransactionOutputReturnSizeError');
16
+ const StateTransitionExecutionContext = require('../../../../../lib/stateTransition/StateTransitionExecutionContext');
17
+
18
+ describe('validateAssetLockTransactionFactory', () => {
19
+ let stateRepositoryMock;
20
+ let validateAssetLockTransaction;
21
+ let rawTransaction;
22
+ let outputIndex;
23
+ let transactionInstance;
24
+ let transactionMock;
25
+ let executionContext;
26
+
27
+ beforeEach(function beforeEach() {
28
+ rawTransaction = '030000000137feb5676d0851337ea3c9a992496aab7a0b3eee60aeeb9774000b7f4bababa5000000006b483045022100d91557de37645c641b948c6cd03b4ae3791a63a650db3e2fee1dcf5185d1b10402200e8bd410bf516ca61715867666d31e44495428ce5c1090bf2294a829ebcfa4ef0121025c3cc7fbfc52f710c941497fd01876c189171ea227458f501afcb38a297d65b4ffffffff021027000000000000166a14152073ca2300a86b510fa2f123d3ea7da3af68dcf77cb0090a0000001976a914152073ca2300a86b510fa2f123d3ea7da3af68dc88ac00000000';
29
+ outputIndex = 0;
30
+ transactionInstance = new Transaction(rawTransaction);
31
+
32
+ executionContext = new StateTransitionExecutionContext();
33
+
34
+ stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
35
+
36
+ stateRepositoryMock.isAssetLockTransactionOutPointAlreadyUsed.returns(false);
37
+
38
+ validateAssetLockTransaction = validateAssetLockTransactionFactory(stateRepositoryMock);
39
+ });
40
+
41
+ afterEach(() => {
42
+ if (transactionMock) {
43
+ transactionMock.restore();
44
+ }
45
+ });
46
+
47
+ it('should be valid transaction', async () => {
48
+ rawTransaction = '030000000137feb5676d085133';
49
+
50
+ validateAssetLockTransaction = validateAssetLockTransactionFactory(stateRepositoryMock);
51
+
52
+ const result = await validateAssetLockTransaction(
53
+ rawTransaction,
54
+ outputIndex,
55
+ executionContext,
56
+ );
57
+
58
+ expectValidationError(result, InvalidIdentityAssetLockTransactionError);
59
+
60
+ const [error] = result.getErrors();
61
+
62
+ expect(error.getCode()).to.equal(1038);
63
+ expect(error.getValidationError()).to.be.instanceOf(Error);
64
+
65
+ expect(result.getData()).to.be.undefined();
66
+ expect(stateRepositoryMock.isAssetLockTransactionOutPointAlreadyUsed).to.not.be.called();
67
+ });
68
+
69
+ it('should return IdentityAssetLockTransactionOutputNotFoundError on invalid outputIndex', async () => {
70
+ outputIndex = 42;
71
+
72
+ const result = await validateAssetLockTransaction(
73
+ rawTransaction,
74
+ outputIndex,
75
+ executionContext,
76
+ );
77
+
78
+ expectValidationError(result, IdentityAssetLockTransactionOutputNotFoundError);
79
+
80
+ const [error] = result.getErrors();
81
+
82
+ expect(error.getCode()).to.equal(1034);
83
+ expect(error.getOutputIndex()).to.equal(outputIndex);
84
+
85
+ expect(result.getData()).to.be.undefined();
86
+ expect(stateRepositoryMock.isAssetLockTransactionOutPointAlreadyUsed).to.not.be.called();
87
+ });
88
+
89
+ it('should point to output with OR_RETURN', async function it() {
90
+ const isDataOut = this.sinonSandbox.stub().returns(false);
91
+
92
+ const stubInstance = this.sinonSandbox.createStubInstance(Transaction);
93
+
94
+ stubInstance.outputs = [{
95
+ script: {
96
+ isDataOut,
97
+ },
98
+ }];
99
+
100
+ stubInstance.getOutPointBuffer.returns(transactionInstance.getOutPointBuffer(outputIndex));
101
+
102
+ transactionMock = this.sinonSandbox.stub(DashCoreLib, 'Transaction').returns(
103
+ stubInstance,
104
+ );
105
+
106
+ const result = await validateAssetLockTransaction(
107
+ rawTransaction,
108
+ outputIndex,
109
+ executionContext,
110
+ );
111
+
112
+ expectValidationError(result, InvalidIdentityAssetLockTransactionOutputError);
113
+
114
+ const [error] = result.getErrors();
115
+
116
+ expect(error.getCode()).to.equal(1039);
117
+ expect(error.getOutputIndex()).to.equal(outputIndex);
118
+ });
119
+
120
+ it('should contain valid public key hash', async function it() {
121
+ const isDataOut = this.sinonSandbox.stub().returns(true);
122
+ const getData = this.sinonSandbox.stub().returns(Buffer.alloc(0));
123
+
124
+ const stubInstance = this.sinonSandbox.createStubInstance(Transaction);
125
+ stubInstance.outputs = [{
126
+ script: {
127
+ isDataOut,
128
+ getData,
129
+ },
130
+ }];
131
+ stubInstance.getOutPointBuffer.returns(transactionInstance.getOutPointBuffer(outputIndex));
132
+
133
+ transactionMock = this.sinonSandbox.stub(DashCoreLib, 'Transaction').returns(
134
+ stubInstance,
135
+ );
136
+
137
+ const result = await validateAssetLockTransaction(
138
+ rawTransaction,
139
+ outputIndex,
140
+ executionContext,
141
+ );
142
+
143
+ expectValidationError(result, InvalidAssetLockTransactionOutputReturnSizeError);
144
+
145
+ const [error] = result.getErrors();
146
+
147
+ expect(error.getCode()).to.equal(1037);
148
+ expect(error.getOutputIndex()).to.equal(outputIndex);
149
+ });
150
+
151
+ it('should return IdentityAssetLockTransactionOutPointAlreadyExistsError if outPoint was already used', async () => {
152
+ stateRepositoryMock.isAssetLockTransactionOutPointAlreadyUsed.returns(true);
153
+
154
+ const result = await validateAssetLockTransaction(
155
+ rawTransaction,
156
+ outputIndex,
157
+ executionContext,
158
+ );
159
+
160
+ expectValidationError(result, IdentityAssetLockTransactionOutPointAlreadyExistsError);
161
+
162
+ const [error] = result.getErrors();
163
+
164
+ expect(error.getCode()).to.equal(1033);
165
+
166
+ const transaction = new Transaction(rawTransaction);
167
+
168
+ expect(Buffer.isBuffer(error.getTransactionId())).to.be.true();
169
+ expect(error.getTransactionId()).to.deep.equal(Buffer.from(transaction.id, 'hex'));
170
+ expect(error.getOutputIndex()).to.deep.equal(outputIndex);
171
+
172
+ expect(result.getData()).to.be.undefined();
173
+ expect(stateRepositoryMock.isAssetLockTransactionOutPointAlreadyUsed)
174
+ .to.be.calledOnceWithExactly(
175
+ transaction.getOutPointBuffer(outputIndex),
176
+ executionContext,
177
+ );
178
+ });
179
+
180
+ it('should return valid result', async () => {
181
+ const result = await validateAssetLockTransaction(
182
+ rawTransaction,
183
+ outputIndex,
184
+ executionContext,
185
+ );
186
+
187
+ expect(result).to.be.an.instanceOf(ValidationResult);
188
+
189
+ expect(result.isValid()).to.be.true();
190
+
191
+ const initialTransaction = new Transaction(rawTransaction);
192
+ const initialPublicKeyHash = initialTransaction.outputs[outputIndex].script.getData();
193
+
194
+ expect(stateRepositoryMock.isAssetLockTransactionOutPointAlreadyUsed)
195
+ .to.be.calledOnceWithExactly(
196
+ initialTransaction.getOutPointBuffer(outputIndex),
197
+ executionContext,
198
+ );
199
+
200
+ const { transaction, publicKeyHash } = result.getData();
201
+ expect(publicKeyHash).to.deep.equal(initialPublicKeyHash);
202
+ expect(transaction).to.be.an.instanceOf(Transaction);
203
+ expect(transaction.toJSON()).to.deep.equal(initialTransaction.toJSON());
204
+ });
205
+ });