Checks for double spending tx
Checks if the received tx spends any of the already-spent tx in
the wallet.Coins. In case the received transaction is RBF, the
already-spent outputs are removed from the Coins collection and
reintroduced. Othewise, if the received transaction is not RBF
then, it is rejected (not processed)
MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -259,6 +259,37 @@ namespace WalletWasabi.Services
keys = KeyManager.GetKeys().ToList();
}
+ // Check double spending tx (invalid transactions has to be rejected)
+ var spentTxOuts = Coins.SelectMany(x=>x.SpentOutputs);
+ var txSpendingOutputs = tx.Transaction.Inputs.ToTxoRefs();
+
+ var alreadySpentOutputs = spentTxOuts.Intersect(txSpendingOutputs).ToArray();
+
+ // if the received tx spends any already-spent outputs and this is a RBF tx
+ // then remove the coins in order to replace them for those in the new tx (RBF)
+ if (alreadySpentOutputs.Any())
+ {
+ if (tx.Transaction.RBF)
+ {
+ foreach (var spentOutput in alreadySpentOutputs)
+ {
+ var coinsToreplace = Coins.Where(x => x.SpentOutputs.Contains(spentOutput)).ToArray();
+ for (var j = 0; j < coinsToreplace.Length; j++)
+ {
+ if (!Coins.TryRemove(coinsToreplace[j]))
+ {
+ // what here? retry?
+ }
+ }
+ }
+ }
+ else // tx is double spending at least one output
+ {
+ // just discard it
+ return;
+ }
+ }
+
// If transaction received to any of the wallet keys:
for (var i = 0; i < tx.Transaction.Outputs.Count; i++)
{

Checks for double spending tx

Checks if the received tx spends any of the already-spent tx in
the wallet.Coins. In case the received transaction is RBF, the
already-spent outputs are removed from the Coins collection and
reintroduced. Othewise, if the received transaction is not RBF
then, it is rejected (not processed)