Skip to content

Commit

Permalink
refactor: add passthrough functions to CInstantSendManager
Browse files Browse the repository at this point in the history
  • Loading branch information
kwvg committed Jan 6, 2025
1 parent 41c8c8f commit a167c0e
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 49 deletions.
28 changes: 26 additions & 2 deletions src/evo/chainhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
#include <consensus/params.h>
#include <evo/specialtxman.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <masternode/payments.h>

CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman,
CGovernanceManager& govman, llmq::CQuorumBlockProcessor& qblockman,
CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman,
CMNHFManager& mnhfman, CGovernanceManager& govman,
llmq::CInstantSendManager& isman, llmq::CQuorumBlockProcessor& qblockman,
const ChainstateManager& chainman, const Consensus::Params& consensus_params,
const CMasternodeSync& mn_sync, const CSporkManager& sporkman,
const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) :
isman{isman},
clhandler{clhandler},
mn_payments{std::make_unique<CMNPaymentsProcessor>(dmnman, govman, chainman, consensus_params, mn_sync, sporkman)},
special_tx{std::make_unique<CSpecialTxProcessor>(cpoolman, dmnman, mnhfman, qblockman, chainman, consensus_params,
Expand All @@ -34,3 +37,24 @@ bool CChainstateHelper::HasChainLock(int nHeight, const uint256& blockHash) cons
}

int32_t CChainstateHelper::GetBestChainLockHeight() const { return clhandler.GetBestChainLock().getHeight(); }

/** Passthrough functions to CInstantSendManager */
std::optional<std::pair</*islock_hash=*/uint256, /*txid=*/uint256>> CChainstateHelper::ConflictingISLockIfAny(
const CTransaction& tx) const
{
const auto islock = isman.GetConflictingLock(tx);
if (!islock) return std::nullopt;
return std::make_pair(::SerializeHash(*islock), islock->txid);
}

bool CChainstateHelper::IsInstantSendWaitingForTx(const uint256& hash) const { return isman.IsWaitingForTx(hash); }

bool CChainstateHelper::RemoveConflictingISLockByTx(const CTransaction& tx)
{
const auto islock = isman.GetConflictingLock(tx);
if (!islock) return false;
isman.RemoveConflictingLock(::SerializeHash(*islock), *islock);
return true;
}

bool CChainstateHelper::ShouldInstantSendRejectConflicts() const { return isman.RejectConflictingBlocks(); }
18 changes: 15 additions & 3 deletions src/evo/chainhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define BITCOIN_EVO_CHAINHELPER_H

#include <memory>
#include <optional>

class CCreditPoolManager;
class CDeterministicMNManager;
Expand All @@ -16,24 +17,29 @@ class CMasternodeSync;
class CGovernanceManager;
class CSpecialTxProcessor;
class CSporkManager;
class CTransaction;
class uint256;

namespace Consensus { struct Params; }
namespace llmq {
class CChainLocksHandler;
class CInstantSendManager;
class CQuorumBlockProcessor;
class CQuorumManager;
}

class CChainstateHelper
{
private:
llmq::CInstantSendManager& isman;
const llmq::CChainLocksHandler& clhandler;

public:
explicit CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, CGovernanceManager& govman,
llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman, const Consensus::Params& consensus_params,
const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler,
explicit CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman,
CGovernanceManager& govman, llmq::CInstantSendManager& isman,
llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman,
const Consensus::Params& consensus_params, const CMasternodeSync& mn_sync,
const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler,
const llmq::CQuorumManager& qman);
~CChainstateHelper();

Expand All @@ -45,6 +51,12 @@ class CChainstateHelper
bool HasChainLock(int nHeight, const uint256& blockHash) const;
int32_t GetBestChainLockHeight() const;

/** Passthrough functions to CInstantSendManager */
std::optional<std::pair</*islock_hash=*/uint256, /*txid=*/uint256>> ConflictingISLockIfAny(const CTransaction& tx) const;
bool IsInstantSendWaitingForTx(const uint256& hash) const;
bool RemoveConflictingISLockByTx(const CTransaction& tx);
bool ShouldInstantSendRejectConflicts() const;

public:
const std::unique_ptr<CMNPaymentsProcessor> mn_payments;
const std::unique_ptr<CSpecialTxProcessor> special_tx;
Expand Down
2 changes: 0 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@
#include <evo/mnhftx.h>
#include <llmq/blockprocessor.h>
#include <llmq/context.h>
#include <llmq/instantsend.h>
#include <llmq/quorums.h>
#include <llmq/dkgsessionmgr.h>
#include <llmq/options.h>
Expand Down Expand Up @@ -1857,7 +1856,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
node.dmnman,
node.evodb,
node.mnhf_manager,
llmq::quorumInstantSendManager,
llmq::quorumSnapshotManager,
node.llmq_ctx,
Assert(node.mempool.get()),
Expand Down
8 changes: 3 additions & 5 deletions src/node/chainstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <evo/evodb.h>
#include <evo/mnhftx.h>
#include <llmq/context.h>
#include <llmq/instantsend.h>
#include <llmq/snapshot.h>

std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
Expand All @@ -31,7 +30,6 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
std::unique_ptr<CDeterministicMNManager>& dmnman,
std::unique_ptr<CEvoDB>& evodb,
std::unique_ptr<CMNHFManager>& mnhf_manager,
std::unique_ptr<llmq::CInstantSendManager>& isman,
std::unique_ptr<llmq::CQuorumSnapshotManager>& qsnapman,
std::unique_ptr<LLMQContext>& llmq_ctx,
CTxMemPool* mempool,
Expand Down Expand Up @@ -65,7 +63,7 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
mnhf_manager.reset();
mnhf_manager = std::make_unique<CMNHFManager>(*evodb);

chainman.InitializeChainstate(mempool, *evodb, chain_helper, isman);
chainman.InitializeChainstate(mempool, *evodb, chain_helper);
chainman.m_total_coinstip_cache = nCoinCacheUsage;
chainman.m_total_coinsdb_cache = nCoinDBCache;

Expand Down Expand Up @@ -241,8 +239,8 @@ void DashChainstateSetup(ChainstateManager& chainman,
mnhf_manager->ConnectManagers(&chainman, llmq_ctx->qman.get());

chain_helper.reset();
chain_helper = std::make_unique<CChainstateHelper>(*cpoolman, *dmnman, *mnhf_manager, govman, *(llmq_ctx->quorum_block_processor), chainman,
consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman));
chain_helper = std::make_unique<CChainstateHelper>(*cpoolman, *dmnman, *mnhf_manager, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor),
chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman));
}

void DashChainstateSetupClose(std::unique_ptr<CChainstateHelper>& chain_helper,
Expand Down
2 changes: 0 additions & 2 deletions src/node/chainstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ class CTxMemPool;
struct LLMQContext;

namespace llmq {
class CInstantSendManager;
class CQuorumSnapshotManager;
}

Expand Down Expand Up @@ -92,7 +91,6 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
std::unique_ptr<CDeterministicMNManager>& dmnman,
std::unique_ptr<CEvoDB>& evodb,
std::unique_ptr<CMNHFManager>& mnhf_manager,
std::unique_ptr<llmq::CInstantSendManager>& isman,
std::unique_ptr<llmq::CQuorumSnapshotManager>& qsnapman,
std::unique_ptr<LLMQContext>& llmq_ctx,
CTxMemPool* mempool,
Expand Down
2 changes: 0 additions & 2 deletions src/test/util/setup_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include <interfaces/chain.h>
#include <netfulfilledman.h>
#include <llmq/context.h>
#include <llmq/instantsend.h>
#include <llmq/quorums.h>
#include <llmq/signing.h>
#include <llmq/signing_shares.h>
Expand Down Expand Up @@ -297,7 +296,6 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
m_node.dmnman,
m_node.evodb,
m_node.mnhf_manager,
llmq::quorumInstantSendManager,
llmq::quorumSnapshotManager,
m_node.llmq_ctx,
Assert(m_node.mempool.get()),
Expand Down
3 changes: 1 addition & 2 deletions src/test/validation_chainstate_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <consensus/validation.h>
#include <evo/evodb.h>
#include <index/txindex.h>
#include <llmq/instantsend.h>
#include <random.h>
#include <sync.h>
#include <rpc/blockchain.h>
Expand Down Expand Up @@ -42,7 +41,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
return outp;
};

CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, llmq::quorumInstantSendManager));
CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper));
c1.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));
Expand Down
11 changes: 5 additions & 6 deletions src/test/validation_chainstatemanager_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <index/txindex.h>
#include <llmq/blockprocessor.h>
#include <llmq/context.h>
#include <llmq/instantsend.h>
#include <node/chainstate.h>
#include <node/utxo_snapshot.h>
#include <random.h>
Expand Down Expand Up @@ -44,7 +43,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)

// Create a legacy (IBD) chainstate.
//
CChainState& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager));
CChainState& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper));
chainstates.push_back(&c1);
c1.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
Expand Down Expand Up @@ -80,7 +79,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
//
const uint256 snapshot_blockhash = GetRandHash();
CChainState& c2 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(
&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager,
&mempool, evodb, m_node.chain_helper,
snapshot_blockhash)
);
chainstates.push_back(&c2);
Expand Down Expand Up @@ -143,7 +142,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)

// Create a legacy (IBD) chainstate.
//
CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager));
CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper));
chainstates.push_back(&c1);
c1.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
Expand All @@ -161,7 +160,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)

// Create a snapshot-based chainstate.
//
CChainState& c2 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager, GetRandHash()));
CChainState& c2 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, GetRandHash()));
chainstates.push_back(&c2);
c2.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
Expand Down Expand Up @@ -402,7 +401,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
BOOST_CHECK_EQUAL(expected_assumed_valid, num_assumed_valid);

CChainState& cs2 = WITH_LOCK(::cs_main,
return chainman.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, llmq::quorumInstantSendManager, GetRandHash()));
return chainman.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, GetRandHash()));

reload_all_block_indexes();

Expand Down
4 changes: 1 addition & 3 deletions src/test/validation_flush_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
#include <evo/evodb.h>
#include <llmq/instantsend.h>
#include <sync.h>
#include <test/util/setup_common.h>
#include <txmempool.h>
Expand All @@ -22,8 +21,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
{
CTxMemPool mempool;
BlockManager blockman{};
CChainState chainstate(&mempool, blockman, *Assert(m_node.chainman), *m_node.evodb, m_node.chain_helper,
llmq::quorumInstantSendManager);
CChainState chainstate(&mempool, blockman, *Assert(m_node.chainman), *m_node.evodb, m_node.chain_helper);
chainstate.InitCoinsDB(/*cache_size_bytes*/ 1 << 10, /*in_memory*/ true, /*should_wipe*/ false);
WITH_LOCK(::cs_main, chainstate.InitCoinsCache(1 << 10));

Expand Down
30 changes: 12 additions & 18 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
#include <evo/specialtxman.h>
#include <governance/governance.h>

#include <llmq/instantsend.h>
#include <llmq/chainlocks.h>

#include <stats/client.h>
Expand Down Expand Up @@ -728,18 +727,18 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
return state.Invalid(TxValidationResult::TX_CONFLICT, "txn-already-in-mempool");
}

llmq::CInstantSendLockPtr conflictLock = llmq::quorumInstantSendManager->GetConflictingLock(tx);
if (conflictLock) {
if (auto conflictLockOpt = m_chain_helper.ConflictingISLockIfAny(tx); conflictLockOpt.has_value()) {
auto& [_, conflict_txid] = conflictLockOpt.value();
uint256 hashBlock;
CTransactionRef txConflict = GetTransaction(/* block_index */ nullptr, &m_pool, conflictLock->txid, chainparams.GetConsensus(), hashBlock);
CTransactionRef txConflict = GetTransaction(/* block_index */ nullptr, &m_pool, conflict_txid, chainparams.GetConsensus(), hashBlock);
if (txConflict) {
GetMainSignals().NotifyInstantSendDoubleSpendAttempt(ptx, txConflict);
}
LogPrintf("ERROR: AcceptToMemoryPool : Transaction %s conflicts with locked TX %s\n", hash.ToString(), conflictLock->txid.ToString());
LogPrintf("ERROR: AcceptToMemoryPool : Transaction %s conflicts with locked TX %s\n", hash.ToString(), conflict_txid.ToString());
return state.Invalid(TxValidationResult::TX_CONFLICT_LOCK, "tx-txlock-conflict");
}

if (llmq::quorumInstantSendManager->IsWaitingForTx(hash)) {
if (m_chain_helper.IsInstantSendWaitingForTx(hash)) {
m_pool.removeConflicts(tx);
m_pool.removeProTxConflicts(tx);
} else {
Expand Down Expand Up @@ -1523,11 +1522,9 @@ CChainState::CChainState(CTxMemPool* mempool,
ChainstateManager& chainman,
CEvoDB& evoDb,
const std::unique_ptr<CChainstateHelper>& chain_helper,
const std::unique_ptr<llmq::CInstantSendManager>& isman,
std::optional<uint256> from_snapshot_blockhash)
: m_mempool(mempool),
m_chain_helper(chain_helper),
m_isman(isman),
m_evoDb(evoDb),
m_blockman(blockman),
m_params(::Params()),
Expand Down Expand Up @@ -2144,7 +2141,6 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
assert(*pindex->phashBlock == block_hash);

assert(m_chain_helper);
assert(m_isman);

// Check it again in case a previous version let a bad block in
// NOTE: We don't currently (re-)invoke ContextualCheckBlock() or
Expand Down Expand Up @@ -2466,21 +2462,21 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,

// DASH : CHECK TRANSACTIONS FOR INSTANTSEND

if (m_isman->RejectConflictingBlocks()) {
if (m_chain_helper->ShouldInstantSendRejectConflicts()) {
// Require other nodes to comply, send them some data in case they are missing it.
const bool has_chainlock = m_chain_helper->HasChainLock(pindex->nHeight, pindex->GetBlockHash());
for (const auto& tx : block.vtx) {
// skip txes that have no inputs
if (tx->vin.empty()) continue;
while (llmq::CInstantSendLockPtr conflictLock = m_isman->GetConflictingLock(*tx)) {
while (auto conflictLockOpt = m_chain_helper->ConflictingISLockIfAny(*tx)) {
auto [conflict_islock_hash, conflict_txid] = conflictLockOpt.value();
if (has_chainlock) {
LogPrint(BCLog::ALL, "ConnectBlock(DASH): chain-locked transaction %s overrides islock %s\n",
tx->GetHash().ToString(), ::SerializeHash(*conflictLock).ToString());
m_isman->RemoveConflictingLock(::SerializeHash(*conflictLock), *conflictLock);
LogPrint(BCLog::ALL, "ConnectBlock(DASH): chain-locked transaction %s overrides islock %s\n", tx->GetHash().ToString(), conflict_islock_hash.ToString());
m_chain_helper->RemoveConflictingISLockByTx(*tx);
} else {
// The node which relayed this should switch to correct chain.
// TODO: relay instantsend data/proof.
LogPrintf("ERROR: ConnectBlock(DASH): transaction %s conflicts with transaction lock %s\n", tx->GetHash().ToString(), conflictLock->txid.ToString());
LogPrintf("ERROR: ConnectBlock(DASH): transaction %s conflicts with transaction lock %s\n", tx->GetHash().ToString(), conflict_txid.ToString());
return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "conflict-tx-lock");
}
}
Expand Down Expand Up @@ -5488,7 +5484,6 @@ std::vector<CChainState*> ChainstateManager::GetAll()
CChainState& ChainstateManager::InitializeChainstate(CTxMemPool* mempool,
CEvoDB& evoDb,
const std::unique_ptr<CChainstateHelper>& chain_helper,
const std::unique_ptr<llmq::CInstantSendManager>& isman,
const std::optional<uint256>& snapshot_blockhash)
{
AssertLockHeld(::cs_main);
Expand All @@ -5500,7 +5495,7 @@ CChainState& ChainstateManager::InitializeChainstate(CTxMemPool* mempool,
throw std::logic_error("should not be overwriting a chainstate");
}

to_modify.reset(new CChainState(mempool, m_blockman, *this, evoDb, chain_helper, isman, snapshot_blockhash));
to_modify.reset(new CChainState(mempool, m_blockman, *this, evoDb, chain_helper, snapshot_blockhash));

// Snapshot chainstates and initial IBD chaintates always become active.
if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {
Expand Down Expand Up @@ -5573,7 +5568,6 @@ bool ChainstateManager::ActivateSnapshot(
/* mempool */ nullptr, m_blockman, *this,
this->ActiveChainstate().m_evoDb,
this->ActiveChainstate().m_chain_helper,
this->ActiveChainstate().m_isman,
base_blockhash
)
);
Expand Down
Loading

0 comments on commit a167c0e

Please sign in to comment.