Try to reduce the risks raised by codescene
MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/SendControlViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/SendControlViewModel.cs
@@ -382,7 +382,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
var payjoinEndPointUri = new Uri(PayjoinEndPoint);
payjoinClient = new PayjoinClient(payjoinEndPointUri, Global.TorManager.TorSocks5EndPoint);
}
- BuildTransactionResult result = await Task.Run(() => Wallet.BuildTransaction(Password, intent, feeStrategy, payjoinClient, allowUnconfirmed: true, allowedInputs: selectedCoinReferences));
+ BuildTransactionResult result = await Task.Run(() => Wallet.BuildTransaction(Password, intent, feeStrategy, allowUnconfirmed: true, allowedInputs: selectedCoinReferences, payjoinClient: payjoinClient));
await DoAfterBuildTransaction(result);
}

MODIFY
WalletWasabi.Tests/RegressionTests/BuildTests.cs
WalletWasabi.Tests/RegressionTests/BuildTests.cs
@@ -118,7 +118,6 @@ namespace WalletWasabi.Tests.RegressionTests
new DestinationRequest(scp, MoneyRequest.CreateAllRemaining(), "zero"),
new DestinationRequest(scp, MoneyRequest.CreateAllRemaining(), "zero")),
FeeStrategy.SevenDaysConfirmationTargetStrategy,
- null,
false));
// Get some money, make it confirm.
@@ -146,30 +145,30 @@ namespace WalletWasabi.Tests.RegressionTests
var operations = new PaymentIntent(
new DestinationRequest(scp, Money.Coins(1m), subtractFee: true),
new DestinationRequest(scp, Money.Coins(0.5m)));
- Assert.Throws<InsufficientBalanceException>(() => wallet.BuildTransaction(password, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, null, false));
+ Assert.Throws<InsufficientBalanceException>(() => wallet.BuildTransaction(password, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, false));
// No enough money (only one confirmed coin, no unconfirmed allowed)
operations = new PaymentIntent(scp, Money.Coins(1.5m));
Assert.Throws<InsufficientBalanceException>(() => wallet.BuildTransaction(null, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy));
// No enough money (only one confirmed coin, unconfirmed allowed)
- Assert.Throws<InsufficientBalanceException>(() => wallet.BuildTransaction(null, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, null, true));
+ Assert.Throws<InsufficientBalanceException>(() => wallet.BuildTransaction(null, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, true));
// Add new money with no confirmation
var txId2 = await rpc.SendToAddressAsync(keyManager.GetNextReceiveKey("bar", out _).GetP2wpkhAddress(network), Money.Coins(2m));
await Task.Delay(1000); // Wait tx to arrive and get processed.
// Enough money (one confirmed coin and one unconfirmed coin, unconfirmed are NOT allowed)
- Assert.Throws<InsufficientBalanceException>(() => wallet.BuildTransaction(null, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, null, false));
+ Assert.Throws<InsufficientBalanceException>(() => wallet.BuildTransaction(null, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, false));
// Enough money (one unconfirmed coin, unconfirmed are allowed)
- var btx = wallet.BuildTransaction(password, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, null, true);
+ var btx = wallet.BuildTransaction(password, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, true);
var spentCoin = Assert.Single(btx.SpentCoins);
Assert.False(spentCoin.Confirmed);
// Enough money (one confirmed coin and one unconfirmed coin, unconfirmed are allowed)
operations = new PaymentIntent(scp, Money.Coins(2.5m));
- btx = wallet.BuildTransaction(password, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, null, true);
+ btx = wallet.BuildTransaction(password, operations, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, true);
Assert.Equal(2, btx.SpentCoins.Count());
Assert.Equal(1, btx.SpentCoins.Count(c => c.Confirmed));
Assert.Equal(1, btx.SpentCoins.Count(c => !c.Confirmed));

MODIFY
WalletWasabi.Tests/RegressionTests/SendTests.cs
WalletWasabi.Tests/RegressionTests/SendTests.cs
@@ -429,7 +429,7 @@ namespace WalletWasabi.Tests.RegressionTests
// covers:
// disallow unconfirmed with allowed inputs
- res = wallet.BuildTransaction(password, toSend, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, null, false, allowedInputs: allowedInputs);
+ res = wallet.BuildTransaction(password, toSend, FeeStrategy.TwentyMinutesConfirmationTargetStrategy, false, allowedInputs: allowedInputs);
activeOutput = res.InnerWalletOutputs.Single(x => x.ScriptPubKey == receive);
Assert.Single(res.InnerWalletOutputs);

MODIFY
WalletWasabi.Tests/UnitTests/Transactions/PayjoinTests.cs
WalletWasabi.Tests/UnitTests/Transactions/PayjoinTests.cs
@@ -34,14 +34,14 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var transactionFactory = CreateTransactionFactory(new[]
{
("Pablo", 0, 0.1m, confirmed: true, anonymitySet: 1)
- }, payjoinClient: payjoinClient);
+ });
var allowedCoins = transactionFactory.Coins.ToArray();
var amount = Money.Coins(0.001m);
var payment = new PaymentIntent(new Key().ScriptPubKey, amount);
- var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), allowedCoins.Select(x => x.OutPoint));
+ var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), allowedCoins.Select(x => x.OutPoint), payjoinClient);
Assert.Equal(TransactionCheckResult.Success, tx.Transaction.Transaction.Check());
Assert.True(tx.Signed);
@@ -81,13 +81,13 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
var transactionFactory = CreateTransactionFactory(new[]
{
("Pablo", 0, 0.1m, confirmed: true, anonymitySet: 1)
- }, payjoinClient: payjoinClient);
+ });
var allowedCoins = transactionFactory.Coins.ToArray();
var payment = new PaymentIntent(new Key().PubKey.WitHash.ScriptPubKey, amountToPay);
- var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), allowedCoins.Select(x => x.OutPoint));
+ var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), allowedCoins.Select(x => x.OutPoint), payjoinClient);
Assert.Equal(TransactionCheckResult.Success, tx.Transaction.Transaction.Check());
Assert.True(tx.Signed);
@@ -119,8 +119,8 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- var transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ var transactionFactory = CreateTransactionFactory(walletCoins);
+ var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
///////
@@ -144,8 +144,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
}
@@ -167,8 +166,8 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- var transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ var transactionFactory = CreateTransactionFactory(walletCoins);
+ var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
////////
@@ -183,8 +182,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
////////
@@ -199,8 +197,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
////////
@@ -215,8 +212,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
////////
@@ -232,8 +228,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
////////
@@ -248,8 +243,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
////////
@@ -264,8 +258,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
////////
@@ -280,8 +273,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
////////
@@ -296,8 +288,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
}
@@ -322,8 +313,8 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
})
};
- var transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ var transactionFactory = CreateTransactionFactory(walletCoins);
+ var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
}
@@ -342,8 +333,8 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
OnSendAsync = PayjoinServer(statusCode: HttpStatusCode.InternalServerError)
};
- var transactionFactory = CreateTransactionFactory(walletCoins, payjoinClient: new PayjoinClient(httpClient));
- var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint));
+ var transactionFactory = CreateTransactionFactory(walletCoins);
+ var tx = transactionFactory.BuildTransaction(payment, new FeeRate(2m), transactionFactory.Coins.Select(x => x.OutPoint), new PayjoinClient(httpClient));
Assert.Single(tx.Transaction.Transaction.Inputs);
}
@@ -375,8 +366,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
private TransactionFactory CreateTransactionFactory(
IEnumerable<(string Label, int KeyIndex, decimal Amount, bool Confirmed, int AnonymitySet)> coins,
bool allowUnconfirmed = true,
- bool watchOnly = false,
- IPayjoinClient payjoinClient = null)
+ bool watchOnly = false)
{
var (password, keyManager) = watchOnly ? WatchOnlyKeyManager() : DefaultKeyManager();
@@ -392,8 +382,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
}
}
var coinsView = new CoinsView(scoins);
- payjoinClient ??= new NullPayjoinClient();
- return new TransactionFactory(Network.Main, keyManager, coinsView, payjoinClient, password, allowUnconfirmed);
+ return new TransactionFactory(Network.Main, keyManager, coinsView, password, allowUnconfirmed);
}
private static (string, KeyManager) DefaultKeyManager()

MODIFY
WalletWasabi.Tests/UnitTests/Transactions/TransactionFactoryTests.cs
WalletWasabi.Tests/UnitTests/Transactions/TransactionFactoryTests.cs
@@ -212,7 +212,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
}
var coinsView = new CoinsView(scoins.ToArray());
- var transactionFactory = new TransactionFactory(Network.Main, keyManager, coinsView, new NullPayjoinClient(), password);
+ var transactionFactory = new TransactionFactory(Network.Main, keyManager, coinsView, password);
// Two 0.9btc coins are enough
var payment = new PaymentIntent(new Key().ScriptPubKey, Money.Coins(1.75m), label: "Sophie");
@@ -585,7 +585,7 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
}
}
var coinsView = new CoinsView(scoins);
- return new TransactionFactory(Network.Main, keyManager, coinsView, new NullPayjoinClient(), password, allowUnconfirmed);
+ return new TransactionFactory(Network.Main, keyManager, coinsView, password, allowUnconfirmed);
}
private static (string, KeyManager) DefaultKeyManager()

MODIFY
WalletWasabi/Blockchain/Transactions/TransactionFactory.cs
WalletWasabi/Blockchain/Transactions/TransactionFactory.cs
@@ -21,14 +21,13 @@ namespace WalletWasabi.Blockchain.Transactions
public class TransactionFactory
{
/// <param name="allowUnconfirmed">Allow to spend unconfirmed transactions, if necessary.</param>
- public TransactionFactory(Network network, KeyManager keyManager, ICoinsView coins, IPayjoinClient payJoinClient, string password = "", bool allowUnconfirmed = false)
+ public TransactionFactory(Network network, KeyManager keyManager, ICoinsView coins, string password = "", bool allowUnconfirmed = false)
{
Network = network;
KeyManager = keyManager;
Coins = coins;
Password = password;
AllowUnconfirmed = allowUnconfirmed;
- PayjoinClient = payJoinClient;
}
public Network Network { get; }
@@ -36,7 +35,6 @@ namespace WalletWasabi.Blockchain.Transactions
public ICoinsView Coins { get; }
public string Password { get; }
public bool AllowUnconfirmed { get; }
- public IPayjoinClient PayjoinClient { get; }
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentNullException"></exception>
@@ -44,8 +42,9 @@ namespace WalletWasabi.Blockchain.Transactions
public BuildTransactionResult BuildTransaction(
PaymentIntent payments,
FeeRate feeRate,
- IEnumerable<OutPoint> allowedInputs = null)
- => BuildTransaction(payments, () => feeRate, allowedInputs, () => LockTime.Zero);
+ IEnumerable<OutPoint> allowedInputs = null,
+ IPayjoinClient payjoinClient = null)
+ => BuildTransaction(payments, () => feeRate, allowedInputs, () => LockTime.Zero, payjoinClient);
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentNullException"></exception>
@@ -54,9 +53,11 @@ namespace WalletWasabi.Blockchain.Transactions
PaymentIntent payments,
Func<FeeRate> feeRateFetcher,
IEnumerable<OutPoint> allowedInputs = null,
- Func<LockTime> lockTimeSelector = null)
+ Func<LockTime> lockTimeSelector = null,
+ IPayjoinClient payjoinClient = null)
{
payments = Guard.NotNull(nameof(payments), payments);
+ payjoinClient ??= new NullPayjoinClient();
lockTimeSelector ??= () => LockTime.Zero;
long totalAmount = payments.TotalAmount.Satoshi;
@@ -244,7 +245,7 @@ namespace WalletWasabi.Blockchain.Transactions
// Try to pay using payjoin
try
{
- psbt = PayjoinClient.RequestPayjoin(psbt,
+ psbt = payjoinClient.RequestPayjoin(psbt,
KeyManager.ExtPubKey,
new RootedKeyPath(KeyManager.MasterFingerprint.Value, KeyManager.DefaultAccountKeyPath),
CancellationToken.None).GetAwaiter().GetResult();

MODIFY
WalletWasabi/Wallets/Wallet.cs
WalletWasabi/Wallets/Wallet.cs
@@ -217,11 +217,11 @@ namespace WalletWasabi.Wallets
string password,
PaymentIntent payments,
FeeStrategy feeStrategy,
- IPayjoinClient payjoinClient = null,
bool allowUnconfirmed = false,
- IEnumerable<OutPoint> allowedInputs = null)
+ IEnumerable<OutPoint> allowedInputs = null,
+ IPayjoinClient payjoinClient = null)
{
- var builder = new TransactionFactory(Network, KeyManager, Coins, payjoinClient ?? new NullPayjoinClient(), password, allowUnconfirmed);
+ var builder = new TransactionFactory(Network, KeyManager, Coins, password, allowUnconfirmed);
return builder.BuildTransaction(
payments,
() =>
@@ -240,7 +240,8 @@ namespace WalletWasabi.Wallets
}
},
allowedInputs,
- SelectLockTimeForTransaction);
+ SelectLockTimeForTransaction,
+ payjoinClient ?? new NullPayjoinClient());
}
public void RenameLabel(SmartCoin coin, SmartLabel newLabel)

Try to reduce the risks raised by codescene