* Fix P2SH-P2WPKH case for Payjoin (Fix #1500)

* fix p2sh issue

Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
This commit is contained in:
Andrew Camilleri
2020-04-25 17:19:24 +02:00
committed by GitHub
parent 4be6c06af5
commit f8b2b18c6e

View File

@@ -384,8 +384,10 @@ namespace BTCPayServer.Payments.PayJoin
Money ourFeeContribution = Money.Zero; Money ourFeeContribution = Money.Zero;
// We need to adjust the fee to keep a constant fee rate // We need to adjust the fee to keep a constant fee rate
var txBuilder = network.NBitcoinNetwork.CreateTransactionBuilder(); var txBuilder = network.NBitcoinNetwork.CreateTransactionBuilder();
txBuilder.AddCoins(psbt.Inputs.Select(i => i.GetSignableCoin())); var coins = psbt.Inputs.Select(i => i.GetSignableCoin())
txBuilder.AddCoins(selectedUTXOs.Select(o => o.Value.AsCoin(derivationSchemeSettings.AccountDerivation))); .Concat(selectedUTXOs.Select(o => o.Value.AsCoin(derivationSchemeSettings.AccountDerivation))).ToArray();
txBuilder.AddCoins(coins);
Money expectedFee = txBuilder.EstimateFees(newTx, originalFeeRate); Money expectedFee = txBuilder.EstimateFees(newTx, originalFeeRate);
Money actualFee = newTx.GetFee(txBuilder.FindSpentCoins(newTx)); Money actualFee = newTx.GetFee(txBuilder.FindSpentCoins(newTx));
Money additionalFee = expectedFee - actualFee; Money additionalFee = expectedFee - actualFee;
@@ -458,7 +460,7 @@ namespace BTCPayServer.Payments.PayJoin
originalPaymentData.ConfirmationCount = -1; originalPaymentData.ConfirmationCount = -1;
originalPaymentData.PayjoinInformation = new PayjoinInformation() originalPaymentData.PayjoinInformation = new PayjoinInformation()
{ {
CoinjoinTransactionHash = newPsbt.GetGlobalTransaction().GetHash(), CoinjoinTransactionHash = GetExpectedHash(newPsbt, sendersInputType, coins),
CoinjoinValue = originalPaymentValue - ourFeeContribution, CoinjoinValue = originalPaymentValue - ourFeeContribution,
ContributedOutPoints = selectedUTXOs.Select(o => o.Key).ToArray() ContributedOutPoints = selectedUTXOs.Select(o => o.Key).ToArray()
}; };
@@ -485,6 +487,27 @@ namespace BTCPayServer.Payments.PayJoin
return Ok(newTx.ToHex()); return Ok(newTx.ToHex());
} }
private uint256 GetExpectedHash(PSBT psbt, ScriptPubKeyType? sendersInputType, Coin[] coins)
{
var tx = psbt.GetGlobalTransaction();
if (sendersInputType is ScriptPubKeyType.Segwit)
return tx.GetHash();
else if (sendersInputType is ScriptPubKeyType.SegwitP2SH)
{
for (int i = 0; i < psbt.Inputs.Count; i++)
{
tx.Inputs[i].ScriptSig = PayToScriptHashTemplate.Instance.GenerateScriptSig(Array.Empty<byte[]>(), ((ScriptCoin)coins.Single(coin => coin.Outpoint == psbt.Inputs[i].PrevOut)).GetP2SHRedeem());
}
return tx.GetHash();
}
else
{
throw new NotSupportedException();
}
}
private JObject CreatePayjoinError(int httpCode, string errorCode, string friendlyMessage) private JObject CreatePayjoinError(int httpCode, string errorCode, string friendlyMessage)
{ {
var o = new JObject(); var o = new JObject();