Skip to content

Commit

Permalink
refactor: drop usage of chainstate globals in asset locks logic
Browse files Browse the repository at this point in the history
  • Loading branch information
kwvg committed Jun 26, 2024
1 parent 21cc12c commit fa20718
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 61 deletions.
8 changes: 4 additions & 4 deletions src/evo/assetlocktx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
/**
* Common code for Asset Lock and Asset Unlock
*/
bool CheckAssetLockUnlockTx(const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, const std::optional<CRangesSet>& indexes, TxValidationState& state)
bool CheckAssetLockUnlockTx(const BlockManager& blockman, const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, const std::optional<CRangesSet>& indexes, TxValidationState& state)
{
switch (tx.nType) {
case TRANSACTION_ASSET_LOCK:
return CheckAssetLockTx(tx, state);
case TRANSACTION_ASSET_UNLOCK:
return CheckAssetUnlockTx(qman, tx, pindexPrev, indexes, state);
return CheckAssetUnlockTx(blockman, qman, tx, pindexPrev, indexes, state);
default:
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-not-asset-locks-at-all");
}
Expand Down Expand Up @@ -141,7 +141,7 @@ bool CAssetUnlockPayload::VerifySig(const llmq::CQuorumManager& qman, const uint
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-assetunlock-not-verified");
}

bool CheckAssetUnlockTx(const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, const std::optional<CRangesSet>& indexes, TxValidationState& state)
bool CheckAssetUnlockTx(const BlockManager& blockman, const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, const std::optional<CRangesSet>& indexes, TxValidationState& state)
{
// Some checks depends from blockchain status also, such as `known indexes` and `withdrawal limits`
// They are omitted here and done by CCreditPool
Expand Down Expand Up @@ -171,7 +171,7 @@ bool CheckAssetUnlockTx(const llmq::CQuorumManager& qman, const CTransaction& tx
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-assetunlock-duplicated-index");
}

if (LOCK(cs_main); g_chainman.m_blockman.LookupBlockIndex(assetUnlockTx.getQuorumHash()) == nullptr) {
if (LOCK(cs_main); blockman.LookupBlockIndex(assetUnlockTx.getQuorumHash()) == nullptr) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-assetunlock-quorum-hash");
}

Expand Down
5 changes: 3 additions & 2 deletions src/evo/assetlocktx.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <optional>

class BlockManager;
class CBlockIndex;
class CRangesSet;
class TxValidationState;
Expand Down Expand Up @@ -172,8 +173,8 @@ class CAssetUnlockPayload
};

bool CheckAssetLockTx(const CTransaction& tx, TxValidationState& state);
bool CheckAssetUnlockTx(const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, const std::optional<CRangesSet>& indexes, TxValidationState& state);
bool CheckAssetLockUnlockTx(const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, const std::optional<CRangesSet>& indexes, TxValidationState& state);
bool CheckAssetUnlockTx(const BlockManager& blockman, const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, const std::optional<CRangesSet>& indexes, TxValidationState& state);
bool CheckAssetLockUnlockTx(const BlockManager& blockman, const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, const std::optional<CRangesSet>& indexes, TxValidationState& state);
bool GetAssetUnlockFee(const CTransaction& tx, CAmount& txfee, TxValidationState& state);

#endif // BITCOIN_EVO_ASSETLOCKTX_H
2 changes: 1 addition & 1 deletion src/evo/chainhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministi
const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler,
const llmq::CQuorumManager& qman)
: mn_payments{std::make_unique<CMNPaymentsProcessor>(dmnman, govman, chainman, consensus_params, mn_sync, sporkman)},
special_tx{std::make_unique<CSpecialTxProcessor>(cpoolman, dmnman, mnhfman, qblockman, consensus_params, clhandler, qman)}
special_tx{std::make_unique<CSpecialTxProcessor>(cpoolman, dmnman, mnhfman, qblockman, chainman, consensus_params, clhandler, qman)}
{}

CChainstateHelper::~CChainstateHelper() = default;
11 changes: 6 additions & 5 deletions src/evo/creditpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,12 @@ bool CCreditPoolDiff::Unlock(const CTransaction& tx, TxValidationState& state)
return true;
}

bool CCreditPoolDiff::ProcessLockUnlockTransaction(const llmq::CQuorumManager& qman, const CTransaction& tx, TxValidationState& state)
bool CCreditPoolDiff::ProcessLockUnlockTransaction(const BlockManager& blockman, const llmq::CQuorumManager& qman, const CTransaction& tx, TxValidationState& state)
{
if (!tx.IsSpecialTxVersion()) return true;
if (tx.nType != TRANSACTION_ASSET_LOCK && tx.nType != TRANSACTION_ASSET_UNLOCK) return true;

if (!CheckAssetLockUnlockTx(qman, tx, pindexPrev, pool.indexes, state)) {
if (!CheckAssetLockUnlockTx(blockman, qman, tx, pindexPrev, pool.indexes, state)) {
// pass the state returned by the function above
return false;
}
Expand All @@ -292,8 +292,9 @@ bool CCreditPoolDiff::ProcessLockUnlockTransaction(const llmq::CQuorumManager& q
}
}

std::optional<CCreditPoolDiff> GetCreditPoolDiffForBlock(CCreditPoolManager& cpoolman, const llmq::CQuorumManager& qman, const CBlock& block, const CBlockIndex* pindexPrev,
const Consensus::Params& consensusParams, const CAmount blockSubsidy, BlockValidationState& state)
std::optional<CCreditPoolDiff> GetCreditPoolDiffForBlock(CCreditPoolManager& cpoolman, const BlockManager& blockman, const llmq::CQuorumManager& qman,
const CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams,
const CAmount blockSubsidy, BlockValidationState& state)
{
try {
const CCreditPool creditPool = cpoolman.GetCreditPool(pindexPrev, consensusParams);
Expand All @@ -302,7 +303,7 @@ std::optional<CCreditPoolDiff> GetCreditPoolDiffForBlock(CCreditPoolManager& cpo
for (size_t i = 1; i < block.vtx.size(); ++i) {
const auto& tx = *block.vtx[i];
TxValidationState tx_state;
if (!creditPoolDiff.ProcessLockUnlockTransaction(qman, tx, tx_state)) {
if (!creditPoolDiff.ProcessLockUnlockTransaction(blockman, qman, tx, tx_state)) {
assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS);
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(),
strprintf("Process Lock/Unlock Transaction failed at Credit Pool (tx hash %s) %s", tx.GetHash().ToString(), tx_state.GetDebugMessage()));
Expand Down
8 changes: 5 additions & 3 deletions src/evo/creditpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <optional>
#include <unordered_set>

class BlockManager;
class CBlockIndex;
class BlockValidationState;
class TxValidationState;
Expand Down Expand Up @@ -83,7 +84,7 @@ class CCreditPoolDiff {
* to change amount of credit pool
* @return true if transaction can be included in this block
*/
bool ProcessLockUnlockTransaction(const llmq::CQuorumManager& qman, const CTransaction& tx, TxValidationState& state);
bool ProcessLockUnlockTransaction(const BlockManager& blockman, const llmq::CQuorumManager& qman, const CTransaction& tx, TxValidationState& state);

/**
* this function returns total amount of credits for the next block
Expand Down Expand Up @@ -135,7 +136,8 @@ class CCreditPoolManager
CCreditPool ConstructCreditPool(const CBlockIndex* block_index, CCreditPool prev, const Consensus::Params& consensusParams);
};

std::optional<CCreditPoolDiff> GetCreditPoolDiffForBlock(CCreditPoolManager& cpoolman, const llmq::CQuorumManager& qman, const CBlock& block, const CBlockIndex* pindexPrev,
const Consensus::Params& consensusParams, const CAmount blockSubsidy, BlockValidationState& state);
std::optional<CCreditPoolDiff> GetCreditPoolDiffForBlock(CCreditPoolManager& cpoolman, const BlockManager& blockman, const llmq::CQuorumManager& qman,
const CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams,
const CAmount blockSubsidy, BlockValidationState& state);

#endif
18 changes: 11 additions & 7 deletions src/evo/specialtxman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
#include <llmq/blockprocessor.h>
#include <llmq/commitment.h>
#include <primitives/block.h>
#include <validation.h>

static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const llmq::CQuorumManager& qman, const CTransaction& tx, const CBlockIndex* pindexPrev,
const CCoinsViewCache& view, const std::optional<CRangesSet>& indexes, bool check_sigs, TxValidationState& state)
static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const ChainstateManager& chainman, const llmq::CQuorumManager& qman, const CTransaction& tx,
const CBlockIndex* pindexPrev, const CCoinsViewCache& view, const std::optional<CRangesSet>& indexes, bool check_sigs,
TxValidationState& state)
{
AssertLockHeld(cs_main);

Expand Down Expand Up @@ -54,7 +56,7 @@ static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const llmq::CQu
if (!DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_V20)) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, "assetlocks-before-v20");
}
return CheckAssetLockUnlockTx(qman, tx, pindexPrev, indexes, state);
return CheckAssetLockUnlockTx(chainman.m_blockman, qman, tx, pindexPrev, indexes, state);
case TRANSACTION_ASSET_UNLOCK:
if (Params().NetworkIDString() == CBaseChainParams::REGTEST && !DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_V20)) {
// TODO: adjust functional tests to make it activated by MN_RR on regtest too
Expand All @@ -63,7 +65,7 @@ static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const llmq::CQu
if (Params().NetworkIDString() != CBaseChainParams::REGTEST && !DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_MN_RR)) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, "assetunlocks-before-mn_rr");
}
return CheckAssetLockUnlockTx(qman, tx, pindexPrev, indexes, state);
return CheckAssetLockUnlockTx(chainman.m_blockman, qman, tx, pindexPrev, indexes, state);
}
} catch (const std::exception& e) {
LogPrintf("%s -- failed: %s\n", __func__, e.what());
Expand All @@ -76,7 +78,7 @@ static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const llmq::CQu
bool CSpecialTxProcessor::CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, bool check_sigs, TxValidationState& state)
{
AssertLockHeld(cs_main);
return CheckSpecialTxInner(m_dmnman, m_qman, tx, pindexPrev, view, std::nullopt, check_sigs, state);
return CheckSpecialTxInner(m_dmnman, m_chainman, m_qman, tx, pindexPrev, view, std::nullopt, check_sigs, state);
}

[[nodiscard]] bool CSpecialTxProcessor::ProcessSpecialTx(const CTransaction& tx, const CBlockIndex* pindex, TxValidationState& state)
Expand Down Expand Up @@ -155,7 +157,7 @@ bool CSpecialTxProcessor::ProcessSpecialTxsInBlock(const CBlock& block, const CB
TxValidationState tx_state;
// At this moment CheckSpecialTx() and ProcessSpecialTx() may fail by 2 possible ways:
// consensus failures and "TX_BAD_SPECIAL"
if (!CheckSpecialTxInner(m_dmnman, m_qman, *ptr_tx, pindex->pprev, view, creditPool.indexes, fCheckCbTxMerkleRoots, tx_state)) {
if (!CheckSpecialTxInner(m_dmnman, m_chainman, m_qman, *ptr_tx, pindex->pprev, view, creditPool.indexes, fCheckCbTxMerkleRoots, tx_state)) {
assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS || tx_state.GetResult() == TxValidationResult::TX_BAD_SPECIAL);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(),
strprintf("Special Transaction check failed (tx hash %s) %s", ptr_tx->GetHash().ToString(), tx_state.GetDebugMessage()));
Expand Down Expand Up @@ -273,10 +275,12 @@ bool CSpecialTxProcessor::UndoSpecialTxsInBlock(const CBlock& block, const CBloc

bool CSpecialTxProcessor::CheckCreditPoolDiffForBlock(const CBlock& block, const CBlockIndex* pindex, const CAmount blockSubsidy, BlockValidationState& state)
{
AssertLockHeld(cs_main);

try {
if (!DeploymentActiveAt(*pindex, m_consensus_params, Consensus::DEPLOYMENT_V20)) return true;

auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_qman, block, pindex->pprev, m_consensus_params, blockSubsidy, state);
auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_chainman.m_blockman, m_qman, block, pindex->pprev, m_consensus_params, blockSubsidy, state);
if (!creditPoolDiff.has_value()) return false;

// If we get there we have v20 activated and credit pool amount must be included in block CbTx
Expand Down
14 changes: 9 additions & 5 deletions src/evo/specialtxman.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class CBlockIndex;
class CCoinsViewCache;
class CCreditPoolManager;
class CDeterministicMNManager;
class ChainstateManager;
class CMNHFManager;
class TxValidationState;
struct MNListUpdates;
Expand All @@ -37,6 +38,7 @@ class CSpecialTxProcessor
CDeterministicMNManager& m_dmnman;
CMNHFManager& m_mnhfman;
llmq::CQuorumBlockProcessor& m_qblockman;
const ChainstateManager& m_chainman;
const Consensus::Params& m_consensus_params;
const llmq::CChainLocksHandler& m_clhandler;
const llmq::CQuorumManager& m_qman;
Expand All @@ -46,10 +48,11 @@ class CSpecialTxProcessor
[[nodiscard]] bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex);

public:
explicit CSpecialTxProcessor(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, llmq::CQuorumBlockProcessor& qblockman,
const Consensus::Params& consensus_params, const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) :
m_cpoolman(cpoolman), m_dmnman{dmnman}, m_mnhfman{mnhfman}, m_qblockman{qblockman}, m_consensus_params{consensus_params}, m_clhandler{clhandler},
m_qman{qman} {}
explicit CSpecialTxProcessor(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman,
llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman, const Consensus::Params& consensus_params,
const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) :
m_cpoolman(cpoolman), m_dmnman{dmnman}, m_mnhfman{mnhfman}, m_qblockman{qblockman}, m_chainman(chainman), m_consensus_params{consensus_params},
m_clhandler{clhandler}, m_qman{qman} {}

bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, bool check_sigs, TxValidationState& state)
EXCLUSIVE_LOCKS_REQUIRED(cs_main);
Expand All @@ -58,7 +61,8 @@ class CSpecialTxProcessor
EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, std::optional<MNListUpdates>& updatesRet)
EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool CheckCreditPoolDiffForBlock(const CBlock& block, const CBlockIndex* pindex, const CAmount blockSubsidy, BlockValidationState& state);
bool CheckCreditPoolDiffForBlock(const CBlock& block, const CBlockIndex* pindex, const CAmount blockSubsidy, BlockValidationState& state)
EXCLUSIVE_LOCKS_REQUIRED(cs_main);
};

#endif // BITCOIN_EVO_SPECIALTXMAN_H
21 changes: 11 additions & 10 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,19 @@ BlockAssembler::Options::Options() {
}

BlockAssembler::BlockAssembler(CChainState& chainstate, const NodeContext& node, const CTxMemPool& mempool, const CChainParams& params, const Options& options) :
chainparams(params),
m_mempool(mempool),
m_chainstate(chainstate),
m_dmnman(*Assert(node.dmnman)),
m_blockman(Assert(node.chainman)->m_blockman),
m_cpoolman(*Assert(node.cpoolman)),
m_chain_helper(*Assert(node.chain_helper)),
m_chainstate(chainstate),
m_dmnman(*Assert(node.dmnman)),
m_evoDb(*Assert(node.evodb)),
m_mnhfman(*Assert(node.mnhf_manager)),
m_quorum_block_processor(*Assert(Assert(node.llmq_ctx)->quorum_block_processor)),
m_qman(*Assert(Assert(node.llmq_ctx)->qman)),
m_clhandler(*Assert(Assert(node.llmq_ctx)->clhandler)),
m_isman(*Assert(Assert(node.llmq_ctx)->isman)),
m_evoDb(*Assert(node.evodb))
chainparams(params),
m_mempool(mempool),
m_quorum_block_processor(*Assert(Assert(node.llmq_ctx)->quorum_block_processor)),
m_qman(*Assert(Assert(node.llmq_ctx)->qman))
{
blockMinFeeRate = options.blockMinFeeRate;
nBlockMaxSize = options.nBlockMaxSize;
Expand Down Expand Up @@ -221,7 +222,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
cbTx.nHeight = nHeight;

BlockValidationState state;
if (!CalcCbTxMerkleRootMNList(*pblock, pindexPrev, cbTx.merkleRootMNList, m_dmnman, state, ::ChainstateActive().CoinsTip())) {
if (!CalcCbTxMerkleRootMNList(*pblock, pindexPrev, cbTx.merkleRootMNList, m_dmnman, state, m_chainstate.CoinsTip())) {
throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootMNList failed: %s", __func__, state.ToString()));
}
if (fDIP0008Active_context) {
Expand All @@ -236,7 +237,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
LogPrintf("CreateNewBlock() h[%d] CbTx failed to find best CL. Inserting null CL\n", nHeight);
}
BlockValidationState state;
const auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_qman, *pblock, pindexPrev, chainparams.GetConsensus(), blockSubsidy, state);
const auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_blockman, m_qman, *pblock, pindexPrev, chainparams.GetConsensus(), blockSubsidy, state);
if (creditPoolDiff == std::nullopt) {
throw std::runtime_error(strprintf("%s: GetCreditPoolDiffForBlock failed: %s", __func__, state.ToString()));
}
Expand Down Expand Up @@ -472,7 +473,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
// `state` is local here because used only to log info about this specific tx
TxValidationState state;

if (!creditPoolDiff->ProcessLockUnlockTransaction(m_qman, iter->GetTx(), state)) {
if (!creditPoolDiff->ProcessLockUnlockTransaction(m_blockman, m_qman, iter->GetTx(), state)) {
if (fUsingModified) {
mapModifiedTx.get<ancestor_score>().erase(modit);
failedTx.insert(iter);
Expand Down
Loading

0 comments on commit fa20718

Please sign in to comment.