diff --git a/doc/man/axe-cli.1 b/doc/man/axe-cli.1 index ce87832cf..06e8bdd70 100755 --- a/doc/man/axe-cli.1 +++ b/doc/man/axe-cli.1 @@ -75,7 +75,8 @@ Timeout during HTTP requests (default: 900) Read extra arguments from standard input, one per line until EOF/Ctrl\-D (recommended for sensitive information such as passphrases) .SH COPYRIGHT -Copyright (C) 2014-2018 The Axe Core developers +Copyright (C) 2017-2019 The Axe Core developers +Copyright (C) 2014-2018 The Dash Core developers Copyright (C) 2009-2018 The Bitcoin Core developers Please contribute if you find Axe Core useful. Visit for diff --git a/doc/man/axe-tx.1 b/doc/man/axe-tx.1 index ca362bd22..c2fffc68c 100755 --- a/doc/man/axe-tx.1 +++ b/doc/man/axe-tx.1 @@ -108,7 +108,8 @@ set=NAME:JSON\-STRING .IP Set register NAME to given JSON\-STRING .SH COPYRIGHT -Copyright (C) 2014-2018 The Axe Core developers +Copyright (C) 2017-2019 The Axe Core developers +Copyright (C) 2014-2018 The Dash Core developers Copyright (C) 2009-2018 The Bitcoin Core developers Please contribute if you find Axe Core useful. Visit for diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 94aafd5f4..563ae7692 100755 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # Copyright (c) 2014-2016 The Bitcoin Core developers -# Copyright (c) 2014-2017 The Axe Core developers +# Copyright (c) 2014-2017 The Dash Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 9f1a13bc5..ac13c00c6 100755 --- 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@ diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 9a1d82f71..148c053d6 100755 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -428,6 +428,8 @@ class CTestNetParams : public CChainParams { assert(genesis.hashMerkleRoot == uint256S("0x987a08c31d7f04f47f1aeccdffc73ca4336e32a6615f619b94cc7109e7c2a7ac")); vFixedSeeds.clear(); + vFixedSeeds = std::vector(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); + vSeeds.clear(); // nodes with support for servicebits filtering should be at the top vSeeds.push_back(CDNSSeedData("seed1.0313370.xyz", "seed2.0313370.xyz")); diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 500da8380..a4e0cbac3 100755 --- 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/deterministicmns.cpp b/src/evo/deterministicmns.cpp index 62b20b00d..b1d319e15 100755 --- 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)); } @@ -438,6 +447,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 +473,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()); diff --git a/src/evo/evodb.cpp b/src/evo/evodb.cpp index aa9fb7d05..4d2e72cbd 100755 --- 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 34253f3d0..7f0d7cf33 100755 --- 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/evo/simplifiedmns.cpp b/src/evo/simplifiedmns.cpp index f167b4445..c60159652 100755 --- 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; } diff --git a/src/init.cpp b/src/init.cpp index 8809ca04a..67de20388 100755 --- 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) { @@ -1963,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 diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index e45356173..d9edd382e 100755 --- 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)); diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 660a15c61..cba5cd6d7 100755 --- 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; diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 8999b8004..2215b201e 100755 --- 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()); diff --git a/src/validation.cpp b/src/validation.cpp index 4f0b16545..df2c3e387 100755 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2222,13 +2222,40 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd pindex->GetBlockHash().ToString(), FormatStateMessage(state)); } - // AXE : MODIFIED TO CHECK MASTERNODE PAYMENTS AND SUPERBLOCKS + // AXE // It's possible that we simply don't have enough data and this could fail // (i.e. block itself could be a correct one and we need to store it), // that's why this is in ConnectBlock. Could be the other way around however - // the peer who sent us this block is missing some data and wasn't able // to recognize that block is actually invalid. + + // AXE : CHECK TRANSACTIONS FOR INSTANTSEND + + if (sporkManager.IsSporkActive(SPORK_3_INSTANTSEND_BLOCK_FILTERING)) { + // Require other nodes to comply, send them some data in case they are missing it. + for (const auto& tx : block.vtx) { + // skip txes that have no inputs + if (tx->vin.empty()) continue; + // LOOK FOR TRANSACTION LOCK IN OUR MAP OF OUTPOINTS + for (const auto& txin : tx->vin) { + uint256 hashLocked; + if (instantsend.GetLockedOutPointTxHash(txin.prevout, hashLocked) && hashLocked != tx->GetHash()) { + // The node which relayed this should switch to correct chain. + // TODO: relay instantsend data/proof. + LOCK(cs_main); + mapRejectedBlocks.insert(std::make_pair(block.GetHash(), GetTime())); + return state.DoS(10, error("ConnectBlock(AXE): transaction %s conflicts with transaction lock %s", tx->GetHash().ToString(), hashLocked.ToString()), + REJECT_INVALID, "conflict-tx-lock"); + } + } + } + } else { + LogPrintf("ConnectBlock(AXE): spork is off, skipping transaction locking checks\n"); + } + + // AXE : MODIFIED TO CHECK MASTERNODE PAYMENTS AND SUPERBLOCKS + // TODO: resync data (both ways?) and try to reprocess this block later. CAmount blockReward = nFees + GetBlockSubsidy(pindex->pprev->nBits, pindex->pprev->nHeight, chainparams.GetConsensus()); std::string strError = ""; @@ -2414,6 +2441,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 +2549,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 +2638,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); @@ -3270,35 +3298,6 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P if (block.vtx[i]->IsCoinBase()) return state.DoS(100, false, REJECT_INVALID, "bad-cb-multiple", false, "more than one coinbase"); - - // AXE : CHECK TRANSACTIONS FOR INSTANTSEND - - if(sporkManager.IsSporkActive(SPORK_3_INSTANTSEND_BLOCK_FILTERING)) { - // We should never accept block which conflicts with completed transaction lock, - // that's why this is in CheckBlock unlike coinbase payee/amount. - // Require other nodes to comply, send them some data in case they are missing it. - for(const auto& tx : block.vtx) { - // skip coinbase, it has no inputs - if (tx->IsCoinBase()) continue; - // LOOK FOR TRANSACTION LOCK IN OUR MAP OF OUTPOINTS - for (const auto& txin : tx->vin) { - uint256 hashLocked; - if(instantsend.GetLockedOutPointTxHash(txin.prevout, hashLocked) && hashLocked != tx->GetHash()) { - // The node which relayed this will have to switch later, - // relaying instantsend data won't help it. - LOCK(cs_main); - mapRejectedBlocks.insert(std::make_pair(block.GetHash(), GetTime())); - return state.DoS(100, false, REJECT_INVALID, "conflict-tx-lock", false, - strprintf("transaction %s conflicts with transaction lock %s", tx->GetHash().ToString(), hashLocked.ToString())); - } - } - } - } else { - LogPrintf("CheckBlock(AXE): spork is off, skipping transaction locking checks\n"); - } - - // END AXE - // Check transactions for (const auto& tx : block.vtx) if (!CheckTransaction(*tx, state)) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index aef3cfef7..5df81c329 100755 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers -// Copyright (c) 2017-2018 The Dash Core developers +// Copyright (c) 2014-2017 The Dash Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php.