Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions doc/release-notes-7052.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Wallet
------

- CoinJoin can now promote and demote between adjacent standard
denominations within a mixing session after V24 activation.
Promotion combines 10 inputs of one denomination into 1 output of the
next larger denomination, while demotion splits 1 input into 10
outputs of the next smaller denomination. Pre-V24 behavior remains
unchanged. (#7052)
546 changes: 523 additions & 23 deletions src/coinjoin/client.cpp

Large diffs are not rendered by default.

44 changes: 43 additions & 1 deletion src/coinjoin/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession

CKeyHolderStorage keyHolderStorage; // storage for keys used in PrepareDenominate

// Post-V24: Promotion/demotion session state
bool m_fPromotion{false}; // True if this session is promoting smaller -> larger denom
bool m_fDemotion{false}; // True if this session is demoting larger -> smaller denom
std::vector<COutPoint> m_vecRebalanceInputs; // Selected inputs for promotion/demotion rebalancing

/// Create denominations
bool CreateDenominated(CAmount nBalanceToDenominate);
bool CreateDenominated(CAmount nBalanceToDenominate, const wallet::CompactTallyItem& tallyItem, bool fCreateMixingCollaterals)
Expand All @@ -97,15 +102,34 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession
bool CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason)
EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet);

bool JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman);
bool JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman,
int nTargetDenom = 0, bool fPromotion = false, bool fDemotion = false);
bool StartNewQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman);
bool StartNewQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman,
int nTargetDenom, bool fPromotion, bool fDemotion);

/// Post-V24: select and lock inputs for a promotion/demotion session. Locked outpoints are
/// recorded in m_vecRebalanceInputs and vecOutPointLocked so UnlockCoins() releases them on
/// any failure path.
bool SelectRebalanceInputs(int nTargetDenom, bool fPromotion, std::vector<CTxDSIn>& vecTxDSInRet);
/// Post-V24: unlock and forget the inputs selected by SelectRebalanceInputs (session setup failed)
void UnlockRebalanceInputs();

/// step 0: select denominated inputs and txouts
bool SelectDenominate(std::string& strErrorRet, std::vector<CTxDSIn>& vecTxDSInRet);
/// step 1: prepare denominated inputs and outputs
bool PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector<CTxDSIn>& vecTxDSIn,
std::vector<std::pair<CTxDSIn, CTxOut>>& vecPSInOutPairsRet, bool fDryRun = false)
EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet);

/// Post-V24: prepare promotion entry (10 inputs of smaller denom -> 1 output of larger denom)
bool PreparePromotionEntry(std::string& strErrorRet, std::vector<std::pair<CTxDSIn, CTxOut>>& vecPSInOutPairsRet)
EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet);

/// Post-V24: prepare demotion entry (1 input of larger denom -> 10 outputs of smaller denom)
bool PrepareDemotionEntry(std::string& strErrorRet, std::vector<std::pair<CTxDSIn, CTxOut>>& vecPSInOutPairsRet)
EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet);

/// step 2: send denominated inputs and outputs prepared in step 1
bool SendDenominate(const std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);

Expand Down Expand Up @@ -231,6 +255,24 @@ class CCoinJoinClientManager : public interfaces::CoinJoin::Client
bool isMixing() const override;
bool startMixing() override;
void stopMixing() override;

/**
* Post-V24: Check if we should promote smaller denominations into larger ones
* @param nSmallerDenom The smaller denomination to promote from
* @param nLargerDenom The larger denomination to promote into
* @param counts Wallet denomination counts, e.g. from CWallet::GetDenominationCounts()
* @return true if promotion is recommended
*/
bool ShouldPromote(int nSmallerDenom, int nLargerDenom, const wallet::CoinJoinDenomCounts& counts) const;

/**
* Post-V24: Check if we should demote larger denominations into smaller ones
* @param nLargerDenom The larger denomination to demote from
* @param nSmallerDenom The smaller denomination to demote into
* @param counts Wallet denomination counts, e.g. from CWallet::GetDenominationCounts()
* @return true if demotion is recommended
*/
bool ShouldDemote(int nLargerDenom, int nSmallerDenom, const wallet::CoinJoinDenomCounts& counts) const;
};

#endif // BITCOIN_COINJOIN_CLIENT_H
Loading
Loading