Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/js-dpp/lib/StateRepositoryInterface.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
* @async
* @method
* @name StateRepository#removeDocument
* @param {Identifier} contractId
* @param {DataContract} dataContract
* @param {string} type
* @param {Identifier} id
* @param {StateTransitionExecutionContext} [StateTransitionExecutionContext]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function applyDocumentsBatchTransitionFactory(
}
case AbstractDocumentTransition.ACTIONS.DELETE: {
return stateRepository.removeDocument(
documentTransition.getDataContractId(),
documentTransition.getDataContract(),
documentTransition.getType(),
documentTransition.getId(),
executionContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ describe('applyDocumentsBatchTransitionFactory', () => {
]);

expect(stateRepositoryMock.removeDocument).to.have.been.calledOnceWithExactly(
documentTransitions[2].getDataContractId(),
documentTransitions[2].getDataContract(),
documentTransitions[2].getType(),
documentTransitions[2].getId(),
executionContext,
Expand Down
12 changes: 8 additions & 4 deletions packages/js-drive/lib/abci/handlers/commitHandlerFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const {
},
},
} = require('@dashevo/abci/types');
const ReadOperation = require('@dashevo/dpp/lib/stateTransition/fee/operations/ReadOperation');
const DataContractCacheItem = require('../../dataContract/DataContractCacheItem');

/**
* @param {CreditsDistributionPool} creditsDistributionPool
Expand Down Expand Up @@ -76,12 +78,14 @@ function commitHandlerFactory(
await groveDBStore.commitTransaction();

// Update data contract cache with new version of
// commited data contract
// committed data contract
for (const dataContract of blockExecutionContext.getDataContracts()) {
const idString = dataContract.getId().toString();
const operations = [new ReadOperation(dataContract.toBuffer().length)];

if (dataContractCache.has(idString)) {
dataContractCache.set(idString, dataContract);
const cacheItem = new DataContractCacheItem(dataContract, operations);

if (dataContractCache.has(cacheItem.getKey())) {
dataContractCache.set(cacheItem.getKey(), cacheItem);
}
}

Expand Down
2 changes: 0 additions & 2 deletions packages/js-drive/lib/createDIContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,6 @@ function createDIContainer(options) {
coreRpcClient,
blockExecutionContext,
simplifiedMasternodeList,
dataContractCache,
);

return new CachedStateRepositoryDecorator(
Expand Down Expand Up @@ -637,7 +636,6 @@ function createDIContainer(options) {
coreRpcClient,
blockExecutionContext,
simplifiedMasternodeList,
dataContractCache,
{
useTransaction: true,
},
Expand Down
44 changes: 44 additions & 0 deletions packages/js-drive/lib/dataContract/DataContractCacheItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class DataContractCacheItem {
/**
* @type {DataContract}
*/
#dataContract;

/**
* @type {AbstractOperation[]}
*/
#operations;

/**
*
* @param {DataContract} dataContract
* @param {AbstractOperation[]} operations
*/
constructor(dataContract, operations) {
this.#dataContract = dataContract;
this.#operations = operations;
}

/**
* @return {DataContract}
*/
getDataContract() {
return this.#dataContract;
}

/**
* @return {AbstractOperation[]}
*/
getOperations() {
return this.#operations;
}

/**
* @return {string}
*/
getKey() {
return this.#dataContract.getId().toString();
}
}

module.exports = DataContractCacheItem;
16 changes: 13 additions & 3 deletions packages/js-drive/lib/document/fetchDocumentsFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const IdentifierError = require('@dashevo/dpp/lib/identifier/errors/IdentifierEr
const Identifier = require('@dashevo/dpp/lib/identifier/Identifier');

const InvalidQueryError = require('./errors/InvalidQueryError');
const DataContractCacheItem = require('../dataContract/DataContractCacheItem');

/**
* @param {DocumentRepository} documentRepository
Expand Down Expand Up @@ -38,11 +39,18 @@ function fetchDocumentsFactory(

const contractIdString = contractIdIdentifier.toString();

let dataContract = dataContractCache.get(contractIdString);
/**
* @type {DataContractCacheItem}
*/
let cacheItem = dataContractCache.get(contractIdString);

let operations = [];
let dataContract;

if (!dataContract) {
if (cacheItem) {
dataContract = cacheItem.getDataContract();
operations = cacheItem.getOperations();
} else {
const dataContractResult = await dataContractRepository.fetch(contractIdIdentifier);

if (dataContractResult.isNull()) {
Expand All @@ -52,7 +60,9 @@ function fetchDocumentsFactory(
dataContract = dataContractResult.getValue();
operations = dataContractResult.getOperations();

dataContractCache.set(contractIdString, dataContract);
cacheItem = new DataContractCacheItem(dataContract, operations);

dataContractCache.set(contractIdString, cacheItem);
}

if (!dataContract.isDocumentDefined(type)) {
Expand Down
35 changes: 27 additions & 8 deletions packages/js-drive/lib/dpp/CachedStateRepositoryDecorator.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
const StateTransitionExecutionContext = require('@dashevo/dpp/lib/stateTransition/StateTransitionExecutionContext');

const DataContractCacheItem = require('../dataContract/DataContractCacheItem');

/**
* @implements StateRepository
*/
Expand Down Expand Up @@ -124,16 +128,31 @@ class CachedStateRepositoryDecorator {
async fetchDataContract(id, executionContext = undefined) {
const idString = id.toString();

let dataContract = this.contractCache.get(idString);
let cacheItem = this.contractCache.get(idString);

if (cacheItem) {
if (executionContext) {
executionContext.addOperation(...cacheItem.getOperations());
}

if (dataContract !== undefined) {
return dataContract;
return cacheItem.getDataContract();
}

dataContract = await this.stateRepository.fetchDataContract(id, executionContext);
const isolatedExecutionContext = new StateTransitionExecutionContext();

const dataContract = await this.stateRepository.fetchDataContract(id, isolatedExecutionContext);

if (executionContext) {
executionContext.addOperation(...isolatedExecutionContext.getOperations());
}

if (dataContract !== null) {
this.contractCache.set(idString, dataContract);
cacheItem = new DataContractCacheItem(
dataContract,
isolatedExecutionContext.getOperations(),
);

this.contractCache.set(idString, cacheItem);
}

return dataContract;
Expand Down Expand Up @@ -192,15 +211,15 @@ class CachedStateRepositoryDecorator {
/**
* Remove document
*
* @param {Identifier} contractId
* @param {DataContract} dataContract
* @param {string} type
* @param {Identifier} id
* @param {StateTransitionExecutionContext} [executionContext]
*
* @returns {Promise<void>}
*/
async removeDocument(contractId, type, id, executionContext = undefined) {
return this.stateRepository.removeDocument(contractId, type, id, executionContext);
async removeDocument(dataContract, type, id, executionContext = undefined) {
return this.stateRepository.removeDocument(dataContract, type, id, executionContext);
}

/**
Expand Down
24 changes: 2 additions & 22 deletions packages/js-drive/lib/dpp/DriveStateRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ const SignatureVerificationOperation = require('@dashevo/dpp/lib/stateTransition
class DriveStateRepository {
#options = {};

/**
* @type {LRUCache}
*/
#dataContractCache;

/**
* @param {IdentityStoreRepository} identityRepository
* @param {PublicKeyToIdentitiesStoreRepository} publicKeyToToIdentitiesRepository
Expand All @@ -24,7 +19,6 @@ class DriveStateRepository {
* @param {RpcClient} coreRpcClient
* @param {BlockExecutionContext} blockExecutionContext
* @param {SimplifiedMasternodeList} simplifiedMasternodeList
* @param {LRUCache} dataContractCache
* @param {Object} [options]
* @param {Object} [options.useTransaction=false]
*/
Expand All @@ -38,7 +32,6 @@ class DriveStateRepository {
coreRpcClient,
blockExecutionContext,
simplifiedMasternodeList,
dataContractCache,
options = {},
) {
this.identityRepository = identityRepository;
Expand All @@ -50,7 +43,6 @@ class DriveStateRepository {
this.coreRpcClient = coreRpcClient;
this.blockExecutionContext = blockExecutionContext;
this.simplifiedMasternodeList = simplifiedMasternodeList;
this.#dataContractCache = dataContractCache;
this.#options = options;
}

Expand Down Expand Up @@ -318,26 +310,14 @@ class DriveStateRepository {
/**
* Remove document
*
* @param {Identifier} contractId
* @param {DataContract} dataContract
* @param {string} type
* @param {Identifier} id
* @param {StateTransitionExecutionContext} [executionContext]
*
* @returns {Promise<void>}
*/
async removeDocument(contractId, type, id, executionContext = undefined) {
const contractIdString = contractId.toString();

// TODO: This is not very clean approach since we have already cached decorator
// to enable caching for the whole state repository
let dataContract = this.#dataContractCache.get(contractIdString);

if (!dataContract) {
dataContract = await this.fetchDataContract(contractId, executionContext);

this.#dataContractCache.set(contractIdString, dataContract);
}

async removeDocument(dataContract, type, id, executionContext = undefined) {
const result = await this.documentRepository.delete(
dataContract,
type,
Expand Down
13 changes: 9 additions & 4 deletions packages/js-drive/lib/dpp/LoggedStateRepositoryDecorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,23 +363,28 @@ class LoggedStateRepositoryDecorator {
/**
* Remove document
*
* @param {Identifier} contractId
* @param {DataContract} dataContract
* @param {string} type
* @param {Identifier} id
* @param {StateTransitionExecutionContext} [executionContext]
*
* @returns {Promise<void>}
*/
async removeDocument(contractId, type, id, executionContext = undefined) {
async removeDocument(dataContract, type, id, executionContext = undefined) {
let response;

try {
response = await this.stateRepository.removeDocument(contractId, type, id, executionContext);
response = await this.stateRepository.removeDocument(
dataContract,
type,
id,
executionContext,
);
} finally {
this.log(
'removeDocument',
{
contractId,
dataContract,
type,
id,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const IdentityPublicKey = require('@dashevo/dpp/lib/identity/IdentityPublicKey');
const ReadOperation = require('@dashevo/dpp/lib/stateTransition/fee/operations/ReadOperation');
const DataContractCacheItem = require('../dataContract/DataContractCacheItem');

/**
* @param {DashPlatformProtocol} dpp
Expand Down Expand Up @@ -71,7 +73,11 @@ function registerSystemDataContractFactory(
});

// Store data contract in the cache
dataContractCache.set(dataContract.getId().toString(), dataContract);
const cacheItem = new DataContractCacheItem(dataContract, [
new ReadOperation(dataContract.toBuffer().length),
]);

dataContractCache.set(cacheItem.getKey(), cacheItem);

return dataContract;
}
Expand Down
14 changes: 0 additions & 14 deletions packages/js-drive/test/integration/fee/feesPrediction.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,6 @@ describe('feesPrediction', () => {
it('should have predicted fee more than actual fee', async () => {
await stateRepository.storeDataContract(dataContract);

// store data contract in cache
const dataContractCache = container.resolve('dataContractCache');
dataContractCache.set(
dataContract.getId().toString(),
await dpp.dataContract.createFromObject(dataContract.toObject()),
);

dataContract.setVersion(2);

const documents = dataContract.getDocuments();
Expand Down Expand Up @@ -437,13 +430,6 @@ describe('feesPrediction', () => {

await stateRepository.storeDataContract(dataContract);

// store data contract in cache
const dataContractCache = container.resolve('dataContractCache');
dataContractCache.set(
dataContract.getId().toString(),
await dpp.dataContract.createFromObject(dataContract.toObject()),
);

// Create documents

documents = [];
Expand Down
Loading