From 475eeb9cc62ab9176aad179256b768a202e508da Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Tue, 14 Jan 2025 23:36:56 +0900 Subject: [PATCH] Relax requirement on mixed input types --- BIP78.Sender/PayjoinClient.cs | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/BIP78.Sender/PayjoinClient.cs b/BIP78.Sender/PayjoinClient.cs index 2e06a51..47fda6a 100644 --- a/BIP78.Sender/PayjoinClient.cs +++ b/BIP78.Sender/PayjoinClient.cs @@ -42,7 +42,6 @@ public async Task RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w if (signedPSBT.IsAllFinalized()) throw new InvalidOperationException("The original PSBT should not be finalized."); var optionalParameters = new PayjoinClientParameters(); - var inputScriptType = wallet.ScriptPubKeyType; var paymentScriptPubKey = bip21.Address?.ScriptPubKey; var changeOutput = signedPSBT.Outputs.CoinsFor(wallet, wallet.AccountKey, wallet.RootedKeyPath) .Where(o => o.ScriptPubKey != paymentScriptPubKey) @@ -56,7 +55,7 @@ public async Task RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w optionalParameters.MaxAdditionalFeeContribution = MaxFeeBumpContribution is null ? // By default, we want to keep same fee rate and a single additional input - originalFeeRate.GetFee(GetVirtualSize(inputScriptType)) + originalFeeRate.GetFee(110) : MaxFeeBumpContribution; if (MinimumFeeRate is FeeRate v) optionalParameters.MinFeeRate = v; @@ -140,9 +139,6 @@ public async Task RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w throw new PayjoinSenderException( "The receiver did not specify non_witness_utxo or witness_utxo for one of their inputs"); sequences.Add(proposedTxIn.Sequence); - // Verify that the payjoin proposal did not introduced mixed input's type. - if (inputScriptType != proposedPSBTInput.GetInputScriptPubKeyType()) - throw new PayjoinSenderException("Mixed input type detected in the proposal"); } } @@ -187,9 +183,9 @@ public async Task RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w // Make sure the actual contribution is only paying fee if (actualContribution > additionalFee) throw new PayjoinSenderException("The actual contribution is not only paying fee"); - // Make sure the actual contribution is only paying for fee incurred by additional inputs - var additionalInputsCount = proposalGlobalTx.Inputs.Count - originalGlobalTx.Inputs.Count; - if (actualContribution > originalFeeRate.GetFee(GetVirtualSize(inputScriptType)) * + // This assumes an additional input can be up to 110 bytes. + var additionalInputsCount = proposalGlobalTx.Inputs.Count - originalGlobalTx.Inputs.Count; + if (actualContribution > originalFeeRate.GetFee(110) * additionalInputsCount) throw new PayjoinSenderException( "The actual contribution is not only paying for additional inputs"); @@ -233,23 +229,6 @@ public async Task RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w return proposal; } - private int GetVirtualSize(ScriptPubKeyType? scriptPubKeyType) - { - switch (scriptPubKeyType) - { - case ScriptPubKeyType.Legacy: - return 148; - case ScriptPubKeyType.Segwit: - return 68; - case ScriptPubKeyType.SegwitP2SH: - return 91; - case ScriptPubKeyType.TaprootBIP86: - return 58; - default: - return 110; - } - } - private static PSBT CreateOriginalPSBT(PSBT signedPSBT) { var original = signedPSBT.Clone();