mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
feat: add CMNHFManager and logic to make hard-forks accordingly received signals
This commit is contained in:
parent
c8d84a8c33
commit
33ab3187b2
@ -15,9 +15,12 @@
|
||||
#include <validation.h>
|
||||
#include <versionbits.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern const std::string MNEHF_REQUESTID_PREFIX = "mnhf";
|
||||
static const std::string DB_SIGNALS = "mnhf_s";
|
||||
|
||||
bool MNHFTx::Verify(const CBlockIndex* pQuorumIndex, const uint256& msgHash, TxValidationState& state) const
|
||||
{
|
||||
@ -80,6 +83,183 @@ bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, TxValida
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool extractSignals(const CBlock& block, const CBlockIndex* const pindex, std::vector<uint8_t>& signals_to_process, BlockValidationState& state)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
// we skip the coinbase
|
||||
for (size_t i = 1; i < block.vtx.size(); ++i) {
|
||||
const CTransaction& tx = *block.vtx[i];
|
||||
|
||||
if (tx.nVersion != 3 || tx.nType != TRANSACTION_MNHF_SIGNAL) {
|
||||
// only interested in special TXs 'TRANSACTION_MNHF_SIGNAL'
|
||||
continue;
|
||||
}
|
||||
|
||||
TxValidationState tx_state;
|
||||
if (!CheckMNHFTx(tx, pindex, tx_state)) {
|
||||
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(), tx_state.GetDebugMessage());
|
||||
}
|
||||
|
||||
MNHFTxPayload mnhfTx;
|
||||
if (!GetTxPayload(tx, mnhfTx)) {
|
||||
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-mnhf-tx-payload");
|
||||
}
|
||||
signals_to_process.push_back(mnhfTx.signal.versionBit);
|
||||
}
|
||||
|
||||
// Checking that there's no any duplicates...
|
||||
std::sort(signals_to_process.begin(), signals_to_process.end());
|
||||
const auto it = std::unique(signals_to_process.begin(), signals_to_process.end());
|
||||
if (std::distance(signals_to_process.begin(), it) != signals_to_process.size()) {
|
||||
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-mnhf-duplicates");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMNHFManager::ProcessBlock(const CBlock& block, const CBlockIndex* const pindex, bool fJustCheck, BlockValidationState& state)
|
||||
{
|
||||
try {
|
||||
std::vector<uint8_t> new_signals;
|
||||
if (!extractSignals(block, pindex, new_signals, state)) {
|
||||
// state is set inside extractSignals
|
||||
return false;
|
||||
}
|
||||
if (new_signals.empty()) {
|
||||
if (!fJustCheck) {
|
||||
AddToCache(GetFromCache(pindex->pprev), pindex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Signals signals = GetFromCache(pindex->pprev);
|
||||
int mined_height = pindex->nHeight;
|
||||
|
||||
// Extra validation of signals to be sure that it can succeed
|
||||
for (const auto& versionBit : new_signals) {
|
||||
LogPrintf("%s: add mnhf bit=%d block:%s number of known signals:%lld\n", __func__, versionBit, pindex->GetBlockHash().ToString(), signals.size());
|
||||
if (signals.find(versionBit) != signals.end()) {
|
||||
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-mnhf-duplicate");
|
||||
}
|
||||
|
||||
if (!Params().UpdateMNActivationParam(versionBit, mined_height, pindex->GetMedianTimePast(), true /* fJustCheck */)) {
|
||||
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-mnhf-non-mn-fork");
|
||||
}
|
||||
}
|
||||
if (fJustCheck) {
|
||||
// We are done, no need actually update any params
|
||||
return true;
|
||||
}
|
||||
for (const auto& versionBit : new_signals) {
|
||||
signals.insert({versionBit, mined_height});
|
||||
|
||||
if (!Params().UpdateMNActivationParam(versionBit, mined_height, pindex->GetMedianTimePast(), false /* fJustCheck */)) {
|
||||
// it should not ever fail - all checks are done above
|
||||
assert(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AddToCache(signals, pindex);
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
LogPrintf("%s -- failed: %s\n", __func__, e.what());
|
||||
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "failed-proc-mnhf-inblock");
|
||||
}
|
||||
}
|
||||
|
||||
bool CMNHFManager::UndoBlock(const CBlock& block, const CBlockIndex* const pindex)
|
||||
{
|
||||
std::vector<uint8_t> excluded_signals;
|
||||
BlockValidationState state;
|
||||
if (!extractSignals(block, pindex, excluded_signals, state)) {
|
||||
LogPrintf("%s: failed to extract signals\n", __func__);
|
||||
return false;
|
||||
}
|
||||
if (excluded_signals.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const Signals signals = GetFromCache(pindex);
|
||||
for (const auto& versionBit : excluded_signals) {
|
||||
assert(versionBit < VERSIONBITS_NUM_BITS);
|
||||
|
||||
LogPrintf("%s: exclude mnhf bit=%d block:%s number of known signals:%lld\n", __func__, versionBit, pindex->GetBlockHash().ToString(), signals.size());
|
||||
assert(signals.find(versionBit) != signals.end());
|
||||
|
||||
bool update_ret = Params().UpdateMNActivationParam(versionBit, 0, pindex->GetMedianTimePast(), false /* fJustCheck */);
|
||||
assert(update_ret);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMNHFManager::UpdateChainParams(const CBlockIndex* const pindex, const CBlockIndex* const pindexOld)
|
||||
{
|
||||
LogPrintf("%s: update chain params %s -> %s\n", __func__, pindexOld ? pindexOld->GetBlockHash().ToString() : "", pindex ? pindex->GetBlockHash().ToString() : "");
|
||||
Signals signals_old{GetFromCache(pindexOld)};
|
||||
for (const auto& signal: signals_old) {
|
||||
uint8_t versionBit = signal.first;
|
||||
assert(versionBit < VERSIONBITS_NUM_BITS);
|
||||
|
||||
LogPrintf("%s: unload mnhf bit=%d block:%s number of known signals:%lld\n", __func__, versionBit, pindex->GetBlockHash().ToString(), signals_old.size());
|
||||
|
||||
bool update_ret = Params().UpdateMNActivationParam(versionBit, 0, pindex->GetMedianTimePast(), false);
|
||||
assert(update_ret);
|
||||
}
|
||||
|
||||
Signals signals{GetFromCache(pindex)};
|
||||
for (const auto& signal: signals) {
|
||||
uint8_t versionBit = signal.first;
|
||||
int value = signal.second;
|
||||
assert(versionBit < VERSIONBITS_NUM_BITS);
|
||||
|
||||
LogPrintf("%s: load mnhf bit=%d block:%s number of known signals:%lld\n", __func__, versionBit, pindex->GetBlockHash().ToString(), signals.size());
|
||||
|
||||
bool update_ret = Params().UpdateMNActivationParam(versionBit, value, pindex->GetMedianTimePast(), false);
|
||||
assert(update_ret);
|
||||
}
|
||||
}
|
||||
|
||||
CMNHFManager::Signals CMNHFManager::GetFromCache(const CBlockIndex* const pindex)
|
||||
{
|
||||
if (pindex == nullptr) return {};
|
||||
const uint256& blockHash = pindex->GetBlockHash();
|
||||
Signals signals{};
|
||||
{
|
||||
LOCK(cs_cache);
|
||||
if (mnhfCache.get(blockHash, signals)) {
|
||||
LogPrintf("CMNHFManager::GetFromCache: mnhf get for block %s from cache: %lld signals\n", pindex->GetBlockHash().ToString(), signals.size());
|
||||
return signals;
|
||||
}
|
||||
}
|
||||
if (VersionBitsState(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, versionbitscache) != ThresholdState::ACTIVE) {
|
||||
LOCK(cs_cache);
|
||||
mnhfCache.insert(blockHash, signals);
|
||||
LogPrintf("CMNHFManager::GetFromCache: mnhf feature is disabled: return empty for block %s\n", pindex->GetBlockHash().ToString());
|
||||
return signals;
|
||||
}
|
||||
if (!m_evoDb.Read(std::make_pair(DB_SIGNALS, blockHash), signals)) {
|
||||
LogPrintf("CMNHFManager::GetFromCache: failure: can't read MnEHF signals from db for %s\n", pindex->GetBlockHash().ToString());
|
||||
}
|
||||
LogPrintf("CMNHFManager::GetFromCache: mnhf for block %s read from evo: %lld\n", pindex->GetBlockHash().ToString(), signals.size());
|
||||
LOCK(cs_cache);
|
||||
mnhfCache.insert(blockHash, signals);
|
||||
return signals;
|
||||
}
|
||||
|
||||
void CMNHFManager::AddToCache(const Signals& signals, const CBlockIndex* const pindex)
|
||||
{
|
||||
const uint256& blockHash = pindex->GetBlockHash();
|
||||
{
|
||||
LOCK(cs_cache);
|
||||
LogPrintf("%s: mnhf for block %s add to cache: %lld\n", __func__, pindex->GetBlockHash().ToString(), signals.size());
|
||||
mnhfCache.insert(blockHash, signals);
|
||||
}
|
||||
m_evoDb.Write(std::make_pair(DB_SIGNALS, blockHash), signals);
|
||||
}
|
||||
|
||||
std::string MNHFTx::ToString() const
|
||||
{
|
||||
return strprintf("MNHFTx(versionBit=%d, quorumHash=%s, sig=%s)",
|
||||
|
@ -11,7 +11,14 @@
|
||||
#include <threadsafety.h>
|
||||
#include <univalue.h>
|
||||
|
||||
#include <saltedhasher.h>
|
||||
#include <unordered_map>
|
||||
#include <unordered_lru_cache.h>
|
||||
|
||||
class BlockValidationState;
|
||||
class CBlock;
|
||||
class CBlockIndex;
|
||||
class CEvoDB;
|
||||
class TxValidationState;
|
||||
extern RecursiveMutex cs_main;
|
||||
|
||||
@ -72,6 +79,45 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CMNHFManager
|
||||
{
|
||||
public:
|
||||
using Signals = std::unordered_map<uint8_t, int>;
|
||||
|
||||
private:
|
||||
CEvoDB& m_evoDb;
|
||||
|
||||
static constexpr size_t MNHFCacheSize = 1000;
|
||||
Mutex cs_cache;
|
||||
// versionBit <-> height
|
||||
unordered_lru_cache<uint256, Signals, StaticSaltedHasher> mnhfCache GUARDED_BY(cs_cache) {MNHFCacheSize};
|
||||
|
||||
public:
|
||||
explicit CMNHFManager(CEvoDB& evoDb) :
|
||||
m_evoDb(evoDb) {}
|
||||
~CMNHFManager() = default;
|
||||
|
||||
/**
|
||||
* Every new block should be processed when Tip() is updated by calling of CMNHFManager::ProcessBlock
|
||||
*/
|
||||
bool ProcessBlock(const CBlock& block, const CBlockIndex* const pindex, bool fJustCheck, BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
/**
|
||||
* Every undo block should be processed when Tip() is updated by calling of CMNHFManager::UndoBlock
|
||||
*/
|
||||
bool UndoBlock(const CBlock& block, const CBlockIndex* const pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
/**
|
||||
* Once app is started, need to initialize dictionary will all known signals at the current Tip()
|
||||
* by calling UpdateChainParams()
|
||||
*/
|
||||
void UpdateChainParams(const CBlockIndex* const pindex, const CBlockIndex* const pindexOld) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
private:
|
||||
void AddToCache(const Signals& signals, const CBlockIndex* const pindex);
|
||||
Signals GetFromCache(const CBlockIndex* const pindex);
|
||||
};
|
||||
|
||||
bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
#endif // BITCOIN_EVO_MNHFTX_H
|
||||
|
@ -122,7 +122,8 @@ static bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler,
|
||||
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager,
|
||||
llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler,
|
||||
const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots,
|
||||
BlockValidationState& state)
|
||||
{
|
||||
@ -134,6 +135,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, ll
|
||||
static int64_t nTimeDMN = 0;
|
||||
static int64_t nTimeMerkle = 0;
|
||||
static int64_t nTimeCbTxCL = 0;
|
||||
static int64_t nTimeMnehf = 0;
|
||||
|
||||
int64_t nTime1 = GetTimeMicros();
|
||||
|
||||
@ -198,6 +200,15 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, ll
|
||||
nTimeCbTxCL += nTime6 - nTime5;
|
||||
LogPrint(BCLog::BENCHMARK, " - CheckCbTxBestChainlock: %.2fms [%.2fs]\n", 0.001 * (nTime6 - nTime5), nTimeCbTxCL * 0.000001);
|
||||
|
||||
if (!mnhfManager.ProcessBlock(block, pindex, fJustCheck, state)) {
|
||||
// pass the state returned by the function above
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t nTime7 = GetTimeMicros();
|
||||
nTimeMnehf += nTime7 - nTime6;
|
||||
LogPrint(BCLog::BENCHMARK, " - mnhfManager: %.2fms [%.2fs]\n", 0.001 * (nTime7 - nTime6), nTimeMnehf * 0.000001);
|
||||
|
||||
if (Params().GetConsensus().V19Height == pindex->nHeight + 1) {
|
||||
// NOTE: The block next to the activation is the one that is using new rules.
|
||||
// V19 activated just activated, so we must switch to the new rules here.
|
||||
@ -212,7 +223,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, ll
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor)
|
||||
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager, llmq::CQuorumBlockProcessor& quorum_block_processor)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
@ -233,6 +244,10 @@ bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq:
|
||||
}
|
||||
}
|
||||
|
||||
if (!mnhfManager.UndoBlock(block, pindex)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!deterministicMNManager->UndoBlock(pindex)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ class BlockValidationState;
|
||||
class CBlock;
|
||||
class CBlockIndex;
|
||||
class CCoinsViewCache;
|
||||
class CMNHFManager;
|
||||
class TxValidationState;
|
||||
namespace llmq {
|
||||
class CQuorumBlockProcessor;
|
||||
@ -26,10 +27,12 @@ extern RecursiveMutex cs_main;
|
||||
|
||||
bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, bool check_sigs,
|
||||
TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler,
|
||||
const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots,
|
||||
BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager,
|
||||
llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler,
|
||||
const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots,
|
||||
BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager,
|
||||
llmq::CQuorumBlockProcessor& quorum_block_processor) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool CheckCreditPoolDiffForBlock(const CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams,
|
||||
const CAmount blockReward, BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
|
@ -87,6 +87,7 @@
|
||||
|
||||
#include <evo/creditpool.h>
|
||||
#include <evo/deterministicmns.h>
|
||||
#include <evo/mnhftx.h>
|
||||
#include <llmq/blockprocessor.h>
|
||||
#include <llmq/chainlocks.h>
|
||||
#include <llmq/context.h>
|
||||
@ -341,6 +342,7 @@ void PrepareShutdown(NodeContext& node)
|
||||
llmq::quorumSnapshotManager.reset();
|
||||
deterministicMNManager.reset();
|
||||
creditPoolManager.reset();
|
||||
node.mnhf_manager.reset();
|
||||
node.evodb.reset();
|
||||
}
|
||||
for (const auto& client : node.chain_clients) {
|
||||
@ -1914,9 +1916,10 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
|
||||
LOCK(cs_main);
|
||||
node.evodb.reset();
|
||||
node.evodb = std::make_unique<CEvoDB>(nEvoDbCache, false, fReset || fReindexChainState);
|
||||
node.mnhf_manager = std::make_unique<CMNHFManager>(*node.evodb);
|
||||
|
||||
chainman.Reset();
|
||||
chainman.InitializeChainstate(Assert(node.mempool.get()), *node.evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
|
||||
chainman.InitializeChainstate(Assert(node.mempool.get()), *node.mnhf_manager, *node.evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
|
||||
chainman.m_total_coinstip_cache = nCoinCacheUsage;
|
||||
chainman.m_total_coinsdb_cache = nCoinDBCache;
|
||||
|
||||
@ -2104,6 +2107,9 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
|
||||
LogPrintf("%s: bls_legacy_scheme=%d\n", __func__, bls::bls_legacy_scheme.load());
|
||||
}
|
||||
|
||||
LogPrintf("init.cpp: update chain params right after bls\n");
|
||||
node.mnhf_manager->UpdateChainParams(::ChainActive().Tip(), nullptr);
|
||||
|
||||
if (!CVerifyDB().VerifyDB(
|
||||
*chainstate, chainparams, chainstate->CoinsDB(),
|
||||
*node.evodb,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <interfaces/chain.h>
|
||||
#include <llmq/context.h>
|
||||
#include <evo/evodb.h>
|
||||
#include <evo/mnhftx.h>
|
||||
#include <net.h>
|
||||
#include <net_processing.h>
|
||||
#include <policy/fees.h>
|
||||
|
@ -20,6 +20,7 @@ class ChainstateManager;
|
||||
class CEvoDB;
|
||||
class CScheduler;
|
||||
class CTxMemPool;
|
||||
class CMNHFManager;
|
||||
class PeerManager;
|
||||
struct CJContext;
|
||||
struct LLMQContext;
|
||||
@ -60,6 +61,7 @@ struct NodeContext {
|
||||
//! Dash
|
||||
std::unique_ptr<LLMQContext> llmq_ctx;
|
||||
std::unique_ptr<CCreditPoolManager> creditPoolManager;
|
||||
std::unique_ptr<CMNHFManager> mnhf_manager;
|
||||
std::unique_ptr<CJContext> cj_ctx;
|
||||
|
||||
std::unique_ptr<CEvoDB> evodb;
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include <evo/creditpool.h>
|
||||
#include <evo/deterministicmns.h>
|
||||
#include <evo/evodb.h>
|
||||
#include <evo/mnhftx.h>
|
||||
#include <evo/specialtx.h>
|
||||
|
||||
#include <memory>
|
||||
@ -164,6 +165,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
|
||||
g_wallet_init_interface.Construct(m_node);
|
||||
fCheckBlockIndex = true;
|
||||
m_node.evodb = std::make_unique<CEvoDB>(1 << 20, true, true);
|
||||
m_node.mnhf_manager = std::make_unique<CMNHFManager>(*m_node.evodb);
|
||||
connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
|
||||
llmq::quorumSnapshotManager.reset(new llmq::CQuorumSnapshotManager(*m_node.evodb));
|
||||
creditPoolManager = std::make_unique<CCreditPoolManager>(*m_node.evodb);
|
||||
@ -180,6 +182,7 @@ BasicTestingSetup::~BasicTestingSetup()
|
||||
connman.reset();
|
||||
llmq::quorumSnapshotManager.reset();
|
||||
creditPoolManager.reset();
|
||||
m_node.mnhf_manager.reset();
|
||||
m_node.evodb.reset();
|
||||
|
||||
LogInstance().DisconnectTestLogger();
|
||||
@ -251,7 +254,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
|
||||
// instead of unit tests, but for now we need these here.
|
||||
RegisterAllCoreRPCCommands(tableRPC);
|
||||
|
||||
m_node.chainman->InitializeChainstate(m_node.mempool.get(), *m_node.evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
|
||||
m_node.chainman->InitializeChainstate(m_node.mempool.get(), *m_node.mnhf_manager, *m_node.evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
|
||||
::ChainstateActive().InitCoinsDB(
|
||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
|
||||
assert(!::ChainstateActive().CanFlushToDisk());
|
||||
|
@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
|
||||
return outp;
|
||||
};
|
||||
|
||||
CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(&mempool, *m_node.evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor));
|
||||
CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(&mempool, *m_node.mnhf_manager, *m_node.evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor));
|
||||
c1.InitCoinsDB(
|
||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
|
||||
WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));
|
||||
|
@ -42,7 +42,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
|
||||
|
||||
// Create a legacy (IBD) chainstate.
|
||||
//
|
||||
CChainState& c1 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(&mempool, evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor));
|
||||
CChainState& c1 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(&mempool, *m_node.mnhf_manager, evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor));
|
||||
chainstates.push_back(&c1);
|
||||
c1.InitCoinsDB(
|
||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
|
||||
@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
|
||||
//
|
||||
const uint256 snapshot_blockhash = GetRandHash();
|
||||
CChainState& c2 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(
|
||||
&mempool, evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor,
|
||||
&mempool, *m_node.mnhf_manager, evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor,
|
||||
snapshot_blockhash)
|
||||
);
|
||||
chainstates.push_back(&c2);
|
||||
@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
|
||||
|
||||
// Create a legacy (IBD) chainstate.
|
||||
//
|
||||
CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(&mempool, evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor));
|
||||
CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(&mempool, *m_node.mnhf_manager, evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor));
|
||||
chainstates.push_back(&c1);
|
||||
c1.InitCoinsDB(
|
||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
|
||||
@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
|
||||
|
||||
// Create a snapshot-based chainstate.
|
||||
//
|
||||
CChainState& c2 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(&mempool, evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor, GetRandHash()));
|
||||
CChainState& c2 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(&mempool, *m_node.mnhf_manager, evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor, GetRandHash()));
|
||||
chainstates.push_back(&c2);
|
||||
c2.InitCoinsDB(
|
||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
|
||||
|
@ -24,7 +24,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
|
||||
{
|
||||
CTxMemPool mempool;
|
||||
BlockManager blockman{};
|
||||
CChainState chainstate(&mempool, blockman, *m_node.evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
|
||||
CChainState chainstate(&mempool, blockman, *m_node.mnhf_manager, *m_node.evodb, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
|
||||
chainstate.InitCoinsDB(/*cache_size_bytes*/ 1 << 10, /*in_memory*/ true, /*should_wipe*/ false);
|
||||
WITH_LOCK(::cs_main, chainstate.InitCoinsCache(1 << 10));
|
||||
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include <masternode/sync.h>
|
||||
|
||||
#include <evo/evodb.h>
|
||||
#include <evo/mnhftx.h>
|
||||
#include <evo/specialtx.h>
|
||||
#include <evo/specialtxman.h>
|
||||
#include <governance/governance.h>
|
||||
@ -1260,12 +1261,14 @@ void CoinsViews::InitCache()
|
||||
|
||||
CChainState::CChainState(CTxMemPool* mempool,
|
||||
BlockManager& blockman,
|
||||
CMNHFManager& mnhfManager,
|
||||
CEvoDB& evoDb,
|
||||
const std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
|
||||
const std::unique_ptr<llmq::CInstantSendManager>& isman,
|
||||
const std::unique_ptr<llmq::CQuorumBlockProcessor>& quorum_block_processor,
|
||||
std::optional<uint256> from_snapshot_blockhash)
|
||||
: m_mempool(mempool),
|
||||
m_mnhfManager(mnhfManager),
|
||||
m_params(::Params()),
|
||||
m_clhandler(clhandler),
|
||||
m_isman(isman),
|
||||
@ -1706,7 +1709,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
|
||||
std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
|
||||
|
||||
if (!UndoSpecialTxsInBlock(block, pindex, *m_quorum_block_processor)) {
|
||||
if (!UndoSpecialTxsInBlock(block, pindex, m_mnhfManager, *m_quorum_block_processor)) {
|
||||
error("DisconnectBlock(): UndoSpecialTxsInBlock failed");
|
||||
return DISCONNECT_FAILED;
|
||||
}
|
||||
@ -2186,7 +2189,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||
bool fDIP0001Active_context = pindex->nHeight >= Params().GetConsensus().DIP0001Height;
|
||||
|
||||
// MUST process special txes before updating UTXO to ensure consistency between mempool and block processing
|
||||
if (!ProcessSpecialTxsInBlock(block, pindex, *m_quorum_block_processor, *m_clhandler, m_params.GetConsensus(), view, fJustCheck, fScriptChecks, state)) {
|
||||
if (!ProcessSpecialTxsInBlock(block, pindex, m_mnhfManager, *m_quorum_block_processor, *m_clhandler, m_params.GetConsensus(), view, fJustCheck, fScriptChecks, state)) {
|
||||
return error("ConnectBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s",
|
||||
pindex->GetBlockHash().ToString(), state.ToString());
|
||||
}
|
||||
@ -4809,7 +4812,7 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i
|
||||
|
||||
// MUST process special txes before updating UTXO to ensure consistency between mempool and block processing
|
||||
BlockValidationState state;
|
||||
if (!ProcessSpecialTxsInBlock(block, pindex, *m_quorum_block_processor, *m_clhandler, m_params.GetConsensus(), inputs, false /*fJustCheck*/, false /*fScriptChecks*/, state)) {
|
||||
if (!ProcessSpecialTxsInBlock(block, pindex, m_mnhfManager, *m_quorum_block_processor, *m_clhandler, m_params.GetConsensus(), inputs, false /*fJustCheck*/, false /*fScriptChecks*/, state)) {
|
||||
return error("RollforwardBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s",
|
||||
pindex->GetBlockHash().ToString(), state.ToString());
|
||||
}
|
||||
@ -5651,6 +5654,7 @@ std::vector<CChainState*> ChainstateManager::GetAll()
|
||||
}
|
||||
|
||||
CChainState& ChainstateManager::InitializeChainstate(CTxMemPool* mempool,
|
||||
CMNHFManager& mnhfManager,
|
||||
CEvoDB& evoDb,
|
||||
const std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
|
||||
const std::unique_ptr<llmq::CInstantSendManager>& isman,
|
||||
@ -5665,7 +5669,7 @@ CChainState& ChainstateManager::InitializeChainstate(CTxMemPool* mempool,
|
||||
throw std::logic_error("should not be overwriting a chainstate");
|
||||
}
|
||||
|
||||
to_modify.reset(new CChainState(mempool, m_blockman, evoDb, clhandler, isman, quorum_block_processor, snapshot_blockhash));
|
||||
to_modify.reset(new CChainState(mempool, m_blockman, mnhfManager, evoDb, clhandler, isman, quorum_block_processor, snapshot_blockhash));
|
||||
|
||||
// Snapshot chainstates and initial IBD chaintates always become active.
|
||||
if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {
|
||||
@ -5735,9 +5739,13 @@ bool ChainstateManager::ActivateSnapshot(
|
||||
}
|
||||
|
||||
auto snapshot_chainstate = WITH_LOCK(::cs_main, return std::make_unique<CChainState>(
|
||||
/* mempool */ nullptr, m_blockman, this->ActiveChainstate().m_evoDb,
|
||||
this->ActiveChainstate().m_clhandler, this->ActiveChainstate().m_isman,
|
||||
this->ActiveChainstate().m_quorum_block_processor, base_blockhash
|
||||
/* mempool */ nullptr, m_blockman,
|
||||
this->ActiveChainstate().m_mnhfManager,
|
||||
this->ActiveChainstate().m_evoDb,
|
||||
this->ActiveChainstate().m_clhandler,
|
||||
this->ActiveChainstate().m_isman,
|
||||
this->ActiveChainstate().m_quorum_block_processor,
|
||||
base_blockhash
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -56,6 +56,7 @@ class CChainParams;
|
||||
struct CCheckpointData;
|
||||
class CInv;
|
||||
class CConnman;
|
||||
class CMNHFManager;
|
||||
class CScriptCheck;
|
||||
class CTxMemPool;
|
||||
class TxValidationState;
|
||||
@ -584,6 +585,7 @@ private:
|
||||
const std::unique_ptr<llmq::CChainLocksHandler>& m_clhandler;
|
||||
const std::unique_ptr<llmq::CInstantSendManager>& m_isman;
|
||||
const std::unique_ptr<llmq::CQuorumBlockProcessor>& m_quorum_block_processor;
|
||||
CMNHFManager& m_mnhfManager;
|
||||
CEvoDB& m_evoDb;
|
||||
|
||||
public:
|
||||
@ -593,6 +595,7 @@ public:
|
||||
|
||||
explicit CChainState(CTxMemPool* mempool,
|
||||
BlockManager& blockman,
|
||||
CMNHFManager& mnhfManager,
|
||||
CEvoDB& evoDb,
|
||||
const std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
|
||||
const std::unique_ptr<llmq::CInstantSendManager>& isman,
|
||||
@ -940,6 +943,7 @@ public:
|
||||
//! @param[in] snapshot_blockhash If given, signify that this chainstate
|
||||
//! is based on a snapshot.
|
||||
CChainState& InitializeChainstate(CTxMemPool* mempool,
|
||||
CMNHFManager& mnhfManager,
|
||||
CEvoDB& evoDb,
|
||||
const std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
|
||||
const std::unique_ptr<llmq::CInstantSendManager>& isman,
|
||||
|
@ -104,6 +104,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
|
||||
"llmq/debug -> llmq/dkgsessionhandler -> llmq/debug"
|
||||
"llmq/debug -> llmq/dkgsessionhandler -> llmq/dkgsession -> llmq/debug"
|
||||
"llmq/utils -> validation -> llmq/utils"
|
||||
"evo/mnhftx -> validation -> evo/mnhftx"
|
||||
)
|
||||
|
||||
EXIT_CODE=0
|
||||
|
Loading…
Reference in New Issue
Block a user