Have only a single constructor for smartcoin
MODIFY
WalletWasabi.Gui/Global.cs
WalletWasabi.Gui/Global.cs
@@ -504,7 +504,7 @@ namespace WalletWasabi.Gui
bool isReceived = e.NewlyReceivedCoins.Any();
bool isConfirmedReceive = e.NewlyConfirmedReceivedCoins.Any();
bool isConfirmedSpent = e.NewlyConfirmedReceivedCoins.Any();
- Money miningFee = e.Transaction.Transaction.GetFee(e.SpentCoins.Select(x => x.GetCoin()).ToArray());
+ Money miningFee = e.Transaction.Transaction.GetFee(e.SpentCoins.Select(x => x.Coin).ToArray());
if (isReceived || isSpent)
{
Money receivedSum = e.NewlyReceivedCoins.Sum(x => x.Amount);

MODIFY
WalletWasabi.Tests/RegressionTests/CoinJoinTests.cs
WalletWasabi.Tests/RegressionTests/CoinJoinTests.cs
@@ -261,7 +261,7 @@ namespace WalletWasabi.Tests.RegressionTests
// Test DelayedClientRoundRegistration logic.
ClientRoundRegistration first = null;
var second = new ClientRoundRegistration(aliceClient,
- new[] { new SmartCoin(uint256.One, 1, Script.Empty, Money.Zero, new[] { new OutPoint(uint256.One, 1) }, Height.Unknown, true, 2) },
+ new[] { new SmartCoin(new Coin(uint256.One, 1, Money.Zero, Script.Empty), new[] { new OutPoint(uint256.One, 1) }, Height.Unknown, true, 2) },
BitcoinAddress.Create("12Rty3c8j3QiZSwLVaBtch6XUMZaja3RC7", Network.Main));
first = second;
second = null;
@@ -1243,7 +1243,7 @@ namespace WalletWasabi.Tests.RegressionTests
Assert.True(smartCoin2.CoinJoinInProgress);
// Make sure it does not throw.
- await chaumianClient1.DequeueCoinsFromMixAsync(new SmartCoin(network.Consensus.ConsensusFactory.CreateTransaction().GetHash(), 1, new Script(), Money.Parse("3"), new[] { new OutPoint(uint256.One, 0) }, Height.Mempool, replaceable: false, anonymitySet: 1), DequeueReason.UserRequested);
+ await chaumianClient1.DequeueCoinsFromMixAsync(new SmartCoin(new Coin(network.Consensus.ConsensusFactory.CreateTransaction().GetHash(), 1, Money.Parse("3"), new Script()), new[] { new OutPoint(uint256.One, 0) }, Height.Mempool, replaceable: false, anonymitySet: 1), DequeueReason.UserRequested);
Assert.True(2 == (await chaumianClient1.QueueCoinsToMixAsync(password, smartCoin1, smartCoin2)).Count());
await chaumianClient1.DequeueCoinsFromMixAsync(smartCoin1, DequeueReason.UserRequested);

MODIFY
WalletWasabi.Tests/UnitTests/SmartCoinTests.cs
WalletWasabi.Tests/UnitTests/SmartCoinTests.cs
@@ -22,10 +22,10 @@ namespace WalletWasabi.Tests.UnitTests
var height = Height.Mempool;
var label = "foo";
- var coin = new SmartCoin(txId, index, scriptPubKey, amount, spentOutputs, height, tx.RBF, tx.GetAnonymitySet(index), label, txId);
+ var coin = new SmartCoin(new Coin(txId, index, amount, scriptPubKey), spentOutputs, height, tx.RBF, tx.GetAnonymitySet(index), label, txId);
// If the txId or the index differ, equality should think it's a different coin.
- var differentCoin = new SmartCoin(txId, index + 1, scriptPubKey, amount, spentOutputs, height, tx.RBF, tx.GetAnonymitySet(index + 1), label, txId);
+ var differentCoin = new SmartCoin(new Coin(txId, index + 1, amount, scriptPubKey), spentOutputs, height, tx.RBF, tx.GetAnonymitySet(index + 1), label, txId);
var differentOutput = tx.Outputs[1];
var differentSpentOutputs = new[]
{
@@ -33,7 +33,7 @@ namespace WalletWasabi.Tests.UnitTests
};
// If the txId and the index are the same, equality should think it's the same coin.
- var sameCoin = new SmartCoin(txId, index, differentOutput.ScriptPubKey, differentOutput.Value, differentSpentOutputs, Height.Unknown, tx.RBF, tx.GetAnonymitySet(index), "boo", null);
+ var sameCoin = new SmartCoin(new Coin(txId, index, differentOutput.Value, differentOutput.ScriptPubKey), differentSpentOutputs, Height.Unknown, tx.RBF, tx.GetAnonymitySet(index), "boo", null);
Assert.Equal(coin, sameCoin);
Assert.NotEqual(coin, differentCoin);

MODIFY
WalletWasabi.Tests/UnitTests/Transactions/PayjoinTests.cs
WalletWasabi.Tests/UnitTests/Transactions/PayjoinTests.cs
@@ -44,7 +44,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
};
pubKey.SetLabel(slabel);
pubKey.SetKeyState(KeyState.Used);
- return new SmartCoin(RandomUtils.GetUInt256(), (uint)randomIndex(), pubKey.P2wpkhScript, Money.Coins(amount), spentOutput, height, false, anonymitySet, slabel, pubKey: pubKey);
+ return new SmartCoin(new Coin(RandomUtils.GetUInt256(), (uint)randomIndex(), Money.Coins(amount), pubKey.P2wpkhScript), spentOutput, height, false, anonymitySet, slabel, pubKey: pubKey);
}
public static PSBT GenerateRandomTransaction()

MODIFY
WalletWasabi.Tests/UnitTests/Transactions/TransactionFactoryTests.cs
WalletWasabi.Tests/UnitTests/Transactions/TransactionFactoryTests.cs
@@ -594,7 +594,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
};
pubKey.SetLabel(slabel);
pubKey.SetKeyState(KeyState.Used);
- return new SmartCoin(RandomUtils.GetUInt256(), (uint)randomIndex(), pubKey.P2wpkhScript, Money.Coins(amount), spentOutput, height, false, anonymitySet, slabel, pubKey: pubKey);
+ return new SmartCoin(new Coin(RandomUtils.GetUInt256(), (uint)randomIndex(), Money.Coins(amount), pubKey.P2wpkhScript), spentOutput, height, false, anonymitySet, slabel, pubKey: pubKey);
}
private TransactionFactory CreateTransactionFactory(

MODIFY
WalletWasabi.Tests/UnitTests/Transactions/TransactionProcessorTests.cs
WalletWasabi.Tests/UnitTests/Transactions/TransactionProcessorTests.cs
@@ -343,7 +343,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
Assert.True(unconfirmedCoin2.IsReplaceable());
// Spend the received coin
- var tx2 = CreateSpendingTransaction(unconfirmedCoin1.GetCoin(), transactionProcessor.NewKey("D").P2wpkhScript);
+ var tx2 = CreateSpendingTransaction(unconfirmedCoin1.Coin, transactionProcessor.NewKey("D").P2wpkhScript);
tx2.Transaction.Outputs[0].Value = Money.Coins(0.7m);
var relevant2 = transactionProcessor.Process(tx2);
Assert.True(relevant2.IsNews);
@@ -468,7 +468,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var tx1 = CreateCreditingTransaction(NewScript("B"), Money.Coins(1.0m), height: 54321);
transactionProcessor.Process(tx0, tx1);
- var createdCoins = transactionProcessor.Coins.Select(x => x.GetCoin()).ToArray(); // 2 coins of 1.0 btc each
+ var createdCoins = transactionProcessor.Coins.Select(x => x.Coin).ToArray(); // 2 coins of 1.0 btc each
// Spend the received coins
var destinationScript = NewScript("myself");
@@ -484,7 +484,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
// At this moment we have one 1.2btc and one 0.8btc replaceable coins and one 1.0btc final coin
var latestCreatedCoin = Assert.Single(transactionProcessor.Coins.CreatedBy(tx3.Transaction.GetHash()));
- var coinsToSpend = createdCoins.Concat(new[] { latestCreatedCoin.GetCoin() }).ToArray();
+ var coinsToSpend = createdCoins.Concat(new[] { latestCreatedCoin.Coin }).ToArray();
// Spend them again with a different amount
var destinationScript2 = new Key().PubKey.WitHash.ScriptPubKey; // spend to someone else
@@ -529,7 +529,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var tx1 = CreateCreditingTransaction(NewScript("B"), Money.Coins(1.0m), height: 54321);
transactionProcessor.Process(tx1);
- var createdCoins = transactionProcessor.Coins.Select(x => x.GetCoin()).ToArray(); // 2 coins of 1.0 btc each
+ var createdCoins = transactionProcessor.Coins.Select(x => x.Coin).ToArray(); // 2 coins of 1.0 btc each
// Spend the received coins (replaceable)
var destinationScript = NewScript("myself");
@@ -744,7 +744,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
// Spend the received coin to someone else B
var changeScript1 = transactionProcessor.NewKey("B").P2wpkhScript;
- var tx1 = CreateSpendingTransaction(new[] { createdCoin.GetCoin() }, new Key().ScriptPubKey, changeScript1);
+ var tx1 = CreateSpendingTransaction(new[] { createdCoin.Coin }, new Key().ScriptPubKey, changeScript1);
transactionProcessor.Process(tx1);
createdCoin = transactionProcessor.Coins.First();
Assert.Equal("A, B", createdCoin.Cluster.Labels);
@@ -752,7 +752,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
// Spend the received coin to myself else C
var myselfScript = transactionProcessor.NewKey("C").P2wpkhScript;
var changeScript2 = transactionProcessor.NewKey("").P2wpkhScript;
- var tx2 = CreateSpendingTransaction(new[] { createdCoin.GetCoin() }, myselfScript, changeScript2);
+ var tx2 = CreateSpendingTransaction(new[] { createdCoin.Coin }, myselfScript, changeScript2);
transactionProcessor.Process(tx2);
Assert.Equal(2, transactionProcessor.Coins.Count());
@@ -793,7 +793,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var scoinC = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "C");
var changeScript = transactionProcessor.NewKey("D").P2wpkhScript;
- var coins = new[] { scoinA.GetCoin(), scoinB.GetCoin(), scoinC.GetCoin() };
+ var coins = new[] { scoinA.Coin, scoinB.Coin, scoinC.Coin };
var tx3 = CreateSpendingTransaction(coins, new Key().ScriptPubKey, changeScript);
transactionProcessor.Process(tx3);
@@ -806,7 +806,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var scoinE = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "E");
changeScript = transactionProcessor.NewKey("F").P2wpkhScript;
- coins = new[] { changeCoinD.GetCoin(), scoinE.GetCoin() };
+ coins = new[] { changeCoinD.Coin, scoinE.Coin };
var tx5 = CreateSpendingTransaction(coins, new Key().ScriptPubKey, changeScript);
transactionProcessor.Process(tx5);
@@ -843,7 +843,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var myself = transactionProcessor.NewKey("D").P2wpkhScript;
var changeScript = transactionProcessor.NewKey("").P2wpkhScript;
- var coins = new[] { scoinA.GetCoin(), scoinB.GetCoin(), scoinC.GetCoin() };
+ var coins = new[] { scoinA.Coin, scoinB.Coin, scoinC.Coin };
var tx3 = CreateSpendingTransaction(coins, myself, changeScript);
transactionProcessor.Process(tx3);
@@ -875,7 +875,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var result = transactionProcessor.Process(tx1);
key = transactionProcessor.NewKey("B");
- var tx2 = CreateSpendingTransaction(result.ReceivedCoins[0].GetCoin(), key.P2wpkhScript);
+ var tx2 = CreateSpendingTransaction(result.ReceivedCoins[0].Coin, key.P2wpkhScript);
transactionProcessor.Process(tx2);
var coins = transactionProcessor.Coins;
@@ -911,14 +911,14 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var myself = transactionProcessor.NewKey("D").P2wpkhScript;
var changeScript = transactionProcessor.NewKey("").P2wpkhScript;
- var coins = new[] { scoinA.GetCoin(), scoinB.GetCoin(), scoinC.GetCoin() };
+ var coins = new[] { scoinA.Coin, scoinB.Coin, scoinC.Coin };
var tx3 = CreateSpendingTransaction(coins, myself, changeScript, replaceable: true);
transactionProcessor.Process(tx3);
var paymentCoin = Assert.Single(transactionProcessor.Coins, c => c.ScriptPubKey == myself);
Assert.Equal("A, B, C, D", paymentCoin.Cluster.Labels);
- coins = new[] { scoinB.GetCoin(), scoinC.GetCoin(), scoinA.GetCoin() };
+ coins = new[] { scoinB.Coin, scoinC.Coin, scoinA.Coin };
var tx4 = CreateSpendingTransaction(coins, myself, changeScript);
transactionProcessor.Process(tx4);
@@ -955,7 +955,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var myself = transactionProcessor.NewKey("D").P2wpkhScript;
var changeScript = transactionProcessor.NewKey("").P2wpkhScript;
- var coins = new[] { scoinA.GetCoin(), scoinB.GetCoin(), scoinC.GetCoin() };
+ var coins = new[] { scoinA.Coin, scoinB.Coin, scoinC.Coin };
var tx3 = CreateSpendingTransaction(coins, myself, changeScript, replaceable: true);
transactionProcessor.Process(tx3);
@@ -967,7 +967,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
transactionProcessor.Process(tx4);
var scoinX = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "X");
- coins = new[] { scoinB.GetCoin(), scoinX.GetCoin(), scoinC.GetCoin(), scoinA.GetCoin() };
+ coins = new[] { scoinB.Coin, scoinX.Coin, scoinC.Coin, scoinA.Coin };
var tx5 = CreateSpendingTransaction(coins, myself, changeScript);
transactionProcessor.Process(tx5);
@@ -1003,7 +1003,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var scoinC = Assert.Single(transactionProcessor.Coins, c => c.Cluster.Labels == "C");
var changeScript = transactionProcessor.NewKey("D").P2wpkhScript;
- var coins = new[] { scoinA.GetCoin(), scoinB.GetCoin(), scoinC.GetCoin() };
+ var coins = new[] { scoinA.Coin, scoinB.Coin, scoinC.Coin };
var tx3 = CreateSpendingTransaction(coins, new Key().ScriptPubKey, changeScript, height: 55555);
transactionProcessor.Process(tx3);

MODIFY
WalletWasabi/Blockchain/TransactionBuilding/SmartCoinSelector.cs
WalletWasabi/Blockchain/TransactionBuilding/SmartCoinSelector.cs
@@ -85,7 +85,7 @@ namespace WalletWasabi.Blockchain.TransactionBuilding
}
}
- return coinsToSpend.Select(c => c.GetCoin());
+ return coinsToSpend.Select(c => c.Coin);
}
}
}

MODIFY
WalletWasabi/Blockchain/TransactionOutputs/SmartCoin.cs
WalletWasabi/Blockchain/TransactionOutputs/SmartCoin.cs
@@ -35,18 +35,9 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
#region Constructors
public SmartCoin(Coin coin, OutPoint[] spentOutputs, Height height, bool replaceable, int anonymitySet, SmartLabel label = null, uint256 spenderTransactionId = null, bool coinJoinInProgress = false, DateTimeOffset? bannedUntilUtc = null, bool spentAccordingToBackend = false, HdPubKey pubKey = null)
- : this(coin.Outpoint.Hash, coin.Outpoint.N, coin.ScriptPubKey, coin.Amount, spentOutputs, height, replaceable, anonymitySet, label, spenderTransactionId, coinJoinInProgress, bannedUntilUtc, spentAccordingToBackend, pubKey)
{
- }
-
- public SmartCoin(uint256 transactionId, uint index, Script scriptPubKey, Money amount, OutPoint[] spentOutputs, Height height, bool replaceable, int anonymitySet, SmartLabel label = null, uint256 spenderTransactionId = null, bool coinJoinInProgress = false, DateTimeOffset? bannedUntilUtc = null, bool spentAccordingToBackend = false, HdPubKey pubKey = null)
- {
- Guard.NotNull(nameof(transactionId), transactionId);
- Guard.NotNull(nameof(index), index);
- OutPoint = new OutPoint(transactionId, index);
+ Coin = coin;
HashCode = (TransactionId, Index).GetHashCode();
- ScriptPubKey = Guard.NotNull(nameof(scriptPubKey), scriptPubKey);
- Amount = Guard.NotNull(nameof(amount), amount);
Height = height;
SpentOutputs = Guard.NotNullOrEmpty(nameof(spentOutputs), spentOutputs);
WasReplaceable = replaceable;
@@ -71,16 +62,18 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
#region Properties
- public uint256 TransactionId => OutPoint.Hash;
+ public Coin Coin { get; }
- public uint Index => OutPoint.N;
- private int HashCode { get; }
+ public Script ScriptPubKey => Coin.ScriptPubKey;
- public OutPoint OutPoint { get; }
+ public Money Amount => Coin.Amount;
- public Script ScriptPubKey { get; }
+ public OutPoint OutPoint => Coin.Outpoint;
- public Money Amount { get; }
+ public uint256 TransactionId => OutPoint.Hash;
+
+ public uint Index => OutPoint.N;
+ private int HashCode { get; }
public Height Height
{
@@ -203,8 +196,6 @@ namespace WalletWasabi.Blockchain.TransactionOutputs
public bool IsReplaceable() => WasReplaceable && !Confirmed;
- public Coin GetCoin() => new Coin(TransactionId, Index, Amount, ScriptPubKey);
-
#endregion Methods
#region EqualityAndComparison

MODIFY
WalletWasabi/Blockchain/TransactionProcessing/TransactionProcessor.cs
WalletWasabi/Blockchain/TransactionProcessing/TransactionProcessor.cs
@@ -201,7 +201,8 @@ namespace WalletWasabi.Blockchain.TransactionProcessing
anonset += spentOwnCoins.Min(x => x.AnonymitySet) - 1;
}
- SmartCoin newCoin = new SmartCoin(txId, i, output.ScriptPubKey, output.Value, tx.Transaction.Inputs.ToOutPoints().ToArray(), tx.Height, tx.IsRBF, anonset, foundKey.Label, spenderTransactionId: null, false, pubKey: foundKey); // Do not inherit locked status from key, that's different.
+ var c = new Coin(txId, i, output.Value, output.ScriptPubKey);
+ SmartCoin newCoin = new SmartCoin(c, tx.Transaction.Inputs.ToOutPoints().ToArray(), tx.Height, tx.IsRBF, anonset, foundKey.Label, spenderTransactionId: null, false, pubKey: foundKey); // Do not inherit locked status from key, that's different.
result.ReceivedCoins.Add(newCoin);
// If we did not have it.

MODIFY
WalletWasabi/Blockchain/Transactions/TransactionFactory.cs
WalletWasabi/Blockchain/Transactions/TransactionFactory.cs
@@ -108,7 +108,7 @@ namespace WalletWasabi.Blockchain.Transactions
TransactionBuilder builder = Network.CreateTransactionBuilder();
builder.SetCoinSelector(new SmartCoinSelector(allowedSmartCoinInputs));
- builder.AddCoins(allowedSmartCoinInputs.Select(c => c.GetCoin()));
+ builder.AddCoins(allowedSmartCoinInputs.Select(c => c.Coin));
builder.SetLockTime(lockTimeSelector());
foreach (var request in payments.Requests.Where(x => x.Amount.Type == MoneyRequestType.Value))
@@ -276,7 +276,8 @@ namespace WalletWasabi.Blockchain.Transactions
TxOut output = tx.Outputs[i];
var anonset = tx.GetAnonymitySet(i) + spentCoins.Min(x => x.AnonymitySet) - 1; // Minus 1, because count own only once.
var foundKey = KeyManager.GetKeyForScriptPubKey(output.ScriptPubKey);
- var coin = new SmartCoin(tx.GetHash(), i, output.ScriptPubKey, output.Value, tx.Inputs.ToOutPoints().ToArray(), Height.Unknown, tx.RBF, anonset, pubKey: foundKey);
+ var c = new Coin(tx.GetHash(), i, output.Value, output.ScriptPubKey);
+ var coin = new SmartCoin(c, tx.Inputs.ToOutPoints().ToArray(), Height.Unknown, tx.RBF, anonset, pubKey: foundKey);
label = SmartLabel.Merge(label, coin.Label); // foundKey's label is already added to the coinlabel.
if (foundKey is null)

MODIFY
WalletWasabi/CoinJoin/Client/Clients/CoinJoinClient.cs
WalletWasabi/CoinJoin/Client/Clients/CoinJoinClient.cs
@@ -399,7 +399,7 @@ namespace WalletWasabi.CoinJoin.Client.Clients
ongoingRound
.Registration
.CoinsRegistered
- .Select(x => x.GetCoin()));
+ .Select(x => x.Coin));
var myDic = new Dictionary<int, WitScript>();

Have only a single constructor for smartcoin