mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 18:11:36 +01:00
Fix: Could not send money from wallet of a coin without segwit
This commit is contained in:
parent
ac8feceaf2
commit
42d60ef84b
@ -2,7 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
<Version>1.0.2.37</Version>
|
<Version>1.0.2.38</Version>
|
||||||
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -40,10 +40,10 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" />
|
||||||
<PackageReference Include="Microsoft.NetCore.Analyzers" Version="2.6.0" />
|
<PackageReference Include="Microsoft.NetCore.Analyzers" Version="2.6.0" />
|
||||||
<PackageReference Include="NBitcoin" Version="4.1.1.18" />
|
<PackageReference Include="NBitcoin" Version="4.1.1.20" />
|
||||||
<PackageReference Include="NBitpayClient" Version="1.0.0.29" />
|
<PackageReference Include="NBitpayClient" Version="1.0.0.29" />
|
||||||
<PackageReference Include="DBreeze" Version="1.87.0" />
|
<PackageReference Include="DBreeze" Version="1.87.0" />
|
||||||
<PackageReference Include="NBXplorer.Client" Version="1.0.2.11" />
|
<PackageReference Include="NBXplorer.Client" Version="1.0.2.12" />
|
||||||
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.2" />
|
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.2" />
|
||||||
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.3" />
|
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.3" />
|
||||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.14" />
|
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.14" />
|
||||||
|
@ -288,7 +288,7 @@ namespace BTCPayServer.Controllers
|
|||||||
var unspentCoins = await wallet.GetUnspentCoins(strategyBase);
|
var unspentCoins = await wallet.GetUnspentCoins(strategyBase);
|
||||||
var changeAddress = await change;
|
var changeAddress = await change;
|
||||||
var send = new[] { (
|
var send = new[] { (
|
||||||
destination: destinationAddress as IDestination,
|
destination: destinationAddress as IDestination,
|
||||||
amount: amountBTC,
|
amount: amountBTC,
|
||||||
substractFees: subsctractFeesValue) };
|
substractFees: subsctractFeesValue) };
|
||||||
|
|
||||||
@ -335,15 +335,15 @@ namespace BTCPayServer.Controllers
|
|||||||
|
|
||||||
Dictionary<uint256, Transaction> parentTransactions = new Dictionary<uint256, Transaction>();
|
Dictionary<uint256, Transaction> parentTransactions = new Dictionary<uint256, Transaction>();
|
||||||
|
|
||||||
if(!strategy.Segwit)
|
if (!strategy.Segwit)
|
||||||
{
|
{
|
||||||
var parentHashes = usedCoins.Select(c => c.Outpoint.Hash).ToHashSet();
|
var parentHashes = usedCoins.Select(c => c.Outpoint.Hash).ToHashSet();
|
||||||
var explorer = _ExplorerProvider.GetExplorerClient(network);
|
var explorer = _ExplorerProvider.GetExplorerClient(network);
|
||||||
var getTransactionAsyncs = parentHashes.Select(h => (Op: explorer.GetTransactionAsync(h), Hash: h)).ToList();
|
var getTransactionAsyncs = parentHashes.Select(h => (Op: explorer.GetTransactionAsync(h), Hash: h)).ToList();
|
||||||
foreach(var getTransactionAsync in getTransactionAsyncs)
|
foreach (var getTransactionAsync in getTransactionAsyncs)
|
||||||
{
|
{
|
||||||
var tx = (await getTransactionAsync.Op);
|
var tx = (await getTransactionAsync.Op);
|
||||||
if(tx == null)
|
if (tx == null)
|
||||||
throw new Exception($"Parent transaction {getTransactionAsync.Hash} not found");
|
throw new Exception($"Parent transaction {getTransactionAsync.Hash} not found");
|
||||||
parentTransactions.Add(tx.Transaction.GetHash(), tx.Transaction);
|
parentTransactions.Add(tx.Transaction.GetHash(), tx.Transaction);
|
||||||
}
|
}
|
||||||
@ -356,7 +356,7 @@ namespace BTCPayServer.Controllers
|
|||||||
KeyPath = foundKeyPath.Derive(keypaths[c.TxOut.ScriptPubKey]),
|
KeyPath = foundKeyPath.Derive(keypaths[c.TxOut.ScriptPubKey]),
|
||||||
PubKey = strategy.Root.Derive(keypaths[c.TxOut.ScriptPubKey]).PubKey
|
PubKey = strategy.Root.Derive(keypaths[c.TxOut.ScriptPubKey]).PubKey
|
||||||
}).ToArray(), unsigned, hasChange ? foundKeyPath.Derive(changeAddress.Item2) : null);
|
}).ToArray(), unsigned, hasChange ? foundKeyPath.Derive(changeAddress.Item2) : null);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var broadcastResult = await wallet.BroadcastTransactionsAsync(new List<Transaction>() { transaction });
|
var broadcastResult = await wallet.BroadcastTransactionsAsync(new List<Transaction>() { transaction });
|
||||||
@ -377,7 +377,7 @@ namespace BTCPayServer.Controllers
|
|||||||
{ result = new LedgerTestResult() { Success = false, Error = "Timeout" }; }
|
{ result = new LedgerTestResult() { Success = false, Error = "Timeout" }; }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{ result = new LedgerTestResult() { Success = false, Error = ex.Message }; }
|
{ result = new LedgerTestResult() { Success = false, Error = ex.Message }; }
|
||||||
|
finally { hw.Dispose(); }
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (result != null)
|
if (result != null)
|
||||||
|
@ -20,9 +20,9 @@ namespace BTCPayServer.Services
|
|||||||
public HardwareWalletException(string message) : base(message) { }
|
public HardwareWalletException(string message) : base(message) { }
|
||||||
public HardwareWalletException(string message, Exception inner) : base(message, inner) { }
|
public HardwareWalletException(string message, Exception inner) : base(message, inner) { }
|
||||||
}
|
}
|
||||||
public class HardwareWalletService
|
public class HardwareWalletService : IDisposable
|
||||||
{
|
{
|
||||||
class WebSocketTransport : LedgerWallet.Transports.ILedgerTransport
|
class WebSocketTransport : LedgerWallet.Transports.ILedgerTransport, IDisposable
|
||||||
{
|
{
|
||||||
private readonly WebSocket webSocket;
|
private readonly WebSocket webSocket;
|
||||||
|
|
||||||
@ -33,26 +33,40 @@ namespace BTCPayServer.Services
|
|||||||
this.webSocket = webSocket;
|
this.webSocket = webSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SemaphoreSlim _Semaphore = new SemaphoreSlim(1, 1);
|
||||||
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(10);
|
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(10);
|
||||||
public async Task<byte[][]> Exchange(byte[][] apdus)
|
public async Task<byte[][]> Exchange(byte[][] apdus)
|
||||||
{
|
{
|
||||||
|
await _Semaphore.WaitAsync();
|
||||||
List<byte[]> responses = new List<byte[]>();
|
List<byte[]> responses = new List<byte[]>();
|
||||||
using (CancellationTokenSource cts = new CancellationTokenSource(Timeout))
|
try
|
||||||
{
|
{
|
||||||
foreach (var apdu in apdus)
|
using (CancellationTokenSource cts = new CancellationTokenSource(Timeout))
|
||||||
{
|
{
|
||||||
await this.webSocket.SendAsync(new ArraySegment<byte>(apdu), WebSocketMessageType.Binary, true, cts.Token);
|
foreach (var apdu in apdus)
|
||||||
}
|
{
|
||||||
foreach (var apdu in apdus)
|
await this.webSocket.SendAsync(new ArraySegment<byte>(apdu), WebSocketMessageType.Binary, true, cts.Token);
|
||||||
{
|
}
|
||||||
byte[] response = new byte[300];
|
foreach (var apdu in apdus)
|
||||||
var result = await this.webSocket.ReceiveAsync(new ArraySegment<byte>(response), cts.Token);
|
{
|
||||||
Array.Resize(ref response, result.Count);
|
byte[] response = new byte[300];
|
||||||
responses.Add(response);
|
var result = await this.webSocket.ReceiveAsync(new ArraySegment<byte>(response), cts.Token);
|
||||||
|
Array.Resize(ref response, result.Count);
|
||||||
|
responses.Add(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_Semaphore.Release();
|
||||||
|
}
|
||||||
return responses.ToArray();
|
return responses.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_Semaphore.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly LedgerClient _Ledger;
|
private readonly LedgerClient _Ledger;
|
||||||
@ -121,7 +135,7 @@ namespace BTCPayServer.Services
|
|||||||
public async Task<KeyPath> GetKeyPath(BTCPayNetwork network, DirectDerivationStrategy directStrategy)
|
public async Task<KeyPath> GetKeyPath(BTCPayNetwork network, DirectDerivationStrategy directStrategy)
|
||||||
{
|
{
|
||||||
List<KeyPath> derivations = new List<KeyPath>();
|
List<KeyPath> derivations = new List<KeyPath>();
|
||||||
if(network.NBitcoinNetwork.Consensus.SupportSegwit)
|
if (network.NBitcoinNetwork.Consensus.SupportSegwit)
|
||||||
derivations.Add(new KeyPath("49'"));
|
derivations.Add(new KeyPath("49'"));
|
||||||
derivations.Add(new KeyPath("44'"));
|
derivations.Add(new KeyPath("44'"));
|
||||||
KeyPath foundKeyPath = null;
|
KeyPath foundKeyPath = null;
|
||||||
@ -155,6 +169,12 @@ namespace BTCPayServer.Services
|
|||||||
_Transport.Timeout = TimeSpan.FromMinutes(5);
|
_Transport.Timeout = TimeSpan.FromMinutes(5);
|
||||||
return await Ledger.SignTransactionAsync(signatureRequests, unsigned, changeKeyPath);
|
return await Ledger.SignTransactionAsync(signatureRequests, unsigned, changeKeyPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if(_Transport != null)
|
||||||
|
_Transport.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LedgerTestResult
|
public class LedgerTestResult
|
||||||
|
Loading…
Reference in New Issue
Block a user