From 1cc47ebcd07f1d2571c067a29e0e4d5e20c71419 Mon Sep 17 00:00:00 2001 From: PastaPastaPasta Date: Tue, 12 Feb 2019 13:50:07 -0600 Subject: [PATCH 1/9] Backport #14701: build: Add CLIENT_VERSION_BUILD to CFBundleGetInfoString (#2687) 8e209340c85fc2493d7d1d7affe7e316bb613cbd build: Add CLIENT_VERSION_BUILD to CFBundleGetInfoString (fanquake) Pull request description: As mentioned in #14697, if you download the `0.17.0.1` dmg, and inspect the `.app` bundle, the version in the GetInfo string reads `0.17.0`, which is confusing given you're expecting `0.17.0.1`: 0 17 0 1 This PR adds `CLIENT_VERSION_BUILD` to the string, so that the full version number is displayed, i.e: this pr Tree-SHA512: f553253d03283639cc4dda00c8004b5c63ae2b489762e5e8c666166e71b14e672792c1df678f87484d51d153b5781c5ec1b145774096600f504833024ae8baea --- share/qt/Info.plist.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 6db46b192fa3..41f37eb43cb9 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -17,7 +17,7 @@ APPL CFBundleGetInfoString - @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@, Copyright © 2009-@COPYRIGHT_YEAR@ The Bitcoin Core developers, 2014-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@ + @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@.@CLIENT_VERSION_BUILD@, Copyright © 2009-@COPYRIGHT_YEAR@ The Bitcoin Core developers, 2014-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@ CFBundleShortVersionString @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@ From e75f971b90b5973d9f8eb6a0d4df2e924d5b604e Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 12 Feb 2019 22:51:50 +0300 Subject: [PATCH 2/9] Do not process blocks in CDeterministicMNManager before dip3 activation (#2698) * Do not process blocks in CDeterministicMNManager before dip3 activation This should save us some cpu/disk on initial sync/reindex * Write initial snapshot on dip3 activation --- src/evo/deterministicmns.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/evo/deterministicmns.cpp b/src/evo/deterministicmns.cpp index 6f664c05a11e..a93965f1b12d 100644 --- a/src/evo/deterministicmns.cpp +++ b/src/evo/deterministicmns.cpp @@ -438,6 +438,13 @@ CDeterministicMNManager::CDeterministicMNManager(CEvoDB& _evoDb) : bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& _state) { + AssertLockHeld(cs_main); + + bool fDIP0003Active = VersionBitsState(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_DIP0003, versionbitscache) == THRESHOLD_ACTIVE; + if (!fDIP0003Active) { + return true; + } + LOCK(cs); int nHeight = pindex->nHeight; @@ -457,7 +464,7 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockInde CDeterministicMNListDiff diff = oldList.BuildDiff(newList); evoDb.Write(std::make_pair(DB_LIST_DIFF, diff.blockHash), diff); - if ((nHeight % SNAPSHOT_LIST_PERIOD) == 0) { + if ((nHeight % SNAPSHOT_LIST_PERIOD) == 0 || oldList.GetHeight() == -1) { evoDb.Write(std::make_pair(DB_LIST_SNAPSHOT, diff.blockHash), newList); LogPrintf("CDeterministicMNManager::%s -- Wrote snapshot. nHeight=%d, mapCurMNs.allMNsCount=%d\n", __func__, nHeight, newList.GetAllMNsCount()); From 9e233f391d9df63ae2d1998df847c06be06f172e Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Tue, 12 Feb 2019 20:52:06 +0100 Subject: [PATCH 3/9] Fix incorrect usage of begin() when genesis block is requested in "protx diff" (#2699) * Fix incorrect usage of begin() when genesis block is requested in "protx diff" .begin() on mapBlockIndex does NOT return the genesis block, but just the block with lowest hash. The fix is to use chainActive[0] to get the genesis block. * Update src/evo/simplifiedmns.cpp Co-Authored-By: codablock --- src/evo/simplifiedmns.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/evo/simplifiedmns.cpp b/src/evo/simplifiedmns.cpp index 875c46dea5b3..6ac8d3b33994 100644 --- a/src/evo/simplifiedmns.cpp +++ b/src/evo/simplifiedmns.cpp @@ -119,25 +119,27 @@ bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& bloc AssertLockHeld(cs_main); mnListDiffRet = CSimplifiedMNListDiff(); - BlockMap::iterator baseBlockIt = mapBlockIndex.begin(); + const CBlockIndex* baseBlockIndex = chainActive.Genesis(); if (!baseBlockHash.IsNull()) { - baseBlockIt = mapBlockIndex.find(baseBlockHash); + auto it = mapBlockIndex.find(baseBlockHash); + if (it == mapBlockIndex.end()) { + errorRet = strprintf("block %s not found", baseBlockHash.ToString()); + return false; + } + baseBlockIndex = it->second; } auto blockIt = mapBlockIndex.find(blockHash); - if (baseBlockIt == mapBlockIndex.end()) { - errorRet = strprintf("block %s not found", baseBlockHash.ToString()); - return false; - } if (blockIt == mapBlockIndex.end()) { errorRet = strprintf("block %s not found", blockHash.ToString()); return false; } + const CBlockIndex* blockIndex = blockIt->second; - if (!chainActive.Contains(baseBlockIt->second) || !chainActive.Contains(blockIt->second)) { + if (!chainActive.Contains(baseBlockIndex) || !chainActive.Contains(blockIndex)) { errorRet = strprintf("block %s and %s are not in the same chain", baseBlockHash.ToString(), blockHash.ToString()); return false; } - if (baseBlockIt->second->nHeight > blockIt->second->nHeight) { + if (baseBlockIndex->nHeight > blockIndex->nHeight) { errorRet = strprintf("base block %s is higher then block %s", baseBlockHash.ToString(), blockHash.ToString()); return false; } @@ -150,7 +152,7 @@ bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& bloc // TODO store coinbase TX in CBlockIndex CBlock block; - if (!ReadBlockFromDisk(block, blockIt->second, Params().GetConsensus())) { + if (!ReadBlockFromDisk(block, blockIndex, Params().GetConsensus())) { errorRet = strprintf("failed to read block %s from disk", blockHash.ToString()); return false; } From f868fbc78780f8a8dfb31c15a43236a76f5c0f0f Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 1 Mar 2019 16:30:30 +0100 Subject: [PATCH 4/9] Stop g_connman first before deleting it (#2734) --- src/init.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 92e94a383ec2..2e880a6d3548 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -256,6 +256,10 @@ void PrepareShutdown() MapPort(false); UnregisterValidationInterface(peerLogic.get()); peerLogic.reset(); + if (g_connman) { + // make sure to stop all threads before g_connman is reset to nullptr as these threads might still be accessing it + g_connman->Stop(); + } g_connman.reset(); if (!fLiteMode && !fRPCInWarmup) { From 43612a2720a04f67e1807706d0b15d46d06a3de7 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Mon, 4 Mar 2019 07:52:14 +0100 Subject: [PATCH 5/9] Only include selected TX types into CMerkleBlock (#2737) It was reported on iOS that CMerkleBlock sometimes included the dummy quorum commitments introduced with v13, which led to banning of nodes as these were not supported/expected there. We should in general only include TXs here that are of interest for SPV nodes, so we should maintain the list of allowed TX types. --- src/merkleblock.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index e453561733eb..d9edd382e350 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -19,10 +19,24 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter) vMatch.reserve(block.vtx.size()); vHashes.reserve(block.vtx.size()); + const static std::set allowedTxTypes = { + TRANSACTION_NORMAL, + TRANSACTION_PROVIDER_REGISTER, + TRANSACTION_PROVIDER_UPDATE_SERVICE, + TRANSACTION_PROVIDER_UPDATE_REGISTRAR, + TRANSACTION_PROVIDER_UPDATE_REVOKE, + TRANSACTION_COINBASE, + }; + for (unsigned int i = 0; i < block.vtx.size(); i++) { - const uint256& hash = block.vtx[i]->GetHash(); - if (filter.IsRelevantAndUpdate(*block.vtx[i])) + const auto& tx = *block.vtx[i]; + if (tx.nVersion == 3 && !allowedTxTypes.count(tx.nType)) { + continue; + } + + const uint256& hash = tx.GetHash(); + if (filter.IsRelevantAndUpdate(tx)) { vMatch.push_back(true); vMatchedTxn.push_back(std::make_pair(i, hash)); From a11e2f9eba6abcd9e032100d62b327339e6d4b01 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 6 Mar 2019 10:01:03 +0300 Subject: [PATCH 6/9] Add collateraladdress into masternode/protx list rpc output (#2740) --- src/evo/deterministicmns.cpp | 9 +++++++++ src/rpc/masternode.cpp | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/evo/deterministicmns.cpp b/src/evo/deterministicmns.cpp index a93965f1b12d..99e59a919cf6 100644 --- a/src/evo/deterministicmns.cpp +++ b/src/evo/deterministicmns.cpp @@ -83,6 +83,15 @@ void CDeterministicMN::ToJson(UniValue& obj) const obj.push_back(Pair("proTxHash", proTxHash.ToString())); obj.push_back(Pair("collateralHash", collateralOutpoint.hash.ToString())); obj.push_back(Pair("collateralIndex", (int)collateralOutpoint.n)); + + Coin coin; + if (GetUTXOCoin(collateralOutpoint, coin)) { + CTxDestination dest; + if (ExtractDestination(coin.out.scriptPubKey, dest)) { + obj.push_back(Pair("collateralAddress", CBitcoinAddress(dest).ToString())); + } + } + obj.push_back(Pair("operatorReward", (double)nOperatorReward / 100)); obj.push_back(Pair("state", stateObj)); } diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index dafc9ae4beae..52a54294334c 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -890,17 +890,26 @@ UniValue masternodelist(const JSONRPCRequest& request) std::string strOutpoint = mnpair.first.ToStringShort(); CScript payeeScript; + std::string collateralAddressStr = "UNKNOWN"; if (deterministicMNManager->IsDeterministicMNsSporkActive()) { auto dmn = deterministicMNManager->GetListAtChainTip().GetMNByCollateral(mn.outpoint); if (dmn) { payeeScript = dmn->pdmnState->scriptPayout; + Coin coin; + if (GetUTXOCoin(dmn->collateralOutpoint, coin)) { + CTxDestination collateralDest; + if (ExtractDestination(coin.out.scriptPubKey, collateralDest)) { + collateralAddressStr = CBitcoinAddress(collateralDest).ToString(); + } + } } } else { payeeScript = GetScriptForDestination(mn.keyIDCollateralAddress); + collateralAddressStr = CBitcoinAddress(mn.keyIDCollateralAddress).ToString(); } CTxDestination payeeDest; - std::string payeeStr = "UNKOWN"; + std::string payeeStr = "UNKNOWN"; if (ExtractDestination(payeeScript, payeeDest)) { payeeStr = CBitcoinAddress(payeeDest).ToString(); } @@ -965,7 +974,8 @@ UniValue masternodelist(const JSONRPCRequest& request) (int64_t)mn.lastPing.sigTime << " " << (int64_t)(mn.lastPing.sigTime - mn.sigTime) << " " << mn.GetLastPaidTime() << " " << - mn.GetLastPaidBlock(); + mn.GetLastPaidBlock() << " " << + collateralAddressStr; std::string strInfo = streamInfo.str(); if (strFilter !="" && strInfo.find(strFilter) == std::string::npos && strOutpoint.find(strFilter) == std::string::npos) continue; @@ -983,6 +993,7 @@ UniValue masternodelist(const JSONRPCRequest& request) objMN.push_back(Pair("lastpaidblock", mn.GetLastPaidBlock())); objMN.push_back(Pair("owneraddress", CBitcoinAddress(mn.keyIDOwner).ToString())); objMN.push_back(Pair("votingaddress", CBitcoinAddress(mn.keyIDVoting).ToString())); + objMN.push_back(Pair("collateraladdress", collateralAddressStr)); obj.push_back(Pair(strOutpoint, objMN)); } else if (strMode == "keyid") { if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue; From 0364e033a7f0c081d3bfa4ab725b28f1ffbdab3a Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Wed, 6 Mar 2019 20:45:39 +0100 Subject: [PATCH 7/9] Implement 2-stage commit for CEvoDB to avoid inconsistencies after crashes (#2744) * Let Commit() return void The boolean return value will loose its meaning in the next commit * Implement 2-stage commits for CDBTransaction and CScopedDBTransaction CDBTransaction is changed to allow CDBBatch, CDBWrapper and other CDBTransactions as parent instead of just CDBWrapper. This in turn allows to implement multi-staged commits in CEvoDB. We now have the "current transaction" which is started and ended (commit or rollback) for each call to Connect-/DisconnectBlock. When the current transaction is committed, it moves its contents into the "root transaction" instead of directly writing to CDBWrapper. CommitRootTransaction() then handles the final commitment to CDBWrapper. It is called at the same time when the chainstate is flushed to disk, which guarantees consistency between chainstate and CEvoDB. * Allow to efficiently move values into parent transactions to avoid copies When CDBTransaction>::Commit() is called, we can avoid copying values from this transaction to the parent transaction and instead pass values by rvalue and let the contents be moved. * Revert "Force FlushStateToDisk on ConnectTip/DisconnectTip while not in IBD (#2560)" This reverts commit 6dfceaba5ac58311ce684987c84ee66d54e2bf1f. --- src/dbwrapper.h | 89 ++++++++++++++++++++++++++++------------------ src/evo/evodb.cpp | 13 ++++++- src/evo/evodb.h | 23 ++++++++---- src/validation.cpp | 13 +++---- 4 files changed, 89 insertions(+), 49 deletions(-) diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 500da8380632..a4e0cbac3ac5 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -344,14 +344,16 @@ class CDBWrapper }; +template class CDBTransaction { -private: - CDBWrapper &db; +protected: + Parent &parent; + CommitTarget &commitTarget; struct KeyHolder { virtual ~KeyHolder() = default; virtual bool Less(const KeyHolder &b) const = 0; - virtual void Erase(CDBBatch &batch) = 0; + virtual void Erase(CommitTarget &commitTarget) = 0; }; typedef std::unique_ptr KeyHolderPtr; @@ -364,15 +366,15 @@ class CDBTransaction { auto *b2 = dynamic_cast*>(&b); return key < b2->key; } - virtual void Erase(CDBBatch &batch) { - batch.Erase(key); + virtual void Erase(CommitTarget &commitTarget) { + commitTarget.Erase(key); } K key; }; struct KeyValueHolder { virtual ~KeyValueHolder() = default; - virtual void Write(CDBBatch &batch) = 0; + virtual void Write(CommitTarget &parent) = 0; }; typedef std::unique_ptr KeyValueHolderPtr; @@ -381,8 +383,13 @@ class CDBTransaction { KeyValueHolderImpl(const KeyHolderImpl &_key, const V &_value) : key(_key), value(_value) { } - virtual void Write(CDBBatch &batch) { - batch.Write(key.key, value); + KeyValueHolderImpl(const KeyHolderImpl &_key, V &&_value) + : key(_key), + value(std::forward(_value)) { } + virtual void Write(CommitTarget &commitTarget) { + // we're moving the value instead of copying it. This means that Write() can only be called once per + // KeyValueHolderImpl instance. Commit() clears the write maps, so this ok. + commitTarget.Write(key.key, std::move(value)); } const KeyHolderImpl &key; V value; @@ -422,22 +429,34 @@ class CDBTransaction { return getMapForType(deletes, create); } -public: - CDBTransaction(CDBWrapper &_db) : db(_db) {} - - template - void Write(const K& key, const V& value) { - KeyHolderPtr k(new KeyHolderImpl(key)); - KeyHolderImpl* k2 = dynamic_cast*>(k.get()); - KeyValueHolderPtr kv(new KeyValueHolderImpl(*k2, value)); + template + void writeImpl(KeyHolderImpl* k, KV&& kv) { + auto k2 = KeyHolderPtr(k); KeyValueMap *ds = getDeletesMap(false); if (ds) - ds->erase(k); + ds->erase(k2); KeyValueMap *ws = getWritesMap(true); - ws->erase(k); - ws->emplace(std::make_pair(std::move(k), std::move(kv))); + ws->erase(k2); + ws->emplace(std::make_pair(std::move(k2), std::forward(kv))); + } + +public: + CDBTransaction(Parent &_parent, CommitTarget &_commitTarget) : parent(_parent), commitTarget(_commitTarget) {} + + template + void Write(const K& key, const V& v) { + auto k = new KeyHolderImpl(key); + auto kv = std::make_unique>(*k, v); + writeImpl(k, std::move(kv)); + } + + template + void Write(const K& key, V&& v) { + auto k = new KeyHolderImpl(key); + auto kv = std::make_unique::type>>(*k, std::forward(v)); + writeImpl(k, std::move(kv)); } template @@ -450,7 +469,7 @@ class CDBTransaction { KeyValueMap *ws = getWritesMap(false); if (ws) { - KeyValueMap::iterator it = ws->find(k); + auto it = ws->find(k); if (it != ws->end()) { auto *impl = dynamic_cast *>(it->second.get()); if (!impl) @@ -460,7 +479,7 @@ class CDBTransaction { } } - return db.Read(key, value); + return parent.Read(key, value); } template @@ -475,7 +494,7 @@ class CDBTransaction { if (ws && ws->count(k)) return true; - return db.Exists(key); + return parent.Exists(key); } template @@ -494,21 +513,18 @@ class CDBTransaction { deletes.clear(); } - bool Commit() { - CDBBatch batch(db); + void Commit() { for (auto &p : deletes) { for (auto &p2 : p.second) { - p2.first->Erase(batch); + p2.first->Erase(commitTarget); } } for (auto &p : writes) { for (auto &p2 : p.second) { - p2.second->Write(batch); + p2.second->Write(commitTarget); } } - bool ret = db.WriteBatch(batch, true); Clear(); - return ret; } bool IsClean() { @@ -516,26 +532,29 @@ class CDBTransaction { } }; +template class CScopedDBTransaction { +public: + typedef CDBTransaction Transaction; + private: - CDBTransaction &dbTransaction; + Transaction &dbTransaction; std::function commitHandler; std::function rollbackHandler; bool didCommitOrRollback{}; public: - CScopedDBTransaction(CDBTransaction &dbTx) : dbTransaction(dbTx) {} + CScopedDBTransaction(Transaction &dbTx) : dbTransaction(dbTx) {} ~CScopedDBTransaction() { if (!didCommitOrRollback) Rollback(); } - bool Commit() { + void Commit() { assert(!didCommitOrRollback); didCommitOrRollback = true; - bool result = dbTransaction.Commit(); + dbTransaction.Commit(); if (commitHandler) commitHandler(); - return result; } void Rollback() { assert(!didCommitOrRollback); @@ -545,9 +564,9 @@ class CScopedDBTransaction { rollbackHandler(); } - static std::unique_ptr Begin(CDBTransaction &dbTx) { + static std::unique_ptr> Begin(Transaction &dbTx) { assert(dbTx.IsClean()); - return std::unique_ptr(new CScopedDBTransaction(dbTx)); + return std::make_unique>(dbTx); } void SetCommitHandler(const std::function &h) { diff --git a/src/evo/evodb.cpp b/src/evo/evodb.cpp index b041be3d99dd..138353dbae7a 100644 --- a/src/evo/evodb.cpp +++ b/src/evo/evodb.cpp @@ -8,10 +8,21 @@ CEvoDB* evoDb; CEvoDB::CEvoDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(fMemory ? "" : (GetDataDir() / "evodb"), nCacheSize, fMemory, fWipe), - dbTransaction(db) + rootBatch(db), + rootDBTransaction(db, rootBatch), + curDBTransaction(rootDBTransaction, rootDBTransaction) { } +bool CEvoDB::CommitRootTransaction() +{ + assert(curDBTransaction.IsClean()); + rootDBTransaction.Commit(); + bool ret = db.WriteBatch(rootBatch); + rootBatch.Clear(); + return ret; +} + bool CEvoDB::VerifyBestBlock(const uint256& hash) { // Make sure evodb is consistent. diff --git a/src/evo/evodb.h b/src/evo/evodb.h index 2506264c04c7..b7fef6d78cac 100644 --- a/src/evo/evodb.h +++ b/src/evo/evodb.h @@ -16,15 +16,22 @@ class CEvoDB private: CCriticalSection cs; CDBWrapper db; - CDBTransaction dbTransaction; + + typedef CDBTransaction RootTransaction; + typedef CDBTransaction CurTransaction; + typedef CScopedDBTransaction ScopedTransaction; + + CDBBatch rootBatch; + RootTransaction rootDBTransaction; + CurTransaction curDBTransaction; public: CEvoDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); - std::unique_ptr BeginTransaction() + std::unique_ptr BeginTransaction() { LOCK(cs); - auto t = CScopedDBTransaction::Begin(dbTransaction); + auto t = ScopedTransaction::Begin(curDBTransaction); return t; } @@ -32,28 +39,28 @@ class CEvoDB bool Read(const K& key, V& value) { LOCK(cs); - return dbTransaction.Read(key, value); + return curDBTransaction.Read(key, value); } template void Write(const K& key, const V& value) { LOCK(cs); - dbTransaction.Write(key, value); + curDBTransaction.Write(key, value); } template bool Exists(const K& key) { LOCK(cs); - return dbTransaction.Exists(key); + return curDBTransaction.Exists(key); } template void Erase(const K& key) { LOCK(cs); - dbTransaction.Erase(key); + curDBTransaction.Erase(key); } CDBWrapper& GetRawDB() @@ -61,6 +68,8 @@ class CEvoDB return db; } + bool CommitRootTransaction(); + bool VerifyBestBlock(const uint256& hash); void WriteBestBlock(const uint256& hash); }; diff --git a/src/validation.cpp b/src/validation.cpp index 2435f2040051..bfa560c463de 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2414,6 +2414,9 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode, int n // Flush the chainstate (which may refer to block index entries). if (!pcoinsTip->Flush()) return AbortNode(state, "Failed to write to coin database"); + if (!evoDb->CommitRootTransaction()) { + return AbortNode(state, "Failed to commit EvoDB"); + } nLastFlush = nNow; } if (fDoFullFlush || ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) { @@ -2519,12 +2522,11 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); bool flushed = view.Flush(); assert(flushed); - bool committed = dbTx->Commit(); - assert(committed); + dbTx->Commit(); } LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); // Write the chain state to disk, if necessary. - if (!FlushStateToDisk(state, IsInitialBlockDownload() ? FLUSH_STATE_IF_NEEDED : FLUSH_STATE_ALWAYS)) + if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; // Resurrect mempool transactions from the disconnected block. std::vector vHashUpdate; @@ -2609,13 +2611,12 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001); bool flushed = view.Flush(); assert(flushed); - bool committed = dbTx->Commit(); - assert(committed); + dbTx->Commit(); } int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3; LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001); // Write the chain state to disk, if necessary. - if (!FlushStateToDisk(state, IsInitialBlockDownload() ? FLUSH_STATE_IF_NEEDED : FLUSH_STATE_ALWAYS)) + if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); From 25222b37866851e224d354f346417a5bf27cf196 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Wed, 6 Mar 2019 20:45:53 +0100 Subject: [PATCH 8/9] Make -masternodeblsprivkey mandatory when -masternode is given (#2745) --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 2e880a6d3548..81b3a133bd43 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1967,7 +1967,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) return InitError(_("Invalid masternodeblsprivkey. Please see documenation.")); } } else { - InitWarning(_("You should specify a masternodeblsprivkey in the configuration. Please see documentation for help.")); + return InitError(_("You must specify a masternodeblsprivkey in the configuration. Please see documentation for help.")); } // init and register activeMasternodeManager From 6374dce99e40cd409e1db04bbfd7a200f60aff64 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 7 Mar 2019 14:29:24 +0100 Subject: [PATCH 9/9] Fix error message for invalid voting addresses (#2747) --- src/rpc/rpcevo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 37a36a51a66a..b83c6cea0450 100644 --- a/src/rpc/rpcevo.cpp +++ b/src/rpc/rpcevo.cpp @@ -693,7 +693,7 @@ UniValue protx_update_registrar(const JSONRPCRequest& request) ptx.pubKeyOperator = ParseBLSPubKey(request.params[2].get_str(), "operator BLS address"); } if (request.params[3].get_str() != "") { - ptx.keyIDVoting = ParsePubKeyIDFromAddress(request.params[3].get_str(), "operator address"); + ptx.keyIDVoting = ParsePubKeyIDFromAddress(request.params[3].get_str(), "voting address"); } CBitcoinAddress payoutAddress(request.params[4].get_str());