@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.
- package/.babelrc +5 -0
- package/.editorconfig +13 -0
- package/.eslintignore +1 -0
- package/.eslintrc +15 -0
- package/.mocharc.yml +4 -0
- package/CHANGELOG.md +397 -0
- package/LICENSE +20 -0
- package/README.md +37 -0
- package/karma.conf.js +53 -0
- package/package.json +107 -0
- package/test/.eslintrc +12 -0
- package/test/integration/DashPlatformProtocol.spec.js +53 -0
- package/test/integration/ajv/keywords/byteArray/addByteArrayKeyword.spec.js +148 -0
- package/test/integration/dataContract/DataContractFacade.spec.js +84 -0
- package/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js +357 -0
- package/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js +444 -0
- package/test/integration/dataContract/validation/validateDataContractFactory.spec.js +2191 -0
- package/test/integration/document/Document.spec.js +90 -0
- package/test/integration/document/DocumentFacade.spec.js +155 -0
- package/test/integration/document/stateTransition/DocumentsBatchTransition/DocumentBatchTransition.spec.js +83 -0
- package/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js +1146 -0
- package/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js +294 -0
- package/test/integration/document/validation/validateDocumentFactory.spec.js +447 -0
- package/test/integration/error/consensus/createConsensusError.spec.js +21 -0
- package/test/integration/identity/IdentityFacade.spec.js +187 -0
- package/test/integration/identity/stateTransition/IdentityCreateTransition/validation/basic/validateIdentityCreateTransitionBasicFactory.spec.js +422 -0
- package/test/integration/identity/stateTransition/IdentityTopUpTransition/validation/basic/validateIdentityTopUpTransitionBasicFactory.spec.js +361 -0
- package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/basic/validateIdentityUpdateTransitionBasicFactory.spec.js +595 -0
- package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validateIdentityUpdateTransitionStateFactory.spec.js +299 -0
- package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validatePublicKeysState.spec.js +66 -0
- package/test/integration/identity/stateTransition/assetLockProof/chain/validateChainAssetLockProofStructureFactory.spec.js +415 -0
- package/test/integration/identity/stateTransition/assetLockProof/fetchAssetLockTransactionOutputFactory.spec.js +134 -0
- package/test/integration/identity/stateTransition/assetLockProof/instant/validateInstantAssetLockProofStructureFactory.spec.js +401 -0
- package/test/integration/identity/stateTransition/assetLockProof/validateAssetLockTransactionFactory.spec.js +205 -0
- package/test/integration/identity/stateTransition/validatePublicKeySignaturesFactory.spec.js +127 -0
- package/test/integration/identity/validation/validateIdentityFactory.spec.js +370 -0
- package/test/integration/identity/validation/validatePublicKeysFactory.spec.js +497 -0
- package/test/integration/stateTransition/AbstractStateTransitionIdentitySigned.spec.js +507 -0
- package/test/integration/stateTransition/StateTransitionFacade.spec.js +418 -0
- package/test/integration/stateTransition/calculateStateTransitionFee.spec.js +35 -0
- package/test/integration/util/generateEntropy.spec.js +17 -0
- package/test/integration/util/serializer.spec.js +24 -0
- package/test/unit/DashPlatformProtocol.spec.js +79 -0
- package/test/unit/Identifier.spec.js +123 -0
- package/test/unit/Metadata.spec.js +37 -0
- package/test/unit/dataContract/DataContract.spec.js +407 -0
- package/test/unit/dataContract/DataContractFactory.spec.js +178 -0
- package/test/unit/dataContract/createDataContract.spec.js +57 -0
- package/test/unit/dataContract/errors/InvalidDataContractError.spec.js +46 -0
- package/test/unit/dataContract/generateDataContractId.spec.js +19 -0
- package/test/unit/dataContract/getBinaryPropertiesFromSchema.spec.js +103 -0
- package/test/unit/dataContract/getPropertyDefinitionByPath.spec.js +84 -0
- package/test/unit/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition.spec.js +160 -0
- package/test/unit/dataContract/stateTransition/DataContractCreateTransition/applyDataContractCreateTransitionFactory.spec.js +48 -0
- package/test/unit/dataContract/stateTransition/DataContractCreateTransition/validation/state/validateDataContractCreateTransitionStateFactory.spec.js +85 -0
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/DataContractUpdateTransition.spec.js +158 -0
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/applyDataContractUpdateTransitionFactory.spec.js +47 -0
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateIndicesAreBackwardCompatible.spec.js +121 -0
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory.spec.js +111 -0
- package/test/unit/dataContract/validation/validateDataContractMaxDepthFactory.spec.js +93 -0
- package/test/unit/dataContract/validation/validateDataContractPatternsFactory.spec.js +64 -0
- package/test/unit/dataTrigger/DataTrigger.spec.js +132 -0
- package/test/unit/dataTrigger/DataTriggerExecutionContext.spec.js +29 -0
- package/test/unit/dataTrigger/dashpayDataTriggers/createContactRequestDataTrigger.spec.js +109 -0
- package/test/unit/dataTrigger/dpnsTriggers/createDomainDataTrigger.spec.js +382 -0
- package/test/unit/dataTrigger/featureFlagDataTriggers/createFeatureFlagDataTrigger.spec.js +101 -0
- package/test/unit/dataTrigger/getDataTriggersFactory.spec.js +113 -0
- package/test/unit/dataTrigger/rejectDataTrigger.spec.js +51 -0
- package/test/unit/dataTrigger/rewardShareDataTriggers/createMasternodeRewardSharesDataTrigger.spec.js +200 -0
- package/test/unit/decodeProtocolEntityFactory.spec.js +75 -0
- package/test/unit/document/Document.spec.js +444 -0
- package/test/unit/document/DocumentFactory.spec.js +376 -0
- package/test/unit/document/errors/InvalidDocumentError.spec.js +46 -0
- package/test/unit/document/fetchAndValidateDataContractFactory.spec.js +66 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js +168 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js +171 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/documentTransition/DocumentCreateTransition.spec.js +25 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesById.spec.js +31 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js +122 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/validatePartialCompoundIndices.spec.js +75 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js +128 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js +811 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +279 -0
- package/test/unit/errors/consensus/codes.spec.js +102 -0
- package/test/unit/identity/Identity.spec.js +243 -0
- package/test/unit/identity/IdentityFactory.spec.js +274 -0
- package/test/unit/identity/IdentityPublicKey.spec.js +273 -0
- package/test/unit/identity/creditsConverter.spec.js +34 -0
- package/test/unit/identity/errors/InvalidIdentityError.spec.js +46 -0
- package/test/unit/identity/stateTransition/IdentityCreateTransition/IdentityCreateTransition.spec.js +184 -0
- package/test/unit/identity/stateTransition/IdentityCreateTransition/applyIdentityCreateTransitionFactory.spec.js +90 -0
- package/test/unit/identity/stateTransition/IdentityCreateTransition/validation/state/validateIdentityCreateTransitionStateFactory.spec.js +71 -0
- package/test/unit/identity/stateTransition/IdentityTopUpTransition/IdentityTopUpTransition.spec.js +137 -0
- package/test/unit/identity/stateTransition/IdentityTopUpTransition/applyIdentityTopUpTransitionFactory.spec.js +108 -0
- package/test/unit/identity/stateTransition/IdentityTopUpTransition/validation/state/validateIdentityTopUpTransitionStateFactory.spec.js +22 -0
- package/test/unit/identity/stateTransition/IdentityUpdateTransition/IdentityUpdateTransition.spec.js +219 -0
- package/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js +149 -0
- package/test/unit/identity/stateTransition/assetLockProof/createAssetLockProofInstance.spec.js +21 -0
- package/test/unit/identity/stateTransition/assetLockProof/fetchAssetLockPublicKeyHashFactory.spec.js +36 -0
- package/test/unit/identity/validation/validateRequiredPurposeAndSecurityLevelFactory.spec.js +47 -0
- package/test/unit/stateTransition/StateTransitionFactory.spec.js +160 -0
- package/test/unit/stateTransition/createStateTransitionFactory.spec.js +72 -0
- package/test/unit/stateTransition/errors/InvalidStateTransitionError.spec.js +51 -0
- package/test/unit/stateTransition/validation/validateStateTransitionBasicFactory.spec.js +138 -0
- package/test/unit/stateTransition/validation/validateStateTransitionFeeFactory.spec.js +372 -0
- package/test/unit/stateTransition/validation/validateStateTransitionIdentitySignatureFactory.spec.js +339 -0
- package/test/unit/stateTransition/validation/validateStateTransitionKeySignatureFactory.spec.js +86 -0
- package/test/unit/stateTransition/validation/validateStateTransitionStateFactory.spec.js +89 -0
- package/test/unit/version/validateProtocolVersionFactory.spec.js +80 -0
- package/webpack.config.js +49 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const createStateTransitionFactory = require('../../../lib/stateTransition/createStateTransitionFactory');
|
|
2
|
+
|
|
3
|
+
const DataContractCreateTransition = require('../../../lib/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition');
|
|
4
|
+
const DocumentsBatchTransition = require('../../../lib/document/stateTransition/DocumentsBatchTransition/DocumentsBatchTransition');
|
|
5
|
+
|
|
6
|
+
const getDataContractFixture = require('../../../lib/test/fixtures/getDataContractFixture');
|
|
7
|
+
const getDocumentsFixture = require('../../../lib/test/fixtures/getDocumentsFixture');
|
|
8
|
+
const getDocumentTranstionsFixture = require('../../../lib/test/fixtures/getDocumentTransitionsFixture');
|
|
9
|
+
|
|
10
|
+
const createStateRepositoryMock = require('../../../lib/test/mocks/createStateRepositoryMock');
|
|
11
|
+
|
|
12
|
+
const InvalidStateTransitionTypeError = require('../../../lib/stateTransition/errors/InvalidStateTransitionTypeError');
|
|
13
|
+
|
|
14
|
+
describe('createStateTransitionFactory', () => {
|
|
15
|
+
let createStateTransition;
|
|
16
|
+
let stateRepositoryMock;
|
|
17
|
+
let dataContract;
|
|
18
|
+
|
|
19
|
+
beforeEach(function beforeEach() {
|
|
20
|
+
dataContract = getDataContractFixture();
|
|
21
|
+
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
22
|
+
stateRepositoryMock.fetchDataContract.resolves(dataContract);
|
|
23
|
+
createStateTransition = createStateTransitionFactory(stateRepositoryMock);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return DataContractCreateTransition if type is DATA_CONTRACT_CREATE', async () => {
|
|
27
|
+
const stateTransition = new DataContractCreateTransition({
|
|
28
|
+
dataContract: dataContract.toObject(),
|
|
29
|
+
entropy: dataContract.getEntropy(),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const result = await createStateTransition(stateTransition.toObject());
|
|
33
|
+
|
|
34
|
+
expect(result).to.be.instanceOf(DataContractCreateTransition);
|
|
35
|
+
expect(result.getDataContract().toObject()).to.deep.equal(dataContract.toObject());
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return DocumentsBatchTransition if type is DOCUMENTS', async () => {
|
|
39
|
+
const documents = getDocumentsFixture(dataContract);
|
|
40
|
+
const documentTransitions = getDocumentTranstionsFixture({
|
|
41
|
+
create: documents,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const stateTransition = new DocumentsBatchTransition({
|
|
45
|
+
ownerId: getDocumentsFixture.ownerId,
|
|
46
|
+
contractId: dataContract.getId(),
|
|
47
|
+
transitions: documentTransitions.map((t) => t.toObject()),
|
|
48
|
+
}, [dataContract]);
|
|
49
|
+
|
|
50
|
+
const result = await createStateTransition(stateTransition.toObject());
|
|
51
|
+
|
|
52
|
+
expect(result).to.be.instanceOf(DocumentsBatchTransition);
|
|
53
|
+
expect(result.getTransitions().map((t) => t.toObject())).to.have.deep.members(
|
|
54
|
+
documentTransitions.map((t) => t.toObject()),
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should throw InvalidStateTransitionTypeError if type is invalid', async () => {
|
|
59
|
+
const rawStateTransition = {
|
|
60
|
+
type: 666,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
await createStateTransition(rawStateTransition);
|
|
65
|
+
|
|
66
|
+
expect.fail('InvalidStateTransitionTypeError is not thrown');
|
|
67
|
+
} catch (e) {
|
|
68
|
+
expect(e).to.be.an.instanceOf(InvalidStateTransitionTypeError);
|
|
69
|
+
expect(e.getType()).to.equal(rawStateTransition.type);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const InvalidStateTransitionError = require('../../../../lib/stateTransition/errors/InvalidStateTransitionError');
|
|
2
|
+
const DataContractCreateTransition = require('../../../../lib/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition');
|
|
3
|
+
const getDataContractFixture = require('../../../../lib/test/fixtures/getDataContractFixture');
|
|
4
|
+
|
|
5
|
+
describe('InvalidStateTransitionError', () => {
|
|
6
|
+
let rawStateTransition;
|
|
7
|
+
let error;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
error = new Error('Some error');
|
|
11
|
+
|
|
12
|
+
const dataContract = getDataContractFixture();
|
|
13
|
+
const dataContractCreateTransition = new DataContractCreateTransition({
|
|
14
|
+
dataContract: dataContract.toObject(),
|
|
15
|
+
entropy: dataContract.getEntropy(),
|
|
16
|
+
});
|
|
17
|
+
rawStateTransition = dataContractCreateTransition.toObject();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should return errors', () => {
|
|
21
|
+
const errors = [error];
|
|
22
|
+
|
|
23
|
+
const invalidStateTransitionError = new InvalidStateTransitionError(errors, rawStateTransition);
|
|
24
|
+
|
|
25
|
+
expect(invalidStateTransitionError.getErrors()).to.deep.equal(errors);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should return State Transition', async () => {
|
|
29
|
+
const errors = [error];
|
|
30
|
+
|
|
31
|
+
const invalidStateTransitionError = new InvalidStateTransitionError(errors, rawStateTransition);
|
|
32
|
+
|
|
33
|
+
expect(invalidStateTransitionError.getRawStateTransition()).to.deep.equal(rawStateTransition);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should contain message for 1 error', async () => {
|
|
37
|
+
const errors = [error];
|
|
38
|
+
|
|
39
|
+
const invalidStateTransitionError = new InvalidStateTransitionError(errors, rawStateTransition);
|
|
40
|
+
|
|
41
|
+
expect(invalidStateTransitionError.message).to.equal(`Invalid State Transition: "${error.message}"`);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should contain message for multiple errors', async () => {
|
|
45
|
+
const errors = [error, error];
|
|
46
|
+
|
|
47
|
+
const invalidStateTransitionError = new InvalidStateTransitionError(errors, rawStateTransition);
|
|
48
|
+
|
|
49
|
+
expect(invalidStateTransitionError.message).to.equal(`Invalid State Transition: "${error.message}" and 1 more`);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
const validateStateTransitionBasicFactory = require('../../../../lib/stateTransition/validation/validateStateTransitionBasicFactory');
|
|
2
|
+
|
|
3
|
+
const DataContractFactory = require('../../../../lib/dataContract/DataContractFactory');
|
|
4
|
+
|
|
5
|
+
const stateTransitionTypes = require('../../../../lib/stateTransition/stateTransitionTypes');
|
|
6
|
+
|
|
7
|
+
const getDataContractFixture = require('../../../../lib/test/fixtures/getDataContractFixture');
|
|
8
|
+
|
|
9
|
+
const StateTransitionMaxSizeExceededError = require('../../../../lib/errors/consensus/basic/stateTransition/StateTransitionMaxSizeExceededError');
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
expectValidationError,
|
|
13
|
+
} = require('../../../../lib/test/expect/expectError');
|
|
14
|
+
|
|
15
|
+
const ValidationResult = require('../../../../lib/validation/ValidationResult');
|
|
16
|
+
|
|
17
|
+
const MissingStateTransitionTypeError = require('../../../../lib/errors/consensus/basic/stateTransition/MissingStateTransitionTypeError');
|
|
18
|
+
const InvalidStateTransitionTypeError = require('../../../../lib/errors/consensus/basic/stateTransition/InvalidStateTransitionTypeError');
|
|
19
|
+
const createDPPMock = require('../../../../lib/test/mocks/createDPPMock');
|
|
20
|
+
const SomeConsensusError = require('../../../../lib/test/mocks/SomeConsensusError');
|
|
21
|
+
const IdentityPublicKey = require('../../../../lib/identity/IdentityPublicKey');
|
|
22
|
+
|
|
23
|
+
describe('validateStateTransitionBasicFactory', () => {
|
|
24
|
+
let validateStateTransitionBasic;
|
|
25
|
+
let validationFunctionMock;
|
|
26
|
+
let rawStateTransition;
|
|
27
|
+
let dataContract;
|
|
28
|
+
let dataContractFactory;
|
|
29
|
+
let createStateTransitionMock;
|
|
30
|
+
let stateTransition;
|
|
31
|
+
|
|
32
|
+
beforeEach(async function beforeEach() {
|
|
33
|
+
validationFunctionMock = this.sinonSandbox.stub();
|
|
34
|
+
|
|
35
|
+
const validationFunctionsByType = {
|
|
36
|
+
[stateTransitionTypes.DATA_CONTRACT_CREATE]: validationFunctionMock,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
dataContract = getDataContractFixture();
|
|
40
|
+
|
|
41
|
+
const privateKey = '9b67f852093bc61cea0eeca38599dbfba0de28574d2ed9b99d10d33dc1bde7b2';
|
|
42
|
+
|
|
43
|
+
dataContractFactory = new DataContractFactory(createDPPMock(), undefined);
|
|
44
|
+
|
|
45
|
+
stateTransition = dataContractFactory.createDataContractCreateTransition(dataContract);
|
|
46
|
+
await stateTransition.signByPrivateKey(privateKey, IdentityPublicKey.TYPES.ECDSA_SECP256K1);
|
|
47
|
+
|
|
48
|
+
rawStateTransition = stateTransition.toObject();
|
|
49
|
+
|
|
50
|
+
createStateTransitionMock = this.sinonSandbox.stub().resolves(stateTransition);
|
|
51
|
+
|
|
52
|
+
validateStateTransitionBasic = validateStateTransitionBasicFactory(
|
|
53
|
+
validationFunctionsByType,
|
|
54
|
+
createStateTransitionMock,
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should return invalid result if ST type is missing', async () => {
|
|
59
|
+
delete rawStateTransition.type;
|
|
60
|
+
|
|
61
|
+
const result = await validateStateTransitionBasic(rawStateTransition);
|
|
62
|
+
|
|
63
|
+
expectValidationError(result);
|
|
64
|
+
|
|
65
|
+
const [error] = result.getErrors();
|
|
66
|
+
|
|
67
|
+
expect(error).to.be.instanceof(MissingStateTransitionTypeError);
|
|
68
|
+
|
|
69
|
+
expect(validationFunctionMock).to.not.be.called();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should return invalid result if ST type is not valid', async () => {
|
|
73
|
+
rawStateTransition.type = 666;
|
|
74
|
+
|
|
75
|
+
const result = await validateStateTransitionBasic(rawStateTransition);
|
|
76
|
+
|
|
77
|
+
expectValidationError(result);
|
|
78
|
+
|
|
79
|
+
const [error] = result.getErrors();
|
|
80
|
+
|
|
81
|
+
expect(error).to.be.instanceof(InvalidStateTransitionTypeError);
|
|
82
|
+
|
|
83
|
+
expect(validationFunctionMock).to.not.be.called();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should return invalid result if ST is invalid against validation function', async () => {
|
|
87
|
+
const extensionError = new SomeConsensusError('test');
|
|
88
|
+
const extensionResult = new ValidationResult([
|
|
89
|
+
extensionError,
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
validationFunctionMock.returns(extensionResult);
|
|
93
|
+
|
|
94
|
+
const result = await validateStateTransitionBasic(rawStateTransition);
|
|
95
|
+
|
|
96
|
+
expectValidationError(result);
|
|
97
|
+
|
|
98
|
+
const [error] = result.getErrors();
|
|
99
|
+
|
|
100
|
+
expect(error).to.equal(extensionError);
|
|
101
|
+
|
|
102
|
+
expect(validationFunctionMock).to.be.calledOnceWith(rawStateTransition);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should return invalid result if ST size is more than 16 kb', async () => {
|
|
106
|
+
const validationFunctionResult = new ValidationResult();
|
|
107
|
+
|
|
108
|
+
validationFunctionMock.returns(validationFunctionResult);
|
|
109
|
+
|
|
110
|
+
// generate big state transition
|
|
111
|
+
for (let i = 0; i < 500; i++) {
|
|
112
|
+
stateTransition.dataContract.documents[`anotherContract${i}`] = rawStateTransition.dataContract.documents.niceDocument;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const result = await validateStateTransitionBasic(
|
|
116
|
+
rawStateTransition,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
expectValidationError(result, StateTransitionMaxSizeExceededError);
|
|
120
|
+
|
|
121
|
+
const [error] = result.getErrors();
|
|
122
|
+
|
|
123
|
+
expect(error.getCode()).to.equal(1045);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should return valid result', async () => {
|
|
127
|
+
const extensionResult = new ValidationResult();
|
|
128
|
+
|
|
129
|
+
validationFunctionMock.returns(extensionResult);
|
|
130
|
+
|
|
131
|
+
const result = await validateStateTransitionBasic(rawStateTransition);
|
|
132
|
+
|
|
133
|
+
expect(result).to.be.an.instanceOf(ValidationResult);
|
|
134
|
+
expect(result.isValid()).to.be.true();
|
|
135
|
+
|
|
136
|
+
expect(validationFunctionMock).to.be.calledOnceWith(rawStateTransition);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
const validateStateTransitionFeeFactory = require('../../../../lib/stateTransition/validation/validateStateTransitionFeeFactory');
|
|
2
|
+
|
|
3
|
+
const createStateRepositoryMock = require('../../../../lib/test/mocks/createStateRepositoryMock');
|
|
4
|
+
|
|
5
|
+
const getIdentityFixture = require('../../../../lib/test/fixtures/getIdentityFixture');
|
|
6
|
+
const getDocumentsFixture = require('../../../../lib/test/fixtures/getDocumentsFixture');
|
|
7
|
+
const getDataContractFixture = require('../../../../lib/test/fixtures/getDataContractFixture');
|
|
8
|
+
const getIdentityCreateTransitionFixture = require('../../../../lib/test/fixtures/getIdentityCreateTransitionFixture');
|
|
9
|
+
const getDocumentTransitionsFixture = require('../../../../lib/test/fixtures/getDocumentTransitionsFixture');
|
|
10
|
+
const getIdentityTopUpTransitionFixture = require('../../../../lib/test/fixtures/getIdentityTopUpTransitionFixture');
|
|
11
|
+
|
|
12
|
+
const DataContractCreateTransition = require('../../../../lib/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition');
|
|
13
|
+
const DocumentsBatchTransition = require('../../../../lib/document/stateTransition/DocumentsBatchTransition/DocumentsBatchTransition');
|
|
14
|
+
|
|
15
|
+
const { expectValidationError } = require('../../../../lib/test/expect/expectError');
|
|
16
|
+
|
|
17
|
+
const IdentityBalanceIsNotEnoughError = require('../../../../lib/errors/consensus/fee/BalanceIsNotEnoughError');
|
|
18
|
+
const InvalidStateTransitionTypeError = require('../../../../lib/stateTransition/errors/InvalidStateTransitionTypeError');
|
|
19
|
+
|
|
20
|
+
const { RATIO } = require('../../../../lib/identity/creditsConverter');
|
|
21
|
+
const StateTransitionExecutionContext = require('../../../../lib/stateTransition/StateTransitionExecutionContext');
|
|
22
|
+
|
|
23
|
+
describe('validateStateTransitionFeeFactory', () => {
|
|
24
|
+
let stateRepositoryMock;
|
|
25
|
+
let validateStateTransitionFee;
|
|
26
|
+
let identity;
|
|
27
|
+
let dataContract;
|
|
28
|
+
let calculateStateTransitionFeeMock;
|
|
29
|
+
let fetchAssetLockTransactionOutputMock;
|
|
30
|
+
|
|
31
|
+
beforeEach(function beforeEach() {
|
|
32
|
+
identity = getIdentityFixture();
|
|
33
|
+
|
|
34
|
+
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
35
|
+
stateRepositoryMock.fetchIdentity.resolves(identity);
|
|
36
|
+
|
|
37
|
+
const output = getIdentityCreateTransitionFixture().getAssetLockProof().getOutput();
|
|
38
|
+
|
|
39
|
+
calculateStateTransitionFeeMock = this.sinonSandbox.stub().returns(42);
|
|
40
|
+
fetchAssetLockTransactionOutputMock = this.sinonSandbox.stub().resolves(output);
|
|
41
|
+
|
|
42
|
+
validateStateTransitionFee = validateStateTransitionFeeFactory(
|
|
43
|
+
stateRepositoryMock,
|
|
44
|
+
calculateStateTransitionFeeMock,
|
|
45
|
+
fetchAssetLockTransactionOutputMock,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
dataContract = getDataContractFixture();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('DataContractCreateTransition', () => {
|
|
52
|
+
let dataContractCreateTransition;
|
|
53
|
+
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
dataContractCreateTransition = new DataContractCreateTransition({
|
|
56
|
+
dataContract: dataContract.toObject(),
|
|
57
|
+
entropy: dataContract.getEntropy(),
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should return invalid result if balance is not enough', async () => {
|
|
62
|
+
identity.balance = 1;
|
|
63
|
+
|
|
64
|
+
const result = await validateStateTransitionFee(dataContractCreateTransition);
|
|
65
|
+
|
|
66
|
+
expectValidationError(result, IdentityBalanceIsNotEnoughError);
|
|
67
|
+
|
|
68
|
+
const [error] = result.getErrors();
|
|
69
|
+
|
|
70
|
+
expect(error.getCode()).to.equal(3000);
|
|
71
|
+
expect(error.getBalance()).to.equal(identity.balance);
|
|
72
|
+
|
|
73
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
74
|
+
dataContract.getOwnerId(),
|
|
75
|
+
dataContractCreateTransition.getExecutionContext(),
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(calculateStateTransitionFeeMock).to.be.calledOnceWithExactly(
|
|
79
|
+
dataContractCreateTransition,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
expect(fetchAssetLockTransactionOutputMock).to.not.be.called();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should return valid result', async () => {
|
|
86
|
+
identity.balance = 42;
|
|
87
|
+
|
|
88
|
+
const result = await validateStateTransitionFee(dataContractCreateTransition);
|
|
89
|
+
|
|
90
|
+
expect(result.isValid()).to.be.true();
|
|
91
|
+
|
|
92
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
93
|
+
dataContract.getOwnerId(),
|
|
94
|
+
dataContractCreateTransition.getExecutionContext(),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
expect(calculateStateTransitionFeeMock).to.be.calledOnceWithExactly(
|
|
98
|
+
dataContractCreateTransition,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
expect(fetchAssetLockTransactionOutputMock).to.not.be.called();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe('DocumentsBatchTransition', () => {
|
|
106
|
+
let documentsBatchTransition;
|
|
107
|
+
|
|
108
|
+
beforeEach(() => {
|
|
109
|
+
const documents = getDocumentsFixture(dataContract);
|
|
110
|
+
|
|
111
|
+
const documentTransitions = getDocumentTransitionsFixture({
|
|
112
|
+
create: documents,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
documentsBatchTransition = new DocumentsBatchTransition({
|
|
116
|
+
ownerId: getDocumentsFixture.ownerId,
|
|
117
|
+
contractId: dataContract.getId(),
|
|
118
|
+
transitions: documentTransitions.map((t) => t.toObject()),
|
|
119
|
+
}, [dataContract]);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should return invalid result if balance is not enough', async () => {
|
|
123
|
+
identity.balance = 1;
|
|
124
|
+
|
|
125
|
+
const result = await validateStateTransitionFee(documentsBatchTransition);
|
|
126
|
+
|
|
127
|
+
expectValidationError(result, IdentityBalanceIsNotEnoughError);
|
|
128
|
+
|
|
129
|
+
const [error] = result.getErrors();
|
|
130
|
+
|
|
131
|
+
expect(error.getCode()).to.equal(3000);
|
|
132
|
+
expect(error.getBalance()).to.equal(identity.balance);
|
|
133
|
+
|
|
134
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
135
|
+
getDocumentsFixture.ownerId,
|
|
136
|
+
documentsBatchTransition.getExecutionContext(),
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
expect(calculateStateTransitionFeeMock).to.be.calledOnceWithExactly(
|
|
140
|
+
documentsBatchTransition,
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
expect(fetchAssetLockTransactionOutputMock).to.not.be.called();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should return valid result', async () => {
|
|
147
|
+
identity.balance = 42;
|
|
148
|
+
|
|
149
|
+
const result = await validateStateTransitionFee(documentsBatchTransition);
|
|
150
|
+
|
|
151
|
+
expect(result.isValid()).to.be.true();
|
|
152
|
+
|
|
153
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
154
|
+
getDocumentsFixture.ownerId,
|
|
155
|
+
documentsBatchTransition.getExecutionContext(),
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
expect(calculateStateTransitionFeeMock).to.be.calledOnceWithExactly(
|
|
159
|
+
documentsBatchTransition,
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
expect(fetchAssetLockTransactionOutputMock).to.not.be.called();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should not increase balance on dry run', async () => {
|
|
166
|
+
documentsBatchTransition.getExecutionContext().enableDryRun();
|
|
167
|
+
|
|
168
|
+
const result = await validateStateTransitionFee(documentsBatchTransition);
|
|
169
|
+
|
|
170
|
+
documentsBatchTransition.getExecutionContext().disableDryRun();
|
|
171
|
+
|
|
172
|
+
expect(result.isValid()).to.be.true();
|
|
173
|
+
|
|
174
|
+
expect(calculateStateTransitionFeeMock).to.be.not.called();
|
|
175
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
176
|
+
getDocumentsFixture.ownerId,
|
|
177
|
+
documentsBatchTransition.getExecutionContext(),
|
|
178
|
+
);
|
|
179
|
+
expect(fetchAssetLockTransactionOutputMock).to.not.be.called();
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('IdentityCreateStateTransition', () => {
|
|
184
|
+
let identityCreateTransition;
|
|
185
|
+
let outputAmount;
|
|
186
|
+
|
|
187
|
+
beforeEach(() => {
|
|
188
|
+
identityCreateTransition = getIdentityCreateTransitionFixture();
|
|
189
|
+
|
|
190
|
+
const { satoshis } = identityCreateTransition
|
|
191
|
+
.getAssetLockProof()
|
|
192
|
+
.getOutput();
|
|
193
|
+
|
|
194
|
+
outputAmount = satoshis * RATIO;
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('should return invalid result if asset lock output amount is not enough', async () => {
|
|
198
|
+
calculateStateTransitionFeeMock.returns(outputAmount + 1);
|
|
199
|
+
|
|
200
|
+
const result = await validateStateTransitionFee(identityCreateTransition);
|
|
201
|
+
|
|
202
|
+
expectValidationError(result, IdentityBalanceIsNotEnoughError);
|
|
203
|
+
|
|
204
|
+
const [error] = result.getErrors();
|
|
205
|
+
|
|
206
|
+
expect(error.getCode()).to.equal(3000);
|
|
207
|
+
expect(error.getBalance()).to.equal(outputAmount);
|
|
208
|
+
|
|
209
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.not.called();
|
|
210
|
+
|
|
211
|
+
expect(calculateStateTransitionFeeMock).to.be.calledOnceWithExactly(
|
|
212
|
+
identityCreateTransition,
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
expect(fetchAssetLockTransactionOutputMock).to.be.calledOnceWithExactly(
|
|
216
|
+
identityCreateTransition.getAssetLockProof(),
|
|
217
|
+
identityCreateTransition.getExecutionContext(),
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('should return valid result', async () => {
|
|
222
|
+
calculateStateTransitionFeeMock.returns(outputAmount);
|
|
223
|
+
|
|
224
|
+
const result = await validateStateTransitionFee(identityCreateTransition);
|
|
225
|
+
|
|
226
|
+
expect(result.isValid()).to.be.true();
|
|
227
|
+
|
|
228
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.not.called();
|
|
229
|
+
|
|
230
|
+
expect(calculateStateTransitionFeeMock).to.be.calledOnceWithExactly(
|
|
231
|
+
identityCreateTransition,
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
expect(fetchAssetLockTransactionOutputMock).to.be.calledOnceWithExactly(
|
|
235
|
+
identityCreateTransition.getAssetLockProof(),
|
|
236
|
+
identityCreateTransition.getExecutionContext(),
|
|
237
|
+
);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('should not increase balance on dry run', async () => {
|
|
241
|
+
identityCreateTransition.getExecutionContext().enableDryRun();
|
|
242
|
+
|
|
243
|
+
const result = await validateStateTransitionFee(identityCreateTransition);
|
|
244
|
+
|
|
245
|
+
identityCreateTransition.getExecutionContext().disableDryRun();
|
|
246
|
+
|
|
247
|
+
expect(result.isValid()).to.be.true();
|
|
248
|
+
|
|
249
|
+
expect(calculateStateTransitionFeeMock).to.be.not.called();
|
|
250
|
+
expect(fetchAssetLockTransactionOutputMock).to.be.calledOnceWithExactly(
|
|
251
|
+
identityCreateTransition.getAssetLockProof(),
|
|
252
|
+
identityCreateTransition.getExecutionContext(),
|
|
253
|
+
);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
describe('IdentityTopUpTransition', () => {
|
|
258
|
+
let identityTopUpTransition;
|
|
259
|
+
let outputAmount;
|
|
260
|
+
|
|
261
|
+
beforeEach(() => {
|
|
262
|
+
identityTopUpTransition = getIdentityTopUpTransitionFixture();
|
|
263
|
+
|
|
264
|
+
const { satoshis } = identityTopUpTransition
|
|
265
|
+
.getAssetLockProof()
|
|
266
|
+
.getOutput();
|
|
267
|
+
|
|
268
|
+
outputAmount = satoshis * RATIO;
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('should return invalid result if sum of balance and asset lock output amount is not enough', async () => {
|
|
272
|
+
identity.balance = 1;
|
|
273
|
+
|
|
274
|
+
calculateStateTransitionFeeMock.returns(outputAmount + 2);
|
|
275
|
+
|
|
276
|
+
const result = await validateStateTransitionFee(identityTopUpTransition);
|
|
277
|
+
|
|
278
|
+
expectValidationError(result, IdentityBalanceIsNotEnoughError);
|
|
279
|
+
|
|
280
|
+
const [error] = result.getErrors();
|
|
281
|
+
|
|
282
|
+
expect(error.getCode()).to.equal(3000);
|
|
283
|
+
expect(error.getBalance()).to.equal(outputAmount + identity.balance);
|
|
284
|
+
|
|
285
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
286
|
+
identityTopUpTransition.getIdentityId(),
|
|
287
|
+
identityTopUpTransition.getExecutionContext(),
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
expect(calculateStateTransitionFeeMock).to.be.calledOnceWithExactly(
|
|
291
|
+
identityTopUpTransition,
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
expect(fetchAssetLockTransactionOutputMock).to.be.calledOnceWithExactly(
|
|
295
|
+
identityTopUpTransition.getAssetLockProof(),
|
|
296
|
+
identityTopUpTransition.getExecutionContext(),
|
|
297
|
+
);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should return valid result', async () => {
|
|
301
|
+
identity.balance = 41;
|
|
302
|
+
|
|
303
|
+
calculateStateTransitionFeeMock.returns(outputAmount - 1);
|
|
304
|
+
|
|
305
|
+
const result = await validateStateTransitionFee(identityTopUpTransition);
|
|
306
|
+
|
|
307
|
+
expect(result.isValid()).to.be.true();
|
|
308
|
+
|
|
309
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
310
|
+
identityTopUpTransition.getIdentityId(),
|
|
311
|
+
identityTopUpTransition.getExecutionContext(),
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
expect(calculateStateTransitionFeeMock).to.be.calledOnceWithExactly(
|
|
315
|
+
identityTopUpTransition,
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
expect(fetchAssetLockTransactionOutputMock).to.be.calledOnceWithExactly(
|
|
319
|
+
identityTopUpTransition.getAssetLockProof(),
|
|
320
|
+
identityTopUpTransition.getExecutionContext(),
|
|
321
|
+
);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('should not increase balance on dry run', async () => {
|
|
325
|
+
identityTopUpTransition.getExecutionContext().enableDryRun();
|
|
326
|
+
|
|
327
|
+
const result = await validateStateTransitionFee(identityTopUpTransition);
|
|
328
|
+
|
|
329
|
+
identityTopUpTransition.getExecutionContext().disableDryRun();
|
|
330
|
+
|
|
331
|
+
expect(result.isValid()).to.be.true();
|
|
332
|
+
|
|
333
|
+
expect(calculateStateTransitionFeeMock).to.be.not.called();
|
|
334
|
+
expect(fetchAssetLockTransactionOutputMock).to.be.calledOnceWithExactly(
|
|
335
|
+
identityTopUpTransition.getAssetLockProof(),
|
|
336
|
+
identityTopUpTransition.getExecutionContext(),
|
|
337
|
+
);
|
|
338
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
339
|
+
identityTopUpTransition.getIdentityId(),
|
|
340
|
+
identityTopUpTransition.getExecutionContext(),
|
|
341
|
+
);
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('should throw InvalidStateTransitionTypeError on invalid State Transition', async function it() {
|
|
346
|
+
const rawStateTransitionMock = {
|
|
347
|
+
data: 'sample data',
|
|
348
|
+
type: -1,
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const stateTransitionMock = {
|
|
352
|
+
getType: this.sinonSandbox.stub().returns(rawStateTransitionMock.type),
|
|
353
|
+
toBuffer: this.sinonSandbox.stub().returns(Buffer.alloc(0)),
|
|
354
|
+
toObject: this.sinonSandbox.stub().returns(rawStateTransitionMock),
|
|
355
|
+
getExecutionContext: this.sinonSandbox.stub().returns(new StateTransitionExecutionContext()),
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
try {
|
|
359
|
+
await validateStateTransitionFee(stateTransitionMock);
|
|
360
|
+
|
|
361
|
+
expect.fail('should throw InvalidStateTransitionTypeError');
|
|
362
|
+
} catch (error) {
|
|
363
|
+
expect(error).to.be.an.instanceOf(InvalidStateTransitionTypeError);
|
|
364
|
+
expect(error.getType()).to.equal(rawStateTransitionMock.type);
|
|
365
|
+
|
|
366
|
+
expect(calculateStateTransitionFeeMock).to.not.be.called();
|
|
367
|
+
expect(stateRepositoryMock.fetchIdentity).to.not.be.called();
|
|
368
|
+
|
|
369
|
+
expect(fetchAssetLockTransactionOutputMock).to.not.be.called();
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
});
|