Fix: Some valid taproot PSBT couldn't parsed and show better error message (Fix #5715) (#5993)

This commit is contained in:
Nicolas Dorier 2024-05-21 10:52:55 +09:00 committed by nicolas.dorier
parent cb136cba82
commit fe9e5eb9c9
No known key found for this signature in database
GPG key ID: 6618763EF09186FE
8 changed files with 36 additions and 28 deletions

View file

@ -31,7 +31,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.5.1" />
<PackageReference Include="NBitcoin" Version="7.0.34" />
<PackageReference Include="NBitcoin" Version="7.0.37" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View file

@ -4,7 +4,7 @@
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="NBXplorer.Client" Version="4.3.0" />
<PackageReference Include="NBXplorer.Client" Version="4.3.1" />
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="2.0.1" />
</ItemGroup>
<ItemGroup Condition="'$(Altcoins)' != 'true'">

View file

@ -6,7 +6,7 @@
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
<PackageReference Include="NBitcoin" Version="7.0.34" />
<PackageReference Include="NBitcoin" Version="7.0.37" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="DigitalRuby.ExchangeSharp" Version="1.0.4" />
</ItemGroup>

View file

@ -99,7 +99,7 @@ services:
custom:
nbxplorer:
image: nicolasdorier/nbxplorer:2.5.0
image: nicolasdorier/nbxplorer:2.5.3
restart: unless-stopped
ports:
- "32838:32838"

View file

@ -96,7 +96,7 @@ services:
custom:
nbxplorer:
image: nicolasdorier/nbxplorer:2.5.0
image: nicolasdorier/nbxplorer:2.5.3
restart: unless-stopped
ports:
- "32838:32838"

View file

@ -151,13 +151,12 @@ namespace BTCPayServer.Controllers
WalletId walletId, WalletPSBTViewModel vm, string command = null)
{
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId.CryptoCode);
var psbt = await vm.GetPSBT(network.NBitcoinNetwork);
var psbt = await vm.GetPSBT(network.NBitcoinNetwork, ModelState);
vm.BackUrl ??= HttpContext.Request.GetTypedHeaders().Referer?.AbsolutePath;
if (psbt is null || vm.InvalidPSBT)
{
ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
return View("WalletSigningOptions", new WalletSigningOptionsModel
{
SigningContext = vm.SigningContext,
@ -241,10 +240,9 @@ namespace BTCPayServer.Controllers
vm.NBXSeedAvailable = await CanUseHotWallet() && derivationSchemeSettings.IsHotWallet;
vm.BackUrl ??= HttpContext.Request.GetTypedHeaders().Referer?.AbsolutePath;
var psbt = await vm.GetPSBT(network.NBitcoinNetwork);
var psbt = await vm.GetPSBT(network.NBitcoinNetwork, ModelState);
if (vm.InvalidPSBT)
{
ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
return View(vm);
}
if (psbt is null)
@ -477,7 +475,7 @@ namespace BTCPayServer.Controllers
WalletId walletId, WalletPSBTViewModel vm, string command, CancellationToken cancellationToken = default)
{
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId.CryptoCode);
PSBT psbt = await vm.GetPSBT(network.NBitcoinNetwork);
PSBT psbt = await vm.GetPSBT(network.NBitcoinNetwork, ModelState);
if (vm.InvalidPSBT || psbt is null)
{
if (vm.InvalidPSBT)
@ -637,16 +635,14 @@ namespace BTCPayServer.Controllers
WalletId walletId, WalletPSBTCombineViewModel vm)
{
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId.CryptoCode);
var psbt = await vm.GetPSBT(network.NBitcoinNetwork);
var psbt = await vm.GetPSBT(network.NBitcoinNetwork, ModelState);
if (psbt == null)
{
ModelState.AddModelError(nameof(vm.PSBT), "Invalid PSBT");
return View(vm);
}
var sourcePSBT = vm.GetSourcePSBT(network.NBitcoinNetwork);
if (sourcePSBT == null)
var sourcePSBT = vm.GetSourcePSBT(network.NBitcoinNetwork, ModelState);
if (sourcePSBT is null)
{
ModelState.AddModelError(nameof(vm.OtherPSBT), "Invalid PSBT");
return View(vm);
}
sourcePSBT = sourcePSBT.Combine(psbt);

View file

@ -2,6 +2,7 @@ using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using NBitcoin;
namespace BTCPayServer.Models.WalletViewModels
@ -17,7 +18,7 @@ namespace BTCPayServer.Models.WalletViewModels
public string BackUrl { get; set; }
public string ReturnUrl { get; set; }
public PSBT GetSourcePSBT(Network network)
public PSBT GetSourcePSBT(Network network, ModelStateDictionary modelState)
{
if (!string.IsNullOrEmpty(OtherPSBT))
{
@ -25,12 +26,12 @@ namespace BTCPayServer.Models.WalletViewModels
{
return NBitcoin.PSBT.Parse(OtherPSBT, network);
}
catch
{ }
catch (Exception ex)
{ modelState.AddModelError(nameof(OtherPSBT), ex.Message); }
}
return null;
}
public async Task<PSBT> GetPSBT(Network network)
public async Task<PSBT> GetPSBT(Network network, ModelStateDictionary modelState)
{
if (UploadedPSBTFile != null)
{
@ -45,8 +46,9 @@ namespace BTCPayServer.Models.WalletViewModels
{
return NBitcoin.PSBT.Load(bytes, network);
}
catch
catch (FormatException ex)
{
modelState.AddModelError(nameof(UploadedPSBTFile), ex.Message);
return null;
}
}
@ -56,8 +58,10 @@ namespace BTCPayServer.Models.WalletViewModels
{
return NBitcoin.PSBT.Parse(PSBT, network);
}
catch
{ }
catch (FormatException ex)
{
modelState.AddModelError(nameof(UploadedPSBTFile), ex.Message);
}
}
return null;
}

View file

@ -4,6 +4,7 @@ using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using NBitcoin;
namespace BTCPayServer.Models.WalletViewModels
@ -35,9 +36,9 @@ namespace BTCPayServer.Models.WalletViewModels
public IFormFile UploadedPSBTFile { get; set; }
public async Task<PSBT> GetPSBT(Network network)
public async Task<PSBT> GetPSBT(Network network, ModelStateDictionary modelState)
{
var psbt = await GetPSBTCore(network);
var psbt = await GetPSBTCore(network, modelState);
if (psbt != null)
{
Decoded = psbt.ToString();
@ -52,7 +53,7 @@ namespace BTCPayServer.Models.WalletViewModels
}
public bool InvalidPSBT { get; set; }
async Task<PSBT> GetPSBTCore(Network network)
async Task<PSBT> GetPSBTCore(Network network, ModelStateDictionary modelState)
{
if (UploadedPSBTFile != null)
{
@ -68,16 +69,20 @@ namespace BTCPayServer.Models.WalletViewModels
}
return NBitcoin.PSBT.Load(bytes, network);
}
catch (Exception)
catch (Exception ex)
{
using var stream = new StreamReader(UploadedPSBTFile.OpenReadStream());
PSBT = await stream.ReadToEndAsync();
modelState.Remove(nameof(PSBT));
modelState.AddModelError(nameof(PSBT), ex.Message);
InvalidPSBT = true;
}
}
if (SigningContext != null && !string.IsNullOrEmpty(SigningContext.PSBT))
{
PSBT = SigningContext.PSBT;
modelState.Remove(nameof(PSBT));
InvalidPSBT = false;
}
if (!string.IsNullOrEmpty(PSBT))
{
@ -86,8 +91,11 @@ namespace BTCPayServer.Models.WalletViewModels
InvalidPSBT = false;
return NBitcoin.PSBT.Parse(PSBT, network);
}
catch
{ InvalidPSBT = true; }
catch (Exception ex) when (!InvalidPSBT)
{
modelState.AddModelError(nameof(PSBT), ex.Message);
InvalidPSBT = true;
}
}
return null;
}