From 7715df919aa55060a54f8e740e1082fb1e982a03 Mon Sep 17 00:00:00 2001 From: Konstantin Shuplenkov Date: Wed, 7 Dec 2022 19:46:59 +0300 Subject: [PATCH 1/2] feat(drive): return latest core chain lock on init chain --- .../abci/handlers/initChainHandlerFactory.js | 11 +++++++++ .../handlers/initChainHandlerFactory.spec.js | 23 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/packages/js-drive/lib/abci/handlers/initChainHandlerFactory.js b/packages/js-drive/lib/abci/handlers/initChainHandlerFactory.js index a1276994cd7..d60f8c2b5e4 100644 --- a/packages/js-drive/lib/abci/handlers/initChainHandlerFactory.js +++ b/packages/js-drive/lib/abci/handlers/initChainHandlerFactory.js @@ -21,6 +21,8 @@ const protoTimestampToMillis = require('../../util/protoTimestampToMillis'); * @param {registerSystemDataContracts} registerSystemDataContracts * @param {GroveDBStore} groveDBStore * @param {RSAbci} rsAbci + * @param {createCoreChainLockUpdate} createCoreChainLockUpdate + * @param {BlockExecutionContext} proposalBlockExecutionContext * @return {initChainHandler} */ function initChainHandlerFactory( @@ -33,6 +35,8 @@ function initChainHandlerFactory( registerSystemDataContracts, groveDBStore, rsAbci, + createCoreChainLockUpdate, + proposalBlockExecutionContext, ) { /** * @typedef initChainHandler @@ -109,6 +113,12 @@ function initChainHandlerFactory( const validatorSetUpdate = createValidatorSetUpdate(validatorSet); + proposalBlockExecutionContext.setCoreChainLockedHeight(initialCoreChainLockedHeight); + + const coreChainLockUpdate = await createCoreChainLockUpdate(0, consensusLogger); + + proposalBlockExecutionContext.reset(); + consensusLogger.trace(validatorSetUpdate, `Validator set initialized with ${quorumHash} quorum`); consensusLogger.info( @@ -125,6 +135,7 @@ function initChainHandlerFactory( appHash, validatorSetUpdate, initialCoreHeight: initialCoreChainLockedHeight, + nextCoreChainLockUpdate: coreChainLockUpdate, }); } diff --git a/packages/js-drive/test/unit/abci/handlers/initChainHandlerFactory.spec.js b/packages/js-drive/test/unit/abci/handlers/initChainHandlerFactory.spec.js index c82a572c536..de0e4821fcd 100644 --- a/packages/js-drive/test/unit/abci/handlers/initChainHandlerFactory.spec.js +++ b/packages/js-drive/test/unit/abci/handlers/initChainHandlerFactory.spec.js @@ -6,6 +6,9 @@ const { ResponseInitChain, ValidatorSetUpdate, }, + types: { + CoreChainLock, + }, }, } = require('@dashevo/abci/types'); @@ -15,6 +18,7 @@ const GroveDBStoreMock = require('../../../../lib/test/mock/GroveDBStoreMock'); const protoTimestampToMillis = require('../../../../lib/util/protoTimestampToMillis'); const millisToProtoTimestamp = require('../../../../lib/util/millisToProtoTimestamp'); const BlockInfo = require('../../../../lib/blockExecution/BlockInfo'); +const BlockExecutionContextMock = require('../../../../lib/test/mock/BlockExecutionContextMock'); describe('initChainHandlerFactory', () => { let initChainHandler; @@ -29,6 +33,9 @@ describe('initChainHandlerFactory', () => { let groveDBStoreMock; let appHashFixture; let rsAbciMock; + let createCoreChainLockUpdateMock; + let coreChainLockUpdate; + let proposalBlockExecutionContextMock; beforeEach(function beforeEach() { initialCoreChainLockedHeight = 1; @@ -66,6 +73,16 @@ describe('initChainHandlerFactory', () => { groveDBStoreMock = new GroveDBStoreMock(this.sinon); groveDBStoreMock.getRootHash.resolves(appHashFixture); + coreChainLockUpdate = new CoreChainLock({ + coreBlockHeight: 42, + coreBlockHash: '1528e523f4c20fa84ba70dd96372d34e00ce260f357d53ad1a8bc892ebf20e2d', + signature: '1897ce8f54d2070f44ca5c29983b68b391e8137c25e44f67416e579f3e3bdfef7b4fd22db7818399147e52907998857b0fbc8edfdc40a64f2c7df0e88544d31d12ca8c15e73d50dda25ca23f754ed3f789ed4bcb392161995f464017c10df404', + }); + + createCoreChainLockUpdateMock = this.sinon.stub().resolves(coreChainLockUpdate); + + proposalBlockExecutionContextMock = new BlockExecutionContextMock(this.sinon); + initChainHandler = initChainHandlerFactory( updateSimplifiedMasternodeListMock, initialCoreChainLockedHeight, @@ -76,6 +93,8 @@ describe('initChainHandlerFactory', () => { registerSystemDataContractsMock, groveDBStoreMock, rsAbciMock, + createCoreChainLockUpdateMock, + proposalBlockExecutionContextMock, ); }); @@ -130,5 +149,9 @@ describe('initChainHandlerFactory', () => { expect(validatorSetMock.getQuorum).to.be.calledOnce(); expect(createValidatorSetUpdateMock).to.be.calledOnceWithExactly(validatorSetMock); + + expect(createCoreChainLockUpdateMock).to.be.calledOnceWithExactly(0, loggerMock); + expect(proposalBlockExecutionContextMock.setCoreChainLockedHeight) + .to.be.calledOnceWithExactly(initialCoreChainLockedHeight); }); }); From 2e8f8b2b7bc7d2db545ae32b84a96ed7cf62784b Mon Sep 17 00:00:00 2001 From: Konstantin Shuplenkov Date: Wed, 7 Dec 2022 20:12:15 +0300 Subject: [PATCH 2/2] feat(drive): return latest core chain lock on init chain --- .../lib/abci/handlers/initChainHandlerFactory.js | 12 +++++------- .../abci/handlers/prepareProposalHandlerFactory.js | 6 +++++- .../proposal/createCoreChainLockUpdateFactory.js | 6 ++---- .../abci/handlers/initChainHandlerFactory.spec.js | 10 ++-------- .../handlers/prepareProposalHandlerFactory.spec.js | 6 +++++- .../createCoreChainLockUpdateFactory.spec.js | 12 ++---------- 6 files changed, 21 insertions(+), 31 deletions(-) diff --git a/packages/js-drive/lib/abci/handlers/initChainHandlerFactory.js b/packages/js-drive/lib/abci/handlers/initChainHandlerFactory.js index d60f8c2b5e4..6364252d3e7 100644 --- a/packages/js-drive/lib/abci/handlers/initChainHandlerFactory.js +++ b/packages/js-drive/lib/abci/handlers/initChainHandlerFactory.js @@ -22,7 +22,6 @@ const protoTimestampToMillis = require('../../util/protoTimestampToMillis'); * @param {GroveDBStore} groveDBStore * @param {RSAbci} rsAbci * @param {createCoreChainLockUpdate} createCoreChainLockUpdate - * @param {BlockExecutionContext} proposalBlockExecutionContext * @return {initChainHandler} */ function initChainHandlerFactory( @@ -36,7 +35,6 @@ function initChainHandlerFactory( groveDBStore, rsAbci, createCoreChainLockUpdate, - proposalBlockExecutionContext, ) { /** * @typedef initChainHandler @@ -113,11 +111,11 @@ function initChainHandlerFactory( const validatorSetUpdate = createValidatorSetUpdate(validatorSet); - proposalBlockExecutionContext.setCoreChainLockedHeight(initialCoreChainLockedHeight); - - const coreChainLockUpdate = await createCoreChainLockUpdate(0, consensusLogger); - - proposalBlockExecutionContext.reset(); + const coreChainLockUpdate = await createCoreChainLockUpdate( + initialCoreChainLockedHeight, + 0, + consensusLogger, + ); consensusLogger.trace(validatorSetUpdate, `Validator set initialized with ${quorumHash} quorum`); diff --git a/packages/js-drive/lib/abci/handlers/prepareProposalHandlerFactory.js b/packages/js-drive/lib/abci/handlers/prepareProposalHandlerFactory.js index 730522c1095..d52dfe59b3e 100644 --- a/packages/js-drive/lib/abci/handlers/prepareProposalHandlerFactory.js +++ b/packages/js-drive/lib/abci/handlers/prepareProposalHandlerFactory.js @@ -122,7 +122,11 @@ function prepareProposalHandlerFactory( // Revert consensus logger after deliverTx proposalBlockExecutionContext.setConsensusLogger(consensusLogger); - const coreChainLockUpdate = await createCoreChainLockUpdate(round, consensusLogger); + const coreChainLockUpdate = await createCoreChainLockUpdate( + coreChainLockedHeight, + round, + consensusLogger, + ); const { consensusParamUpdates, diff --git a/packages/js-drive/lib/abci/handlers/proposal/createCoreChainLockUpdateFactory.js b/packages/js-drive/lib/abci/handlers/proposal/createCoreChainLockUpdateFactory.js index 2c9856c449f..d13008a3aea 100644 --- a/packages/js-drive/lib/abci/handlers/proposal/createCoreChainLockUpdateFactory.js +++ b/packages/js-drive/lib/abci/handlers/proposal/createCoreChainLockUpdateFactory.js @@ -7,23 +7,21 @@ const { } = require('@dashevo/abci/types'); /** * - * @param {BlockExecutionContext} proposalBlockExecutionContext * @param {LatestCoreChainLock} latestCoreChainLock * @return {createCoreChainLockUpdate} */ function createCoreChainLockUpdateFactory( - proposalBlockExecutionContext, latestCoreChainLock, ) { /** * @typedef createCoreChainLockUpdate + * @param {number} contextCoreChainLockedHeight * @param {number} round * @param {BaseLogger} consensusLogger * @return {Promise} */ - async function createCoreChainLockUpdate(round, consensusLogger) { + async function createCoreChainLockUpdate(contextCoreChainLockedHeight, round, consensusLogger) { // Update Core Chain Locks - const contextCoreChainLockedHeight = proposalBlockExecutionContext.getCoreChainLockedHeight(); const coreChainLock = latestCoreChainLock.getChainLock(); let coreChainLockUpdate; diff --git a/packages/js-drive/test/unit/abci/handlers/initChainHandlerFactory.spec.js b/packages/js-drive/test/unit/abci/handlers/initChainHandlerFactory.spec.js index de0e4821fcd..f637a2cca3f 100644 --- a/packages/js-drive/test/unit/abci/handlers/initChainHandlerFactory.spec.js +++ b/packages/js-drive/test/unit/abci/handlers/initChainHandlerFactory.spec.js @@ -18,7 +18,6 @@ const GroveDBStoreMock = require('../../../../lib/test/mock/GroveDBStoreMock'); const protoTimestampToMillis = require('../../../../lib/util/protoTimestampToMillis'); const millisToProtoTimestamp = require('../../../../lib/util/millisToProtoTimestamp'); const BlockInfo = require('../../../../lib/blockExecution/BlockInfo'); -const BlockExecutionContextMock = require('../../../../lib/test/mock/BlockExecutionContextMock'); describe('initChainHandlerFactory', () => { let initChainHandler; @@ -35,7 +34,6 @@ describe('initChainHandlerFactory', () => { let rsAbciMock; let createCoreChainLockUpdateMock; let coreChainLockUpdate; - let proposalBlockExecutionContextMock; beforeEach(function beforeEach() { initialCoreChainLockedHeight = 1; @@ -81,8 +79,6 @@ describe('initChainHandlerFactory', () => { createCoreChainLockUpdateMock = this.sinon.stub().resolves(coreChainLockUpdate); - proposalBlockExecutionContextMock = new BlockExecutionContextMock(this.sinon); - initChainHandler = initChainHandlerFactory( updateSimplifiedMasternodeListMock, initialCoreChainLockedHeight, @@ -94,7 +90,6 @@ describe('initChainHandlerFactory', () => { groveDBStoreMock, rsAbciMock, createCoreChainLockUpdateMock, - proposalBlockExecutionContextMock, ); }); @@ -150,8 +145,7 @@ describe('initChainHandlerFactory', () => { expect(createValidatorSetUpdateMock).to.be.calledOnceWithExactly(validatorSetMock); - expect(createCoreChainLockUpdateMock).to.be.calledOnceWithExactly(0, loggerMock); - expect(proposalBlockExecutionContextMock.setCoreChainLockedHeight) - .to.be.calledOnceWithExactly(initialCoreChainLockedHeight); + expect(createCoreChainLockUpdateMock) + .to.be.calledOnceWithExactly(initialCoreChainLockedHeight, 0, loggerMock); }); }); diff --git a/packages/js-drive/test/unit/abci/handlers/prepareProposalHandlerFactory.spec.js b/packages/js-drive/test/unit/abci/handlers/prepareProposalHandlerFactory.spec.js index b2a3a3e977f..27d70c5e9fd 100644 --- a/packages/js-drive/test/unit/abci/handlers/prepareProposalHandlerFactory.spec.js +++ b/packages/js-drive/test/unit/abci/handlers/prepareProposalHandlerFactory.spec.js @@ -164,7 +164,11 @@ describe('prepareProposalHandlerFactory', () => { expect(deliverTxMock).to.be.calledThrice(); - expect(updateCoreChainLockMock).to.be.calledOnceWithExactly(round, loggerMock); + expect(updateCoreChainLockMock).to.be.calledOnceWithExactly( + request.coreChainLockedHeight, + round, + loggerMock, + ); expect(endBlockMock).to.be.calledOnceWithExactly( { diff --git a/packages/js-drive/test/unit/abci/handlers/proposal/createCoreChainLockUpdateFactory.spec.js b/packages/js-drive/test/unit/abci/handlers/proposal/createCoreChainLockUpdateFactory.spec.js index 3ec8a29a421..7e52c580dfc 100644 --- a/packages/js-drive/test/unit/abci/handlers/proposal/createCoreChainLockUpdateFactory.spec.js +++ b/packages/js-drive/test/unit/abci/handlers/proposal/createCoreChainLockUpdateFactory.spec.js @@ -6,7 +6,6 @@ const { }, } = require('@dashevo/abci/types'); const createCoreChainLockUpdateFactory = require('../../../../../lib/abci/handlers/proposal/createCoreChainLockUpdateFactory'); -const BlockExecutionContextMock = require('../../../../../lib/test/mock/BlockExecutionContextMock'); const LoggerMock = require('../../../../../lib/test/mock/LoggerMock'); describe('createCoreChainLockUpdateFactory', () => { @@ -16,7 +15,6 @@ describe('createCoreChainLockUpdateFactory', () => { let coreChainLockedHeight; let loggerMock; let round; - let proposalBlockExecutionContextMock; beforeEach(function beforeEach() { round = 0; @@ -30,17 +28,11 @@ describe('createCoreChainLockUpdateFactory', () => { coreChainLockedHeight = 2; - proposalBlockExecutionContextMock = new BlockExecutionContextMock(this.sinon); - - proposalBlockExecutionContextMock.hasDataContract.returns(true); - proposalBlockExecutionContextMock.getCoreChainLockedHeight.returns(coreChainLockedHeight); - latestCoreChainLockMock = { getChainLock: this.sinon.stub().returns(chainLockMock), }; createCoreChainLockUpdate = createCoreChainLockUpdateFactory( - proposalBlockExecutionContextMock, latestCoreChainLockMock, ); }); @@ -48,7 +40,7 @@ describe('createCoreChainLockUpdateFactory', () => { it('should return nextCoreChainLockUpdate if latestCoreChainLock above header height', async () => { chainLockMock.height = 3; - const response = await createCoreChainLockUpdate(round, loggerMock); + const response = await createCoreChainLockUpdate(coreChainLockedHeight, round, loggerMock); expect(latestCoreChainLockMock.getChainLock).to.have.been.calledOnceWithExactly(); @@ -64,7 +56,7 @@ describe('createCoreChainLockUpdateFactory', () => { it('should return undefined', async () => { chainLockMock.height = 1; - const response = await createCoreChainLockUpdate(round, loggerMock); + const response = await createCoreChainLockUpdate(coreChainLockedHeight, round, loggerMock); expect(latestCoreChainLockMock.getChainLock).to.have.been.calledOnceWithExactly();