/// <returns>(allowed, reject-reason)</returns> public static async Task <(bool accept, string rejectReason)> TestMempoolAcceptAsync(this RPCClient rpc, IEnumerable <Coin> coins) { // Check if mempool would accept a fake transaction created with the registered inputs. // This will catch ascendant/descendant count and size limits for example. var fakeTransaction = rpc.Network.CreateTransaction(); fakeTransaction.Inputs.AddRange(coins.Select(coin => new TxIn(coin.Outpoint))); Money fakeOutputValue = NBitcoinHelpers.TakeAReasonableFee(coins.Sum(coin => coin.TxOut.Value)); fakeTransaction.Outputs.Add(fakeOutputValue, new Key()); MempoolAcceptResult testMempoolAcceptResult = await rpc.TestMempoolAcceptAsync(fakeTransaction, allowHighFees : true); if (!testMempoolAcceptResult.IsAllowed) { string rejected = testMempoolAcceptResult.RejectReason; if (!(rejected.Contains("mandatory-script-verify-flag-failed", StringComparison.OrdinalIgnoreCase) || rejected.Contains("non-mandatory-script-verify-flag", StringComparison.OrdinalIgnoreCase))) { return(false, rejected); } } return(true, ""); }
public static async Task <(bool accept, string rejectReason)> TestMempoolAcceptAsync(this IRPCClient rpc, IEnumerable <Coin> coins, int fakeOutputCount, Money feePerInputs, Money feePerOutputs) { // Check if mempool would accept a fake transaction created with the registered inputs. // This will catch ascendant/descendant count and size limits for example. var fakeTransaction = rpc.Network.CreateTransaction(); fakeTransaction.Inputs.AddRange(coins.Select(coin => new TxIn(coin.Outpoint))); Money totalFakeOutputsValue; try { totalFakeOutputsValue = NBitcoinHelpers.TakeFee(coins, fakeOutputCount, feePerInputs, feePerOutputs); } catch (InvalidOperationException ex) { return(false, ex.Message); } for (int i = 0; i < fakeOutputCount; i++) { var fakeOutputValue = totalFakeOutputsValue / fakeOutputCount; fakeTransaction.Outputs.Add(fakeOutputValue, new Key()); } MempoolAcceptResult testMempoolAcceptResult = await rpc.TestMempoolAcceptAsync(fakeTransaction, allowHighFees : true); if (!testMempoolAcceptResult.IsAllowed) { string rejected = testMempoolAcceptResult.RejectReason; if (!(rejected.Contains("mandatory-script-verify-flag-failed", StringComparison.OrdinalIgnoreCase) || rejected.Contains("non-mandatory-script-verify-flag", StringComparison.OrdinalIgnoreCase))) { return(false, rejected); } } return(true, ""); }