Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
49d7d5f
feat: coinjoin promotion / demotion
PastaPastaPasta Jul 10, 2026
3d6d49a
test: cover CoinJoin promotion/demotion validation and decision logic
PastaPastaPasta Jul 10, 2026
33702b4
docs: add release notes for pr 7052
PastaPastaPasta Jul 10, 2026
9c29052
feat(coinjoin): gate rebalance sessions and require session-denom cover
PastaPastaPasta Aug 1, 2026
363d305
fix(coinjoin): tolerate one-block tip skew only at the V24 boundary
PastaPastaPasta Aug 1, 2026
efff25c
fix(coinjoin): only announce unbalanced DSTXes to peers that support …
PastaPastaPasta Aug 1, 2026
9cae6f4
feat(coinjoin): reset mixing rounds on promotion/demotion outputs
PastaPastaPasta Aug 1, 2026
9e83d6a
fix(coinjoin): don't announce oversized balanced DSTXes to legacy peers
PastaPastaPasta Aug 17, 2026
88d4e6b
fix(coinjoin): guard against null prevtx in GetRealOutpointCoinJoinRo…
PastaPastaPasta Aug 17, 2026
9727337
fix(coinjoin): keep relaying islocks when withholding a DSTX from leg…
PastaPastaPasta Aug 17, 2026
50c62c9
fix(coinjoin): annotate m_fRebalanceSession as GUARDED_BY(cs_coinjoin)
PastaPastaPasta Aug 17, 2026
f7d2bbb
fix(coinjoin): bind entry admission and charging to the validated ses…
PastaPastaPasta Aug 18, 2026
1ff74e9
fix(coinjoin): latch rebalance capability on admission, not on creato…
PastaPastaPasta Aug 18, 2026
032bc99
fix(coinjoin): widen the V24 DSTX skew tolerance and downgrade withhe…
PastaPastaPasta Aug 18, 2026
428eb97
fix(coinjoin): recognize unbalanced mixing transactions as denominated
PastaPastaPasta Aug 18, 2026
6af461c
fix(coinjoin): scale the rebalance gap threshold with the denoms goal
PastaPastaPasta Aug 18, 2026
e78b965
test(coinjoin): cover session finalization race and gap-threshold bou…
PastaPastaPasta Aug 18, 2026
5748316
refactor(coinjoin): use static_cast in new promotion/demotion code
PastaPastaPasta Aug 18, 2026
0dc132f
docs: describe rebalance session gating and DSTX downgrade accurately
PastaPastaPasta Aug 18, 2026
3646c95
fix(coinjoin): tolerate DSTX tip skew from V24 lock-in, and address r…
PastaPastaPasta Aug 18, 2026
e6687d9
fix(coinjoin): tolerate arbitrary tip skew when validating a final tr…
PastaPastaPasta Aug 18, 2026
f232f02
fix(coinjoin): keep the V24 tip-skew tolerance at one block
PastaPastaPasta Aug 18, 2026
123858d
fix(coinjoin): don't burn queue announcements a rebalance pass skips
UdjinM6 Aug 17, 2026
26d0a98
fix(coinjoin): tell participants when an uncovered session is reset
UdjinM6 Aug 17, 2026
adb2765
fix(coinjoin): bound the sides of a post-V24 DSTX against each other
UdjinM6 Aug 18, 2026
d1fca89
fix(coinjoin): decide the pool state from one consistent snapshot
PastaPastaPasta Aug 19, 2026
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
501 changes: 477 additions & 24 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 @@ -89,6 +89,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 @@ -102,16 +107,35 @@ 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);
CDeterministicMNCPtr GetRandomNotUsedMasternode();

/// 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 @@ -256,6 +280,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
*/
static bool ShouldPromote(int nSmallerDenom, int nLargerDenom, const wallet::CoinJoinDenomCounts& counts);

/**
* 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
*/
static bool ShouldDemote(int nLargerDenom, int nSmallerDenom, const wallet::CoinJoinDenomCounts& counts);
};

#endif // BITCOIN_COINJOIN_CLIENT_H
Loading