@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,101 @@
|
|
|
1
|
+
const Long = require('long');
|
|
2
|
+
|
|
3
|
+
const createFeatureFlagDataTrigger = require('../../../../lib/dataTrigger/featureFlagsDataTriggers/createFeatureFlagDataTrigger');
|
|
4
|
+
|
|
5
|
+
const getIdentityFixture = require('../../../../lib/test/fixtures/getIdentityFixture');
|
|
6
|
+
const getFeatureFlagsDocumentsFixture = require('../../../../lib/test/fixtures/getFeatureFlagsDocumentsFixture');
|
|
7
|
+
const getDocumentTransitionsFixture = require('../../../../lib/test/fixtures/getDocumentTransitionsFixture');
|
|
8
|
+
const createStateRepositoryMock = require('../../../../lib/test/mocks/createStateRepositoryMock');
|
|
9
|
+
const DataTriggerExecutionResult = require('../../../../lib/dataTrigger/DataTriggerExecutionResult');
|
|
10
|
+
const DataTriggerConditionError = require('../../../../lib/errors/consensus/state/dataContract/dataTrigger/DataTriggerConditionError');
|
|
11
|
+
const Identifier = require('../../../../lib/identifier/Identifier');
|
|
12
|
+
const StateTransitionExecutionContext = require('../../../../lib/stateTransition/StateTransitionExecutionContext');
|
|
13
|
+
|
|
14
|
+
describe('createFeatureFlagDataTrigger', () => {
|
|
15
|
+
let contextMock;
|
|
16
|
+
let stateRepositoryMock;
|
|
17
|
+
let documentTransition;
|
|
18
|
+
let topLevelIdentityId;
|
|
19
|
+
|
|
20
|
+
beforeEach(function beforeEach() {
|
|
21
|
+
topLevelIdentityId = getIdentityFixture().getId();
|
|
22
|
+
|
|
23
|
+
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
24
|
+
stateRepositoryMock.fetchLatestPlatformBlockHeader.resolves({
|
|
25
|
+
height: new Long(42),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const [document] = getFeatureFlagsDocumentsFixture();
|
|
29
|
+
|
|
30
|
+
[documentTransition] = getDocumentTransitionsFixture({
|
|
31
|
+
create: [document],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const context = new StateTransitionExecutionContext();
|
|
35
|
+
|
|
36
|
+
contextMock = {
|
|
37
|
+
getStateRepository: () => stateRepositoryMock,
|
|
38
|
+
getOwnerId: this.sinonSandbox.stub(),
|
|
39
|
+
getDataContract: () => getFeatureFlagsDocumentsFixture.dataContract,
|
|
40
|
+
getStateTransitionExecutionContext: () => context,
|
|
41
|
+
};
|
|
42
|
+
contextMock.getOwnerId.returns(topLevelIdentityId);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should return an error if height is lower than block height', async () => {
|
|
46
|
+
documentTransition.data.enableAtHeight = 1;
|
|
47
|
+
|
|
48
|
+
const result = await createFeatureFlagDataTrigger(
|
|
49
|
+
documentTransition, contextMock, topLevelIdentityId,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
53
|
+
expect(result.isOk()).to.be.false();
|
|
54
|
+
|
|
55
|
+
const [error] = result.getErrors();
|
|
56
|
+
|
|
57
|
+
expect(error).to.be.an.instanceOf(DataTriggerConditionError);
|
|
58
|
+
expect(error.message).to.equal('Feature flag cannot be enabled in the past on block 1. Current block height is 42');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should return an error if owner id is not equal to top level identity id', async () => {
|
|
62
|
+
contextMock.getOwnerId.returns(Identifier.from(Buffer.alloc(32, 1)));
|
|
63
|
+
|
|
64
|
+
const result = await createFeatureFlagDataTrigger(
|
|
65
|
+
documentTransition, contextMock, topLevelIdentityId,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
69
|
+
expect(result.isOk()).to.be.false();
|
|
70
|
+
|
|
71
|
+
const [error] = result.getErrors();
|
|
72
|
+
|
|
73
|
+
expect(error).to.be.an.instanceOf(DataTriggerConditionError);
|
|
74
|
+
expect(error.message).to.equal('This identity can\'t activate selected feature flag');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should pass', async () => {
|
|
78
|
+
const result = await createFeatureFlagDataTrigger(
|
|
79
|
+
documentTransition, contextMock, topLevelIdentityId,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
83
|
+
expect(result.isOk()).to.be.true();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should pass on dry run', async () => {
|
|
87
|
+
contextMock.getStateTransitionExecutionContext().enableDryRun();
|
|
88
|
+
|
|
89
|
+
const result = await createFeatureFlagDataTrigger(
|
|
90
|
+
documentTransition, contextMock, topLevelIdentityId,
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
contextMock.getStateTransitionExecutionContext().disableDryRun();
|
|
94
|
+
|
|
95
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
96
|
+
expect(result.isOk()).to.be.true();
|
|
97
|
+
|
|
98
|
+
expect(contextMock.getOwnerId).to.not.be.called();
|
|
99
|
+
expect(stateRepositoryMock.fetchLatestPlatformBlockHeader).to.not.be.called();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const {
|
|
2
|
+
contractId: dpnsContractId,
|
|
3
|
+
ownerId: dpnsOwnerId,
|
|
4
|
+
} = require('@dashevo/dpns-contract/lib/systemIds');
|
|
5
|
+
|
|
6
|
+
const AbstractDocumentTransition = require('../../../lib/document/stateTransition/DocumentsBatchTransition/documentTransition/AbstractDocumentTransition');
|
|
7
|
+
|
|
8
|
+
const getDataTriggersFactory = require('../../../lib/dataTrigger/getDataTriggersFactory');
|
|
9
|
+
|
|
10
|
+
const getDpnsDocumentFixture = require('../../../lib/test/fixtures/getDpnsDocumentFixture');
|
|
11
|
+
|
|
12
|
+
const DataTrigger = require('../../../lib/dataTrigger/DataTrigger');
|
|
13
|
+
|
|
14
|
+
const createDomainDataTrigger = require('../../../lib/dataTrigger/dpnsTriggers/createDomainDataTrigger');
|
|
15
|
+
const rejectDataTrigger = require('../../../lib/dataTrigger/rejectDataTrigger');
|
|
16
|
+
const Identifier = require('../../../lib/identifier/Identifier');
|
|
17
|
+
|
|
18
|
+
describe('getDataTriggers', () => {
|
|
19
|
+
let getDataTriggers;
|
|
20
|
+
|
|
21
|
+
let createDocument;
|
|
22
|
+
let updateDocument;
|
|
23
|
+
let deleteDocument;
|
|
24
|
+
|
|
25
|
+
let createTrigger;
|
|
26
|
+
let updateTrigger;
|
|
27
|
+
let deleteTrigger;
|
|
28
|
+
|
|
29
|
+
let updatePreorderTrigger;
|
|
30
|
+
let deletePreorderTrigger;
|
|
31
|
+
|
|
32
|
+
let dataContractId;
|
|
33
|
+
let topLevelIdentity;
|
|
34
|
+
|
|
35
|
+
let processMock;
|
|
36
|
+
|
|
37
|
+
beforeEach(function beforeEach() {
|
|
38
|
+
createDocument = getDpnsDocumentFixture.getChildDocumentFixture();
|
|
39
|
+
updateDocument = getDpnsDocumentFixture.getChildDocumentFixture();
|
|
40
|
+
deleteDocument = getDpnsDocumentFixture.getChildDocumentFixture();
|
|
41
|
+
deleteDocument.data = {};
|
|
42
|
+
|
|
43
|
+
dataContractId = Identifier.from(dpnsContractId);
|
|
44
|
+
topLevelIdentity = Identifier.from(dpnsOwnerId);
|
|
45
|
+
|
|
46
|
+
createTrigger = new DataTrigger(
|
|
47
|
+
dataContractId, 'domain', AbstractDocumentTransition.ACTIONS.CREATE, createDomainDataTrigger, topLevelIdentity,
|
|
48
|
+
);
|
|
49
|
+
updateTrigger = new DataTrigger(
|
|
50
|
+
dataContractId, 'domain', AbstractDocumentTransition.ACTIONS.REPLACE, rejectDataTrigger,
|
|
51
|
+
);
|
|
52
|
+
deleteTrigger = new DataTrigger(
|
|
53
|
+
dataContractId, 'domain', AbstractDocumentTransition.ACTIONS.DELETE, rejectDataTrigger,
|
|
54
|
+
);
|
|
55
|
+
updatePreorderTrigger = new DataTrigger(
|
|
56
|
+
dataContractId, 'preorder', AbstractDocumentTransition.ACTIONS.REPLACE, rejectDataTrigger,
|
|
57
|
+
);
|
|
58
|
+
deletePreorderTrigger = new DataTrigger(
|
|
59
|
+
dataContractId, 'preorder', AbstractDocumentTransition.ACTIONS.DELETE, rejectDataTrigger,
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
processMock = this.sinonSandbox.stub(process, 'env').value({
|
|
63
|
+
DPNS_CONTRACT_ID: dataContractId,
|
|
64
|
+
DPNS_TOP_LEVEL_IDENTITY: topLevelIdentity,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
getDataTriggers = getDataTriggersFactory();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
afterEach(() => {
|
|
71
|
+
processMock.restore();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should return matching triggers', () => {
|
|
75
|
+
let result = getDataTriggers(
|
|
76
|
+
dataContractId, createDocument.getType(), AbstractDocumentTransition.ACTIONS.CREATE,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
expect(result).to.deep.equal([createTrigger]);
|
|
80
|
+
|
|
81
|
+
result = getDataTriggers(
|
|
82
|
+
dataContractId, updateDocument.getType(), AbstractDocumentTransition.ACTIONS.REPLACE,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
expect(result).to.deep.equal([updateTrigger]);
|
|
86
|
+
|
|
87
|
+
result = getDataTriggers(
|
|
88
|
+
dataContractId, deleteDocument.getType(), AbstractDocumentTransition.ACTIONS.DELETE,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
expect(result).to.deep.equal([deleteTrigger]);
|
|
92
|
+
|
|
93
|
+
result = getDataTriggers(
|
|
94
|
+
dataContractId, 'preorder', AbstractDocumentTransition.ACTIONS.REPLACE,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
expect(result).to.deep.equal([updatePreorderTrigger]);
|
|
98
|
+
|
|
99
|
+
result = getDataTriggers(
|
|
100
|
+
dataContractId, 'preorder', AbstractDocumentTransition.ACTIONS.DELETE,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect(result).to.deep.equal([deletePreorderTrigger]);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should return empty trigger array for any other type except `domain`', () => {
|
|
107
|
+
const result = getDataTriggers(
|
|
108
|
+
dataContractId, 'otherType', AbstractDocumentTransition.ACTIONS.CREATE,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(result).to.deep.equal([]);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const bs58 = require('bs58');
|
|
2
|
+
const rejectDataTrigger = require('../../../lib/dataTrigger/rejectDataTrigger');
|
|
3
|
+
|
|
4
|
+
const DataTriggerExecutionContext = require('../../../lib/dataTrigger/DataTriggerExecutionContext');
|
|
5
|
+
|
|
6
|
+
const { getChildDocumentFixture } = require('../../../lib/test/fixtures/getDpnsDocumentFixture');
|
|
7
|
+
|
|
8
|
+
const createStateRepositoryMock = require('../../../lib/test/mocks/createStateRepositoryMock');
|
|
9
|
+
|
|
10
|
+
const getDpnsContractFixture = require('../../../lib/test/fixtures/getDpnsContractFixture');
|
|
11
|
+
const getDocumentTransitionFixture = require('../../../lib/test/fixtures/getDocumentTransitionsFixture');
|
|
12
|
+
|
|
13
|
+
const DataTriggerExecutionResult = require('../../../lib/dataTrigger/DataTriggerExecutionResult');
|
|
14
|
+
const StateTransitionExecutionContext = require('../../../lib/stateTransition/StateTransitionExecutionContext');
|
|
15
|
+
|
|
16
|
+
describe('rejectDataTrigger', () => {
|
|
17
|
+
let documentTransition;
|
|
18
|
+
let context;
|
|
19
|
+
let stateRepositoryMock;
|
|
20
|
+
let dataContract;
|
|
21
|
+
|
|
22
|
+
beforeEach(function beforeEach() {
|
|
23
|
+
dataContract = getDpnsContractFixture();
|
|
24
|
+
const document = getChildDocumentFixture();
|
|
25
|
+
|
|
26
|
+
[documentTransition] = getDocumentTransitionFixture({
|
|
27
|
+
create: [],
|
|
28
|
+
delete: [document],
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
32
|
+
context = new DataTriggerExecutionContext(
|
|
33
|
+
stateRepositoryMock,
|
|
34
|
+
bs58.decode('5zcXZpTLWFwZjKjq3ME5KVavtZa9YUaZESVzrndehBhq'),
|
|
35
|
+
dataContract,
|
|
36
|
+
new StateTransitionExecutionContext(),
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should always fail', async () => {
|
|
41
|
+
const result = await rejectDataTrigger(documentTransition, context);
|
|
42
|
+
|
|
43
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
44
|
+
|
|
45
|
+
expect(result.isOk()).to.be.false();
|
|
46
|
+
|
|
47
|
+
const [error] = result.getErrors();
|
|
48
|
+
|
|
49
|
+
expect(error.message).to.equal('Action is not allowed');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
const SimplifiedMNListEntry = require('@dashevo/dashcore-lib/lib/deterministicmnlist/SimplifiedMNListEntry');
|
|
2
|
+
const getIdentityFixture = require('../../../../lib/test/fixtures/getIdentityFixture');
|
|
3
|
+
const createStateRepositoryMock = require('../../../../lib/test/mocks/createStateRepositoryMock');
|
|
4
|
+
const getMasternodeRewardShareDocumentsFixture = require('../../../../lib/test/fixtures/getMasternodeRewardShareDocumentsFixture');
|
|
5
|
+
const getMasternodeRewardSharesContractFixture = require('../../../../lib/test/fixtures/getMasternodeRewardSharesContractFixture');
|
|
6
|
+
const getDocumentTransitionsFixture = require('../../../../lib/test/fixtures/getDocumentTransitionsFixture');
|
|
7
|
+
const createRewardShareDataTrigger = require('../../../../lib/dataTrigger/rewardShareDataTriggers/createMasternodeRewardSharesDataTrigger');
|
|
8
|
+
const DataTriggerExecutionResult = require('../../../../lib/dataTrigger/DataTriggerExecutionResult');
|
|
9
|
+
const DataTriggerConditionError = require('../../../../lib/errors/consensus/state/dataContract/dataTrigger/DataTriggerConditionError');
|
|
10
|
+
const StateTransitionExecutionContext = require('../../../../lib/stateTransition/StateTransitionExecutionContext');
|
|
11
|
+
|
|
12
|
+
describe('createMasternodeRewardSharesDataTrigger', () => {
|
|
13
|
+
let contextMock;
|
|
14
|
+
let stateRepositoryMock;
|
|
15
|
+
let documentTransition;
|
|
16
|
+
let topLevelIdentityId;
|
|
17
|
+
let smlStoreMock;
|
|
18
|
+
let smlMock;
|
|
19
|
+
let documentsFixture;
|
|
20
|
+
let executionContext;
|
|
21
|
+
|
|
22
|
+
beforeEach(function beforeEach() {
|
|
23
|
+
topLevelIdentityId = Buffer.from('c286807d463b06c7aba3b9a60acf64c1fc03da8c1422005cd9b4293f08cf0562', 'hex');
|
|
24
|
+
|
|
25
|
+
smlMock = {
|
|
26
|
+
getQuorum: this.sinonSandbox.stub(),
|
|
27
|
+
toSimplifiedMNListDiff: this.sinonSandbox.stub(),
|
|
28
|
+
getQuorumsOfType: this.sinonSandbox.stub(),
|
|
29
|
+
getValidMasternodesList: this.sinonSandbox.stub().returns([
|
|
30
|
+
new SimplifiedMNListEntry({
|
|
31
|
+
proRegTxHash: 'c286807d463b06c7aba3b9a60acf64c1fc03da8c1422005cd9b4293f08cf0562',
|
|
32
|
+
confirmedHash: '4eb56228c535db3b234907113fd41d57bcc7cdcb8e0e00e57590af27ee88c119',
|
|
33
|
+
service: '192.168.65.2:20101',
|
|
34
|
+
pubKeyOperator: '809519c5f6f3be1c08782ac42ae9a83b6c7205eba43f9a96a4f032ec7a73f1a7c25fa78cce0d6d9c135f7e2c28527179',
|
|
35
|
+
votingAddress: 'yXmprXYP51uzfMyndtWwxz96MnkCKkFc9x',
|
|
36
|
+
isValid: true,
|
|
37
|
+
}),
|
|
38
|
+
new SimplifiedMNListEntry({
|
|
39
|
+
proRegTxHash: 'a3e1edc6bd352eeaf0ae58e30781ef4b127854241a3fe7fddf36d5b7e1dc2b3f',
|
|
40
|
+
confirmedHash: '27a0b637b56af038c45e2fd1f06c2401c8dadfa28ca5e0d19ca836cc984a8378',
|
|
41
|
+
service: '192.168.65.2:20201',
|
|
42
|
+
pubKeyOperator: '987a4873caba62cd45a2f7d4aa6d94519ee6753e9bef777c927cb94ade768a542b0ff34a93231d3a92b4e75ffdaa366e',
|
|
43
|
+
votingAddress: 'ycL7L4mhYoaZdm9TH85svvpfeKtdfo249u',
|
|
44
|
+
isValid: true,
|
|
45
|
+
}),
|
|
46
|
+
]),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const dataContract = getMasternodeRewardSharesContractFixture();
|
|
50
|
+
|
|
51
|
+
documentsFixture = getMasternodeRewardShareDocumentsFixture(undefined, undefined, dataContract);
|
|
52
|
+
|
|
53
|
+
smlStoreMock = {
|
|
54
|
+
getSMLbyHeight: this.sinonSandbox.stub().returns(smlMock),
|
|
55
|
+
getCurrentSML: this.sinonSandbox.stub().returns(smlMock),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
59
|
+
stateRepositoryMock.fetchSMLStore.resolves(smlStoreMock);
|
|
60
|
+
stateRepositoryMock.fetchIdentity.resolves(getIdentityFixture());
|
|
61
|
+
stateRepositoryMock.fetchDocuments.resolves([]);
|
|
62
|
+
|
|
63
|
+
const [document] = getMasternodeRewardShareDocumentsFixture(undefined, undefined, dataContract);
|
|
64
|
+
|
|
65
|
+
[documentTransition] = getDocumentTransitionsFixture({
|
|
66
|
+
create: [document],
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
executionContext = new StateTransitionExecutionContext();
|
|
70
|
+
|
|
71
|
+
contextMock = {
|
|
72
|
+
getStateRepository: () => stateRepositoryMock,
|
|
73
|
+
getOwnerId: this.sinonSandbox.stub(),
|
|
74
|
+
getDataContract: () => dataContract,
|
|
75
|
+
getStateTransitionExecutionContext: () => executionContext,
|
|
76
|
+
};
|
|
77
|
+
contextMock.getOwnerId.returns(topLevelIdentityId);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should return an error if percentage > 10000', async () => {
|
|
81
|
+
stateRepositoryMock.fetchDocuments.resolves(documentsFixture);
|
|
82
|
+
// documentsFixture contains percentage = 500
|
|
83
|
+
documentTransition.data.percentage = 9501;
|
|
84
|
+
|
|
85
|
+
const result = await createRewardShareDataTrigger(
|
|
86
|
+
documentTransition, contextMock,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
90
|
+
expect(result.isOk()).to.be.false();
|
|
91
|
+
|
|
92
|
+
const [error] = result.getErrors();
|
|
93
|
+
|
|
94
|
+
expect(error).to.be.an.instanceOf(DataTriggerConditionError);
|
|
95
|
+
expect(error.message).to.equal('Percentage can not be more than 10000');
|
|
96
|
+
|
|
97
|
+
expect(stateRepositoryMock.fetchSMLStore).to.be.calledOnce();
|
|
98
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
99
|
+
documentTransition.data.payToId,
|
|
100
|
+
executionContext,
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should return an error if payToId does not exist', async () => {
|
|
105
|
+
stateRepositoryMock.fetchIdentity.resolves(null);
|
|
106
|
+
|
|
107
|
+
const result = await createRewardShareDataTrigger(
|
|
108
|
+
documentTransition, contextMock,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
112
|
+
expect(result.isOk()).to.be.false();
|
|
113
|
+
|
|
114
|
+
const [error] = result.getErrors();
|
|
115
|
+
|
|
116
|
+
expect(error).to.be.an.instanceOf(DataTriggerConditionError);
|
|
117
|
+
expect(error.message).to.equal(`Identity ${documentTransition.data.payToId} doesn't exist`);
|
|
118
|
+
|
|
119
|
+
expect(stateRepositoryMock.fetchSMLStore).to.be.calledOnce();
|
|
120
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
121
|
+
documentTransition.data.payToId,
|
|
122
|
+
executionContext,
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should return an error if ownerId is not a masternode identity', async () => {
|
|
127
|
+
contextMock.getOwnerId.returns(getIdentityFixture().getId());
|
|
128
|
+
|
|
129
|
+
const result = await createRewardShareDataTrigger(
|
|
130
|
+
documentTransition, contextMock,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
134
|
+
expect(result.isOk()).to.be.false();
|
|
135
|
+
|
|
136
|
+
const [error] = result.getErrors();
|
|
137
|
+
|
|
138
|
+
expect(error).to.be.an.instanceOf(DataTriggerConditionError);
|
|
139
|
+
expect(error.message).to.equal('Only masternode identities can share rewards');
|
|
140
|
+
|
|
141
|
+
expect(stateRepositoryMock.fetchSMLStore).to.be.calledOnce();
|
|
142
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.not.called();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should pass', async () => {
|
|
146
|
+
const result = await createRewardShareDataTrigger(
|
|
147
|
+
documentTransition, contextMock,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
151
|
+
expect(result.isOk()).to.be.true();
|
|
152
|
+
|
|
153
|
+
expect(stateRepositoryMock.fetchSMLStore).to.be.calledOnce();
|
|
154
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
155
|
+
documentTransition.data.payToId,
|
|
156
|
+
executionContext,
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should pass on dry run', async () => {
|
|
161
|
+
stateRepositoryMock.fetchIdentity.resolves(null);
|
|
162
|
+
|
|
163
|
+
executionContext.enableDryRun();
|
|
164
|
+
|
|
165
|
+
const result = await createRewardShareDataTrigger(
|
|
166
|
+
documentTransition, contextMock,
|
|
167
|
+
);
|
|
168
|
+
executionContext.disableDryRun();
|
|
169
|
+
|
|
170
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
171
|
+
expect(result.isOk()).to.be.true();
|
|
172
|
+
expect(stateRepositoryMock.fetchSMLStore).to.not.be.called();
|
|
173
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
174
|
+
documentTransition.data.payToId,
|
|
175
|
+
executionContext,
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should return an error if there are 16 stored shares', async () => {
|
|
180
|
+
stateRepositoryMock.fetchDocuments.resolves(new Array(16).fill(0));
|
|
181
|
+
|
|
182
|
+
const result = await createRewardShareDataTrigger(
|
|
183
|
+
documentTransition, contextMock,
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
expect(result).to.be.an.instanceOf(DataTriggerExecutionResult);
|
|
187
|
+
expect(result.isOk()).to.be.false();
|
|
188
|
+
|
|
189
|
+
const [error] = result.getErrors();
|
|
190
|
+
|
|
191
|
+
expect(error).to.be.an.instanceOf(DataTriggerConditionError);
|
|
192
|
+
expect(error.message).to.equal('Reward shares cannot contain more than 16 identities');
|
|
193
|
+
|
|
194
|
+
expect(stateRepositoryMock.fetchSMLStore).to.be.calledOnce();
|
|
195
|
+
expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly(
|
|
196
|
+
documentTransition.data.payToId,
|
|
197
|
+
executionContext,
|
|
198
|
+
);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const decodeProtocolEntityFactory = require('../../lib/decodeProtocolEntityFactory');
|
|
2
|
+
const ProtocolVersionParsingError = require('../../lib/errors/consensus/basic/decode/ProtocolVersionParsingError');
|
|
3
|
+
const SerializedObjectParsingError = require('../../lib/errors/consensus/basic/decode/SerializedObjectParsingError');
|
|
4
|
+
|
|
5
|
+
const { encode } = require('../../lib/util/serializer');
|
|
6
|
+
|
|
7
|
+
describe('decodeProtocolEntityFactory', () => {
|
|
8
|
+
let decodeProtocolEntity;
|
|
9
|
+
let versionCompatibilityMap;
|
|
10
|
+
let parsedProtocolVersion;
|
|
11
|
+
let entityBuffer;
|
|
12
|
+
let protocolVersionBuffer;
|
|
13
|
+
let rawEntity;
|
|
14
|
+
let buffer;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
parsedProtocolVersion = 0;
|
|
18
|
+
|
|
19
|
+
protocolVersionBuffer = Buffer.alloc(4);
|
|
20
|
+
protocolVersionBuffer.writeUInt32LE(parsedProtocolVersion, 0);
|
|
21
|
+
|
|
22
|
+
rawEntity = { test: 'successful' };
|
|
23
|
+
entityBuffer = encode(rawEntity);
|
|
24
|
+
|
|
25
|
+
buffer = Buffer.concat([protocolVersionBuffer, entityBuffer]);
|
|
26
|
+
|
|
27
|
+
versionCompatibilityMap = {
|
|
28
|
+
0: 0,
|
|
29
|
+
1: 0,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
decodeProtocolEntity = decodeProtocolEntityFactory(
|
|
33
|
+
versionCompatibilityMap,
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should throw ProtocolVersionParsingError if can\'t parse protocol version', () => {
|
|
38
|
+
buffer = Buffer.alloc(0);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
decodeProtocolEntity(buffer);
|
|
42
|
+
|
|
43
|
+
expect.fail('should throw ProtocolVersionParsingError');
|
|
44
|
+
} catch (e) {
|
|
45
|
+
expect(e).to.be.an.instanceOf(ProtocolVersionParsingError);
|
|
46
|
+
|
|
47
|
+
expect(e.getParsingError()).to.be.instanceOf(Error);
|
|
48
|
+
expect(e.getCode()).to.equal(1000);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should throw SerializedObjectParsingError if entity decoding fails', () => {
|
|
53
|
+
entityBuffer = Buffer.alloc(5).fill(1);
|
|
54
|
+
|
|
55
|
+
buffer = Buffer.concat([protocolVersionBuffer, entityBuffer]);
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
decodeProtocolEntity(buffer);
|
|
59
|
+
|
|
60
|
+
expect.fail('should throw SerializedObjectParsingError');
|
|
61
|
+
} catch (e) {
|
|
62
|
+
expect(e).to.be.an.instanceOf(SerializedObjectParsingError);
|
|
63
|
+
|
|
64
|
+
expect(e.getParsingError()).to.be.an.instanceOf(Error);
|
|
65
|
+
expect(e.getCode()).to.equal(1001);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should decode protocol version and entity successfully', () => {
|
|
70
|
+
const [protocolVersion, actualRawEntity] = decodeProtocolEntity(buffer);
|
|
71
|
+
|
|
72
|
+
expect(protocolVersion).to.equal(parsedProtocolVersion);
|
|
73
|
+
expect(rawEntity).to.deep.equal(actualRawEntity);
|
|
74
|
+
});
|
|
75
|
+
});
|