Cleanup the design for multi currencies support, use a single nbxplorer instead of two

This commit is contained in:
nicolas.dorier 2018-01-12 11:54:57 +09:00
parent 8596e16feb
commit b59021a0be
14 changed files with 124 additions and 164 deletions

View File

@ -48,11 +48,11 @@ namespace BTCPayServer.Tests
NetworkProvider = new BTCPayNetworkProvider(ChainType.Regtest);
ExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_RPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("BTC").NBitcoinNetwork);
ExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_BTCRPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("BTC").NBitcoinNetwork);
LTCExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_LTCRPCCONNECTION", "server=http://127.0.0.1:43783;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("LTC").NBitcoinNetwork);
ExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("BTC").NBitcoinNetwork, new Uri(GetEnvironment("TESTS_NBXPLORERURL", "http://127.0.0.1:32838/")));
LTCExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("LTC").NBitcoinNetwork, new Uri(GetEnvironment("TESTS_LTCNBXPLORERURL", "http://127.0.0.1:32839/")));
ExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("BTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_BTCNBXPLORERURL", "http://127.0.0.1:32838/")));
LTCExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("LTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_LTCNBXPLORERURL", "http://127.0.0.1:32838/")));
PayTester = new BTCPayServerTester(Path.Combine(_Directory, "pay"))
{

View File

@ -10,18 +10,17 @@ services:
context: ..
dockerfile: BTCPayServer.Tests/Dockerfile
environment:
TESTS_RPCCONNECTION: server=http://bitcoind:43782;ceiwHEbqWI83:DwubwWsoo3
TESTS_BTCRPCCONNECTION: server=http://bitcoind:43782;ceiwHEbqWI83:DwubwWsoo3
TESTS_LTCRPCCONNECTION: server=http://litecoind:43782;ceiwHEbqWI83:DwubwWsoo3
TESTS_NBXPLORERURL: http://bitcoin-nbxplorer:32838/
TESTS_LTCNBXPLORERURL: http://litecoin-nbxplorer:32839/
TESTS_BTCNBXPLORERURL: http://nbxplorer:32838/
TESTS_LTCNBXPLORERURL: http://nbxplorer:32838/
TESTS_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Database=btcpayserver
TESTS_PORT: 80
TESTS_HOSTNAME: tests
expose:
- "80"
links:
- bitcoin-nbxplorer
- litecoin-nbxplorer
- nbxplorer
- postgres
extra_hosts:
- "tests:127.0.0.1"
@ -34,45 +33,32 @@ services:
regtest=1
connect=bitcoind:39388
links:
- bitcoin-nbxplorer
- litecoin-nbxplorer
- nbxplorer
- postgres
bitcoin-nbxplorer:
image: nicolasdorier/nbxplorer:1.0.0.48
nbxplorer:
image: nicolasdorier/nbxplorer:1.0.0.50
ports:
- "32838:32838"
expose:
- "32838"
environment:
NBXPLORER_NETWORK: regtest
NBXPLORER_RPCURL: http://bitcoind:43782/
NBXPLORER_RPCUSER: ceiwHEbqWI83
NBXPLORER_RPCPASSWORD: DwubwWsoo3
NBXPLORER_NODEENDPOINT: bitcoind:39388
NBXPLORER_CHAINS: "btc,ltc"
NBXPLORER_BTCRPCURL: http://bitcoind:43782/
NBXPLORER_BTCNODEENDPOINT: bitcoind:39388
NBXPLORER_BTCRPCUSER: ceiwHEbqWI83
NBXPLORER_BTCRPCPASSWORD: DwubwWsoo3
NBXPLORER_LTCRPCURL: http://litecoind:43782/
NBXPLORER_LTCNODEENDPOINT: litecoind:39388
NBXPLORER_LTCRPCUSER: ceiwHEbqWI83
NBXPLORER_LTCRPCPASSWORD: DwubwWsoo3
NBXPLORER_BIND: 0.0.0.0:32838
NBXPLORER_VERBOSE: 1
NBXPLORER_NOAUTH: 1
links:
- bitcoind
litecoin-nbxplorer:
image: nicolasdorier/nbxplorer:1.0.0.48
ports:
- "32839:32839"
expose:
- "32839"
environment:
NBXPLORER_NETWORK: ltc-regtest
NBXPLORER_RPCURL: http://litecoind:43782/
NBXPLORER_RPCUSER: ceiwHEbqWI83
NBXPLORER_RPCPASSWORD: DwubwWsoo3
NBXPLORER_NODEENDPOINT: litecoind:39388
NBXPLORER_BIND: 0.0.0.0:32839
NBXPLORER_VERBOSE: 1
NBXPLORER_NOAUTH: 1
links:
- litecoind
- litecoind
bitcoind:
container_name: btcpayserver_dev_bitcoind
@ -86,15 +72,11 @@ services:
rpcport=43782
port=39388
whitelist=0.0.0.0/0
zmqpubrawblock=tcp://0.0.0.0:29000
zmqpubrawtx=tcp://0.0.0.0:29000
txindex=1
ports:
- "43782:43782"
expose:
- "43782" # RPC
- "39388" # P2P
- "29000" # zmq
litecoind:
container_name: btcpayserver_dev_litecoind
@ -108,15 +90,11 @@ services:
rpcport=43782
port=39388
whitelist=0.0.0.0/0
zmqpubrawblock=tcp://0.0.0.0:29000
zmqpubrawtx=tcp://0.0.0.0:29000
txindex=1
ports:
- "43783:43782"
expose:
- "43782" # RPC
- "39388" # P2P
- "29000" # zmq
postgres:
image: postgres:9.6.5

View File

@ -5,16 +5,10 @@ using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Services.Rates;
using NBitcoin;
using NBXplorer.Configuration;
using NBXplorer;
namespace BTCPayServer
{
public enum ChainType
{
Regtest,
Main,
Test
}
public class BTCPayDefaultSettings
{
static BTCPayDefaultSettings()
@ -67,7 +61,7 @@ namespace BTCPayServer
}
public string CryptoImagePath { get; set; }
public NetworkInformation NBXplorerNetwork { get; set; }
public NBXplorer.NBXplorerNetwork NBXplorerNetwork { get; set; }
public BTCPayDefaultSettings DefaultSettings { get; set; }

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Services.Rates;
using NBitcoin;
using NBitpayClient;
using NBXplorer;
namespace BTCPayServer
{
public partial class BTCPayNetworkProvider
{
public void InitBitcoin()
{
var nbxplorerNetwork = NBXplorerNetworkProvider.GetFromCryptoCode("BTC");
var coinaverage = new CoinAverageRateProvider("BTC");
var bitpay = new BitpayRateProvider(new Bitpay(new Key(), new Uri("https://bitpay.com/")));
var btcRate = new FallbackRateProvider(new IRateProvider[] { coinaverage, bitpay });
Add(new BTCPayNetwork()
{
CryptoCode = nbxplorerNetwork.CryptoCode,
BlockExplorerLink = "https://testnet.smartbit.com.au/tx/{0}",
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "bitcoin",
DefaultRateProvider = btcRate,
CryptoImagePath = "imlegacy/bitcoin-symbol.svg",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NBXplorerNetworkProvider.ChainType)
});
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Services.Rates;
using NBXplorer;
namespace BTCPayServer
{
public partial class BTCPayNetworkProvider
{
public void InitLitecoin()
{
NBXplorer.Altcoins.Litecoin.Networks.EnsureRegistered();
var ltcRate = new CoinAverageRateProvider("LTC");
var nbxplorerNetwork = NBXplorerNetworkProvider.GetFromCryptoCode("LTC");
Add(new BTCPayNetwork()
{
CryptoCode = nbxplorerNetwork.CryptoCode,
BlockExplorerLink = "https://live.blockcypher.com/ltc/tx/{0}/",
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "litecoin",
DefaultRateProvider = ltcRate,
CryptoImagePath = "imlegacy/litecoin-symbol.svg",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NBXplorerNetworkProvider.ChainType)
});
}
}
}

View File

@ -7,95 +7,29 @@ using BTCPayServer.Services.Rates;
using Microsoft.Extensions.Caching.Memory;
using NBitcoin;
using NBitpayClient;
using NBXplorer.Configuration;
using NBXplorer;
namespace BTCPayServer
{
public class BTCPayNetworkProvider
public partial class BTCPayNetworkProvider
{
static BTCPayNetworkProvider()
{
NBXplorer.Altcoins.Litecoin.Networks.EnsureRegistered();
}
Dictionary<string, BTCPayNetwork> _Networks = new Dictionary<string, BTCPayNetwork>();
private readonly NBXplorerNetworkProvider _NBXplorerNetworkProvider;
public NBXplorerNetworkProvider NBXplorerNetworkProvider
{
get
{
return _NBXplorerNetworkProvider;
}
}
public BTCPayNetworkProvider(ChainType chainType)
{
var coinaverage = new CoinAverageRateProvider("BTC");
var bitpay = new BitpayRateProvider(new Bitpay(new Key(), new Uri("https://bitpay.com/")));
var btcRate = new FallbackRateProvider(new IRateProvider[] { coinaverage, bitpay });
var ltcRate = new CoinAverageRateProvider("LTC");
if (chainType == ChainType.Main)
{
Add(new BTCPayNetwork()
{
CryptoCode = "BTC",
BlockExplorerLink = "https://www.smartbit.com.au/tx/{0}",
NBitcoinNetwork = Network.Main,
UriScheme = "bitcoin",
DefaultRateProvider = btcRate,
CryptoImagePath = "imlegacy/bitcoin-symbol.svg"
});
Add(new BTCPayNetwork()
{
CryptoCode = "LTC",
BlockExplorerLink = "https://live.blockcypher.com/ltc/tx/{0}/",
NBitcoinNetwork = NBXplorer.Altcoins.Litecoin.Networks.Mainnet,
UriScheme = "litecoin",
DefaultRateProvider = ltcRate,
CryptoImagePath = "imlegacy/litecoin-symbol.svg"
});
}
if (chainType == ChainType.Test)
{
Add(new BTCPayNetwork()
{
CryptoCode = "BTC",
BlockExplorerLink = "https://testnet.smartbit.com.au/tx/{0}",
NBitcoinNetwork = Network.TestNet,
UriScheme = "bitcoin",
DefaultRateProvider = btcRate,
CryptoImagePath = "imlegacy/bitcoin-symbol.svg"
});
Add(new BTCPayNetwork()
{
CryptoCode = "LTC",
BlockExplorerLink = "http://explorer.litecointools.com/tx/{0}",
NBitcoinNetwork = NBXplorer.Altcoins.Litecoin.Networks.Testnet,
UriScheme = "litecoin",
DefaultRateProvider = ltcRate,
CryptoImagePath = "imlegacy/litecoin-symbol.svg"
});
}
if (chainType == ChainType.Regtest)
{
Add(new BTCPayNetwork()
{
CryptoCode = "BTC",
BlockExplorerLink = "https://testnet.smartbit.com.au/tx/{0}",
NBitcoinNetwork = Network.RegTest,
UriScheme = "bitcoin",
DefaultRateProvider = btcRate,
CryptoImagePath = "imlegacy/bitcoin-symbol.svg"
});
Add(new BTCPayNetwork()
{
CryptoCode = "LTC",
BlockExplorerLink = "http://explorer.litecointools.com/tx/{0}",
NBitcoinNetwork = NBXplorer.Altcoins.Litecoin.Networks.Regtest,
UriScheme = "litecoin",
DefaultRateProvider = ltcRate,
CryptoImagePath = "imlegacy/litecoin-symbol.svg",
});
}
foreach(var n in _Networks)
{
n.Value.NBXplorerNetwork = NetworkInformation.GetNetworkByName(n.Value.NBitcoinNetwork.Name);
n.Value.DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(chainType);
}
_NBXplorerNetworkProvider = new NBXplorerNetworkProvider(chainType);
InitBitcoin();
InitLitecoin();
}
[Obsolete("To use only for legacy stuff")]

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<Version>1.0.0.66</Version>
<Version>1.0.0.67</Version>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Build\dockerfiles\**" />
@ -24,7 +24,7 @@
<PackageReference Include="NBitcoin" Version="4.0.0.51" />
<PackageReference Include="NBitpayClient" Version="1.0.0.16" />
<PackageReference Include="DBreeze" Version="1.87.0" />
<PackageReference Include="NBXplorer.Client" Version="1.0.0.29" />
<PackageReference Include="NBXplorer.Client" Version="1.0.0.31" />
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.1" />
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.2" />
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.13" />

View File

@ -44,16 +44,16 @@ namespace BTCPayServer.Configuration
var supportedChains = conf.GetOrDefault<string>("chains", "btc")
.Split(',', StringSplitOptions.RemoveEmptyEntries)
.Select(t => t.ToLowerInvariant());
.Select(t => t.ToUpperInvariant());
var validChains = new List<string>();
foreach (var net in new BTCPayNetworkProvider(ChainType).GetAll())
{
if (supportedChains.Contains(net.CryptoCode.ToLowerInvariant()))
if (supportedChains.Contains(net.CryptoCode))
{
validChains.Add(net.CryptoCode.ToLowerInvariant());
var explorer = conf.GetOrDefault<Uri>($"{net.CryptoCode}.explorer.url", new Uri(net.NBXplorerNetwork.GetDefaultExplorerUrl()));
var cookieFile = conf.GetOrDefault<string>($"{net.CryptoCode}.explorer.cookiefile", net.NBXplorerNetwork.GetDefaultCookieFile());
if (cookieFile.Trim() == "0")
validChains.Add(net.CryptoCode);
var explorer = conf.GetOrDefault<Uri>($"{net.CryptoCode}.explorer.url", net.NBXplorerNetwork.DefaultSettings.DefaultUrl);
var cookieFile = conf.GetOrDefault<string>($"{net.CryptoCode}.explorer.cookiefile", net.NBXplorerNetwork.DefaultSettings.DefaultCookieFile);
if (cookieFile.Trim() == "0" || string.IsNullOrEmpty(cookieFile.Trim()))
cookieFile = null;
if (explorer != null)
{
@ -65,14 +65,14 @@ namespace BTCPayServer.Configuration
if(!string.IsNullOrEmpty(invalidChains))
throw new ConfigException($"Invalid chains {invalidChains}");
Logs.Configuration.LogInformation("Supported chains: " + String.Join(';', supportedChains.ToArray()));
Logs.Configuration.LogInformation("Supported chains: " + String.Join(',', supportedChains.ToArray()));
PostgresConnectionString = conf.GetOrDefault<string>("postgres", null);
ExternalUrl = conf.GetOrDefault<Uri>("externalurl", null);
}
private static ExplorerClient CreateExplorerClient(BTCPayNetwork n, Uri uri, string cookieFile)
{
var explorer = new ExplorerClient(n.NBitcoinNetwork, uri);
var explorer = new ExplorerClient(n.NBXplorerNetwork, uri);
if (cookieFile == null || !explorer.SetCookieAuth(cookieFile))
explorer.SetNoAuth();
return explorer;

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using NBitcoin;
using System.Text;
using CommandLine;
using NBXplorer;
namespace BTCPayServer.Configuration
{
@ -32,8 +33,9 @@ namespace BTCPayServer.Configuration
app.Option("--postgres", $"Connection string to postgres database (default: sqlite is used)", CommandOptionType.SingleValue);
foreach (var network in provider.GetAll())
{
app.Option($"--{network.CryptoCode}explorerurl", $"Url of the NBxplorer for {network.CryptoCode} (default: {network.NBXplorerNetwork.GetDefaultExplorerUrl()})", CommandOptionType.SingleValue);
app.Option($"--{network.CryptoCode}explorercookiefile", $"Path to the cookie file (default: {network.NBXplorerNetwork.GetDefaultCookieFile()})", CommandOptionType.SingleValue);
var crypto = network.CryptoCode.ToLowerInvariant();
app.Option($"--{crypto}explorerurl", $"Url of the NBxplorer for {network.CryptoCode} (default: {network.NBXplorerNetwork.DefaultSettings.DefaultUrl})", CommandOptionType.SingleValue);
app.Option($"--{crypto}explorercookiefile", $"Path to the cookie file (default: {network.NBXplorerNetwork.DefaultSettings.DefaultCookieFile})", CommandOptionType.SingleValue);
}
app.Option("--externalurl", $"The expected external url of this service, to use if BTCPay is behind a reverse proxy (default: empty, use the incoming HTTP request to figure out)", CommandOptionType.SingleValue);
return app;
@ -62,12 +64,7 @@ namespace BTCPayServer.Configuration
if (network != null)
{
var n = Network.GetNetwork(network);
if (n == Network.Main)
return ChainType.Main;
if (n == Network.TestNet)
return ChainType.Test;
if (n == Network.RegTest)
return ChainType.Regtest;
return n.ToChainType();
}
var net = conf.GetOrDefault<bool>("regtest", false) ? ChainType.Regtest:
conf.GetOrDefault<bool>("testnet", false) ? ChainType.Test : ChainType.Main;
@ -92,8 +89,8 @@ namespace BTCPayServer.Configuration
builder.AppendLine("### NBXplorer settings ###");
foreach (var n in new BTCPayNetworkProvider(defaultSettings.ChainType).GetAll())
{
builder.AppendLine($"#{n.CryptoCode}.explorer.url={n.NBXplorerNetwork.GetDefaultExplorerUrl()}");
builder.AppendLine($"#{n.CryptoCode}.explorer.cookiefile={ n.NBXplorerNetwork.GetDefaultCookieFile()}");
builder.AppendLine($"#{n.CryptoCode}.explorer.url={n.NBXplorerNetwork.DefaultSettings.DefaultUrl}");
builder.AppendLine($"#{n.CryptoCode}.explorer.cookiefile={ n.NBXplorerNetwork.DefaultSettings.DefaultCookieFile}");
}
return builder.ToString();
}

View File

@ -88,7 +88,7 @@ namespace BTCPayServer
}
}
Logs.Events.LogInformation($"New event: {evt.ToString()}");
Logs.Events.LogInformation(evt.ToString());
foreach (var sub in actionList)
{
try

View File

@ -7,9 +7,10 @@ namespace BTCPayServer.Events
{
public class NewBlockEvent
{
public string CryptoCode { get; set; }
public override string ToString()
{
return "New block";
return $"{CryptoCode}: New block";
}
}
}

View File

@ -24,14 +24,6 @@ namespace BTCPayServer
{
public static class Extensions
{
public static string GetDefaultExplorerUrl(this NBXplorer.Configuration.NetworkInformation networkInfo)
{
return $"http://127.0.0.1:{networkInfo.DefaultExplorerPort}/";
}
public static string GetDefaultCookieFile(this NBXplorer.Configuration.NetworkInformation networkInfo)
{
return Path.Combine(networkInfo.DefaultDataDirectory, ".cookie");
}
public static bool SupportDropColumn(this Microsoft.EntityFrameworkCore.Migrations.Migration migration, string activeProvider)
{
return activeProvider != "Microsoft.EntityFrameworkCore.Sqlite";

View File

@ -135,7 +135,7 @@ namespace BTCPayServer.HostedServices
{
case NBXplorer.Models.NewBlockEvent evt:
_TxCache.GetTransactionCache(network).NewBlock(evt.Hash, evt.PreviousBlockHash);
_Aggregator.Publish(new Events.NewBlockEvent());
_Aggregator.Publish(new Events.NewBlockEvent() { CryptoCode = evt.CryptoCode });
break;
case NBXplorer.Models.NewTransactionEvent evt:
foreach (var txout in evt.Outputs)

View File

@ -58,7 +58,7 @@ namespace BTCPayServer.Services.Wallets
public async Task<BitcoinAddress> ReserveAddressAsync(DerivationStrategyBase derivationStrategy)
{
var pathInfo = await _Client.GetUnusedAsync(derivationStrategy, DerivationFeature.Deposit, 0, true).ConfigureAwait(false);
return pathInfo.ScriptPubKey.GetDestinationAddress(_Client.Network);
return pathInfo.ScriptPubKey.GetDestinationAddress(Network.NBitcoinNetwork);
}
public async Task TrackAsync(DerivationStrategyBase derivationStrategy)