diff --git a/src/masternodes/masternodes.h b/src/masternodes/masternodes.h index d118096ce6..1a82da95b8 100644 --- a/src/masternodes/masternodes.h +++ b/src/masternodes/masternodes.h @@ -259,7 +259,8 @@ class CMasternodesView virtual CMasternode const * ExistMasternode(uint256 const & id) const; - virtual void WriteMintedBlockHeader(uint256 const & txid, uint64_t const mintedBlocks, uint256 const & hash, CBlockHeader const & blockHeader, bool fIsFakeNet = true) { assert(false); } + virtual void CommitHeaders() { assert(false); } + virtual void WriteMintedBlockHeader(uint256 const & txid, uint64_t const mintedBlocks, uint256 const & hash, CBlockHeader const & blockHeader, bool isBatched, bool fIsFakeNet = true) { assert(false); } virtual bool FindMintedBlockHeader(uint256 const & txid, uint64_t const mintedBlocks, std::map & blockHeaders, bool fIsFakeNet = true) { assert(false); } virtual void EraseMintedBlockHeader(uint256 const & txid, uint64_t const mintedBlocks, uint256 const & hash) { assert(false); } diff --git a/src/masternodes/mn_txdb.cpp b/src/masternodes/mn_txdb.cpp index b0c696857e..ad86ea4ba9 100644 --- a/src/masternodes/mn_txdb.cpp +++ b/src/masternodes/mn_txdb.cpp @@ -93,6 +93,15 @@ void CMasternodesViewDB::CommitBatch() } } +void CMasternodesViewDB::CommitHeaders() +{ + if (headersBatch) + { + db->WriteBatch(*headersBatch); + headersBatch.reset(); + } +} + bool CMasternodesViewDB::ReadHeight(int & h) { // it's a hack, cause we don't know active chain tip at the loading time @@ -118,13 +127,20 @@ void CMasternodesViewDB::EraseMasternode(uint256 const & txid) BatchErase(make_pair(DB_MASTERNODES, txid)); } -void CMasternodesViewDB::WriteMintedBlockHeader(uint256 const & txid, uint64_t const mintedBlocks, uint256 const & hash, CBlockHeader const & blockHeader, bool fIsFakeNet) +void CMasternodesViewDB::WriteMintedBlockHeader(uint256 const & txid, uint64_t const mintedBlocks, uint256 const & hash, CBlockHeader const & blockHeader, bool isBatched, bool fIsFakeNet) { if (fIsFakeNet) { return; } - db->Write(DBMNBlockHeadersKey{DB_MN_BLOCK_HEADERS, DBMNBlockHeadersSearchKey{txid, mintedBlocks}, hash}, blockHeader); + if (!headersBatch) + { + headersBatch.reset(new CDBBatch(*db)); + } + headersBatch->Write(DBMNBlockHeadersKey{DB_MN_BLOCK_HEADERS, DBMNBlockHeadersSearchKey{txid, mintedBlocks}, hash}, blockHeader); + if (!isBatched) { + CommitHeaders(); + } } bool CMasternodesViewDB::FindMintedBlockHeader(uint256 const & txid, uint64_t const mintedBlocks, std::map & blockHeaders, bool fIsFakeNet) diff --git a/src/masternodes/mn_txdb.h b/src/masternodes/mn_txdb.h index 5684d6077a..cc1263ce39 100644 --- a/src/masternodes/mn_txdb.h +++ b/src/masternodes/mn_txdb.h @@ -25,6 +25,7 @@ class CMasternodesViewDB : public CMasternodesView private: boost::shared_ptr db; boost::scoped_ptr batch; + boost::scoped_ptr headersBatch; public: CMasternodesViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); @@ -88,6 +89,7 @@ class CMasternodesViewDB : public CMasternodesView protected: void CommitBatch(); + void CommitHeaders() override; bool ReadHeight(int & h); void WriteHeight(int h); @@ -95,19 +97,19 @@ class CMasternodesViewDB : public CMasternodesView void WriteMasternode(uint256 const & txid, CMasternode const & node); void EraseMasternode(uint256 const & txid); - void WriteMintedBlockHeader(uint256 const & txid, uint64_t mintedBlocks, uint256 const & hash, CBlockHeader const & blockHeader, bool fIsFakeNet = true); - bool FindMintedBlockHeader(uint256 const & txid, uint64_t mintedBlocks, std::map & blockHeaders, bool fIsFakeNet = true); - void EraseMintedBlockHeader(uint256 const & txid, uint64_t mintedBlocks, uint256 const & hash); + void WriteMintedBlockHeader(uint256 const & txid, uint64_t mintedBlocks, uint256 const & hash, CBlockHeader const & blockHeader, bool isBatched, bool fIsFakeNet = true) override; + bool FindMintedBlockHeader(uint256 const & txid, uint64_t mintedBlocks, std::map & blockHeaders, bool fIsFakeNet = true) override; + void EraseMintedBlockHeader(uint256 const & txid, uint64_t mintedBlocks, uint256 const & hash) override; - void WriteCriminal(uint256 const & mnId, CDoubleSignFact const & doubleSignFact); - void EraseCriminal(uint256 const & mnId); + void WriteCriminal(uint256 const & mnId, CDoubleSignFact const & doubleSignFact) override; + void EraseCriminal(uint256 const & mnId) override; - void WriteCurrentTeam(std::set const & currentTeam); - bool LoadCurrentTeam(std::set & newTeam); - bool EraseCurrentTeam(); + void WriteCurrentTeam(std::set const & currentTeam) override; + bool LoadCurrentTeam(std::set & newTeam) override; + bool EraseCurrentTeam() override; - void WriteFoundationsDebt(CAmount const foundationsDebt); - bool LoadFoundationsDebt(); + void WriteFoundationsDebt(CAmount const foundationsDebt) override; + bool LoadFoundationsDebt() override; // void WriteDeadIndex(int height, uint256 const & txid, char type); // void EraseDeadIndex(int height, uint256 const & txid); diff --git a/src/test/double_sign.cpp b/src/test/double_sign.cpp index 3f2de402a4..fa0d4ca8c8 100644 --- a/src/test/double_sign.cpp +++ b/src/test/double_sign.cpp @@ -79,8 +79,8 @@ BOOST_AUTO_TEST_CASE(check_doublesign) uint64_t mintedBlocks = 0; std::vector criminalsBlockHeaders = GenerateTwoCriminalsHeaders(minterKey, mintedBlocks, masternodeID); - pmasternodesview->WriteMintedBlockHeader(masternodeID, mintedBlocks, criminalsBlockHeaders[0].GetHash(), criminalsBlockHeaders[0], false); - pmasternodesview->WriteMintedBlockHeader(masternodeID, mintedBlocks, criminalsBlockHeaders[1].GetHash(), criminalsBlockHeaders[1], false); + pmasternodesview->WriteMintedBlockHeader(masternodeID, mintedBlocks, criminalsBlockHeaders[0].GetHash(), criminalsBlockHeaders[0], false, false); + pmasternodesview->WriteMintedBlockHeader(masternodeID, mintedBlocks, criminalsBlockHeaders[1].GetHash(), criminalsBlockHeaders[1], false, false); BOOST_CHECK(!pmasternodesview->CheckDoubleSign(criminalsBlockHeaders[0], criminalsBlockHeaders[1])); std::map blockHeaders; diff --git a/src/validation.cpp b/src/validation.cpp index 6b9292e1f5..838acd83a4 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3688,7 +3688,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c return true; } -bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex) +bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool isBatched) { AssertLockHeld(cs_main); // Check for duplicate @@ -3728,7 +3728,7 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, CValidationState auto existingBlockHeader = blockHeaders.find(hash); if (!blockHeaders.size() || existingBlockHeader == blockHeaders.end()) { - pmasternodesview->WriteMintedBlockHeader(nodeId, block.mintedBlocks, hash, block, fIsFakeNet); + pmasternodesview->WriteMintedBlockHeader(nodeId, block.mintedBlocks, hash, block, isBatched, fIsFakeNet); } for (std::pair blockHeader : blockHeaders) { @@ -3811,17 +3811,19 @@ bool ProcessNewBlockHeaders(const std::vector& headers, CValidatio CMasternodesViewHistory history(pmasternodesview.get()); for (const CBlockHeader& header : headers) { CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast - bool accepted = g_blockman.AcceptBlockHeader(header, state, chainparams, &pindex/*, &history.GetState(header.height)*/); + bool accepted = g_blockman.AcceptBlockHeader(header, state, chainparams, &pindex, true/*, &history.GetState(header.height)*/); ::ChainstateActive().CheckBlockIndex(chainparams.GetConsensus()); if (!accepted) { if (first_invalid) *first_invalid = header; + pmasternodesview->CommitHeaders(); // commit headers anyway return false; } if (ppindex) { *ppindex = pindex; } } + pmasternodesview->CommitHeaders(); } NotifyHeaderTip(); { diff --git a/src/validation.h b/src/validation.h index 5e3357474d..58a57c6dfb 100644 --- a/src/validation.h +++ b/src/validation.h @@ -502,7 +502,7 @@ class BlockManager { const CBlockHeader& block, CValidationState& state, const CChainParams& chainparams, - CBlockIndex** ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); + CBlockIndex** ppindex, bool isBatched = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main); }; /**