From f4e6aa2ce5bafa73fb57c547671238ef5cbc5414 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Tue, 18 Aug 2026 02:10:03 +0700 Subject: [PATCH 1/9] test: merge multiple core_write instances to one module for circular dependency linter Division of core_write to submodules in evo/, llmq/, governance/ split out evo, llmq, governance code and potentially is useful to reduce binaries size ; for instance the binary dash-tx links only libbitcoin_common + consensus/util so main core_write should not have governance/ code. This commit is fixing linter's bug and adds suppressions for existing circular dependencies. --- contrib/devtools/circular-dependencies.py | 3 +++ test/lint/lint-circular-dependencies.py | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/contrib/devtools/circular-dependencies.py b/contrib/devtools/circular-dependencies.py index a6cdc343d5cb..e3ce1e4bcf6f 100755 --- a/contrib/devtools/circular-dependencies.py +++ b/contrib/devtools/circular-dependencies.py @@ -11,6 +11,9 @@ MAPPING = { 'core_read.cpp': 'core_io.cpp', 'core_write.cpp': 'core_io.cpp', + 'evo/core_write.cpp': 'core_io.cpp', + 'governance/core_write.cpp': 'core_io.cpp', + 'llmq/core_write.cpp': 'core_io.cpp', } # Directories with header-based modules, where the assumption that .cpp files diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index 13d3b388c268..524e3b07d2e0 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -29,11 +29,16 @@ ) EXPECTED_DASH_CIRCULAR_DEPENDENCIES = ( + "core_io -> evo/smldiff -> core_io", + "core_io -> governance/governance -> governance/superblock -> core_io", + "coinjoin/coinjoin -> core_io -> rpc/util -> node/transaction -> net_processing -> coinjoin/coinjoin", + "coinjoin/coinjoin -> core_io -> rpc/util -> node/transaction -> node/context -> coinjoin/coinjoin", + "coinjoin/client -> core_io -> rpc/util -> node/transaction -> net_processing -> coinjoin/walletman -> coinjoin/client", + "coinjoin/coinjoin -> core_io -> rpc/util -> node/transaction -> node/context -> dsnotificationinterface -> coinjoin/coinjoin", "index/addressindex -> index/base -> node/context -> index/addressindex", "index/base -> node/context -> index/spentindex -> index/base", "index/base -> node/context -> index/timestampindex -> index/base", "banman -> common/bloom -> evo/assetlocktx -> llmq/quorumsman -> llmq/blockprocessor -> net -> banman", - "coinjoin/client -> coinjoin/util -> wallet/wallet -> psbt -> node/transaction -> net_processing -> coinjoin/walletman -> coinjoin/client", "common/bloom -> evo/assetlocktx -> llmq/commitment -> evo/deterministicmns -> evo/simplifiedmns -> merkleblock -> common/bloom", "common/bloom -> evo/assetlocktx -> llmq/quorumsman -> llmq/blockprocessor -> net -> common/bloom", "consensus/tx_verify -> evo/assetlocktx -> llmq/commitment -> validation -> consensus/tx_verify", From 6c67fc38d98c757f7a783e021c8660a5d1efa9e1 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Tue, 18 Aug 2026 18:09:55 +0700 Subject: [PATCH 2/9] refactor: drop unused core_io.h include from evo/smldiff The include was left behind when CSimplifiedMNListDiff::ToJson() moved out to evo/core_write.cpp; nothing in smldiff.cpp uses core_io anymore. Now that the linter maps evo/core_write.cpp into the core_io module, the stale include manifests as the circular dependency core_io -> evo/smldiff -> core_io. --- src/evo/smldiff.cpp | 1 - test/lint/lint-circular-dependencies.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/evo/smldiff.cpp b/src/evo/smldiff.cpp index f48467719c62..2fbf0fe2e821 100644 --- a/src/evo/smldiff.cpp +++ b/src/evo/smldiff.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index 524e3b07d2e0..c573f0fe2529 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -29,7 +29,6 @@ ) EXPECTED_DASH_CIRCULAR_DEPENDENCIES = ( - "core_io -> evo/smldiff -> core_io", "core_io -> governance/governance -> governance/superblock -> core_io", "coinjoin/coinjoin -> core_io -> rpc/util -> node/transaction -> net_processing -> coinjoin/coinjoin", "coinjoin/coinjoin -> core_io -> rpc/util -> node/transaction -> node/context -> coinjoin/coinjoin", From 99464cfef5b593b5b6cf128845a8bcdfe1393fdc Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 19 Aug 2026 03:36:34 +0700 Subject: [PATCH 3/9] refactor: move RPC help definitions out of core_io module into rpc/ The GetJsonHelp()/GetRpcResult() definitions lived in the {evo,llmq, governance}/core_write.cpp files, which form the core_io module and are built into libbitcoin_common for the sake of their ToJson() halves (dash-tx prints special-tx payloads via TxToUniv()). The help halves forced rpc/util.h into core_io's dependency closure, creating four circular dependencies through core_io -> rpc/util -> node/transaction, and shipped the help tables in libbitcoin_common although every consumer (rpc/blockchain, rpc/coinjoin, rpc/evo, rpc/governance, rpc/masternode, rpc/quorums, rpc/rawtransaction) is in libbitcoin_node. Move RPCRESULT_MAP, GetRpcResult() and all GetJsonHelp() definitions verbatim into a new rpc/json_help.{h,cpp} in libbitcoin_node, and move the GetRpcResult() declaration from core_io.h to the new header. The core_write files keep only their ToJson() definitions. The help is RPC documentation shared by several command files, so it gets its own translation unit rather than being spliced into the generic machinery of rpc/util.cpp, which is part of libbitcoin_common and would keep the tables in the common library. The four coinjoin suppressions through core_io -> rpc/util are gone; the longer pre-existing coinjoin/client -> coinjoin/util -> wallet/wallet cycle they had been shadowing is visible to the linter again and returns to the suppression list. --- src/Makefile.am | 2 + src/core_io.h | 4 - src/evo/core_write.cpp | 322 -------------- src/governance/core_write.cpp | 82 ---- src/llmq/core_write.cpp | 145 +----- src/rpc/coinjoin.cpp | 1 + src/rpc/json_help.cpp | 568 ++++++++++++++++++++++++ src/rpc/json_help.h | 16 + src/rpc/masternode.cpp | 1 + src/rpc/quorums.cpp | 1 + test/lint/lint-circular-dependencies.py | 5 +- test/util/data/non-backported.txt | 1 + 12 files changed, 593 insertions(+), 555 deletions(-) create mode 100644 src/rpc/json_help.cpp create mode 100644 src/rpc/json_help.h diff --git a/src/Makefile.am b/src/Makefile.am index 0cf8ce802fdb..1d505ab5d06b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -373,6 +373,7 @@ BITCOIN_CORE_H = \ rpc/blockchain.h \ rpc/client.h \ rpc/evo_util.h \ + rpc/json_help.h \ rpc/mempool.h \ rpc/mining.h \ rpc/protocol.h \ @@ -638,6 +639,7 @@ libbitcoin_node_a_SOURCES = \ rpc/evo.cpp \ rpc/fees.cpp \ rpc/governance.cpp \ + rpc/json_help.cpp \ rpc/masternode.cpp \ rpc/mempool.cpp \ rpc/mining.cpp \ diff --git a/src/core_io.h b/src/core_io.h index 85deffd5c2fd..537067bf0952 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -18,7 +18,6 @@ class CTxUndo; class uint256; struct CMutableTransaction; struct CSpentIndexTxInfo; -struct RPCResult; class UniValue; @@ -57,7 +56,4 @@ std::string SighashToStr(unsigned char sighash_type); void ScriptToUniv(const CScript& script, UniValue& out, bool include_hex = true, bool include_address = false); void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr, TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS, const CSpentIndexTxInfo* ptxSpentInfo = nullptr); -// evo/core_write.cpp -RPCResult GetRpcResult(const std::string& key, bool optional = false, const std::string& override_name = ""); - #endif // BITCOIN_CORE_IO_H diff --git a/src/evo/core_write.cpp b/src/evo/core_write.cpp index 0aaafa6e545b..b01ebd5bce66 100644 --- a/src/evo/core_write.cpp +++ b/src/evo/core_write.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -17,75 +16,14 @@ #include #include -#include #include