Consolidate progress
MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/CoinViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/CoinViewModel.cs
@@ -54,7 +54,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
.DisposeWith(Disposables);
_cluster = Model
- .WhenAnyValue(x => x.Cluster, x => x.Cluster.Labels)
+ .WhenAnyValue(x => x.HdPubKey.Cluster, x => x.HdPubKey.Cluster.Labels)
.Select(x => x.Item2.ToString())
.ToProperty(this, x => x.Cluster, scheduler: RxApp.MainThreadScheduler)
.DisposeWith(Disposables);

MODIFY
WalletWasabi.Tests/Common.cs
WalletWasabi.Tests/Common.cs
@@ -63,8 +63,8 @@ namespace WalletWasabi.Tests
var keys = keyManager.GetKeys().Take(coinArray.Length).ToArray();
for (int i = 0; i < coinArray.Length; i++)
{
- var k = keys[i];
var c = coinArray[i];
+ var k = keys[c.KeyIndex];
k.SetLabel(c.Label);
}
@@ -73,7 +73,7 @@ namespace WalletWasabi.Tests
{
foreach (var sameLabelCoin in scoins.Where(c => !c.HdPubKey.Label.IsEmpty && c.HdPubKey.Label == coin.HdPubKey.Label))
{
- sameLabelCoin.Cluster = coin.Cluster;
+ sameLabelCoin.HdPubKey.Cluster = coin.HdPubKey.Cluster;
}
}
var coinsView = new CoinsView(scoins);

MODIFY
WalletWasabi.Tests/UnitTests/Transactions/TransactionFactoryTests.cs
WalletWasabi.Tests/UnitTests/Transactions/TransactionFactoryTests.cs
@@ -197,18 +197,18 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
// cluster 1 is known by 7 people: Pablo, Daniel, Adolf, Maria, Ding, Joseph and Eve
var coinsCluster1 = new[] { scoins[0], scoins[1], scoins[2], scoins[3], scoins[4], scoins[5], scoins[6] };
- var cluster1 = new Cluster(coinsCluster1);
+ var cluster1 = new Cluster(coinsCluster1.Select(x => x.HdPubKey));
foreach (var coin in coinsCluster1)
{
- coin.Cluster = cluster1;
+ coin.HdPubKey.Cluster = cluster1;
}
// cluster 2 is known by 6 people: Julio, Lee, Jean, Donald, Onur and Satoshi
var coinsCluster2 = new[] { scoins[7], scoins[8], scoins[9] };
- var cluster2 = new Cluster(coinsCluster2);
+ var cluster2 = new Cluster(coinsCluster2.Select(x => x.HdPubKey));
foreach (var coin in coinsCluster2)
{
- coin.Cluster = cluster2;
+ coin.HdPubKey.Cluster = cluster2;
}
var coinsView = new CoinsView(scoins.ToArray());
@@ -221,7 +221,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var result = transactionFactory.BuildTransaction(payment, feeRate);
Assert.Equal(2, result.SpentCoins.Count());
- Assert.All(result.SpentCoins, c => Assert.Equal(c.Cluster, cluster2));
+ Assert.All(result.SpentCoins, c => Assert.Equal(c.HdPubKey.Cluster, cluster2));
Assert.Contains(coinsByLabel["Julio"], result.SpentCoins);
Assert.Contains(coinsByLabel["Donald, Jean, Lee, Onur"], result.SpentCoins);
@@ -231,7 +231,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
result = transactionFactory.BuildTransaction(payment, feeRate);
Assert.Equal(3, result.SpentCoins.Count());
- Assert.All(result.SpentCoins, c => Assert.Equal(c.Cluster, cluster2));
+ Assert.All(result.SpentCoins, c => Assert.Equal(c.HdPubKey.Cluster, cluster2));
Assert.Contains(coinsByLabel["Julio"], result.SpentCoins);
Assert.Contains(coinsByLabel["Donald, Jean, Lee, Onur"], result.SpentCoins);
Assert.Contains(coinsByLabel["Satoshi"], result.SpentCoins);
@@ -243,7 +243,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
result = transactionFactory.BuildTransaction(payment, feeRate);
Assert.Equal(4, result.SpentCoins.Count());
- Assert.All(result.SpentCoins, c => Assert.Equal(c.Cluster, cluster1));
+ Assert.All(result.SpentCoins, c => Assert.Equal(c.HdPubKey.Cluster, cluster1));
Assert.Contains(coinsByLabel["Pablo"], result.SpentCoins);
Assert.Contains(coinsByLabel["Daniel"], result.SpentCoins);
Assert.Contains(coinsByLabel["Adolf"], result.SpentCoins);

MODIFY
WalletWasabi.Tests/UnitTests/Transactions/TransactionProcessorTests.cs
WalletWasabi.Tests/UnitTests/Transactions/TransactionProcessorTests.cs
@@ -740,14 +740,14 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
transactionProcessor.Process(tx0);
var createdCoin = transactionProcessor.Coins.First();
- Assert.Equal("A", createdCoin.Cluster.Labels);
+ Assert.Equal("A", createdCoin.HdPubKey.Cluster.Labels);
// Spend the received coin to someone else B
var changeScript1 = transactionProcessor.NewKey("B").P2wpkhScript;
var tx1 = CreateSpendingTransaction(new[] { createdCoin.Coin }, new Key().ScriptPubKey, changeScript1);
transactionProcessor.Process(tx1);
createdCoin = transactionProcessor.Coins.First();
- Assert.Equal("A, B", createdCoin.Cluster.Labels);
+ Assert.Equal("A, B", createdCoin.HdPubKey.Cluster.Labels);
// Spend the received coin to myself else C
var myselfScript = transactionProcessor.NewKey("C").P2wpkhScript;
@@ -757,10 +757,10 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
Assert.Equal(2, transactionProcessor.Coins.Count());
createdCoin = transactionProcessor.Coins.First();
- Assert.Equal("A, B, C", createdCoin.Cluster.Labels);
+ Assert.Equal("A, B, C", createdCoin.HdPubKey.Cluster.Labels);
var createdchangeCoin = transactionProcessor.Coins.Last();
- Assert.Equal("A, B, C", createdchangeCoin.Cluster.Labels);
+ Assert.Equal("A, B, C", createdchangeCoin.HdPubKey.Cluster.Labels);
}
[Fact]
@@ -788,9 +788,9 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var tx2 = CreateCreditingTransaction(key.P2wpkhScript, Money.Coins(1.0m));
transactionProcessor.Process(tx2);
- var scoinA = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "A");
- var scoinB = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "B");
- var scoinC = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "C");
+ var scoinA = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "A");
+ var scoinB = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "B");
+ var scoinC = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "C");
var changeScript = transactionProcessor.NewKey("D").P2wpkhScript;
var coins = new[] { scoinA.Coin, scoinB.Coin, scoinC.Coin };
@@ -798,12 +798,12 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
transactionProcessor.Process(tx3);
var changeCoinD = Assert.Single(transactionProcessor.Coins);
- Assert.Equal("A, B, C, D", changeCoinD.Cluster.Labels);
+ Assert.Equal("A, B, C, D", changeCoinD.HdPubKey.Cluster.Labels);
key = transactionProcessor.NewKey("E");
var tx4 = CreateCreditingTransaction(key.P2wpkhScript, Money.Coins(1.0m));
transactionProcessor.Process(tx4);
- var scoinE = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "E");
+ var scoinE = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "E");
changeScript = transactionProcessor.NewKey("F").P2wpkhScript;
coins = new[] { changeCoinD.Coin, scoinE.Coin };
@@ -811,7 +811,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
transactionProcessor.Process(tx5);
var changeCoin = Assert.Single(transactionProcessor.Coins);
- Assert.Equal("A, B, C, D, E, F", changeCoin.Cluster.Labels);
+ Assert.Equal("A, B, C, D, E, F", changeCoin.HdPubKey.Cluster.Labels);
}
[Fact]
@@ -837,9 +837,9 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var tx2 = CreateCreditingTransaction(key.P2wpkhScript, Money.Coins(1.0m));
transactionProcessor.Process(tx2);
- var scoinA = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "A");
- var scoinB = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "B");
- var scoinC = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "C");
+ var scoinA = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "A");
+ var scoinB = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "B");
+ var scoinC = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "C");
var myself = transactionProcessor.NewKey("D").P2wpkhScript;
var changeScript = transactionProcessor.NewKey("").P2wpkhScript;
@@ -848,13 +848,13 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
transactionProcessor.Process(tx3);
var paymentCoin = Assert.Single(transactionProcessor.Coins, c => c.ScriptPubKey == myself);
- Assert.Equal("A, B, C, D", paymentCoin.Cluster.Labels);
+ Assert.Equal("A, B, C, D", paymentCoin.HdPubKey.Cluster.Labels);
var tx4 = CreateCreditingTransaction(myself, Money.Coins(7.0m));
transactionProcessor.Process(tx4);
Assert.Equal(2, transactionProcessor.Coins.Count(c => c.ScriptPubKey == myself));
var newPaymentCoin = Assert.Single(transactionProcessor.Coins, c => c.Amount == Money.Coins(7.0m));
- Assert.Equal("A, B, C, D", newPaymentCoin.Cluster.Labels);
+ Assert.Equal("A, B, C, D", newPaymentCoin.HdPubKey.Cluster.Labels);
}
[Fact]
@@ -879,8 +879,8 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
transactionProcessor.Process(tx2);
var coins = transactionProcessor.Coins;
- Assert.Equal(coins.First().Cluster, coins.Last().Cluster);
- Assert.Equal("A, B", coins.First().Cluster.Labels.ToString());
+ Assert.Equal(coins.First().HdPubKey.Cluster, coins.Last().HdPubKey.Cluster);
+ Assert.Equal("A, B", coins.First().HdPubKey.Cluster.Labels.ToString());
}
[Fact]
@@ -905,9 +905,9 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var tx2 = CreateCreditingTransaction(key.P2wpkhScript, Money.Coins(1.0m));
transactionProcessor.Process(tx2);
- var scoinA = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "A");
- var scoinB = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "B");
- var scoinC = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "C");
+ var scoinA = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "A");
+ var scoinB = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "B");
+ var scoinC = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "C");
var myself = transactionProcessor.NewKey("D").P2wpkhScript;
var changeScript = transactionProcessor.NewKey("").P2wpkhScript;
@@ -916,14 +916,14 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
transactionProcessor.Process(tx3);
var paymentCoin = Assert.Single(transactionProcessor.Coins, c => c.ScriptPubKey == myself);
- Assert.Equal("A, B, C, D", paymentCoin.Cluster.Labels);
+ Assert.Equal("A, B, C, D", paymentCoin.HdPubKey.Cluster.Labels);
coins = new[] { scoinB.Coin, scoinC.Coin, scoinA.Coin };
var tx4 = CreateSpendingTransaction(coins, myself, changeScript);
transactionProcessor.Process(tx4);
paymentCoin = Assert.Single(transactionProcessor.Coins, c => c.ScriptPubKey == myself);
- Assert.Equal("A, B, C, D", paymentCoin.Cluster.Labels);
+ Assert.Equal("A, B, C, D", paymentCoin.HdPubKey.Cluster.Labels);
}
[Fact]
@@ -949,9 +949,9 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var tx2 = CreateCreditingTransaction(key.P2wpkhScript, Money.Coins(1.0m));
transactionProcessor.Process(tx2);
- var scoinA = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "A");
- var scoinB = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "B");
- var scoinC = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "C");
+ var scoinA = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "A");
+ var scoinB = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "B");
+ var scoinC = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "C");
var myself = transactionProcessor.NewKey("D").P2wpkhScript;
var changeScript = transactionProcessor.NewKey("").P2wpkhScript;
@@ -960,19 +960,19 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
transactionProcessor.Process(tx3);
var paymentCoin = Assert.Single(transactionProcessor.Coins, c => c.ScriptPubKey == myself);
- Assert.Equal("A, B, C, D", paymentCoin.Cluster.Labels);
+ Assert.Equal("A, B, C, D", paymentCoin.HdPubKey.Cluster.Labels);
key = transactionProcessor.NewKey("X");
var tx4 = CreateCreditingTransaction(key.P2wpkhScript, Money.Coins(1.0m));
transactionProcessor.Process(tx4);
- var scoinX = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "X");
+ var scoinX = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "X");
coins = new[] { scoinB.Coin, scoinX.Coin, scoinC.Coin, scoinA.Coin };
var tx5 = CreateSpendingTransaction(coins, myself, changeScript);
transactionProcessor.Process(tx5);
paymentCoin = Assert.Single(transactionProcessor.Coins, c => c.ScriptPubKey == myself);
- Assert.Equal("A, B, C, D, X", paymentCoin.Cluster.Labels);
+ Assert.Equal("A, B, C, D, X", paymentCoin.HdPubKey.Cluster.Labels);
}
[Fact]
@@ -998,9 +998,9 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var tx2 = CreateCreditingTransaction(key.P2wpkhScript, Money.Coins(1.0m), height: 54323);
transactionProcessor.Process(tx2);
- var scoinA = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "A");
- var scoinB = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "B");
- var scoinC = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "C");
+ var scoinA = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "A");
+ var scoinB = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "B");
+ var scoinC = Assert.Single(transactionProcessor.Coins, c => c.HdPubKey.Cluster.Labels == "C");
var changeScript = transactionProcessor.NewKey("D").P2wpkhScript;
var coins = new[] { scoinA.Coin, scoinB.Coin, scoinC.Coin };
@@ -1008,20 +1008,20 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
transactionProcessor.Process(tx3);
var changeCoinD = Assert.Single(transactionProcessor.Coins);
- Assert.Equal("A, B, C, D", changeCoinD.Cluster.Labels);
- Assert.Equal(scoinA.Cluster, changeCoinD.Cluster);
- Assert.Equal(scoinB.Cluster, changeCoinD.Cluster);
- Assert.Equal(scoinC.Cluster, changeCoinD.Cluster);
+ Assert.Equal("A, B, C, D", changeCoinD.HdPubKey.Cluster.Labels);
+ Assert.Equal(scoinA.HdPubKey.Cluster, changeCoinD.HdPubKey.Cluster);
+ Assert.Equal(scoinB.HdPubKey.Cluster, changeCoinD.HdPubKey.Cluster);
+ Assert.Equal(scoinC.HdPubKey.Cluster, changeCoinD.HdPubKey.Cluster);
// reorg
Assert.True(changeCoinD.Confirmed);
transactionProcessor.UndoBlock(tx3.Height);
Assert.False(changeCoinD.Confirmed);
- Assert.Equal("A, B, C, D", changeCoinD.Cluster.Labels);
- Assert.Equal(scoinA.Cluster, changeCoinD.Cluster);
- Assert.Equal(scoinB.Cluster, changeCoinD.Cluster);
- Assert.Equal(scoinC.Cluster, changeCoinD.Cluster);
+ Assert.Equal("A, B, C, D", changeCoinD.HdPubKey.Cluster.Labels);
+ Assert.Equal(scoinA.HdPubKey.Cluster, changeCoinD.HdPubKey.Cluster);
+ Assert.Equal(scoinB.HdPubKey.Cluster, changeCoinD.HdPubKey.Cluster);
+ Assert.Equal(scoinC.HdPubKey.Cluster, changeCoinD.HdPubKey.Cluster);
}
[Fact]
@@ -1058,8 +1058,8 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var anonymousCoin = Assert.Single(transactionProcessor.Coins, c => c.Amount == Money.Coins(0.1m));
var changeCoin = Assert.Single(transactionProcessor.Coins, c => c.Amount == Money.Coins(0.9m));
- Assert.Empty(anonymousCoin.Cluster.Labels);
- Assert.NotEmpty(changeCoin.Cluster.Labels);
+ Assert.Empty(anonymousCoin.HdPubKey.Cluster.Labels);
+ Assert.NotEmpty(changeCoin.HdPubKey.Cluster.Labels);
}
private static SmartTransaction CreateSpendingTransaction(Coin coin, Script scriptPubKey = null, int height = 0)

MODIFY
WalletWasabi/Blockchain/Analysis/Clustering/Cluster.cs
WalletWasabi/Blockchain/Analysis/Clustering/Cluster.cs
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using WalletWasabi.Bases;
-using WalletWasabi.Blockchain.TransactionOutputs;
+using WalletWasabi.Blockchain.Keys;
namespace WalletWasabi.Blockchain.Analysis.Clustering
{
@@ -10,17 +10,17 @@ namespace WalletWasabi.Blockchain.Analysis.Clustering
{
private SmartLabel _labels;
- public Cluster(params SmartCoin[] coins)
- : this(coins as IEnumerable<SmartCoin>)
+ public Cluster(params HdPubKey[] keys)
+ : this(keys as IEnumerable<HdPubKey>)
{
}
- public Cluster(IEnumerable<SmartCoin> coins)
+ public Cluster(IEnumerable<HdPubKey> keys)
{
Lock = new object();
- Coins = coins.ToList();
- CoinsSet = Coins.ToHashSet();
- _labels = SmartLabel.Merge(Coins.Select(x => x.HdPubKey.Label));
+ Keys = keys.ToList();
+ CoinsSet = Keys.ToHashSet();
+ _labels = SmartLabel.Merge(Keys.Select(x => x.Label));
}
public SmartLabel Labels
@@ -29,42 +29,34 @@ namespace WalletWasabi.Blockchain.Analysis.Clustering
private set => RaiseAndSetIfChanged(ref _labels, value);
}
- public int Size => Coins.Count;
+ public int Size => Keys.Count;
private object Lock { get; }
- private List<SmartCoin> Coins { get; set; }
- private HashSet<SmartCoin> CoinsSet { get; set; }
+ private List<HdPubKey> Keys { get; set; }
+ private HashSet<HdPubKey> CoinsSet { get; set; }
- public void Merge(Cluster cluster) => Merge(cluster.Coins);
+ public void Merge(Cluster cluster) => Merge(cluster.Keys);
- public void Merge(IEnumerable<SmartCoin> coins)
+ public void Merge(IEnumerable<HdPubKey> keys)
{
lock (Lock)
{
var insertPosition = 0;
- foreach (var coin in coins.ToList())
+ foreach (var key in keys.ToList())
{
- if (CoinsSet.Add(coin))
+ if (CoinsSet.Add(key))
{
- Coins.Insert(insertPosition++, coin);
+ Keys.Insert(insertPosition++, key);
}
- coin.Cluster = this;
+ key.Cluster = this;
}
if (insertPosition > 0) // at least one element was inserted
{
- Labels = SmartLabel.Merge(Coins.Select(x => x.HdPubKey.Label));
+ Labels = SmartLabel.Merge(Keys.Select(x => x.Label));
}
}
}
- public IEnumerable<SmartCoin> GetCoins()
- {
- lock (Lock)
- {
- return Coins.ToList();
- }
- }
-
#region EqualityAndComparison
public override bool Equals(object? obj) => Equals(obj as Cluster);
@@ -76,11 +68,11 @@ namespace WalletWasabi.Blockchain.Analysis.Clustering
lock (Lock)
{
int hash = 0;
- if (Coins is { })
+ if (Keys is { })
{
- foreach (var coin in Coins)
+ foreach (var key in Keys)
{
- hash ^= coin.GetHashCode();
+ hash ^= key.GetHashCode();
}
}
return hash;

MODIFY
WalletWasabi/Blockchain/Keys/HdPubKey.cs
WalletWasabi/Blockchain/Keys/HdPubKey.cs
@@ -3,6 +3,7 @@ using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
+using WalletWasabi.Bases;
using WalletWasabi.Blockchain.Analysis.Clustering;
using WalletWasabi.Blockchain.TransactionOutputs;
using WalletWasabi.Helpers;
@@ -11,13 +12,16 @@ using WalletWasabi.JsonConverters;
namespace WalletWasabi.Blockchain.Keys
{
[JsonObject(MemberSerialization.OptIn)]
- public class HdPubKey : IEquatable<HdPubKey>
+ public class HdPubKey : NotifyPropertyChangedBase, IEquatable<HdPubKey>
{
+ private Cluster _cluster;
+
public HdPubKey(PubKey pubKey, KeyPath fullKeyPath, SmartLabel label, KeyState keyState)
{
PubKey = Guard.NotNull(nameof(pubKey), pubKey);
FullKeyPath = Guard.NotNull(nameof(fullKeyPath), fullKeyPath);
SetLabel(label, null);
+ _cluster = new Cluster(this);
KeyState = keyState;
P2pkScript = PubKey.ScriptPubKey;
@@ -46,6 +50,12 @@ namespace WalletWasabi.Blockchain.Keys
}
}
+ public Cluster Cluster
+ {
+ get => _cluster;
+ set => RaiseAndSetIfChanged(ref _cluster, value);
+ }
+
public HashSet<SmartCoin> Coins { get; } = new HashSet<SmartCoin>();
[JsonProperty(Order = 1)]

MODIFY
WalletWasabi/Blockchain/TransactionBuilding/SmartCoinSelector.cs
WalletWasabi/Blockchain/TransactionBuilding/SmartCoinSelector.cs
@@ -30,14 +30,14 @@ namespace WalletWasabi.Blockchain.TransactionBuilding
// Get unique clusters.
IEnumerable<Cluster> uniqueClusters = UnspentCoins
- .Select(coin => coin.Cluster)
+ .Select(coin => coin.HdPubKey.Cluster)
.Distinct();
// Build all the possible coin clusters, except when it's computationally too expensive.
List<IEnumerable<SmartCoin>> coinClusters = uniqueClusters.Count() < 10
? uniqueClusters
.CombinationsWithoutRepetition(ofLength: 1, upToLength: 6)
- .Select(clusterCombination => UnspentCoins.Where(coin => clusterCombination.Contains(coin.Cluster)))
+ .Select(clusterCombination => UnspentCoins.Where(coin => clusterCombination.Contains(coin.HdPubKey.Cluster)))
.ToList()
: new List<IEnumerable<SmartCoin>>();
@@ -45,7 +45,7 @@ namespace WalletWasabi.Blockchain.TransactionBuilding
// This operation is doing super advanced grouping on the coin clusters and adding properties to each of them.
var sayajinCoinClusters = coinClusters
- .Select(coins => (Coins: coins, Privacy: 1.0m / (1 + coins.Sum(x => x.Cluster.Labels.Count()))))
+ .Select(coins => (Coins: coins, Privacy: 1.0m / (1 + coins.Sum(x => x.HdPubKey.Cluster.Labels.Count()))))
.Select(group => new
{
group.Coins,
@@ -67,12 +67,9 @@ namespace WalletWasabi.Blockchain.TransactionBuilding
var coinsInBestClusterByScript = bestCoinCluster
.GroupBy(c => c.ScriptPubKey)
- .Select(group => new
- {
- Coins = group
- });
+ .Select(group => new { Coins = group });
- List<SmartCoin> coinsToSpend = new List<SmartCoin>();
+ var coinsToSpend = new List<SmartCoin>();
foreach (IGrouping<Script, SmartCoin> coinsGroup in coinsInBestClusterByScript
.Select(group => group.Coins))

MODIFY
WalletWasabi/Blockchain/TransactionOutputs/CoinsRegistry.cs
WalletWasabi/Blockchain/TransactionOutputs/CoinsRegistry.cs
@@ -18,7 +18,6 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
LatestCoinsSnapshot = new HashSet<SmartCoin>();
LatestSpentCoinsSnapshot = new HashSet<SmartCoin>();
InvalidateSnapshot = false;
- ClustersByScriptPubKey = new Dictionary<Script, Cluster>();
CoinsByOutPoint = new Dictionary<OutPoint, HashSet<SmartCoin>>();
PrivacyLevelThreshold = privacyLevelThreshold;
Lock = new object();
@@ -30,7 +29,6 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
private object Lock { get; set; }
private HashSet<SmartCoin> SpentCoins { get; }
private HashSet<SmartCoin> LatestSpentCoinsSnapshot { get; set; }
- private Dictionary<Script, Cluster> ClustersByScriptPubKey { get; }
private Dictionary<OutPoint, HashSet<SmartCoin>> CoinsByOutPoint { get; }
private int PrivacyLevelThreshold { get; }
@@ -87,15 +85,6 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
coin.RegisterToHdPubKey();
if (added)
{
- if (ClustersByScriptPubKey.TryGetValue(coin.ScriptPubKey, out var cluster))
- {
- coin.Cluster = cluster;
- }
- else
- {
- ClustersByScriptPubKey.Add(coin.ScriptPubKey, coin.Cluster);
- }
-
foreach (var outPoint in coin.Transaction.Transaction.Inputs.Select(x => x.PrevOut))
{
var newCoinSet = new HashSet<SmartCoin> { coin };
@@ -178,9 +167,8 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
{
if (newCoin.AnonymitySet < PrivacyLevelThreshold)
{
- spentCoin.Cluster.Merge(newCoin.Cluster);
- newCoin.Cluster = spentCoin.Cluster;
- ClustersByScriptPubKey.AddOrReplace(newCoin.ScriptPubKey, newCoin.Cluster);
+ spentCoin.HdPubKey.Cluster.Merge(newCoin.HdPubKey.Cluster);
+ newCoin.HdPubKey.Cluster = spentCoin.HdPubKey.Cluster;
}
}
}

MODIFY
WalletWasabi/Blockchain/TransactionOutputs/SmartCoin.cs
WalletWasabi/Blockchain/TransactionOutputs/SmartCoin.cs
@@ -24,8 +24,6 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
private ISecret? _secret;
- private Cluster _cluster;
-
private bool _confirmed;
private bool _isBanned;
@@ -52,8 +50,6 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
HdPubKey = pubKey;
- _cluster = new Cluster(this);
-
Transaction.WalletOutputs.Add(this);
}
@@ -144,12 +140,6 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
set => RaiseAndSetIfChanged(ref _secret, value);
}
- public Cluster Cluster
- {
- get => _cluster;
- set => RaiseAndSetIfChanged(ref _cluster, value);
- }
-
public bool Confirmed
{
get => _confirmed;

Consolidate progress