@dashevo/wasm-dpp 0.24.0-dev.11 → 0.24.0-dev.12
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.
- package/dist/index.js +1 -1
- package/dist/lib/dpp.d.ts +9 -0
- package/dist/lib/errors/AbstractConsensusError.d.ts +10 -0
- package/dist/lib/errors/DPPError.d.ts +5 -0
- package/dist/lib/errors/patchConsensusErrors.d.ts +1 -0
- package/dist/lib/{patchIdentifier.d.ts → identifier/patchIdentifier.d.ts} +1 -1
- package/dist/{index.d.ts → lib/index.d.ts} +1 -1
- package/dist/lib/utils/extend.d.ts +1 -0
- package/dist/wasm/wasm_dpp.d.ts +352 -205
- package/lib/dpp.ts +24 -0
- package/lib/errors/AbstractConsensusError.ts +13 -0
- package/lib/errors/DPPError.ts +15 -0
- package/lib/errors/patchConsensusErrors.ts +175 -0
- package/lib/{patchIdentifier.ts → identifier/patchIdentifier.ts} +1 -1
- package/{index.ts → lib/index.ts} +4 -3
- package/lib/test/expect/expectError.js +4 -2
- package/lib/utils/extend.ts +6 -0
- package/package.json +5 -5
- package/src/data_contract/errors/invalid_data_contract.rs +21 -0
- package/src/data_contract/state_transition/data_contract_create_transition/mod.rs +4 -4
- package/src/data_contract/state_transition/data_contract_create_transition/validation.rs +2 -2
- package/src/data_contract/state_transition/data_contract_update_transition/apply.rs +44 -0
- package/src/data_contract/state_transition/data_contract_update_transition/mod.rs +147 -0
- package/src/data_contract/state_transition/data_contract_update_transition/validation.rs +46 -0
- package/src/data_contract/state_transition/mod.rs +2 -0
- package/src/data_contract_factory/data_contract_factory.rs +27 -12
- package/src/errors/consensus/basic/data_contract/data_contract_max_depth_exceed_error.rs +5 -5
- package/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs +4 -4
- package/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs +36 -0
- package/src/errors/consensus/basic/document/missing_document_transition_type_error.rs +20 -0
- package/src/errors/consensus/basic/document/mod.rs +4 -0
- package/src/errors/consensus/basic/identity/duplicated_identity_public_key_error.rs +2 -2
- package/src/errors/consensus/basic/identity/duplicated_identity_public_key_id_error.rs +2 -2
- package/src/errors/consensus/basic/identity/invalid_identity_public_key_security_level_error.rs +2 -2
- package/src/errors/consensus/basic/json_schema_error.rs +1 -1
- package/src/errors/consensus_error.rs +15 -8
- package/src/errors/from.rs +1 -1
- package/src/errors/mod.rs +1 -0
- package/src/errors/protocol_error.rs +12 -0
- package/src/{identifier.rs → identifier/mod.rs} +0 -0
- package/src/{identity_facade.rs → identity/identity_facade.rs} +1 -1
- package/src/{identity_public_key → identity/identity_public_key}/key_type.rs +0 -0
- package/src/{identity_public_key → identity/identity_public_key}/mod.rs +0 -3
- package/src/{identity_public_key → identity/identity_public_key}/purpose.rs +0 -0
- package/src/{identity_public_key → identity/identity_public_key}/security_level.rs +0 -0
- package/src/{identity.rs → identity/mod.rs} +6 -7
- package/src/identity/validation/mod.rs +3 -0
- package/src/identity/validation/public_keys_validator.rs +70 -0
- package/src/lib.rs +1 -6
- package/src/utils.rs +2 -2
- package/src/validation/mod.rs +3 -0
- package/src/{validation_result.rs → validation/validation_result.rs} +0 -0
- package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validateIdentityUpdateTransitionStateFactory.spec.js +1 -1
- package/test/integration/identity/validation/validatePublicKeysFactory.spec.js +79 -114
- package/test/integration/stateTransition/AbstractStateTransitionIdentitySigned.spec.js +0 -11
- package/test/integration/stateTransition/StateTransitionFacade.spec.js +1 -1
- package/test/integration/stateTransition/calculateStateTransitionFeeFactory.spec.js +135 -0
- package/test/unit/dataContract/DataContract.spec.js +5 -9
- package/test/unit/dataContract/DataContractFactory.spec.js +13 -6
- package/test/unit/dataContract/errors/InvalidDataContractError.spec.js +11 -3
- package/test/unit/dataContract/stateTransition/DataContractCreateTransition/validation/state/validateDataContractCreateTransitionStateFactory.spec.js +20 -16
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/DataContractUpdateTransition.spec.js +23 -59
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/applyDataContractUpdateTransitionFactory.spec.js +27 -23
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateIndicesAreBackwardCompatible.spec.js +29 -12
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory.spec.js +66 -49
- package/test/unit/dataContract/validation/validateDataContractPatterns.spec.js +73 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js +1 -1
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js +1 -1
- package/test/unit/identity/IdentityPublicKey.spec.js +25 -31
- package/tsconfig.json +1 -1
- package/wasm/wasm_dpp.d.ts +352 -205
- package/wasm/wasm_dpp.js +759 -372
- package/wasm/wasm_dpp_bg.js +1 -1
- package/wasm/wasm_dpp_bg.wasm +0 -0
- package/wasm/wasm_dpp_bg.wasm.d.ts +205 -175
- package/webpack.config.js +1 -1
- package/src/identity_public_key/public_keys_validator.rs +0 -44
- package/test/integration/stateTransition/calculateStateTransitionFee.spec.js +0 -32
- package/test/unit/dataContract/validation/validateDataContractMaxDepthFactory.spec.js +0 -93
- package/test/unit/dataContract/validation/validateDataContractPatternsFactory.spec.js +0 -64
|
@@ -1,41 +1,9 @@
|
|
|
1
|
-
const { getRE2Class } = require('@dashevo/wasm-re2');
|
|
2
|
-
|
|
3
1
|
const crypto = require('crypto');
|
|
4
2
|
|
|
5
|
-
const createAjv = require('@dashevo/dpp/lib/ajv/createAjv');
|
|
6
|
-
|
|
7
|
-
const JsonSchemaValidator = require(
|
|
8
|
-
'@dashevo/dpp/lib/validation/JsonSchemaValidator',
|
|
9
|
-
);
|
|
10
|
-
|
|
11
|
-
const validatePublicKeysFactory = require(
|
|
12
|
-
'@dashevo/dpp/lib/identity/validation/validatePublicKeysFactory',
|
|
13
|
-
);
|
|
14
|
-
|
|
15
3
|
const getIdentityFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityFixture');
|
|
16
4
|
|
|
17
|
-
const DuplicatedIdentityPublicKeyError = require(
|
|
18
|
-
'@dashevo/dpp/lib/errors/consensus/basic/identity/DuplicatedIdentityPublicKeyError',
|
|
19
|
-
);
|
|
20
|
-
const DuplicatedIdentityPublicKeyIdError = require(
|
|
21
|
-
'@dashevo/dpp/lib/errors/consensus/basic/identity/DuplicatedIdentityPublicKeyIdError',
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
const InvalidIdentityPublicKeyDataError = require(
|
|
25
|
-
'@dashevo/dpp/lib/errors/consensus/basic/identity/InvalidIdentityPublicKeyDataError',
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
const InvalidIdentityPublicKeySecurityLevelError = require(
|
|
29
|
-
'@dashevo/dpp/lib/errors/consensus/basic/identity/InvalidIdentityPublicKeySecurityLevelError',
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
const IdentityPublicKey = require(
|
|
33
|
-
'@dashevo/dpp/lib/identity/IdentityPublicKey',
|
|
34
|
-
);
|
|
35
5
|
const BlsSignatures = require('@dashevo/dpp/lib/bls/bls');
|
|
36
6
|
|
|
37
|
-
const identityPublicKeySchema = require('@dashevo/dpp/schema/identity/publicKey.json');
|
|
38
|
-
const stateTransitionPublicKeySchema = require('@dashevo/dpp/schema/identity/stateTransition/publicKey.json');
|
|
39
7
|
const {
|
|
40
8
|
expectValidationError,
|
|
41
9
|
expectJsonSchemaError,
|
|
@@ -46,24 +14,29 @@ const { default: loadWasmDpp } = require('../../../../dist');
|
|
|
46
14
|
describe('validatePublicKeysFactory', () => {
|
|
47
15
|
let rawPublicKeys;
|
|
48
16
|
let validatePublicKeys;
|
|
49
|
-
let validator;
|
|
50
17
|
let bls;
|
|
51
|
-
let PublicKeysValidator;
|
|
52
18
|
let publicKeysValidator;
|
|
53
|
-
|
|
19
|
+
|
|
20
|
+
let PublicKeysValidator;
|
|
54
21
|
let PublicKeyValidationError;
|
|
22
|
+
let IdentityPublicKey;
|
|
23
|
+
|
|
24
|
+
let DuplicatedIdentityPublicKeyError;
|
|
25
|
+
let DuplicatedIdentityPublicKeyIdError;
|
|
26
|
+
let InvalidIdentityPublicKeyDataError;
|
|
27
|
+
let InvalidIdentityPublicKeySecurityLevelError;
|
|
55
28
|
|
|
56
29
|
beforeEach(async () => {
|
|
57
30
|
({ publicKeys: rawPublicKeys } = getIdentityFixture().toObject());
|
|
58
31
|
|
|
59
32
|
({
|
|
60
|
-
PublicKeysValidator,
|
|
61
|
-
InvalidIdentityPublicKeyDataError
|
|
33
|
+
PublicKeysValidator, IdentityPublicKey,
|
|
34
|
+
InvalidIdentityPublicKeyDataError,
|
|
35
|
+
DuplicatedIdentityPublicKeyError, DuplicatedIdentityPublicKeyIdError,
|
|
36
|
+
InvalidIdentityPublicKeyDataError, InvalidIdentityPublicKeySecurityLevelError,
|
|
62
37
|
PublicKeyValidationError,
|
|
63
38
|
} = await loadWasmDpp());
|
|
64
39
|
|
|
65
|
-
const RE2 = await getRE2Class();
|
|
66
|
-
const ajv = createAjv(RE2);
|
|
67
40
|
bls = await BlsSignatures.getInstance();
|
|
68
41
|
|
|
69
42
|
const blsAdapter = {
|
|
@@ -80,23 +53,17 @@ describe('validatePublicKeysFactory', () => {
|
|
|
80
53
|
},
|
|
81
54
|
};
|
|
82
55
|
|
|
83
|
-
validator = new JsonSchemaValidator(ajv);
|
|
84
|
-
|
|
85
|
-
validatePublicKeys = validatePublicKeysFactory(
|
|
86
|
-
validator,
|
|
87
|
-
identityPublicKeySchema,
|
|
88
|
-
bls,
|
|
89
|
-
);
|
|
90
|
-
|
|
91
56
|
publicKeysValidator = new PublicKeysValidator(blsAdapter);
|
|
57
|
+
|
|
58
|
+
validatePublicKeys = (keys) => publicKeysValidator.validateKeys(keys);
|
|
92
59
|
});
|
|
93
60
|
|
|
94
61
|
describe('id', () => {
|
|
95
|
-
it('should be present', () => {
|
|
62
|
+
it('should be present', async () => {
|
|
96
63
|
delete rawPublicKeys[1].id;
|
|
97
64
|
|
|
98
65
|
const result = publicKeysValidator.validateKeys(rawPublicKeys);
|
|
99
|
-
expectJsonSchemaError(result);
|
|
66
|
+
await expectJsonSchemaError(result);
|
|
100
67
|
|
|
101
68
|
const [error] = result.getErrors();
|
|
102
69
|
|
|
@@ -105,12 +72,12 @@ describe('validatePublicKeysFactory', () => {
|
|
|
105
72
|
expect(error.getParams().missingProperty).to.equal('id');
|
|
106
73
|
});
|
|
107
74
|
|
|
108
|
-
it('should be a number', () => {
|
|
75
|
+
it('should be a number', async () => {
|
|
109
76
|
rawPublicKeys[1].id = 'string';
|
|
110
77
|
|
|
111
78
|
const result = validatePublicKeys(rawPublicKeys);
|
|
112
79
|
|
|
113
|
-
expectJsonSchemaError(result);
|
|
80
|
+
await expectJsonSchemaError(result);
|
|
114
81
|
|
|
115
82
|
const [error] = result.getErrors();
|
|
116
83
|
|
|
@@ -118,12 +85,12 @@ describe('validatePublicKeysFactory', () => {
|
|
|
118
85
|
expect(error.getKeyword()).to.equal('type');
|
|
119
86
|
});
|
|
120
87
|
|
|
121
|
-
it('should be an integer', () => {
|
|
88
|
+
it('should be an integer', async () => {
|
|
122
89
|
rawPublicKeys[1].id = 1.1;
|
|
123
90
|
|
|
124
91
|
const result = validatePublicKeys(rawPublicKeys);
|
|
125
92
|
|
|
126
|
-
expectJsonSchemaError(result);
|
|
93
|
+
await expectJsonSchemaError(result);
|
|
127
94
|
|
|
128
95
|
const [error] = result.getErrors();
|
|
129
96
|
|
|
@@ -131,12 +98,12 @@ describe('validatePublicKeysFactory', () => {
|
|
|
131
98
|
expect(error.getKeyword()).to.equal('type');
|
|
132
99
|
});
|
|
133
100
|
|
|
134
|
-
it('should be greater or equal to one', () => {
|
|
101
|
+
it('should be greater or equal to one', async () => {
|
|
135
102
|
rawPublicKeys[1].id = -1;
|
|
136
103
|
|
|
137
104
|
const result = validatePublicKeys(rawPublicKeys);
|
|
138
105
|
|
|
139
|
-
expectJsonSchemaError(result);
|
|
106
|
+
await expectJsonSchemaError(result);
|
|
140
107
|
|
|
141
108
|
const [error] = result.getErrors();
|
|
142
109
|
|
|
@@ -146,12 +113,12 @@ describe('validatePublicKeysFactory', () => {
|
|
|
146
113
|
});
|
|
147
114
|
|
|
148
115
|
describe('type', () => {
|
|
149
|
-
it('should be present', () => {
|
|
116
|
+
it('should be present', async () => {
|
|
150
117
|
delete rawPublicKeys[1].type;
|
|
151
118
|
|
|
152
119
|
const result = validatePublicKeys(rawPublicKeys);
|
|
153
120
|
|
|
154
|
-
expectJsonSchemaError(result);
|
|
121
|
+
await expectJsonSchemaError(result, 4);
|
|
155
122
|
|
|
156
123
|
const [error] = result.getErrors();
|
|
157
124
|
|
|
@@ -159,27 +126,30 @@ describe('validatePublicKeysFactory', () => {
|
|
|
159
126
|
expect(error.getKeyword()).to.equal('minItems');
|
|
160
127
|
});
|
|
161
128
|
|
|
162
|
-
it('should be a number', () => {
|
|
129
|
+
it('should be a number', async () => {
|
|
163
130
|
rawPublicKeys[1].type = 'string';
|
|
164
131
|
|
|
165
132
|
const result = validatePublicKeys(rawPublicKeys);
|
|
166
133
|
|
|
167
|
-
expectJsonSchemaError(result);
|
|
134
|
+
await expectJsonSchemaError(result, 2);
|
|
168
135
|
|
|
169
|
-
const [
|
|
136
|
+
const [typeError, enumError] = result.getErrors();
|
|
170
137
|
|
|
171
|
-
expect(
|
|
172
|
-
expect(
|
|
138
|
+
expect(typeError.getInstancePath()).to.equal('/type');
|
|
139
|
+
expect(typeError.getKeyword()).to.equal('type');
|
|
140
|
+
|
|
141
|
+
expect(enumError.getInstancePath()).to.equal('/type');
|
|
142
|
+
expect(enumError.getKeyword()).to.equal('enum');
|
|
173
143
|
});
|
|
174
144
|
});
|
|
175
145
|
|
|
176
146
|
describe('data', () => {
|
|
177
|
-
it('should be present', () => {
|
|
147
|
+
it('should be present', async () => {
|
|
178
148
|
delete rawPublicKeys[1].data;
|
|
179
149
|
|
|
180
150
|
const result = validatePublicKeys(rawPublicKeys);
|
|
181
151
|
|
|
182
|
-
expectJsonSchemaError(result);
|
|
152
|
+
await expectJsonSchemaError(result);
|
|
183
153
|
|
|
184
154
|
const [error] = result.getErrors();
|
|
185
155
|
|
|
@@ -188,28 +158,29 @@ describe('validatePublicKeysFactory', () => {
|
|
|
188
158
|
expect(error.getParams().missingProperty).to.equal('data');
|
|
189
159
|
});
|
|
190
160
|
|
|
191
|
-
it('should be a byte array', () => {
|
|
161
|
+
it('should be a byte array', async () => {
|
|
192
162
|
rawPublicKeys[1].data = new Array(33).fill('string');
|
|
193
163
|
|
|
194
164
|
const result = validatePublicKeys(rawPublicKeys);
|
|
195
165
|
|
|
196
|
-
expectJsonSchemaError(result,
|
|
166
|
+
await expectJsonSchemaError(result, 33);
|
|
197
167
|
|
|
198
168
|
const [error, byteArrayError] = result.getErrors();
|
|
199
169
|
|
|
200
170
|
expect(error.getInstancePath()).to.equal('/data/0');
|
|
201
171
|
expect(error.getKeyword()).to.equal('type');
|
|
202
172
|
|
|
203
|
-
expect(byteArrayError.
|
|
173
|
+
expect(byteArrayError.getInstancePath()).to.equal('/data/1');
|
|
174
|
+
expect(byteArrayError.getKeyword()).to.equal('type');
|
|
204
175
|
});
|
|
205
176
|
|
|
206
177
|
describe('ECDSA_SECP256K1', () => {
|
|
207
|
-
it('should be no less than 33 bytes', () => {
|
|
178
|
+
it('should be no less than 33 bytes', async () => {
|
|
208
179
|
rawPublicKeys[1].data = Buffer.alloc(32);
|
|
209
180
|
|
|
210
181
|
const result = validatePublicKeys(rawPublicKeys);
|
|
211
182
|
|
|
212
|
-
expectJsonSchemaError(result);
|
|
183
|
+
await expectJsonSchemaError(result);
|
|
213
184
|
|
|
214
185
|
const [error] = result.getErrors();
|
|
215
186
|
|
|
@@ -217,12 +188,12 @@ describe('validatePublicKeysFactory', () => {
|
|
|
217
188
|
expect(error.getKeyword()).to.equal('minItems');
|
|
218
189
|
});
|
|
219
190
|
|
|
220
|
-
it('should be no longer than 33 bytes', () => {
|
|
191
|
+
it('should be no longer than 33 bytes', async () => {
|
|
221
192
|
rawPublicKeys[1].data = Buffer.alloc(34);
|
|
222
193
|
|
|
223
194
|
const result = validatePublicKeys(rawPublicKeys);
|
|
224
195
|
|
|
225
|
-
expectJsonSchemaError(result);
|
|
196
|
+
await expectJsonSchemaError(result);
|
|
226
197
|
|
|
227
198
|
const [error] = result.getErrors();
|
|
228
199
|
|
|
@@ -232,13 +203,13 @@ describe('validatePublicKeysFactory', () => {
|
|
|
232
203
|
});
|
|
233
204
|
|
|
234
205
|
describe('BLS12_381', () => {
|
|
235
|
-
it('should be no less than 48 bytes', () => {
|
|
206
|
+
it('should be no less than 48 bytes', async () => {
|
|
236
207
|
rawPublicKeys[1].data = Buffer.alloc(47);
|
|
237
208
|
rawPublicKeys[1].type = 1;
|
|
238
209
|
|
|
239
210
|
const result = validatePublicKeys(rawPublicKeys);
|
|
240
211
|
|
|
241
|
-
expectJsonSchemaError(result);
|
|
212
|
+
await expectJsonSchemaError(result);
|
|
242
213
|
|
|
243
214
|
const [error] = result.getErrors();
|
|
244
215
|
|
|
@@ -246,13 +217,13 @@ describe('validatePublicKeysFactory', () => {
|
|
|
246
217
|
expect(error.getKeyword()).to.equal('minItems');
|
|
247
218
|
});
|
|
248
219
|
|
|
249
|
-
it('should be no longer than 48 bytes', () => {
|
|
220
|
+
it('should be no longer than 48 bytes', async () => {
|
|
250
221
|
rawPublicKeys[1].data = Buffer.alloc(49);
|
|
251
222
|
rawPublicKeys[1].type = 1;
|
|
252
223
|
|
|
253
224
|
const result = validatePublicKeys(rawPublicKeys);
|
|
254
225
|
|
|
255
|
-
expectJsonSchemaError(result);
|
|
226
|
+
await expectJsonSchemaError(result);
|
|
256
227
|
|
|
257
228
|
const [error] = result.getErrors();
|
|
258
229
|
|
|
@@ -262,13 +233,13 @@ describe('validatePublicKeysFactory', () => {
|
|
|
262
233
|
});
|
|
263
234
|
|
|
264
235
|
describe('ECDSA_HASH160', () => {
|
|
265
|
-
it('should be no less than 20 bytes', () => {
|
|
236
|
+
it('should be no less than 20 bytes', async () => {
|
|
266
237
|
rawPublicKeys[1].data = Buffer.alloc(19);
|
|
267
238
|
rawPublicKeys[1].type = 2;
|
|
268
239
|
|
|
269
240
|
const result = validatePublicKeys(rawPublicKeys);
|
|
270
241
|
|
|
271
|
-
expectJsonSchemaError(result);
|
|
242
|
+
await expectJsonSchemaError(result);
|
|
272
243
|
|
|
273
244
|
const [error] = result.getErrors();
|
|
274
245
|
|
|
@@ -276,13 +247,13 @@ describe('validatePublicKeysFactory', () => {
|
|
|
276
247
|
expect(error.getKeyword()).to.equal('minItems');
|
|
277
248
|
});
|
|
278
249
|
|
|
279
|
-
it('should be no longer than 20 bytes', () => {
|
|
250
|
+
it('should be no longer than 20 bytes', async () => {
|
|
280
251
|
rawPublicKeys[1].data = Buffer.alloc(21);
|
|
281
252
|
rawPublicKeys[1].type = 2;
|
|
282
253
|
|
|
283
254
|
const result = validatePublicKeys(rawPublicKeys);
|
|
284
255
|
|
|
285
|
-
expectJsonSchemaError(result);
|
|
256
|
+
await expectJsonSchemaError(result);
|
|
286
257
|
|
|
287
258
|
const [error] = result.getErrors();
|
|
288
259
|
|
|
@@ -292,13 +263,13 @@ describe('validatePublicKeysFactory', () => {
|
|
|
292
263
|
});
|
|
293
264
|
|
|
294
265
|
describe('BIP13_SCRIPT_HASH', () => {
|
|
295
|
-
it('should be no less than 20 bytes', () => {
|
|
266
|
+
it('should be no less than 20 bytes', async () => {
|
|
296
267
|
rawPublicKeys[1].data = Buffer.alloc(19);
|
|
297
268
|
rawPublicKeys[1].type = 3;
|
|
298
269
|
|
|
299
270
|
const result = validatePublicKeys(rawPublicKeys);
|
|
300
271
|
|
|
301
|
-
expectJsonSchemaError(result);
|
|
272
|
+
await expectJsonSchemaError(result);
|
|
302
273
|
|
|
303
274
|
const [error] = result.getErrors();
|
|
304
275
|
|
|
@@ -306,13 +277,13 @@ describe('validatePublicKeysFactory', () => {
|
|
|
306
277
|
expect(error.getKeyword()).to.equal('minItems');
|
|
307
278
|
});
|
|
308
279
|
|
|
309
|
-
it('should be no longer than 20 bytes', () => {
|
|
280
|
+
it('should be no longer than 20 bytes', async () => {
|
|
310
281
|
rawPublicKeys[1].data = Buffer.alloc(21);
|
|
311
282
|
rawPublicKeys[1].type = 3;
|
|
312
283
|
|
|
313
284
|
const result = validatePublicKeys(rawPublicKeys);
|
|
314
285
|
|
|
315
|
-
expectJsonSchemaError(result);
|
|
286
|
+
await expectJsonSchemaError(result);
|
|
316
287
|
|
|
317
288
|
const [error] = result.getErrors();
|
|
318
289
|
|
|
@@ -322,12 +293,12 @@ describe('validatePublicKeysFactory', () => {
|
|
|
322
293
|
});
|
|
323
294
|
});
|
|
324
295
|
|
|
325
|
-
it('should return invalid result if there are duplicate key ids', () => {
|
|
296
|
+
it('should return invalid result if there are duplicate key ids', async () => {
|
|
326
297
|
rawPublicKeys[1].id = rawPublicKeys[0].id;
|
|
327
298
|
|
|
328
299
|
const result = validatePublicKeys(rawPublicKeys);
|
|
329
300
|
|
|
330
|
-
expectValidationError(result, DuplicatedIdentityPublicKeyIdError);
|
|
301
|
+
await expectValidationError(result, DuplicatedIdentityPublicKeyIdError);
|
|
331
302
|
|
|
332
303
|
const [error] = result.getErrors();
|
|
333
304
|
|
|
@@ -335,12 +306,12 @@ describe('validatePublicKeysFactory', () => {
|
|
|
335
306
|
expect(error.getDuplicatedIds()).to.deep.equal([rawPublicKeys[1].id]);
|
|
336
307
|
});
|
|
337
308
|
|
|
338
|
-
it('should return invalid result if there are duplicate keys', () => {
|
|
309
|
+
it('should return invalid result if there are duplicate keys', async () => {
|
|
339
310
|
rawPublicKeys[1].data = rawPublicKeys[0].data;
|
|
340
311
|
|
|
341
312
|
const result = validatePublicKeys(rawPublicKeys);
|
|
342
313
|
|
|
343
|
-
expectValidationError(result, DuplicatedIdentityPublicKeyError);
|
|
314
|
+
await expectValidationError(result, DuplicatedIdentityPublicKeyError);
|
|
344
315
|
|
|
345
316
|
const [error] = result.getErrors();
|
|
346
317
|
|
|
@@ -348,28 +319,28 @@ describe('validatePublicKeysFactory', () => {
|
|
|
348
319
|
expect(error.getDuplicatedPublicKeysIds()).to.deep.equal([rawPublicKeys[1].id]);
|
|
349
320
|
});
|
|
350
321
|
|
|
351
|
-
it('should return invalid result if key data is not a valid DER', () => {
|
|
322
|
+
it('should return invalid result if key data is not a valid DER', async () => {
|
|
352
323
|
rawPublicKeys[1].data = Buffer.alloc(33);
|
|
353
324
|
|
|
354
325
|
const result = validatePublicKeys(rawPublicKeys);
|
|
355
326
|
|
|
356
|
-
expectValidationError(result, InvalidIdentityPublicKeyDataError);
|
|
327
|
+
await expectValidationError(result, InvalidIdentityPublicKeyDataError);
|
|
357
328
|
|
|
358
329
|
const [error] = result.getErrors();
|
|
359
330
|
|
|
360
331
|
expect(error.getCode()).to.equal(1040);
|
|
361
332
|
expect(error.getPublicKeyId()).to.deep.equal(rawPublicKeys[1].id);
|
|
362
|
-
expect(error.getValidationError()).to.be.instanceOf(
|
|
363
|
-
expect(error.getValidationError().message).to.equal('
|
|
333
|
+
expect(error.getValidationError()).to.be.instanceOf(PublicKeyValidationError);
|
|
334
|
+
expect(error.getValidationError().message).to.equal('Key secp256k1 error: malformed public key');
|
|
364
335
|
});
|
|
365
336
|
|
|
366
|
-
it('should return invalid result if key has an invalid combination of purpose and security level', () => {
|
|
337
|
+
it('should return invalid result if key has an invalid combination of purpose and security level', async () => {
|
|
367
338
|
rawPublicKeys[1].purpose = IdentityPublicKey.PURPOSES.ENCRYPTION;
|
|
368
339
|
rawPublicKeys[1].securityLevel = IdentityPublicKey.SECURITY_LEVELS.MASTER;
|
|
369
340
|
|
|
370
341
|
const result = validatePublicKeys(rawPublicKeys);
|
|
371
342
|
|
|
372
|
-
expectValidationError(result, InvalidIdentityPublicKeySecurityLevelError);
|
|
343
|
+
await expectValidationError(result, InvalidIdentityPublicKeySecurityLevelError);
|
|
373
344
|
|
|
374
345
|
const [error] = result.getErrors();
|
|
375
346
|
|
|
@@ -395,7 +366,7 @@ describe('validatePublicKeysFactory', () => {
|
|
|
395
366
|
data: Buffer.from('01fac99ca2c8f39c286717c213e190aba4b7af76db320ec43f479b7d9a2012313a0ae59ca576edf801444bc694686694', 'hex'),
|
|
396
367
|
}];
|
|
397
368
|
|
|
398
|
-
const result =
|
|
369
|
+
const result = validatePublicKeys(rawPublicKeys);
|
|
399
370
|
|
|
400
371
|
expect(result.isValid()).to.be.true();
|
|
401
372
|
});
|
|
@@ -427,7 +398,7 @@ describe('validatePublicKeysFactory', () => {
|
|
|
427
398
|
|
|
428
399
|
const result = publicKeysValidator.validateKeys(rawPublicKeys);
|
|
429
400
|
|
|
430
|
-
await expectValidationError(result,
|
|
401
|
+
await expectValidationError(result, InvalidIdentityPublicKeyDataError);
|
|
431
402
|
|
|
432
403
|
const [error] = result.getErrors();
|
|
433
404
|
|
|
@@ -451,11 +422,7 @@ describe('validatePublicKeysFactory', () => {
|
|
|
451
422
|
|
|
452
423
|
describe('State Transition Schema', () => {
|
|
453
424
|
beforeEach(() => {
|
|
454
|
-
validatePublicKeys =
|
|
455
|
-
validator,
|
|
456
|
-
stateTransitionPublicKeySchema,
|
|
457
|
-
bls,
|
|
458
|
-
);
|
|
425
|
+
validatePublicKeys = (keys) => publicKeysValidator.validateKeysInStateTransition(keys);
|
|
459
426
|
|
|
460
427
|
rawPublicKeys.forEach((rawPublicKey) => {
|
|
461
428
|
// eslint-disable-next-line no-param-reassign
|
|
@@ -464,16 +431,16 @@ describe('validatePublicKeysFactory', () => {
|
|
|
464
431
|
});
|
|
465
432
|
|
|
466
433
|
describe('signature', () => {
|
|
467
|
-
it('should be present', () => {
|
|
434
|
+
it('should be present', async () => {
|
|
468
435
|
delete rawPublicKeys[0].signature;
|
|
469
436
|
|
|
470
437
|
const result = validatePublicKeys(rawPublicKeys);
|
|
471
438
|
|
|
472
|
-
expectJsonSchemaError(result);
|
|
439
|
+
await expectJsonSchemaError(result);
|
|
473
440
|
|
|
474
441
|
const [error] = result.getErrors();
|
|
475
442
|
|
|
476
|
-
expect(error.
|
|
443
|
+
expect(error.getInstancePath()).to.equal('');
|
|
477
444
|
expect(error.getKeyword()).to.equal('required');
|
|
478
445
|
expect(error.getParams().missingProperty).to.equal('signature');
|
|
479
446
|
});
|
|
@@ -483,39 +450,37 @@ describe('validatePublicKeysFactory', () => {
|
|
|
483
450
|
|
|
484
451
|
const result = validatePublicKeys(rawPublicKeys);
|
|
485
452
|
|
|
486
|
-
expectJsonSchemaError(result,
|
|
453
|
+
await expectJsonSchemaError(result, 65);
|
|
487
454
|
|
|
488
|
-
const [error
|
|
455
|
+
const [error] = result.getErrors();
|
|
489
456
|
|
|
490
|
-
expect(error.instancePath).to.equal('/signature/0');
|
|
491
457
|
expect(error.getKeyword()).to.equal('type');
|
|
492
|
-
|
|
493
|
-
expect(byteArrayError.getKeyword()).to.equal('byteArray');
|
|
458
|
+
expect(error.getInstancePath()).to.equal('/signature/0');
|
|
494
459
|
});
|
|
495
460
|
|
|
496
|
-
it('should be not shorter than 65 bytes', () => {
|
|
461
|
+
it('should be not shorter than 65 bytes', async () => {
|
|
497
462
|
rawPublicKeys[0].signature = Buffer.alloc(64);
|
|
498
463
|
|
|
499
464
|
const result = validatePublicKeys(rawPublicKeys);
|
|
500
465
|
|
|
501
|
-
expectJsonSchemaError(result);
|
|
466
|
+
await expectJsonSchemaError(result);
|
|
502
467
|
|
|
503
468
|
const [error] = result.getErrors();
|
|
504
469
|
|
|
505
|
-
expect(error.
|
|
470
|
+
expect(error.getInstancePath()).to.equal('/signature');
|
|
506
471
|
expect(error.getKeyword()).to.equal('minItems');
|
|
507
472
|
});
|
|
508
473
|
|
|
509
|
-
it('should be not longer than 65 bytes', () => {
|
|
474
|
+
it('should be not longer than 65 bytes', async () => {
|
|
510
475
|
rawPublicKeys[0].signature = Buffer.alloc(66);
|
|
511
476
|
|
|
512
477
|
const result = validatePublicKeys(rawPublicKeys);
|
|
513
478
|
|
|
514
|
-
expectJsonSchemaError(result);
|
|
479
|
+
await expectJsonSchemaError(result);
|
|
515
480
|
|
|
516
481
|
const [error] = result.getErrors();
|
|
517
482
|
|
|
518
|
-
expect(error.
|
|
483
|
+
expect(error.getInstancePath()).to.equal('/signature');
|
|
519
484
|
expect(error.getKeyword()).to.equal('maxItems');
|
|
520
485
|
});
|
|
521
486
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const { PrivateKey, crypto: { Hash } } = require('@dashevo/dashcore-lib');
|
|
2
2
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
|
-
const calculateStateTransitionFee = require('@dashevo/dpp/lib/stateTransition/fee/calculateStateTransitionFee');
|
|
5
4
|
|
|
6
5
|
const StateTransitionMock = require('@dashevo/dpp/lib/test/mocks/StateTransitionMock');
|
|
7
6
|
const IdentityPublicKey = require('@dashevo/dpp/lib/identity/IdentityPublicKey');
|
|
@@ -494,14 +493,4 @@ describe('AbstractStateTransitionIdentitySigned', () => {
|
|
|
494
493
|
expect(stateTransition.signaturePublicKeyId).to.equal(signaturePublicKeyId);
|
|
495
494
|
});
|
|
496
495
|
});
|
|
497
|
-
|
|
498
|
-
describe('#calculateFee', () => {
|
|
499
|
-
it('should calculate fee', () => {
|
|
500
|
-
const result = stateTransition.calculateFee();
|
|
501
|
-
|
|
502
|
-
const fee = calculateStateTransitionFee(stateTransition);
|
|
503
|
-
|
|
504
|
-
expect(result).to.equal(fee);
|
|
505
|
-
});
|
|
506
|
-
});
|
|
507
496
|
});
|
|
@@ -71,7 +71,7 @@ describe('StateTransitionFacade', () => {
|
|
|
71
71
|
|
|
72
72
|
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
73
73
|
stateRepositoryMock.fetchIdentity.resolves(identity);
|
|
74
|
-
stateRepositoryMock.fetchLatestPlatformBlockTime.
|
|
74
|
+
stateRepositoryMock.fetchLatestPlatformBlockTime.resolves(blockTime);
|
|
75
75
|
|
|
76
76
|
dpp = new DashPlatformProtocol({
|
|
77
77
|
stateRepository: stateRepositoryMock,
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const calculateStateTransitionFeeFactory = require('@dashevo/dpp/lib/stateTransition/fee/calculateStateTransitionFeeFactory');
|
|
2
|
+
|
|
3
|
+
const getIdentityCreateTransitionFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityCreateTransitionFixture');
|
|
4
|
+
const IdentityPublicKey = require('@dashevo/dpp/lib/identity/IdentityPublicKey');
|
|
5
|
+
|
|
6
|
+
const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock');
|
|
7
|
+
|
|
8
|
+
describe('calculateStateTransitionFeeFactory', () => {
|
|
9
|
+
let stateTransition;
|
|
10
|
+
let calculateStateTransitionFee;
|
|
11
|
+
let stateRepositoryMock;
|
|
12
|
+
let calculateOperationFeesMock;
|
|
13
|
+
|
|
14
|
+
beforeEach(async function beforeEach() {
|
|
15
|
+
const privateKey = 'af432c476f65211f45f48f1d42c9c0b497e56696aa1736b40544ef1a496af837';
|
|
16
|
+
|
|
17
|
+
stateTransition = getIdentityCreateTransitionFixture();
|
|
18
|
+
await stateTransition.signByPrivateKey(privateKey, IdentityPublicKey.TYPES.ECDSA_SECP256K1);
|
|
19
|
+
|
|
20
|
+
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
21
|
+
|
|
22
|
+
calculateOperationFeesMock = this.sinonSandbox.stub();
|
|
23
|
+
|
|
24
|
+
calculateStateTransitionFee = calculateStateTransitionFeeFactory(
|
|
25
|
+
stateRepositoryMock,
|
|
26
|
+
calculateOperationFeesMock,
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should throw an error if more than two identities have refunds', async () => {
|
|
31
|
+
const calculatedOperationsFeesResult = {
|
|
32
|
+
storageFee: 10000,
|
|
33
|
+
processingFee: 1000,
|
|
34
|
+
feeRefunds: [
|
|
35
|
+
{
|
|
36
|
+
identifier: stateTransition.getOwnerId().toBuffer(),
|
|
37
|
+
creditsPerEpoch: {
|
|
38
|
+
0: -100,
|
|
39
|
+
1: -50,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
identifier: stateTransition.getOwnerId().toBuffer(),
|
|
44
|
+
creditsPerEpoch: {
|
|
45
|
+
1: -50,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
calculateOperationFeesMock.returns(calculatedOperationsFeesResult);
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
await calculateStateTransitionFee(stateTransition);
|
|
55
|
+
|
|
56
|
+
expect.fail('should fail');
|
|
57
|
+
} catch (e) {
|
|
58
|
+
expect(e.message).to.equals('State Transition removed bytes from several identities that is not defined by protocol');
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should throw an error if refunded identity is not owner of state transition', async () => {
|
|
63
|
+
const calculatedOperationsFeesResult = {
|
|
64
|
+
storageFee: 10000,
|
|
65
|
+
processingFee: 1000,
|
|
66
|
+
feeRefunds: [
|
|
67
|
+
{
|
|
68
|
+
identifier: Buffer.alloc(32, 1),
|
|
69
|
+
creditsPerEpoch: {
|
|
70
|
+
0: -100,
|
|
71
|
+
1: -50,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
calculateOperationFeesMock.returns(calculatedOperationsFeesResult);
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
await calculateStateTransitionFee(stateTransition);
|
|
81
|
+
|
|
82
|
+
expect.fail('should fail');
|
|
83
|
+
} catch (e) {
|
|
84
|
+
expect(e.message).to.equals('State Transition removed bytes from different identity');
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should calculate fee based on executed operations', async () => {
|
|
89
|
+
const storageFee = 10000;
|
|
90
|
+
const processingFee = 1000;
|
|
91
|
+
const feeRefundsSum = 450 + 995 + 400 + 400;
|
|
92
|
+
const total = storageFee + processingFee - feeRefundsSum;
|
|
93
|
+
|
|
94
|
+
const calculatedOperationsFeesResult = {
|
|
95
|
+
storageFee,
|
|
96
|
+
processingFee,
|
|
97
|
+
feeRefunds: [
|
|
98
|
+
{
|
|
99
|
+
identifier: stateTransition.getOwnerId().toBuffer(),
|
|
100
|
+
creditsPerEpoch: {
|
|
101
|
+
0: 1000,
|
|
102
|
+
1: 500,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
calculateOperationFeesMock.returns(calculatedOperationsFeesResult);
|
|
109
|
+
|
|
110
|
+
stateRepositoryMock.calculateStorageFeeDistributionAmountAndLeftovers
|
|
111
|
+
.onCall(0).resolves([995, 400]);
|
|
112
|
+
|
|
113
|
+
stateRepositoryMock.calculateStorageFeeDistributionAmountAndLeftovers
|
|
114
|
+
.onCall(1).resolves([450, 400]);
|
|
115
|
+
|
|
116
|
+
const result = await calculateStateTransitionFee(stateTransition);
|
|
117
|
+
|
|
118
|
+
expect(result).to.equal(total);
|
|
119
|
+
|
|
120
|
+
expect(stateRepositoryMock.calculateStorageFeeDistributionAmountAndLeftovers)
|
|
121
|
+
.to.have.been.calledWithExactly(1000, 0);
|
|
122
|
+
|
|
123
|
+
expect(stateRepositoryMock.calculateStorageFeeDistributionAmountAndLeftovers)
|
|
124
|
+
.to.have.been.calledWithExactly(500, 1);
|
|
125
|
+
|
|
126
|
+
const lastCalculatedFeeDetails = stateTransition.getExecutionContext()
|
|
127
|
+
.getLastCalculatedFeeDetails();
|
|
128
|
+
|
|
129
|
+
expect(lastCalculatedFeeDetails).to.be.deep.equal({
|
|
130
|
+
...calculatedOperationsFeesResult,
|
|
131
|
+
feeRefundsSum,
|
|
132
|
+
total,
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
});
|