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: 6 additions & 3 deletions src/wallet/coinjoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,13 @@ int CWallet::GetRealOutpointCoinJoinRounds(const COutPoint& outpoint, int nRound
const CWalletTx* wtx{GetWalletTx(outpoint.hash)};

if (wtx == nullptr || wtx->tx == nullptr) {
// no such tx in this wallet
*nRoundsRef = -1;
// No such tx in this wallet: don't memoize the result, the wallet may
// still learn about the tx later (e.g. a rescan in progress) and nothing
// invalidates the cache when it does. RPCs feed user-supplied outpoints
// into this via IsFullyMixed, so this path is reachable for any outpoint.
mapOutpointRoundsCache.erase(pair.first);
WalletCJLogPrint(this, "%s FAILED %-70s %3d\n", __func__, outpoint.ToStringShort(), -1);
return *nRoundsRef;
return -1;
}

// bounds check
Expand Down
23 changes: 23 additions & 0 deletions src/wallet/test/coinjoin_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,29 @@ BOOST_FIXTURE_TEST_CASE(coinjoin_rebalance_rounds_reset_tests, CTransactionBuild
}
}

BOOST_FIXTURE_TEST_CASE(coinjoin_rounds_cache_unknown_tx_tests, CTransactionBuilderTestSetup)
{
constexpr CAmount nDenomAmount{10000100}; // 0.100001 DASH
BOOST_REQUIRE(CoinJoin::IsDenominatedAmount(nDenomAmount));

CompactTallyItem tallyItem = GetTallyItem({nDenomAmount});
const CScript scriptOurs = GetScriptForRawPubKey(coinbaseKey.GetPubKey());

CMutableTransaction mtxMix;
mtxMix.vin.emplace_back(tallyItem.outpoints[0]);
mtxMix.vout.emplace_back(nDenomAmount, scriptOurs);
const COutPoint outpointMixed{mtxMix.GetHash(), 0};

// Queried before the wallet knows the tx, the way RPCs do for user-supplied
// preset inputs: unknown, reported as -1
BOOST_CHECK_EQUAL(wallet->GetRealOutpointCoinJoinRounds(outpointMixed), -1);

// Once the wallet learns the tx its rounds are computed from it; the miss
// above must not stick in mapOutpointRoundsCache
BOOST_REQUIRE(wallet->AddToWallet(MakeTransactionRef(mtxMix), TxStateInMempool{}));
BOOST_CHECK_EQUAL(wallet->GetRealOutpointCoinJoinRounds(outpointMixed), 1);
}

BOOST_FIXTURE_TEST_CASE(CTransactionBuilderTest, CTransactionBuilderTestSetup)
{
// NOTE: Mock wallet version is FEATURE_BASE which means that it uses uncompressed pubkeys
Expand Down