Provide useful info about invalid transactions
ADD
WalletWasabi.Tests/UnitTests/InvalidTxExceptionTests.cs
+using System;
+using System.Linq;
+using NBitcoin;
+using NBitcoin.Policy;
+using WalletWasabi.Blockchain.Keys;
+using WalletWasabi.Exceptions;
+using WalletWasabi.Helpers;
+using WalletWasabi.Tests.Helpers;
+using Xunit;
+
+namespace WalletWasabi.Tests.UnitTests
+{
+ public class InvalidTxExceptionTests
+ {
+ [Fact]
+ public void ExceptionMessageContainsUsefulInformation()
+ {
+ var crazyInvalidTx = BitcoinFactory.CreateSmartTransaction(
+ 9,
+ Enumerable.Repeat(Money.Coins(1m), 9),
+ new[] { (Money.Coins(1.1m), 1) },
+ new[] { (Money.Coins(1m), HdPubKey.DefaultHighAnonymitySet) }
+ );
+
+ TransactionPolicyError[] crazyInvalidTxErrors = {
+ new NotEnoughFundsPolicyError("Fees different than expected"),
+ new OutputPolicyError("Output value should not be less than zero", (int)-10),
+ new CoinNotFoundPolicyError(new IndexedTxIn { TxIn = new TxIn { PrevOut = OutPoint.Zero }})
+ };
+
+ var ex = new InvalidTxException(crazyInvalidTx.Transaction, crazyInvalidTxErrors);
+ Assert.Contains(crazyInvalidTxErrors[0].ToString(), ex.Message);
+ Assert.Contains(crazyInvalidTxErrors[1].ToString(), ex.Message);
+ Assert.Contains(crazyInvalidTxErrors[2].ToString(), ex.Message);
+ }
+ }
+}
\ No newline at end of file

MODIFY
WalletWasabi/Exceptions/InvalidTxException.cs
WalletWasabi/Exceptions/InvalidTxException.cs
@@ -2,19 +2,30 @@ using NBitcoin;
using NBitcoin.Policy;
using System;
using System.Collections.Generic;
+using System.Linq;
using WalletWasabi.Helpers;
namespace WalletWasabi.Exceptions
{
public class InvalidTxException : Exception
{
- public InvalidTxException(Transaction invalidTx, IEnumerable<TransactionPolicyError>? errors = null)
+ public InvalidTxException(Transaction invalidTx, IEnumerable<TransactionPolicyError> errors)
{
- Transaction = Guard.NotNull(nameof(invalidTx), invalidTx);
+ Transaction = invalidTx;
Errors = errors;
}
public Transaction Transaction { get; }
- public IEnumerable<TransactionPolicyError>? Errors { get; }
+ public IEnumerable<TransactionPolicyError> Errors { get; }
+
+ public override string Message
+ {
+ get
+ {
+ var errors = string.Join(Environment.NewLine, Errors.Select((error, i) => $"#{i}: {error}."));
+ var txHex = string.Join(Environment.NewLine, Transaction.ToHex().ChunkBy(200).Select(x => new string(x.ToArray())));
+ return string.Join(Environment.NewLine, "Invalid transaction:", txHex, "Policy errors:", errors);
+ }
+ }
}
}

Provide useful info about invalid transactions