Prefer TxoRef class to (uint256 txid, uint index) ValueTuple
MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
@@ -181,7 +181,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
try
{
- (uint256 TransactionId, uint Index)[] toDequeue = selectedCoinViewModels.Where(x => x.CoinJoinInProgress).Select(x => (x.Model.TransactionId, x.Model.Index)).ToArray();
+ TxoRef[] toDequeue = selectedCoinViewModels.Where(x => x.CoinJoinInProgress).Select(x => x.Model.GetTxoRef()).ToArray();
if (toDequeue != null && toDequeue.Any())
{
await Global.ChaumianClient.DequeueCoinsFromMixAsync(toDequeue);

MODIFY
WalletWasabi/Models/ChaumianCoinJoin/CcjClientState.cs
WalletWasabi/Models/ChaumianCoinJoin/CcjClientState.cs
@@ -38,11 +38,11 @@ namespace WalletWasabi.Models.ChaumianCoinJoin
}
}
- public IEnumerable<(uint256 txid, uint index)> GetSpentCoins()
+ public IEnumerable<TxoRef> GetSpentCoins()
{
lock (StateLock)
{
- return WaitingList.Keys.Concat(Rounds.SelectMany(x => x.CoinsRegistered)).Where(x => !x.Unspent).Select(x => (x.TransactionId, x.Index)).ToArray();
+ return WaitingList.Keys.Concat(Rounds.SelectMany(x => x.CoinsRegistered)).Where(x => !x.Unspent).Select(x => x.GetTxoRef()).ToArray();
}
}
@@ -74,11 +74,11 @@ namespace WalletWasabi.Models.ChaumianCoinJoin
}
}
- public SmartCoin GetSingleOrDefaultCoin((uint256 txid, uint index) coinReference)
+ public SmartCoin GetSingleOrDefaultCoin(TxoRef coinReference)
{
lock (StateLock)
{
- return WaitingList.Keys.Concat(Rounds.SelectMany(x => x.CoinsRegistered)).SingleOrDefault(x => x.TransactionId == coinReference.txid && x.Index == coinReference.index);
+ return WaitingList.Keys.Concat(Rounds.SelectMany(x => x.CoinsRegistered)).SingleOrDefault(x => x.GetTxoRef() == coinReference);
}
}
@@ -90,19 +90,19 @@ namespace WalletWasabi.Models.ChaumianCoinJoin
}
}
- public SmartCoin GetSingleOrDefaultFromWaitingList((uint256 txid, uint index) coinReference)
+ public SmartCoin GetSingleOrDefaultFromWaitingList(TxoRef coinReference)
{
lock (StateLock)
{
- return WaitingList.Keys.SingleOrDefault(x => x.TransactionId == coinReference.txid && x.Index == coinReference.index);
+ return WaitingList.Keys.SingleOrDefault(x => x.GetTxoRef() == coinReference);
}
}
- public IEnumerable<(uint256 txid, uint index)> GetAllQueuedCoins()
+ public IEnumerable<TxoRef> GetAllQueuedCoins()
{
lock (StateLock)
{
- return WaitingList.Keys.Concat(Rounds.SelectMany(x => x.CoinsRegistered)).Select(x => (x.TransactionId, x.Index)).ToArray();
+ return WaitingList.Keys.Concat(Rounds.SelectMany(x => x.CoinsRegistered)).Select(x => x.GetTxoRef()).ToArray();
}
}
@@ -130,29 +130,29 @@ namespace WalletWasabi.Models.ChaumianCoinJoin
}
}
- public IEnumerable<(uint256 txid, uint index)> GetAllWaitingCoins()
+ public IEnumerable<TxoRef> GetAllWaitingCoins()
{
lock (StateLock)
{
- return WaitingList.Keys.Select(x => (x.TransactionId, x.Index)).ToArray();
+ return WaitingList.Keys.Select(x => x.GetTxoRef()).ToArray();
}
}
- public IEnumerable<(uint256 txid, uint index)> GetAllRegisteredCoins()
+ public IEnumerable<TxoRef> GetAllRegisteredCoins()
{
lock (StateLock)
{
- return Rounds.SelectMany(x => x.CoinsRegistered).Select(x => (x.TransactionId, x.Index)).ToArray();
+ return Rounds.SelectMany(x => x.CoinsRegistered).Select(x => x.GetTxoRef()).ToArray();
}
}
- public IEnumerable<(uint256 txid, uint index)> GetRegistrableCoins(int maximumInputCountPerPeer, Money denomination, Money feePerInputs, Money feePerOutputs)
+ public IEnumerable<TxoRef> GetRegistrableCoins(int maximumInputCountPerPeer, Money denomination, Money feePerInputs, Money feePerOutputs)
{
lock (StateLock)
{
if (!WaitingList.Any()) // To avoid computations.
{
- return Enumerable.Empty<(uint256 txid, uint index)>();
+ return Enumerable.Empty<TxoRef>();
}
Money amountNeededExceptInputFees = denomination + (feePerOutputs * 2);
@@ -168,11 +168,11 @@ namespace WalletWasabi.Models.ChaumianCoinJoin
}
}
- private IEnumerable<(uint256 txid, uint index)> GetRegistrableCoinsNoLock(int maximumInputCountPerPeer, Money feePerInputs, Money amountNeededExceptInputFees, bool allowUnconfirmedZeroLink)
+ private IEnumerable<TxoRef> GetRegistrableCoinsNoLock(int maximumInputCountPerPeer, Money feePerInputs, Money amountNeededExceptInputFees, bool allowUnconfirmedZeroLink)
{
if (!WaitingList.Any()) // To avoid computations.
{
- return Enumerable.Empty<(uint256 txid, uint index)>();
+ return Enumerable.Empty<TxoRef>();
}
Func<SmartCoin, bool> confirmationPredicate;
@@ -200,11 +200,11 @@ namespace WalletWasabi.Models.ChaumianCoinJoin
.FirstOrDefault();
if (best != default)
{
- return best.Select(x => (x.TransactionId, x.Index)).ToArray();
+ return best.Select(x => x.GetTxoRef()).ToArray();
}
}
- return Enumerable.Empty<(uint256 txid, uint index)>(); // Inputs are too small, max input to be registered is reached.
+ return Enumerable.Empty<TxoRef>(); // Inputs are too small, max input to be registered is reached.
}
public IEnumerable<long> GetActivelyMixingRounds()

MODIFY
WalletWasabi/Services/CcjClient.cs
WalletWasabi/Services/CcjClient.cs
@@ -429,7 +429,7 @@ namespace WalletWasabi.Services
{
try
{
- List<(uint256 txid, uint index)> registrableCoins = State.GetRegistrableCoins(
+ List<TxoRef> registrableCoins = State.GetRegistrableCoins(
inputRegistrableRound.State.MaximumInputCountPerPeer,
inputRegistrableRound.State.Denomination,
inputRegistrableRound.State.FeePerInputs,
@@ -477,7 +477,7 @@ namespace WalletWasabi.Services
internalNotCachedLockedKeys = KeyManager.GetKeys(KeyState.Locked, isInternal: true).Except(AccessCache.Keys);
Money inputSum = Money.Zero;
- foreach ((uint256 txid, uint index) coinReference in registrableCoins)
+ foreach (TxoRef coinReference in registrableCoins)
{
SmartCoin coin = State.GetSingleOrDefaultFromWaitingList(coinReference);
inputSum += coin.Amount;
@@ -571,7 +571,7 @@ namespace WalletWasabi.Services
uint256 blindedOutputScriptsHash = new uint256(Hashes.SHA256(blindedOutputScriptHashesByte));
var inputProofs = new List<InputProofModel>();
- foreach ((uint256 txid, uint index) coinReference in registrableCoins)
+ foreach (TxoRef coinReference in registrableCoins)
{
SmartCoin coin = State.GetSingleOrDefaultFromWaitingList(coinReference);
if (coin is null) throw new NotSupportedException("This is impossible.");
@@ -596,7 +596,7 @@ namespace WalletWasabi.Services
int minuteInt = int.Parse(minutesString);
string bannedInputString = parts[2].TrimEnd('.');
string[] bannedInputStringParts = bannedInputString.Split(':', StringSplitOptions.RemoveEmptyEntries);
- (uint256 txid, uint index) coinReference = (new uint256(bannedInputStringParts[1]), uint.Parse(bannedInputStringParts[0]));
+ TxoRef coinReference = new TxoRef(new uint256(bannedInputStringParts[1]), uint.Parse(bannedInputStringParts[0]));
SmartCoin coin = State.GetSingleOrDefaultFromWaitingList(coinReference);
if (coin is null) throw new NotSupportedException("This is impossible.");
coin.BannedUntilUtc = DateTimeOffset.UtcNow + TimeSpan.FromMinutes(minuteInt);
@@ -611,7 +611,7 @@ namespace WalletWasabi.Services
string[] parts = ex.Message.Split(new[] { "Provided input is not unspent: " }, StringSplitOptions.RemoveEmptyEntries);
string spentInputString = parts[1].TrimEnd('.');
string[] bannedInputStringParts = spentInputString.Split(':', StringSplitOptions.RemoveEmptyEntries);
- (uint256 txid, uint index) coinReference = (new uint256(bannedInputStringParts[1]), uint.Parse(bannedInputStringParts[0]));
+ TxoRef coinReference = new TxoRef(new uint256(bannedInputStringParts[1]), uint.Parse(bannedInputStringParts[0]));
SmartCoin coin = State.GetSingleOrDefaultFromWaitingList(coinReference);
if (coin is null) throw new NotSupportedException("This is impossible.");
coin.SpentAccordingToBackend = true;
@@ -640,7 +640,7 @@ namespace WalletWasabi.Services
}
var coinsRegistered = new List<SmartCoin>();
- foreach ((uint256 txid, uint index) coinReference in registrableCoins)
+ foreach (TxoRef coinReference in registrableCoins)
{
var coin = State.GetSingleOrDefaultFromWaitingList(coinReference);
if (coin is null) throw new NotSupportedException("This is impossible.");
@@ -753,19 +753,19 @@ namespace WalletWasabi.Services
{
await DequeueCoinsFromMixNoLockAsync(State.GetSpentCoins().ToArray());
- await DequeueCoinsFromMixNoLockAsync(coins.Select(x => (x.TransactionId, x.Index)).ToArray());
+ await DequeueCoinsFromMixNoLockAsync(coins.Select(x => x.GetTxoRef()).ToArray());
}
}
catch (TaskCanceledException)
{
await DequeueCoinsFromMixNoLockAsync(State.GetSpentCoins().ToArray());
- await DequeueCoinsFromMixNoLockAsync(coins.Select(x => (x.TransactionId, x.Index)).ToArray());
+ await DequeueCoinsFromMixNoLockAsync(coins.Select(x => x.GetTxoRef()).ToArray());
}
}
}
- public async Task DequeueCoinsFromMixAsync(params (uint256 txid, uint index)[] coins)
+ public async Task DequeueCoinsFromMixAsync(params TxoRef[] coins)
{
if (coins is null || !coins.Any()) return;
@@ -812,7 +812,7 @@ namespace WalletWasabi.Services
await DequeueCoinsFromMixNoLockAsync(State.GetAllQueuedCoins().ToArray());
}
- private async Task DequeueCoinsFromMixNoLockAsync(params (uint256 txid, uint index)[] coins)
+ private async Task DequeueCoinsFromMixNoLockAsync(params TxoRef[] coins)
{
if (coins is null || !coins.Any()) return;
@@ -919,7 +919,7 @@ namespace WalletWasabi.Services
State.DisposeAllAliceClients();
- IEnumerable<(uint256 txid, uint index)> allCoins = State.GetAllQueuedCoins();
+ IEnumerable<TxoRef> allCoins = State.GetAllQueuedCoins();
foreach (var coinReference in allCoins)
{
try
@@ -929,7 +929,7 @@ namespace WalletWasabi.Services
{
continue; // The coin isn't present anymore. Good. This should never happen though.
}
- await DequeueCoinsFromMixNoLockAsync((coin.TransactionId, coin.Index));
+ await DequeueCoinsFromMixNoLockAsync(coin.GetTxoRef());
}
catch (Exception ex)
{

Prefer TxoRef class to (uint256 txid, uint index) ValueTuple