Adjusts the anonset of the inputs to the newly calculated output anonsets.
MODIFY
WalletWasabi.Tests/UnitTests/BlockchainAnalysis/PubKeyReuseAnonScoreTests.cs
WalletWasabi.Tests/UnitTests/BlockchainAnalysis/PubKeyReuseAnonScoreTests.cs
@@ -110,6 +110,26 @@ namespace WalletWasabi.Tests.UnitTests.BlockchainAnalysis
Assert.Equal(100, tx.WalletOutputs.First().HdPubKey.AnonymitySet);
}
+ [Fact]
+ public void InputOutputSidePreviouslyUsedAddress()
+ {
+ // If there's reuse in input and output side, then output side didn't gain, nor lose anonymity.
+ var analyser = ServiceFactory.CreateBlockchainAnalyzer();
+ var reuse = BitcoinFactory.CreateHdPubKey(ServiceFactory.CreateKeyManager());
+ var tx = BitcoinFactory.CreateSmartTransaction(
+ 9,
+ Enumerable.Repeat(Money.Coins(1m), 9),
+ new[] { (Money.Coins(1.1m), 100, BitcoinFactory.CreateHdPubKey(ServiceFactory.CreateKeyManager())) },
+ new[] { (Money.Coins(1m), HdPubKey.DefaultHighAnonymitySet, reuse) });
+
+ reuse.AnonymitySet = 30;
+
+ analyser.Analyze(tx);
+
+ Assert.True(tx.WalletOutputs.First().HdPubKey.AnonymitySet < 30);
+ Assert.All(tx.WalletInputs, x => Assert.True(x.HdPubKey.AnonymitySet < 30));
+ }
+
[Fact]
public void OutputSideAddressReusePunished()
{

MODIFY
WalletWasabi/Blockchain/Analysis/BlockchainAnalyzer.cs
WalletWasabi/Blockchain/Analysis/BlockchainAnalyzer.cs
@@ -48,11 +48,28 @@ namespace WalletWasabi.Blockchain.Analysis
{
AnalyzeCoinjoin(tx, newInputAnonset, distinctWalletInputPubKeys);
}
+
+ AdjustWalletInputs(tx, distinctWalletInputPubKeys, newInputAnonset);
}
AnalyzeClusters(tx);
}
+ /// <summary>
+ /// Adjusts the anonset of the inputs to the newly calculated output anonsets.
+ /// </summary>
+ private static void AdjustWalletInputs(SmartTransaction tx, HashSet<HdPubKey> distinctWalletInputPubKeys, int newInputAnonset)
+ {
+ var smallestOutputAnonset = tx.WalletOutputs.Min(x => x.HdPubKey.AnonymitySet);
+ if (smallestOutputAnonset < newInputAnonset)
+ {
+ foreach (var key in distinctWalletInputPubKeys)
+ {
+ key.AnonymitySet = smallestOutputAnonset;
+ }
+ }
+ }
+
private void AnalyzeCoinjoin(SmartTransaction tx, int newInputAnonset, ISet<HdPubKey> distinctWalletInputPubKeys)
{
var indistinguishableWalletOutputs = tx

Adjusts the anonset of the inputs to the newly calculated output anonsets.