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 src/dsnotificationinterface.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2015 The Bitcoin Core developers
// Copyright (c) 2015 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down
11 changes: 0 additions & 11 deletions src/evo/chainhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,9 @@

#include <consensus/params.h>
#include <evo/specialtxman.h>
#include <index/txindex.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <masternode/payments.h>
#include <node/transaction.h>
#include <txmempool.h>

using node::GetTransaction;

CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman,
CMNHFManager& mnhfman, CGovernanceManager& govman, llmq::CInstantSendManager& isman,
Expand Down Expand Up @@ -64,9 +59,3 @@ bool CChainstateHelper::RemoveConflictingISLockByTx(const CTransaction& tx)

bool CChainstateHelper::ShouldInstantSendRejectConflicts() const { return isman.RejectConflictingBlocks(); }

std::pair<CTransactionRef, uint256> GetTransactionBlock(const uint256& hash, const CTxMemPool* const mempool)
{
uint256 hashBlock{};
if (!g_txindex && !mempool) return {nullptr, hashBlock}; // Fast-fail as we don't have any other way to search
return {GetTransaction(/*block_index=*/nullptr, mempool, hash, Params().GetConsensus(), hashBlock), hashBlock};
}
7 changes: 0 additions & 7 deletions src/evo/chainhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class CGovernanceManager;
class CSpecialTxProcessor;
class CSporkManager;
class CTransaction;
class CTxMemPool;
class uint256;

namespace Consensus { struct Params; }
Expand All @@ -30,8 +29,6 @@ class CQuorumManager;
class CQuorumSnapshotManager;
}

using CTransactionRef = std::shared_ptr<const CTransaction>;

class CChainstateHelper
{
private:
Expand Down Expand Up @@ -66,8 +63,4 @@ class CChainstateHelper
const std::unique_ptr<CSpecialTxProcessor> special_tx;
};

/* Retrieve transaction and block from txindex (or mempool) */
std::pair</*tx=*/CTransactionRef, /*hash_block=*/uint256> GetTransactionBlock(const uint256& hash,
const CTxMemPool* const mempool = nullptr);

#endif // BITCOIN_EVO_CHAINHELPER_H
16 changes: 10 additions & 6 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <evo/chainhelper.h>
#include <evo/deterministicmns.h>
#include <evo/dmn_types.h>
#include <evo/dmnstate.h>
#include <evo/evodb.h>
#include <evo/providertx.h>
#include <evo/specialtx.h>
#include <index/txindex.h>
#include <llmq/commitment.h>
#include <llmq/utils.h>

Expand Down Expand Up @@ -50,11 +50,15 @@ UniValue CDeterministicMN::ToJson() const
obj.pushKV("collateralHash", collateralOutpoint.hash.ToString());
obj.pushKV("collateralIndex", (int)collateralOutpoint.n);

auto [collateralTx, _] = GetTransactionBlock(collateralOutpoint.hash);
if (collateralTx) {
CTxDestination dest;
if (ExtractDestination(collateralTx->vout[collateralOutpoint.n].scriptPubKey, dest)) {
obj.pushKV("collateralAddress", EncodeDestination(dest));
if (g_txindex) {
CTransactionRef collateralTx;
uint256 nBlockHash;
g_txindex->FindTx(collateralOutpoint.hash, nBlockHash, collateralTx);
if (collateralTx) {
CTxDestination dest;
if (ExtractDestination(collateralTx->vout[collateralOutpoint.n].scriptPubKey, dest)) {
obj.pushKV("collateralAddress", EncodeDestination(dest));
}
}
}

Expand Down
10 changes: 7 additions & 3 deletions src/governance/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
#include <bls/bls.h>
#include <chainparams.h>
#include <core_io.h>
#include <evo/chainhelper.h>
#include <evo/deterministicmns.h>
#include <governance/governance.h>
#include <governance/validators.h>
#include <index/txindex.h>
#include <masternode/meta.h>
#include <masternode/node.h>
#include <masternode/sync.h>
Expand Down Expand Up @@ -453,8 +453,12 @@ bool CGovernanceObject::IsCollateralValid(const ChainstateManager& chainman, std
fMissingConfirmations = false;
uint256 nExpectedHash = GetHash();

// RETRIEVE TRANSACTION IN QUESTION
auto [txCollateral, nBlockHash] = GetTransactionBlock(m_obj.collateralHash);
CTransactionRef txCollateral;
uint256 nBlockHash;
if (g_txindex) {
g_txindex->FindTx(m_obj.collateralHash, nBlockHash, txCollateral);
}

if (!txCollateral) {
strError = strprintf("Can't find collateral tx %s", m_obj.collateralHash.ToString());
LogPrintf("CGovernanceObject::IsCollateralValid -- %s\n", strError);
Expand Down
26 changes: 25 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2327,7 +2327,31 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
}

chainman.m_load_block = std::thread(&util::TraceThread, "loadblk", [=, &args, &chainman, &node] {
ThreadImport(chainman, *node.dmnman, *g_ds_notification_interface, vImportFiles, node.mn_activeman.get(), args);
ThreadImport(chainman, vImportFiles, args);

// force UpdatedBlockTip to initialize nCachedBlockHeight for DS, MN payments and budgets
// but don't call it directly to prevent triggering of other listeners like zmq etc.
// GetMainSignals().UpdatedBlockTip(::ChainActive().Tip());
g_ds_notification_interface->InitializeCurrentBlockTip();

{
// Get all UTXOs for each MN collateral in one go so that we can fill coin cache early
// and reduce further locking overhead for cs_main in other parts of code including GUI
LogPrintf("Filling coin cache with masternode UTXOs...\n");
LOCK(cs_main);
const auto start{SteadyClock::now()};
const auto mnList{node.dmnman->GetListAtChainTip()};
mnList.ForEachMN(false, [&](auto& dmn) {
Coin coin;
GetUTXOCoin(chainman.ActiveChainstate(), dmn.collateralOutpoint, coin);
});
LogPrintf("Filling coin cache with masternode UTXOs: done in %dms\n", Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
}

if (node.mn_activeman != nullptr) {
node.mn_activeman->Init(chainman.ActiveTip());
}

});
#ifdef ENABLE_WALLET
if (!args.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
Expand Down
13 changes: 10 additions & 3 deletions src/llmq/chainlocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <chain.h>
#include <chainparams.h>
#include <consensus/validation.h>
#include <evo/chainhelper.h>
#include <masternode/sync.h>
#include <node/blockstorage.h>
#include <node/interface_ui.h>
Expand All @@ -26,6 +25,14 @@

using node::ReadBlockFromDisk;

// Forward declaration to break dependency over node/transaction.h
namespace node
{
CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool,
const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock);
} // namespace node
using node::GetTransaction;

static bool ChainLocksSigningEnabled(const CSporkManager& sporkman)
{
return sporkman.GetSporkValue(SPORK_19_CHAINLOCKS_ENABLED) == 0;
Expand Down Expand Up @@ -638,8 +645,8 @@ void CChainLocksHandler::Cleanup()
}
}
for (auto it = txFirstSeenTime.begin(); it != txFirstSeenTime.end(); ) {
auto [tx, hashBlock] = GetTransactionBlock(it->first, &mempool);
if (!tx) {
uint256 hashBlock;
if (auto tx = GetTransaction(nullptr, &mempool, it->first, Params().GetConsensus(), hashBlock); !tx) {
// tx has vanished, probably due to conflicts
it = txFirstSeenTime.erase(it);
} else if (!hashBlock.IsNull()) {
Expand Down
19 changes: 15 additions & 4 deletions src/llmq/instantsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include <chainparams.h>
#include <consensus/validation.h>
#include <dbwrapper.h>
#include <evo/chainhelper.h>
#include <index/txindex.h>
#include <masternode/sync.h>
#include <net_processing.h>
Expand All @@ -31,6 +30,14 @@
using node::fImporting;
using node::fReindex;

// Forward declaration to break dependency over node/transaction.h
namespace node
{
CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool,
const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock);
} // namespace node
using node::GetTransaction;

namespace llmq
{

Expand Down Expand Up @@ -578,7 +585,8 @@ bool CInstantSendManager::CheckCanLock(const COutPoint& outpoint, bool printDebu
return false;
}

auto [tx, hashBlock] = GetTransactionBlock(outpoint.hash, &mempool);
uint256 hashBlock{};
const auto tx = GetTransaction(nullptr, &mempool, outpoint.hash, params, hashBlock);
// this relies on enabled txindex and won't work if we ever try to remove the requirement for txindex for masternodes
if (!tx) {
if (printDebug) {
Expand Down Expand Up @@ -635,7 +643,9 @@ void CInstantSendManager::HandleNewInputLockRecoveredSig(const CRecoveredSig& re
g_txindex->BlockUntilSyncedToCurrentChain();
}

auto [tx, hashBlock] = GetTransactionBlock(txid, &mempool);

uint256 hashBlock{};
const auto tx = GetTransaction(nullptr, &mempool, txid, Params().GetConsensus(), hashBlock);
if (!tx) {
return;
}
Expand Down Expand Up @@ -1017,7 +1027,8 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, PeerManager& peerm
return;
}

auto [tx, hashBlock] = GetTransactionBlock(islock->txid, &mempool);
uint256 hashBlock{};
const auto tx = GetTransaction(nullptr, &mempool, islock->txid, Params().GetConsensus(), hashBlock);
const CBlockIndex* pindexMined{nullptr};
// we ignore failure here as we must be able to propagate the lock even if we don't have the TX locally
if (tx && !hashBlock.IsNull()) {
Expand Down
29 changes: 1 addition & 28 deletions src/node/blockstorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@
#include <chainparams.h>
#include <clientversion.h>
#include <consensus/validation.h>
#include <dsnotificationinterface.h>
#include <evo/deterministicmns.h>
#include <flatfile.h>
#include <fs.h>
#include <hash.h>
#include <masternode/node.h>
#include <pow.h>
#include <shutdown.h>
#include <streams.h>
Expand Down Expand Up @@ -825,8 +822,7 @@ struct CImportingNow {
}
};

void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CDSNotificationInterface& dsnfi,
std::vector<fs::path> vImportFiles, CActiveMasternodeManager* const mn_activeman, const ArgsManager& args)
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
{
ScheduleBatchPriority();

Expand Down Expand Up @@ -899,29 +895,6 @@ void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman,
}
} // End scope of CImportingNow

// force UpdatedBlockTip to initialize nCachedBlockHeight for DS, MN payments and budgets
// but don't call it directly to prevent triggering of other listeners like zmq etc.
// GetMainSignals().UpdatedBlockTip(::ChainActive().Tip());
dsnfi.InitializeCurrentBlockTip();

{
// Get all UTXOs for each MN collateral in one go so that we can fill coin cache early
// and reduce further locking overhead for cs_main in other parts of code including GUI
LogPrintf("Filling coin cache with masternode UTXOs...\n");
LOCK(cs_main);
const auto start{SteadyClock::now()};
auto mnList = dmnman.GetListAtChainTip();
mnList.ForEachMN(false, [&](auto& dmn) {
Coin coin;
GetUTXOCoin(chainman.ActiveChainstate(), dmn.collateralOutpoint, coin);
});
LogPrintf("Filling coin cache with masternode UTXOs: done in %dms\n", Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
}

if (mn_activeman != nullptr) {
mn_activeman->Init(chainman.ActiveTip());
}

chainman.ActiveChainstate().LoadMempool(args);
}
} // namespace node
6 changes: 1 addition & 5 deletions src/node/blockstorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,13 @@

extern RecursiveMutex cs_main;

class CActiveMasternodeManager;
class ArgsManager;
class BlockValidationState;
class CBlock;
class CBlockUndo;
class CChain;
class CChainParams;
class CChainState;
class CDeterministicMNManager;
class CDSNotificationInterface;
class ChainstateManager;
struct CCheckpointData;
struct FlatFilePos;
Expand Down Expand Up @@ -229,8 +226,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus

bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);

void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CDSNotificationInterface& dsnfi,
std::vector<fs::path> vImportFiles, CActiveMasternodeManager* const mn_activeman, const ArgsManager& args);
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args);
} // namespace node

#endif // BITCOIN_NODE_BLOCKSTORAGE_H
11 changes: 9 additions & 2 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
#include <evo/chainhelper.h>
#include <evo/deterministicmns.h>
#include <evo/evodb.h>
#include <evo/mnhftx.h>
#include <evo/specialtx.h>
#include <evo/specialtxman.h>
#include <llmq/chainlocks.h>
Expand Down Expand Up @@ -138,6 +137,13 @@ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
uint256 hashAssumeValid;
arith_uint256 nMinimumChainWork;

// Forward declaration to break dependency over node/transaction.h
namespace node
{
CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock);
} // namespace node
using node::GetTransaction;

const CBlockIndex* CChainState::FindForkInGlobalIndex(const CBlockLocator& locator) const
{
AssertLockHeld(cs_main);
Expand Down Expand Up @@ -752,7 +758,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
if (auto conflictLockOpt = m_chain_helper.ConflictingISLockIfAny(tx); conflictLockOpt.has_value()) {
auto& [_, conflict_txid] = conflictLockOpt.value();

if (auto [txConflict, _] = GetTransactionBlock(conflict_txid, &m_pool); txConflict) {
uint256 hashBlock;
if (auto txConflict = GetTransaction(nullptr, &m_pool, conflict_txid, chainparams.GetConsensus(), hashBlock); txConflict) {
GetMainSignals().NotifyInstantSendDoubleSpendAttempt(ptx, txConflict);
}
LogPrintf("ERROR: AcceptToMemoryPool : Transaction %s conflicts with locked TX %s\n", hash.ToString(), conflict_txid.ToString());
Expand Down
11 changes: 2 additions & 9 deletions test/lint/lint-circular-dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,17 @@
"consensus/tx_verify -> evo/assetlocktx -> llmq/commitment -> validation -> consensus/tx_verify",
"consensus/tx_verify -> evo/assetlocktx -> llmq/signing -> net_processing -> txmempool -> consensus/tx_verify",
"core_io -> evo/cbtx -> evo/simplifiedmns -> core_io",
"dsnotificationinterface -> llmq/chainlocks -> node/blockstorage -> dsnotificationinterface",
"evo/assetlocktx -> llmq/signing -> net_processing -> txmempool -> evo/assetlocktx",
"evo/cbtx -> evo/simplifiedmns -> evo/cbtx",
"evo/chainhelper -> evo/specialtxman -> evo/deterministicmns -> evo/chainhelper",
"evo/chainhelper -> evo/specialtxman -> validation -> evo/chainhelper",
"evo/chainhelper -> llmq/chainlocks -> evo/chainhelper",
"evo/chainhelper -> llmq/instantsend -> evo/chainhelper",
"evo/chainhelper -> masternode/payments -> governance/classes -> governance/object -> evo/chainhelper",
"evo/chainhelper -> node/transaction -> node/context -> evo/chainhelper",
"evo/deterministicmns -> index/txindex -> validation -> evo/deterministicmns",
"evo/deterministicmns -> index/txindex -> validation -> txmempool -> evo/deterministicmns",
"evo/deterministicmns -> llmq/commitment -> evo/deterministicmns",
"evo/deterministicmns -> llmq/commitment -> validation -> evo/deterministicmns",
"evo/deterministicmns -> llmq/commitment -> validation -> txmempool -> evo/deterministicmns",
"evo/deterministicmns -> llmq/utils -> evo/deterministicmns",
"evo/deterministicmns -> llmq/utils -> llmq/snapshot -> evo/simplifiedmns -> evo/deterministicmns",
"evo/deterministicmns -> llmq/utils -> net -> evo/deterministicmns",
"evo/deterministicmns -> validationinterface -> evo/deterministicmns",
"evo/deterministicmns -> validationinterface -> governance/vote -> evo/deterministicmns",
"evo/mnhftx -> validation -> evo/mnhftx",
"evo/simplifiedmns -> llmq/blockprocessor -> llmq/utils -> llmq/snapshot -> evo/simplifiedmns",
"evo/specialtxman -> validation -> evo/specialtxman",
"governance/governance -> governance/object -> governance/governance",
Expand Down
Loading