From d95da694b90bf0599f8054b8a591b91c33617ded Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 8 Aug 2025 14:53:21 -0400 Subject: [PATCH] WIP donation via z_shieldcoinbase --- .../asyncrpcoperation_shieldcoinbase.cpp | 65 ++++++++++--------- src/wallet/asyncrpcoperation_shieldcoinbase.h | 9 +-- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 57113f930..ce4da86fe 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -161,24 +161,7 @@ void AsyncRPCOperation_shieldcoinbase::main() { bool AsyncRPCOperation_shieldcoinbase::main_impl() { CAmount minersFee = fee_; - - size_t numInputs = inputs_.size(); - - /* - // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects - size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); - { - LOCK(cs_main); - if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { - limit = 0; - } - } - if (limit>0 && numInputs > limit) { - throw JSONRPCError(RPC_WALLET_ERROR, - strprintf("Number of inputs %d is greater than mempooltxinputlimit of %d", - numInputs, limit)); - } - */ + size_t numInputs = inputs_.size(); CAmount targetAmount = 0; for (ShieldCoinbaseUTXO & utxo : inputs_) { @@ -192,10 +175,12 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() { } CAmount sendAmount = targetAmount - minersFee; - LogPrint("zrpc", "%s: spending %s to shield %s with fee %s\n", + LogPrint("zrpc", "%s: spending %s to shield %s with fee %s, donation=%d\n", getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee)); - return boost::apply_visitor(ShieldToAddress(this, sendAmount), tozaddr_); + //TODO: pass this in from RPC + CAmount donation = 2; + return boost::apply_visitor(ShieldToAddress(this, sendAmount, donation), tozaddr_); } extern UniValue signrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk); @@ -229,19 +214,37 @@ bool ShieldToAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) c } } + //TODO: if donation==true, send X% of value to zaddr and Y% of of value to donatezaddr // Send all value to the target z-addr - m_op->builder_.SendChangeTo(zaddr, ovk); + if(donation) { + // add original recipient as first output + m_op->builder_.AddSaplingOutput(ovk, zaddr, sendAmount); + + CAmount donationAmount = 0; //TODO calculate exact donation amount in puposhis + // donation recipient as second output + m_op->builder_.AddSaplingOutput(ovk, donationZaddr, donationAmount); + + // zdust as third output, so donation txs are indistinguishable from + // non-donation z_shieldcoinbase txs + auto zdust1 = DecodePaymentAddress(randomSietchZaddr()); + auto sietchZout1 = boost::get(zdust1); + m_op->builder_.AddSaplingOutput(ovk, sietchZout1, 0); + + } else { + m_op->builder_.SendChangeTo(zaddr, ovk); + + // Sietchified Shielding of Coinbase Funds + // Add Sietch zouts so it's unclear which zout contains value :) + // This reduces metadata leakage of coinbase t=>z tx's + CAmount amount = 0; + auto zdust1 = DecodePaymentAddress(randomSietchZaddr()); + auto zdust2 = DecodePaymentAddress(randomSietchZaddr()); + auto sietchZout1 = boost::get(zdust1); + auto sietchZout2 = boost::get(zdust2); + m_op->builder_.AddSaplingOutput(ovk, sietchZout1, amount); + m_op->builder_.AddSaplingOutput(ovk, sietchZout2, amount); + } - // Sietchified Shielding of Coinbase Funds - // Add Sietch zouts so it's unclear which zout contains value :) - // This reduces metadata leakage of coinbase t=>z tx's - CAmount amount = 0; - auto zdust1 = DecodePaymentAddress(randomSietchZaddr()); - auto zdust2 = DecodePaymentAddress(randomSietchZaddr()); - auto sietchZout1 = boost::get(zdust1); - auto sietchZout2 = boost::get(zdust2); - m_op->builder_.AddSaplingOutput(ovk, sietchZout1, amount); - m_op->builder_.AddSaplingOutput(ovk, sietchZout2, amount); // Build the transaction auto maybe_tx = m_op->builder_.Build(); diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.h b/src/wallet/asyncrpcoperation_shieldcoinbase.h index bd606e23e..7a018e0d7 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.h +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.h @@ -63,7 +63,6 @@ public: virtual UniValue getStatus() const; bool testmode = false; // Set to true to disable sending txs and generating proofs - bool cheatSpend = false; // set when this is shielding a cheating coinbase private: friend class ShieldToAddress; @@ -96,15 +95,15 @@ class ShieldToAddress : public boost::static_visitor private: AsyncRPCOperation_shieldcoinbase *m_op; CAmount sendAmount; + CAmount donation = 0; public: - ShieldToAddress(AsyncRPCOperation_shieldcoinbase *op, CAmount sendAmount) : - m_op(op), sendAmount(sendAmount) {} + ShieldToAddress(AsyncRPCOperation_shieldcoinbase *op, CAmount sendAmount, bool donation) : + m_op(op), sendAmount(sendAmount), donation(donation) {} bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; - // To test private methods, a friend class can act as a proxy class TEST_FRIEND_AsyncRPCOperation_shieldcoinbase { public: @@ -135,6 +134,4 @@ public: } }; - #endif /* ASYNCRPCOPERATION_SHIELDCOINBASE_H */ -