From d9828a9ccdea75d32637c3e6102a47c16376ac36 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:29:58 +0000 Subject: [PATCH 01/10] refactor: move `ToJson` definitions relied by `TxToUniv` to source file This helps us get rid of the redefinitions responsible for `-Wredundant-decls` unhappiness. --- src/Makefile.am | 1 + src/evo/assetlocktx.h | 35 +--------- src/evo/cbtx.h | 21 +----- src/evo/core_write.cpp | 144 +++++++++++++++++++++++++++++++++++++++++ src/evo/mnhftx.h | 9 +-- src/evo/providertx.h | 72 ++------------------- src/llmq/commitment.h | 10 +-- 7 files changed, 154 insertions(+), 138 deletions(-) create mode 100644 src/evo/core_write.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 8f5cac84d768..1f82cbf9f8bc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -773,6 +773,7 @@ libbitcoin_common_a_SOURCES = \ core_read.cpp \ core_write.cpp \ deploymentinfo.cpp \ + evo/core_write.cpp \ governance/common.cpp \ init/common.cpp \ key.cpp \ diff --git a/src/evo/assetlocktx.h b/src/evo/assetlocktx.h index d63ef4092e32..0af346be0a20 100644 --- a/src/evo/assetlocktx.h +++ b/src/evo/assetlocktx.h @@ -22,10 +22,6 @@ namespace llmq { class CQuorumManager; } // namespace llmq -// Forward declaration from core_io to get rid of circular dependency -UniValue ValueFromAmount(const CAmount amount); -void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex, bool include_addresses); - class CAssetLockPayload { public: @@ -53,23 +49,7 @@ class CAssetLockPayload std::string ToString() const; - [[nodiscard]] UniValue ToJson() const - { - UniValue outputs(UniValue::VARR); - for (const CTxOut& credit_output : creditOutputs) { - UniValue out(UniValue::VOBJ); - out.pushKV("value", ValueFromAmount(credit_output.nValue)); - out.pushKV("valueSat", credit_output.nValue); - UniValue spk(UniValue::VOBJ); - ScriptPubKeyToUniv(credit_output.scriptPubKey, spk, /* fIncludeHex = */ true, /* include_addresses = */ false); - out.pushKV("scriptPubKey", spk); - outputs.push_back(out); - } - UniValue obj(UniValue::VOBJ); - obj.pushKV("version", int(nVersion)); - obj.pushKV("creditOutputs", outputs); - return obj; - } + [[nodiscard]] UniValue ToJson() const; // getters uint8_t getVersion() const @@ -126,18 +106,7 @@ class CAssetUnlockPayload std::string ToString() const; - [[nodiscard]] UniValue ToJson() const - { - UniValue obj; - obj.setObject(); - obj.pushKV("version", int(nVersion)); - obj.pushKV("index", int(index)); - obj.pushKV("fee", int(fee)); - obj.pushKV("requestedHeight", int(requestedHeight)); - obj.pushKV("quorumHash", quorumHash.ToString()); - obj.pushKV("quorumSig", quorumSig.ToString()); - return obj; - } + [[nodiscard]] UniValue ToJson() const; bool VerifySig(const llmq::CQuorumManager& qman, const uint256& msgHash, gsl::not_null pindexTip, TxValidationState& state) const; diff --git a/src/evo/cbtx.h b/src/evo/cbtx.h index dce93949bb20..b18918c7173c 100644 --- a/src/evo/cbtx.h +++ b/src/evo/cbtx.h @@ -24,9 +24,6 @@ class CQuorumBlockProcessor; class CQuorumSnapshotManager; }// namespace llmq -// Forward declaration from core_io to get rid of circular dependency -UniValue ValueFromAmount(const CAmount amount); - // coinbase transaction class CCbTx { @@ -65,23 +62,7 @@ class CCbTx std::string ToString() const; - [[nodiscard]] UniValue ToJson() const - { - UniValue obj; - obj.setObject(); - obj.pushKV("version", (int)nVersion); - obj.pushKV("height", nHeight); - obj.pushKV("merkleRootMNList", merkleRootMNList.ToString()); - if (nVersion >= Version::MERKLE_ROOT_QUORUMS) { - obj.pushKV("merkleRootQuorums", merkleRootQuorums.ToString()); - if (nVersion >= Version::CLSIG_AND_BALANCE) { - obj.pushKV("bestCLHeightDiff", static_cast(bestCLHeightDiff)); - obj.pushKV("bestCLSignature", bestCLSignature.ToString()); - obj.pushKV("creditPoolBalance", ValueFromAmount(creditPoolBalance)); - } - } - return obj; - } + [[nodiscard]] UniValue ToJson() const; }; template<> struct is_serializable_enum : std::true_type {}; diff --git a/src/evo/core_write.cpp b/src/evo/core_write.cpp new file mode 100644 index 000000000000..b2a2cdbd7f0a --- /dev/null +++ b/src/evo/core_write.cpp @@ -0,0 +1,144 @@ +// Copyright (c) 2018-2025 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include +#include +#include + +#include + +[[nodiscard]] UniValue CAssetLockPayload::ToJson() const +{ + UniValue outputs(UniValue::VARR); + for (const CTxOut& credit_output : creditOutputs) { + UniValue out(UniValue::VOBJ); + out.pushKV("value", ValueFromAmount(credit_output.nValue)); + out.pushKV("valueSat", credit_output.nValue); + UniValue spk(UniValue::VOBJ); + ScriptPubKeyToUniv(credit_output.scriptPubKey, spk, /*include_hex=*/true, /*include_address=*/false); + out.pushKV("scriptPubKey", spk); + outputs.push_back(out); + } + + UniValue ret(UniValue::VOBJ); + ret.pushKV("version", int(nVersion)); + ret.pushKV("creditOutputs", outputs); + return ret; +} + +[[nodiscard]] UniValue CAssetUnlockPayload::ToJson() const +{ + UniValue ret(UniValue::VOBJ); + ret.pushKV("version", int(nVersion)); + ret.pushKV("index", int(index)); + ret.pushKV("fee", int(fee)); + ret.pushKV("requestedHeight", int(requestedHeight)); + ret.pushKV("quorumHash", quorumHash.ToString()); + ret.pushKV("quorumSig", quorumSig.ToString()); + return ret; +} + +[[nodiscard]] UniValue CCbTx::ToJson() const +{ + UniValue ret(UniValue::VOBJ); + ret.pushKV("version", (int)nVersion); + ret.pushKV("height", nHeight); + ret.pushKV("merkleRootMNList", merkleRootMNList.ToString()); + if (nVersion >= CCbTx::Version::MERKLE_ROOT_QUORUMS) { + ret.pushKV("merkleRootQuorums", merkleRootQuorums.ToString()); + if (nVersion >= CCbTx::Version::CLSIG_AND_BALANCE) { + ret.pushKV("bestCLHeightDiff", static_cast(bestCLHeightDiff)); + ret.pushKV("bestCLSignature", bestCLSignature.ToString()); + ret.pushKV("creditPoolBalance", ValueFromAmount(creditPoolBalance)); + } + } + return ret; +} + +[[nodiscard]] UniValue CProRegTx::ToJson() const +{ + UniValue ret(UniValue::VOBJ); + ret.pushKV("version", nVersion); + ret.pushKV("type", ToUnderlying(nType)); + ret.pushKV("collateralHash", collateralOutpoint.hash.ToString()); + ret.pushKV("collateralIndex", (int)collateralOutpoint.n); + ret.pushKV("service", addr.ToStringAddrPort()); + ret.pushKV("ownerAddress", EncodeDestination(PKHash(keyIDOwner))); + ret.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting))); + if (CTxDestination dest; ExtractDestination(scriptPayout, dest)) { + ret.pushKV("payoutAddress", EncodeDestination(dest)); + } + ret.pushKV("pubKeyOperator", pubKeyOperator.ToString()); + ret.pushKV("operatorReward", (double)nOperatorReward / 100); + if (nType == MnType::Evo) { + ret.pushKV("platformNodeID", platformNodeID.ToString()); + ret.pushKV("platformP2PPort", platformP2PPort); + ret.pushKV("platformHTTPPort", platformHTTPPort); + } + ret.pushKV("inputsHash", inputsHash.ToString()); + return ret; +} + +[[nodiscard]] UniValue CProUpRegTx::ToJson() const +{ + UniValue ret(UniValue::VOBJ); + ret.pushKV("version", nVersion); + ret.pushKV("proTxHash", proTxHash.ToString()); + ret.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting))); + if (CTxDestination dest; ExtractDestination(scriptPayout, dest)) { + ret.pushKV("payoutAddress", EncodeDestination(dest)); + } + ret.pushKV("pubKeyOperator", pubKeyOperator.ToString()); + ret.pushKV("inputsHash", inputsHash.ToString()); + return ret; +} + +[[nodiscard]] UniValue CProUpRevTx::ToJson() const +{ + UniValue ret(UniValue::VOBJ); + ret.pushKV("version", nVersion); + ret.pushKV("proTxHash", proTxHash.ToString()); + ret.pushKV("reason", (int)nReason); + ret.pushKV("inputsHash", inputsHash.ToString()); + return ret; +} + +[[nodiscard]] UniValue CProUpServTx::ToJson() const +{ + UniValue ret(UniValue::VOBJ); + ret.pushKV("version", nVersion); + ret.pushKV("type", ToUnderlying(nType)); + ret.pushKV("proTxHash", proTxHash.ToString()); + ret.pushKV("service", addr.ToStringAddrPort()); + if (CTxDestination dest; ExtractDestination(scriptOperatorPayout, dest)) { + ret.pushKV("operatorPayoutAddress", EncodeDestination(dest)); + } + if (nType == MnType::Evo) { + ret.pushKV("platformNodeID", platformNodeID.ToString()); + ret.pushKV("platformP2PPort", platformP2PPort); + ret.pushKV("platformHTTPPort", platformHTTPPort); + } + ret.pushKV("inputsHash", inputsHash.ToString()); + return ret; +} + +[[nodiscard]] UniValue MNHFTxPayload::ToJson() const +{ + UniValue ret(UniValue::VOBJ); + ret.pushKV("version", (int)nVersion); + ret.pushKV("signal", signal.ToJson()); + return ret; +} + +[[nodiscard]] UniValue llmq::CFinalCommitmentTxPayload::ToJson() const +{ + UniValue ret(UniValue::VOBJ); + ret.pushKV("version", int{nVersion}); + ret.pushKV("height", int(nHeight)); + ret.pushKV("commitment", commitment.ToJson()); + return ret; +} diff --git a/src/evo/mnhftx.h b/src/evo/mnhftx.h index 1d6b577f3c1f..d6a3ca59bcb2 100644 --- a/src/evo/mnhftx.h +++ b/src/evo/mnhftx.h @@ -86,14 +86,7 @@ class MNHFTxPayload std::string ToString() const; - [[nodiscard]] UniValue ToJson() const - { - UniValue obj; - obj.setObject(); - obj.pushKV("version", (int)nVersion); - obj.pushKV("signal", signal.ToJson()); - return obj; - } + [[nodiscard]] UniValue ToJson() const; }; class CMNHFManager : public AbstractEHFManager diff --git a/src/evo/providertx.h b/src/evo/providertx.h index 037dc3c24bc9..50f777293221 100644 --- a/src/evo/providertx.h +++ b/src/evo/providertx.h @@ -91,31 +91,7 @@ class CProRegTx std::string ToString() const; - [[nodiscard]] UniValue ToJson() const - { - UniValue obj; - obj.setObject(); - obj.pushKV("version", nVersion); - obj.pushKV("type", ToUnderlying(nType)); - obj.pushKV("collateralHash", collateralOutpoint.hash.ToString()); - obj.pushKV("collateralIndex", (int)collateralOutpoint.n); - obj.pushKV("service", addr.ToStringAddrPort()); - obj.pushKV("ownerAddress", EncodeDestination(PKHash(keyIDOwner))); - obj.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting))); - - if (CTxDestination dest; ExtractDestination(scriptPayout, dest)) { - obj.pushKV("payoutAddress", EncodeDestination(dest)); - } - obj.pushKV("pubKeyOperator", pubKeyOperator.ToString()); - obj.pushKV("operatorReward", (double)nOperatorReward / 100); - if (nType == MnType::Evo) { - obj.pushKV("platformNodeID", platformNodeID.ToString()); - obj.pushKV("platformP2PPort", platformP2PPort); - obj.pushKV("platformHTTPPort", platformHTTPPort); - } - obj.pushKV("inputsHash", inputsHash.ToString()); - return obj; - } + [[nodiscard]] UniValue ToJson() const; bool IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const; }; @@ -175,25 +151,7 @@ class CProUpServTx std::string ToString() const; - [[nodiscard]] UniValue ToJson() const - { - UniValue obj; - obj.setObject(); - obj.pushKV("version", nVersion); - obj.pushKV("type", ToUnderlying(nType)); - obj.pushKV("proTxHash", proTxHash.ToString()); - obj.pushKV("service", addr.ToStringAddrPort()); - if (CTxDestination dest; ExtractDestination(scriptOperatorPayout, dest)) { - obj.pushKV("operatorPayoutAddress", EncodeDestination(dest)); - } - if (nType == MnType::Evo) { - obj.pushKV("platformNodeID", platformNodeID.ToString()); - obj.pushKV("platformP2PPort", platformP2PPort); - obj.pushKV("platformHTTPPort", platformHTTPPort); - } - obj.pushKV("inputsHash", inputsHash.ToString()); - return obj; - } + [[nodiscard]] UniValue ToJson() const; bool IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const; }; @@ -243,20 +201,7 @@ class CProUpRegTx std::string ToString() const; - [[nodiscard]] UniValue ToJson() const - { - UniValue obj; - obj.setObject(); - obj.pushKV("version", nVersion); - obj.pushKV("proTxHash", proTxHash.ToString()); - obj.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting))); - if (CTxDestination dest; ExtractDestination(scriptPayout, dest)) { - obj.pushKV("payoutAddress", EncodeDestination(dest)); - } - obj.pushKV("pubKeyOperator", pubKeyOperator.ToString()); - obj.pushKV("inputsHash", inputsHash.ToString()); - return obj; - } + [[nodiscard]] UniValue ToJson() const; bool IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const; }; @@ -309,16 +254,7 @@ class CProUpRevTx std::string ToString() const; - [[nodiscard]] UniValue ToJson() const - { - UniValue obj; - obj.setObject(); - obj.pushKV("version", nVersion); - obj.pushKV("proTxHash", proTxHash.ToString()); - obj.pushKV("reason", (int)nReason); - obj.pushKV("inputsHash", inputsHash.ToString()); - return obj; - } + [[nodiscard]] UniValue ToJson() const; bool IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const; }; diff --git a/src/llmq/commitment.h b/src/llmq/commitment.h index 02fb2e3cac9b..3c88256bbbe5 100644 --- a/src/llmq/commitment.h +++ b/src/llmq/commitment.h @@ -166,15 +166,7 @@ class CFinalCommitmentTxPayload READWRITE(obj.nVersion, obj.nHeight, obj.commitment); } - [[nodiscard]] UniValue ToJson() const - { - UniValue obj; - obj.setObject(); - obj.pushKV("version", int{nVersion}); - obj.pushKV("height", int(nHeight)); - obj.pushKV("commitment", commitment.ToJson()); - return obj; - } + [[nodiscard]] UniValue ToJson() const; }; bool CheckLLMQCommitment(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, From c587838c63b501b441af5f34d047b33019d65eab Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 22 Apr 2025 16:57:38 +0000 Subject: [PATCH 02/10] refactor: use `GetTransactionBlock()` as narrow `GetTransaction()` proxy Currently, we rely on redefinition to avoid an explosion in reported circular dependencies but that is verboten with `-Wredundant-decls`. To trim down the amount of circular dependencies that would happen once we remove the circular definition, we have to proxy `GetTransaction()` through another function located elsewhere. Since all Dash-specific invocations either rely on the txindex or the mempool, we can safely trim down the number of arguments and add a fast-fail. Since we do (sometimes) care about the block the transaction is in, we return that as well. --- src/coinjoin/client.cpp | 2 +- src/coinjoin/util.cpp | 1 - src/evo/assetlocktx.cpp | 2 +- src/evo/cbtx.cpp | 1 - src/evo/chainhelper.cpp | 10 ++++++++++ src/evo/chainhelper.h | 7 +++++++ src/evo/deterministicmns.cpp | 14 +++++++------- src/governance/object.cpp | 4 ++-- src/governance/vote.cpp | 1 - src/llmq/chainlocks.cpp | 4 ++-- src/llmq/dkgsession.cpp | 1 - src/llmq/instantsend.cpp | 12 +++++------- src/llmq/utils.cpp | 1 - src/rpc/blockchain.h | 2 +- src/rpc/mempool.cpp | 1 + src/test/block_reward_reallocation_tests.cpp | 1 + src/test/evo_deterministicmns_tests.cpp | 1 + src/validation.cpp | 5 ++--- src/validation.h | 2 -- test/lint/lint-circular-dependencies.py | 15 ++++++++++----- 20 files changed, 51 insertions(+), 36 deletions(-) diff --git a/src/coinjoin/client.cpp b/src/coinjoin/client.cpp index 7e2747c91a6b..26b1e7cb70f5 100644 --- a/src/coinjoin/client.cpp +++ b/src/coinjoin/client.cpp @@ -4,6 +4,7 @@ #include +#include #include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/src/coinjoin/util.cpp b/src/coinjoin/util.cpp index a7c3235d3765..0a379a054f86 100644 --- a/src/coinjoin/util.cpp +++ b/src/coinjoin/util.cpp @@ -7,7 +7,6 @@ #include #include #include