Fix: Recreating an aborted TX in MultiSig on Server setup crashes (#6682)

This commit is contained in:
Nicolas Dorier
2025-04-21 17:10:28 +09:00
committed by GitHub
parent 2f26979ed7
commit 3d363baa9e
8 changed files with 118 additions and 37 deletions

View File

@@ -145,39 +145,38 @@ namespace BTCPayServer.Controllers
_displayFormatter = displayFormatter;
}
[HttpGet("{walletId}/pending/{transactionId}/cancel")]
[HttpGet("{walletId}/pending/{pendingTransactionId}/cancel")]
public IActionResult CancelPendingTransaction(
[ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
string transactionId)
string pendingTransactionId)
{
return View("Confirm", new ConfirmModel("Abort Pending Transaction",
"Proceeding with this action will invalidate Pending Transaction and all accepted signatures.",
"Confirm Abort"));
}
[HttpPost("{walletId}/pending/{transactionId}/cancel")]
[HttpPost("{walletId}/pending/{pendingTransactionId}/cancel")]
public async Task<IActionResult> CancelPendingTransactionConfirmed(
[ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
string transactionId)
string pendingTransactionId)
{
await _pendingTransactionService.CancelPendingTransaction(walletId.CryptoCode, walletId.StoreId, transactionId);
await _pendingTransactionService.CancelPendingTransaction(GetPendingTxId(walletId, pendingTransactionId));
TempData.SetStatusMessageModel(new StatusMessageModel()
{
Severity = StatusMessageModel.StatusSeverity.Success,
Message = $"Aborted Pending Transaction {transactionId}"
Message = $"Aborted Pending Transaction {pendingTransactionId}"
});
return RedirectToAction(nameof(WalletTransactions), new { walletId = walletId.ToString() });
}
[HttpGet("{walletId}/pending/{transactionId}")]
[HttpGet("{walletId}/pending/{pendingTransactionId}")]
public async Task<IActionResult> ViewPendingTransaction(
[ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
string transactionId)
string pendingTransactionId)
{
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId.CryptoCode);
var pendingTransaction =
await _pendingTransactionService.GetPendingTransaction(walletId.CryptoCode, walletId.StoreId,
transactionId);
await _pendingTransactionService.GetPendingTransaction(GetPendingTxId(walletId, pendingTransactionId));
if (pendingTransaction is null)
return NotFound();
var blob = pendingTransaction.GetBlob();
@@ -197,7 +196,7 @@ namespace BTCPayServer.Controllers
CryptoCode = network.CryptoCode,
SigningContext = new SigningContextModel(currentPsbt)
{
PendingTransactionId = transactionId,
PendingTransactionId = pendingTransactionId,
PSBT = currentPsbt.ToBase64(),
},
};
@@ -206,6 +205,10 @@ namespace BTCPayServer.Controllers
return View("WalletPSBTDecoded", vm);
}
private PendingTransactionService.PendingTransactionFullId GetPendingTxId(WalletId walletId, string pendingTransactionId)
=> new (walletId.CryptoCode, walletId.StoreId, pendingTransactionId);
[Route("{walletId}/transactions/bump")]
[Route("{walletId}/transactions/{transactionId}/bump")]
public async Task<IActionResult> WalletBumpFee([ModelBinder(typeof(WalletIdModelBinder))]
@@ -1354,7 +1357,7 @@ namespace BTCPayServer.Controllers
if (vm.SigningContext.PendingTransactionId is not null)
{
var psbt = PSBT.Parse(vm.SigningContext.PSBT, NetworkProvider.GetNetwork<BTCPayNetwork>(walletId.CryptoCode).NBitcoinNetwork);
var pendingTransaction = await _pendingTransactionService.CollectSignature(psbt, CancellationToken.None);
var pendingTransaction = await _pendingTransactionService.CollectSignature(GetPendingTxId(walletId, vm.SigningContext.PendingTransactionId), psbt, CancellationToken.None);
if (pendingTransaction != null)
return RedirectToAction(nameof(WalletTransactions), new { walletId = walletId.ToString() });