From 080496aefdac21f2ffc800f6d0b47d5a85feaa06 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 11 Mar 2026 17:38:46 +0700 Subject: [PATCH 1/4] refactor: new stub implementation (NullNodeSyncNotifier) of NodeSyncNotifier is introduced to use it for CChainState --- src/masternode/sync.cpp | 5 +++++ src/masternode/sync.h | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/masternode/sync.cpp b/src/masternode/sync.cpp index 2b69c71cb47d..e367a24e3e27 100644 --- a/src/masternode/sync.cpp +++ b/src/masternode/sync.cpp @@ -9,6 +9,11 @@ #include #include +#include + +void NullNodeSyncNotifier::SyncReset() { assert(false); } +void NullNodeSyncNotifier::SyncFinished() { assert(false); } + CMasternodeSync::CMasternodeSync(std::unique_ptr&& sync_notifier) : nTimeAssetSyncStarted{GetTime()}, nTimeLastBumped{GetTime()}, diff --git a/src/masternode/sync.h b/src/masternode/sync.h index 247d8d0ff889..98401982727e 100644 --- a/src/masternode/sync.h +++ b/src/masternode/sync.h @@ -32,6 +32,20 @@ class NodeSyncNotifier virtual ~NodeSyncNotifier() = default; }; +/** Stub implementation for use in chainstate-only (non-network) contexts. + * CMasternodeSync constructed with this notifier permanently returns + * IsBlockchainSynced()=false and IsSynced()=false, which correctly disables + * network-dependent validation paths. + * + * Asserts on any call — if sync state is being advanced, a real notifier + * (NodeSyncNotifierImpl) must be used instead. */ +class NullNodeSyncNotifier final : public NodeSyncNotifier +{ +public: + void SyncReset() override; + void SyncFinished() override; +}; + // // CMasternodeSync : Sync masternode assets in stages // From 613304be6bd08c34eae11cfd863ac7e6feddbdcc Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 13 May 2026 02:59:09 +0700 Subject: [PATCH 2/4] refactor: move network code from llmq/utils to llmq/net_quorum --- src/active/dkgsessionhandler.cpp | 50 ++++++++++++- src/active/dkgsessionhandler.h | 1 + src/llmq/net_quorum.cpp | 73 ++++++++++++++++++- src/llmq/net_quorum.h | 6 ++ src/llmq/utils.cpp | 117 ------------------------------- src/llmq/utils.h | 11 --- 6 files changed, 127 insertions(+), 131 deletions(-) diff --git a/src/active/dkgsessionhandler.cpp b/src/active/dkgsessionhandler.cpp index 9b796d796516..54cb101184fa 100644 --- a/src/active/dkgsessionhandler.cpp +++ b/src/active/dkgsessionhandler.cpp @@ -10,8 +10,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -423,6 +425,50 @@ bool ProcessPendingMessageBatch(const CConnman& connman, CDKGSession& session, C return true; } +static void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CMasternodeMetaMan& mn_metaman, + const CSporkManager& sporkman, const UtilParameters& util_params, + const CDeterministicMNList& tip_mn_list, const uint256& myProTxHash) +{ + assert(mn_metaman.IsValid()); + + if (!IsQuorumPoseEnabled(llmqParams.type, sporkman)) { + return; + } + + auto members = utils::GetAllQuorumMembers(llmqParams.type, util_params); + auto curTime = GetTime().count(); + + Uint256HashSet probeConnections; + for (const auto& dmn : members) { + if (dmn->proTxHash == myProTxHash) { + continue; + } + auto lastOutbound = mn_metaman.GetLastOutboundSuccess(dmn->proTxHash); + if (curTime - lastOutbound < 10 * 60) { + // avoid re-probing nodes too often + continue; + } + probeConnections.emplace(dmn->proTxHash); + } + + if (!probeConnections.empty()) { + if (LogAcceptDebug(BCLog::LLMQ)) { + std::string debugMsg = strprintf("%s -- adding masternodes probes for quorum %s:\n", __func__, + util_params.m_base_index->GetBlockHash().ToString()); + for (const auto& c : probeConnections) { + auto dmn = tip_mn_list.GetValidMN(c); + if (!dmn) { + debugMsg += strprintf(" %s (not in valid MN set anymore)\n", c.ToString()); + } else { + debugMsg += strprintf(" %s (%s)\n", c.ToString(), + dmn->pdmnState->netInfo->GetPrimary().ToStringAddrPort()); + } + } + LogPrint(BCLog::NET_NETCONN, debugMsg.c_str()); /* Continued */ + } + connman.AddPendingProbeConnections(probeConnections); + } +} void ActiveDKGSessionHandler::HandleDKGRound(CConnman& connman, PeerManager& peerman) { WaitForNextPhase(std::nullopt, QuorumPhase::Initialized); @@ -460,10 +506,10 @@ void ActiveDKGSessionHandler::HandleDKGRound(CConnman& connman, PeerManager& pee } const auto tip_mn_list = m_dmnman.GetListAtChainTip(); - utils::EnsureQuorumConnections(params, connman, m_sporkman, {m_dmnman, m_qsnapman, m_chainman, pQuorumBaseBlockIndex}, + llmq::EnsureQuorumConnections(params, connman, m_sporkman, {m_dmnman, m_qsnapman, m_chainman, pQuorumBaseBlockIndex}, tip_mn_list, curSession->ProTx(), /*is_masternode=*/true, m_quorums_watch); if (curSession->AreWeMember()) { - utils::AddQuorumProbeConnections(params, connman, m_mn_metaman, m_sporkman, + AddQuorumProbeConnections(params, connman, m_mn_metaman, m_sporkman, {m_dmnman, m_qsnapman, m_chainman, pQuorumBaseBlockIndex}, tip_mn_list, curSession->ProTx()); } diff --git a/src/active/dkgsessionhandler.h b/src/active/dkgsessionhandler.h index 845a50d74461..e5c51bca5af1 100644 --- a/src/active/dkgsessionhandler.h +++ b/src/active/dkgsessionhandler.h @@ -113,6 +113,7 @@ class ActiveDKGSessionHandler final : public llmq::CDKGSessionHandler void HandleDKGRound(CConnman& connman, PeerManager& peerman) EXCLUSIVE_LOCKS_REQUIRED(!cs_phase_qhash); void PhaseHandlerThread(CConnman& connman, PeerManager& peerman) EXCLUSIVE_LOCKS_REQUIRED(!cs_phase_qhash); }; + } // namespace llmq #endif // BITCOIN_ACTIVE_DKGSESSIONHANDLER_H diff --git a/src/llmq/net_quorum.cpp b/src/llmq/net_quorum.cpp index 1f255c78296e..a5eafb8be4fd 100644 --- a/src/llmq/net_quorum.cpp +++ b/src/llmq/net_quorum.cpp @@ -394,7 +394,7 @@ void NetQuorum::CheckQuorumConnections(const Consensus::LLMQParams& llmqParams, std::ranges::any_of(lastQuorums, [&proTxHash](const auto& old_quorum) { return old_quorum->IsMember(proTxHash); }); for (const auto& quorum : lastQuorums) { - if (utils::EnsureQuorumConnections(llmqParams, m_connman, m_sporkman, + if (EnsureQuorumConnections(llmqParams, m_connman, m_sporkman, {m_dmnman, m_qsnapman, m_chainman, quorum->m_quorum_base_block_index}, m_dmnman.GetListAtChainTip(), proTxHash, /*is_masternode=*/is_masternode, @@ -708,4 +708,75 @@ void NetQuorum::StartCleanupOldQuorumDataThread(gsl::not_nullproTxHash == myProTxHash; }) != + members.end(); + + if (!isMember && !quorums_watch) { + return false; + } + + LogPrint(BCLog::NET_NETCONN, "%s -- isMember=%d for quorum %s:\n", __func__, isMember, + util_params.m_base_index->GetBlockHash().ToString()); + + Uint256HashSet connections; + Uint256HashSet relayMembers; + if (isMember) { + connections = utils::GetQuorumConnections(llmqParams, sporkman, util_params, myProTxHash, /*onlyOutbound=*/true); + // If all-members-connected is enabled for this quorum type, leverage the full-mesh + // connections for low-latency recovered sig propagation by treating all members as + // relay members (instead of the ring-based subset). This ensures peers will send + // QSENDRECSIGS to each other across the full mesh and set m_wants_recsigs widely. + if (IsAllMembersConnectedEnabled(llmqParams.type, sporkman)) { + for (const auto& dmn : members) { + if (dmn->proTxHash != myProTxHash) { + relayMembers.emplace(dmn->proTxHash); + } + } + } else { + relayMembers = utils::GetQuorumRelayMembers(llmqParams, util_params, myProTxHash, true); + } + } else { + auto cindexes = utils::CalcDeterministicWatchConnections(llmqParams.type, util_params.m_base_index, members.size(), 1); + for (auto idx : cindexes) { + connections.emplace(members[idx]->proTxHash); + } + relayMembers = connections; + } + if (!connections.empty()) { + if (!connman.HasMasternodeQuorumNodes(llmqParams.type, util_params.m_base_index->GetBlockHash()) && + LogAcceptDebug(BCLog::LLMQ)) { + std::string debugMsg = strprintf("%s -- adding masternodes quorum connections for quorum %s:\n", __func__, + util_params.m_base_index->GetBlockHash().ToString()); + for (const auto& c : connections) { + auto dmn = tip_mn_list.GetValidMN(c); + if (!dmn) { + debugMsg += strprintf(" %s (not in valid MN set anymore)\n", c.ToString()); + } else { + debugMsg += strprintf(" %s (%s)\n", c.ToString(), + dmn->pdmnState->netInfo->GetPrimary().ToStringAddrPort()); + } + } + LogPrint(BCLog::NET_NETCONN, debugMsg.c_str()); /* Continued */ + } + connman.SetMasternodeQuorumNodes(llmqParams.type, util_params.m_base_index->GetBlockHash(), connections); + } + if (!relayMembers.empty()) { + connman.SetMasternodeQuorumRelayMembers(llmqParams.type, util_params.m_base_index->GetBlockHash(), relayMembers); + } + return true; +} + } // namespace llmq diff --git a/src/llmq/net_quorum.h b/src/llmq/net_quorum.h index 8b48f1e743c8..4e5f91749b99 100644 --- a/src/llmq/net_quorum.h +++ b/src/llmq/net_quorum.h @@ -32,6 +32,7 @@ namespace llmq { class CQuorumManager; class CQuorumSnapshotManager; class QuorumRole; +struct UtilParameters; } // namespace llmq namespace llmq { @@ -122,6 +123,11 @@ class NetQuorum final : public NetHandler, public CValidationInterface mutable ctpl::thread_pool workerPool; mutable CThreadInterrupt quorumThreadInterrupt; }; + +bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, const CSporkManager& sporkman, + const UtilParameters& util_params, const CDeterministicMNList& tip_mn_list, + const uint256& myProTxHash, bool is_masternode, bool quorums_watch); + } // namespace llmq #endif // BITCOIN_LLMQ_NET_QUORUM_H diff --git a/src/llmq/utils.cpp b/src/llmq/utils.cpp index 9648c3d009e9..33dad50279c8 100644 --- a/src/llmq/utils.cpp +++ b/src/llmq/utils.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -23,7 +22,6 @@ #include #include #include -#include /** * Forward declarations @@ -777,120 +775,5 @@ std::unordered_set CalcDeterministicWatchConnections(Consensus::LLMQType return result; } -bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, const CSporkManager& sporkman, - const UtilParameters& util_params, const CDeterministicMNList& tip_mn_list, - const uint256& myProTxHash, bool is_masternode, bool quorums_watch) -{ - if (!is_masternode && !quorums_watch) { - return false; - } - - auto members = GetAllQuorumMembers(llmqParams.type, util_params); - if (members.empty()) { - return false; - } - - bool isMember = std::ranges::find_if(members, [&](const auto& dmn) { return dmn->proTxHash == myProTxHash; }) != - members.end(); - - if (!isMember && !quorums_watch) { - return false; - } - - LogPrint(BCLog::NET_NETCONN, "%s -- isMember=%d for quorum %s:\n", __func__, isMember, - util_params.m_base_index->GetBlockHash().ToString()); - - Uint256HashSet connections; - Uint256HashSet relayMembers; - if (isMember) { - connections = GetQuorumConnections(llmqParams, sporkman, util_params, myProTxHash, /*onlyOutbound=*/true); - // If all-members-connected is enabled for this quorum type, leverage the full-mesh - // connections for low-latency recovered sig propagation by treating all members as - // relay members (instead of the ring-based subset). This ensures peers will send - // QSENDRECSIGS to each other across the full mesh and set m_wants_recsigs widely. - if (IsAllMembersConnectedEnabled(llmqParams.type, sporkman)) { - for (const auto& dmn : members) { - if (dmn->proTxHash != myProTxHash) { - relayMembers.emplace(dmn->proTxHash); - } - } - } else { - relayMembers = GetQuorumRelayMembers(llmqParams, util_params, myProTxHash, true); - } - } else { - auto cindexes = CalcDeterministicWatchConnections(llmqParams.type, util_params.m_base_index, members.size(), 1); - for (auto idx : cindexes) { - connections.emplace(members[idx]->proTxHash); - } - relayMembers = connections; - } - if (!connections.empty()) { - if (!connman.HasMasternodeQuorumNodes(llmqParams.type, util_params.m_base_index->GetBlockHash()) && - LogAcceptDebug(BCLog::LLMQ)) { - std::string debugMsg = strprintf("%s -- adding masternodes quorum connections for quorum %s:\n", __func__, - util_params.m_base_index->GetBlockHash().ToString()); - for (const auto& c : connections) { - auto dmn = tip_mn_list.GetValidMN(c); - if (!dmn) { - debugMsg += strprintf(" %s (not in valid MN set anymore)\n", c.ToString()); - } else { - debugMsg += strprintf(" %s (%s)\n", c.ToString(), - dmn->pdmnState->netInfo->GetPrimary().ToStringAddrPort()); - } - } - LogPrint(BCLog::NET_NETCONN, debugMsg.c_str()); /* Continued */ - } - connman.SetMasternodeQuorumNodes(llmqParams.type, util_params.m_base_index->GetBlockHash(), connections); - } - if (!relayMembers.empty()) { - connman.SetMasternodeQuorumRelayMembers(llmqParams.type, util_params.m_base_index->GetBlockHash(), relayMembers); - } - return true; -} - -void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CMasternodeMetaMan& mn_metaman, - const CSporkManager& sporkman, const UtilParameters& util_params, - const CDeterministicMNList& tip_mn_list, const uint256& myProTxHash) -{ - assert(mn_metaman.IsValid()); - - if (!IsQuorumPoseEnabled(llmqParams.type, sporkman)) { - return; - } - - auto members = GetAllQuorumMembers(llmqParams.type, util_params); - auto curTime = GetTime().count(); - - Uint256HashSet probeConnections; - for (const auto& dmn : members) { - if (dmn->proTxHash == myProTxHash) { - continue; - } - auto lastOutbound = mn_metaman.GetLastOutboundSuccess(dmn->proTxHash); - if (curTime - lastOutbound < 10 * 60) { - // avoid re-probing nodes too often - continue; - } - probeConnections.emplace(dmn->proTxHash); - } - - if (!probeConnections.empty()) { - if (LogAcceptDebug(BCLog::LLMQ)) { - std::string debugMsg = strprintf("%s -- adding masternodes probes for quorum %s:\n", __func__, - util_params.m_base_index->GetBlockHash().ToString()); - for (const auto& c : probeConnections) { - auto dmn = tip_mn_list.GetValidMN(c); - if (!dmn) { - debugMsg += strprintf(" %s (not in valid MN set anymore)\n", c.ToString()); - } else { - debugMsg += strprintf(" %s (%s)\n", c.ToString(), - dmn->pdmnState->netInfo->GetPrimary().ToStringAddrPort()); - } - } - LogPrint(BCLog::NET_NETCONN, debugMsg.c_str()); /* Continued */ - } - connman.AddPendingProbeConnections(probeConnections); - } -} } // namespace utils } // namespace llmq diff --git a/src/llmq/utils.h b/src/llmq/utils.h index 2f839dc16810..4e755c9c6257 100644 --- a/src/llmq/utils.h +++ b/src/llmq/utils.h @@ -20,11 +20,8 @@ #include class CBlockIndex; -class CConnman; -class CDeterministicMNList; class CDeterministicMNManager; class ChainstateManager; -class CMasternodeMetaMan; class CSporkManager; namespace llmq { class CQuorumSnapshotManager; @@ -76,14 +73,6 @@ Uint256HashSet GetQuorumConnections(const Consensus::LLMQParams& llmqParams, con Uint256HashSet GetQuorumRelayMembers(const Consensus::LLMQParams& llmqParams, const UtilParameters& util_params, const uint256& forMember, bool onlyOutbound); -bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, const CSporkManager& sporkman, - const UtilParameters& util_params, const CDeterministicMNList& tip_mn_list, - const uint256& myProTxHash, bool is_masternode, bool quorums_watch); - -void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CMasternodeMetaMan& mn_metaman, - const CSporkManager& sporkman, const UtilParameters& util_params, - const CDeterministicMNList& tip_mn_list, const uint256& myProTxHash); - template inline void InitQuorumsCache(CacheType& cache, const Consensus::Params& consensus_params, bool limit_by_connections = true) { From 98c76869149fec00ffc8e7f208d8ea7c5f7227ca Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 3 Mar 2022 19:31:14 +0000 Subject: [PATCH 3/4] Merge bitcoin/bitcoin#24304: [kernel 0/n] Introduce `bitcoin-chainstate` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BACKPORT NOTES: - UpdateUncommittedBlockStructures is segwit related; omitted from bitcoin-chainstate.cpp - call chainman.UnloadBlockIndex is removed by bitcoin#22564 - binary name is renamed from bitcoin-chainstate to dash-chainstate. Names of source files and some variables are untouched - added LIBDASHBLS to list of libraries to link - couple functions are reimplemented to avoid balooning dash-chainstate by including extra heavy depenencies - ValueFromAmount (reimplemented, core_write.cpp) - GetPrettyExceptionStr (reimplemented, stacktrackes.cpp) - g_stats_client (redefined) There are several modules that should be removed in the near future from dash-chainstate binary - protocol.cpp move NetMsgType inline helpers out of chainlock/clsig.h, governance/object.h, evo/simplifiedmns.h into their .cpp files - llmq/dkgsession.cpp, llmq/dkgsessionhandler.cpp, llmq/dkgsessionmgr.cpp, llmq/debug.cpp, batchedlogger.cpp CQuorumManager already null-guards m_qdkgsman; drop once ConnectManagers() is never called on the kernel side - llmq/signing.cpp split CSigningManager out of LLMQContext into a post-construction Connect() so the context becomes quorum-only - governance/*.cpp promote the 4 methods used by CMNPaymentsProcessor (IsValid, IsSuperblockTriggered, IsValidSuperblock, GetSuperblockPayments) to a base interface; instantiate a NullGovernanceManager in bitcoin-chainstate.cpp ORIGINAL PR Description: 2c03cec2ff8cdbfd5da92bfb507d218e5c6435b0 ci: Build bitcoin-chainstate (Carl Dong) 095aa6ca37bf0bd5c5e221bab779978a99b2a34c build: Add example bitcoin-chainstate executable (Carl Dong) Pull request description: Part of: #24303 This PR introduces an example/demo `bitcoin-chainstate` executable using said library which can print out information about a datadir and take in new blocks on stdin. Please read the commit messages for more details. ----- #### You may ask: WTF?! Why is `index/*.cpp`, etc. being linked in? This PR is meant only to capture the state of dependencies in our consensus engine as of right now. There are many things to decouple from consensus, which will be done in subsequent PRs. Listing the files out right now in `bitcoin_chainstate_SOURCES` is purely to give us a clear picture of the task at hand, it is **not** to say that these dependencies _belongs_ there in any way. ### TODO 1. Clean up `bitcoin-chainstate.cpp` It is quite ugly, with a lot of comments I've left for myself, I should clean it up to the best of my abilities (the ugliness of our init/shutdown might be the upper bound on cleanliness here...) ACKs for top commit: ajtowns: ACK 2c03cec2ff8cdbfd5da92bfb507d218e5c6435b0 ryanofsky: Code review ACK 2c03cec2ff8cdbfd5da92bfb507d218e5c6435b0. Just rebase, comments, formatting change since last review MarcoFalke: re-ACK 2c03cec2ff8cdbfd5da92bfb507d218e5c6435b0 🏔 Tree-SHA512: 86e7fb5718caa577df8abc8288c754f4a590650d974df9d2f6476c87ed25c70f923c4db651c6963f33498fc7a3a31f6692b9a75cbc996bf4888c5dac2f34a13b --- .gitignore | 1 + ci/dash/matrix.sh | 2 +- ...p_env_native_nowallet_libbitcoinkernel.sh} | 4 +- configure.ac | 14 + src/Makefile.am | 161 +++++++++ src/bitcoin-chainstate.cpp | 330 ++++++++++++++++++ 6 files changed, 509 insertions(+), 3 deletions(-) rename ci/test/{00_setup_env_native_nowallet.sh => 00_setup_env_native_nowallet_libbitcoinkernel.sh} (81%) create mode 100644 src/bitcoin-chainstate.cpp diff --git a/.gitignore b/.gitignore index be9ddf9c6069..eab9f3f83ec1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ src/dash-gui src/dash-node src/dash-tx src/dash-util +src/dash-chainstate src/dash-wallet src/test/fuzz/fuzz src/test/test_dash diff --git a/ci/dash/matrix.sh b/ci/dash/matrix.sh index 6e249fc476d1..de01eaf6d6c7 100755 --- a/ci/dash/matrix.sh +++ b/ci/dash/matrix.sh @@ -27,7 +27,7 @@ elif [ "$BUILD_TARGET" = "linux64_fuzz" ]; then elif [ "$BUILD_TARGET" = "linux64_multiprocess" ]; then source ./ci/test/00_setup_env_native_multiprocess.sh elif [ "$BUILD_TARGET" = "linux64_nowallet" ]; then - source ./ci/test/00_setup_env_native_nowallet.sh + source ./ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh elif [ "$BUILD_TARGET" = "linux64_sqlite" ]; then source ./ci/test/00_setup_env_native_sqlite.sh elif [ "$BUILD_TARGET" = "linux64_tsan" ]; then diff --git a/ci/test/00_setup_env_native_nowallet.sh b/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh similarity index 81% rename from ci/test/00_setup_env_native_nowallet.sh rename to ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh index 3e083c3d4d62..ef228c677fef 100755 --- a/ci/test/00_setup_env_native_nowallet.sh +++ b/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh @@ -6,9 +6,9 @@ export LC_ALL=C.UTF-8 -export CONTAINER_NAME=ci_native_nowallet +export CONTAINER_NAME=ci_native_nowallet_libbitcoinkernel export HOST=x86_64-pc-linux-gnu export PACKAGES="python3-zmq" export DEP_OPTS="NO_WALLET=1 CC=gcc-14 CXX=g++-14" export GOAL="install" -export BITCOIN_CONFIG="--enable-reduce-exports CC=gcc-14 CXX=g++-14" +export BITCOIN_CONFIG="--enable-reduce-exports CC=gcc-14 CXX=g++-14 --enable-experimental-util-chainstate" diff --git a/configure.ac b/configure.ac index 215b797f544c..19b30c8bacf3 100644 --- a/configure.ac +++ b/configure.ac @@ -35,6 +35,7 @@ BITCOIN_TEST_NAME=test_dash BITCOIN_CLI_NAME=dash-cli BITCOIN_TX_NAME=dash-tx BITCOIN_UTIL_NAME=dash-util +BITCOIN_CHAINSTATE_NAME=dash-chainstate BITCOIN_WALLET_TOOL_NAME=dash-wallet dnl Multi Process BITCOIN_MP_NODE_NAME=dash-node @@ -769,6 +770,13 @@ AC_ARG_ENABLE([util-util], [build_bitcoin_util=$enableval], [build_bitcoin_util=$build_bitcoin_utils]) +AC_ARG_ENABLE([experimental-util-chainstate], + [AS_HELP_STRING([--enable-experimental-util-chainstate], + [build experimental dash-chainstate executable (default=no)])], + [build_bitcoin_chainstate=$enableval], + [build_bitcoin_chainstate=no]) + + AC_ARG_WITH([libs], [AS_HELP_STRING([--with-libs], [build libraries (default=yes)])], @@ -1443,6 +1451,7 @@ if test "$enable_fuzz" = "yes"; then build_bitcoin_cli=no build_bitcoin_tx=no build_bitcoin_util=no + build_bitcoin_chainstate=no build_bitcoin_wallet=no build_bitcoind=no build_bitcoin_libs=no @@ -1781,6 +1790,10 @@ AC_MSG_CHECKING([whether to build dash-util]) AM_CONDITIONAL([BUILD_BITCOIN_UTIL], [test $build_bitcoin_util = "yes"]) AC_MSG_RESULT($build_bitcoin_util) +AC_MSG_CHECKING([whether to build experimental dash-chainstate]) +AM_CONDITIONAL([BUILD_BITCOIN_CHAINSTATE], [test $build_bitcoin_chainstate = "yes"]) +AC_MSG_RESULT($build_bitcoin_chainstate) + AC_MSG_CHECKING([whether to build libraries]) AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test $build_bitcoin_libs = "yes"]) if test "$build_bitcoin_libs" = "yes"; then @@ -1995,6 +2008,7 @@ AC_SUBST(BITCOIN_TEST_NAME) AC_SUBST(BITCOIN_CLI_NAME) AC_SUBST(BITCOIN_TX_NAME) AC_SUBST(BITCOIN_UTIL_NAME) +AC_SUBST(BITCOIN_CHAINSTATE_NAME) AC_SUBST(BITCOIN_WALLET_TOOL_NAME) AC_SUBST(BITCOIN_MP_NODE_NAME) AC_SUBST(BITCOIN_MP_GUI_NAME) diff --git a/src/Makefile.am b/src/Makefile.am index a0eca537b48d..66f1f9f6ae97 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -148,6 +148,10 @@ if BUILD_BITCOIN_UTIL bin_PROGRAMS += dash-util endif +if BUILD_BITCOIN_CHAINSTATE + bin_PROGRAMS += dash-chainstate +endif + .PHONY: FORCE check-symbols check-security # dash core # BITCOIN_CORE_H = \ @@ -1156,6 +1160,163 @@ dash_util_LDADD = \ $(BACKTRACE_LIBS) dash_util_LDADD += $(BOOST_LIBS) + +# dash-chainstate binary # +dash_chainstate_SOURCES = \ + bitcoin-chainstate.cpp \ + addressindex.cpp \ + arith_uint256.cpp \ + base58.cpp \ + batchedlogger.cpp \ + bech32.cpp \ + blockfilter.cpp \ + bls/bls.cpp \ + bls/bls_worker.cpp \ + chain.cpp \ + chainparamsbase.cpp \ + chainparams.cpp \ + clientversion.cpp \ + coins.cpp \ + compressor.cpp \ + chainlock/clsig.cpp \ + chainlock/chainlock.cpp \ + consensus/merkle.cpp \ + consensus/tx_check.cpp \ + consensus/tx_verify.cpp \ + common/bloom.cpp \ + core_read.cpp \ + dbwrapper.cpp \ + deploymentinfo.cpp \ + deploymentstatus.cpp \ + evo/assetlocktx.cpp \ + evo/cbtx.cpp \ + evo/creditpool.cpp \ + evo/chainhelper.cpp \ + evo/deterministicmns.cpp \ + evo/dmnstate.cpp \ + evo/evodb.cpp \ + evo/netinfo.cpp \ + evo/mnhftx.cpp \ + evo/providertx.cpp \ + evo/simplifiedmns.cpp \ + evo/smldiff.cpp \ + evo/specialtx.cpp \ + evo/specialtx_filter.cpp \ + evo/specialtxman.cpp \ + flatfile.cpp \ + fs.cpp \ + governance/classes.cpp \ + governance/common.cpp \ + governance/exceptions.cpp \ + governance/governance.cpp \ + governance/object.cpp \ + governance/validators.cpp \ + governance/vote.cpp \ + governance/votedb.cpp \ + gsl/assert.cpp \ + hash.cpp \ + index/base.cpp \ + index/blockfilterindex.cpp \ + index/coinstatsindex.cpp \ + index/txindex.cpp \ + instantsend/db.cpp \ + instantsend/instantsend.cpp \ + init/common.cpp \ + key.cpp \ + key_io.cpp \ + llmq/blockprocessor.cpp \ + llmq/commitment.cpp \ + llmq/context.cpp \ + llmq/debug.cpp \ + llmq/dkgsession.cpp \ + llmq/dkgsessionhandler.cpp \ + llmq/dkgsessionmgr.cpp \ + llmq/options.cpp \ + llmq/quorums.cpp \ + llmq/quorumsman.cpp \ + llmq/signhash.cpp \ + llmq/signing.cpp \ + llmq/snapshot.cpp \ + llmq/utils.cpp \ + logging.cpp \ + netaddress.cpp \ + netbase.cpp \ + node/blockstorage.cpp \ + node/chainstate.cpp \ + node/transaction.cpp \ + kernel/coinstats.cpp \ + masternode/meta.cpp \ + masternode/payments.cpp \ + masternode/sync.cpp \ + messagesigner.cpp \ + merkleblock.cpp \ + node/interface_ui.cpp \ + policy/feerate.cpp \ + policy/fees.cpp \ + policy/packages.cpp \ + policy/policy.cpp \ + policy/settings.cpp \ + pow.cpp \ + protocol.cpp \ + primitives/block.cpp \ + primitives/transaction.cpp \ + pubkey.cpp \ + random.cpp \ + randomenv.cpp \ + saltedhasher.cpp \ + scheduler.cpp \ + script/interpreter.cpp \ + script/script.cpp \ + script/script_error.cpp \ + script/sigcache.cpp \ + script/standard.cpp \ + spork.cpp \ + shutdown.cpp \ + support/cleanse.cpp \ + support/lockedpool.cpp \ + sync.cpp \ + timedata.cpp \ + txdb.cpp \ + txmempool.cpp \ + uint256.cpp \ + util/asmap.cpp \ + util/bytevectorhash.cpp \ + util/check.cpp \ + util/getuniquepath.cpp \ + util/hasher.cpp \ + util/message.cpp \ + util/moneystr.cpp \ + util/ranges_set.cpp \ + util/serfloat.cpp \ + util/settings.cpp \ + util/sock.cpp \ + util/string.cpp \ + util/strencodings.cpp \ + util/syserror.cpp \ + util/system.cpp \ + util/thread.cpp \ + util/threadinterrupt.cpp \ + util/threadnames.cpp \ + util/time.cpp \ + util/tokenpipe.cpp \ + validation.cpp \ + validationinterface.cpp \ + versionbits.cpp \ + warnings.cpp +dash_chainstate_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +dash_chainstate_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +dash_chainstate_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) +dash_chainstate_LDADD = \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBUNIVALUE) \ + $(LIBSECP256K1) \ + $(LIBDASHBLS) \ + $(LIBLEVELDB) \ + $(LIBMEMENV) + +# Required for obj/build.h to be generated first. +# More details: https://www.gnu.org/software/automake/manual/html_node/Built-Sources-Example.html +dash_chainstate-clientversion.$(OBJEXT): obj/build.h # # dashconsensus library # diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp new file mode 100644 index 000000000000..60ad1d1f7866 --- /dev/null +++ b/src/bitcoin-chainstate.cpp @@ -0,0 +1,330 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// +// The bitcoin-chainstate executable serves to surface the dependencies required +// by a program wishing to use Bitcoin Core's consensus engine as it is right +// now. +// +// DEVELOPER NOTE: Since this is a "demo-only", experimental, etc. executable, +// it may diverge from Bitcoin Core's coding style. +// +// It is part of the libbitcoinkernel project. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include