Merge pull request #1046 from Kukks/pre-monero

General optimizations and fixes
This commit is contained in:
Nicolas Dorier
2019-09-22 00:15:37 +09:00
committed by GitHub
17 changed files with 84 additions and 62 deletions

View File

@@ -54,7 +54,8 @@ namespace BTCPayServer
public KeyPath CoinType { get; internal set; }
public Dictionary<uint, DerivationType> ElectrumMapping = new Dictionary<uint, DerivationType>();
public int MaxTrackedConfirmation { get; internal set; } = 6;
public string UriScheme { get; internal set; }
public KeyPath GetRootKeyPath(DerivationType type)
{
KeyPath baseKey;
@@ -105,7 +106,6 @@ namespace BTCPayServer
public string CryptoCode { get; internal set; }
public string BlockExplorerLink { get; internal set; }
public string UriScheme { get; internal set; }
public string DisplayName { get; set; }
[Obsolete("Should not be needed")]
@@ -118,8 +118,6 @@ namespace BTCPayServer
}
public string CryptoImagePath { get; set; }
public int MaxTrackedConfirmation { get; internal set; } = 6;
public string[] DefaultRateRules { get; internal set; } = Array.Empty<string>();
public override string ToString()
{

View File

@@ -0,0 +1,7 @@
namespace BTCPayServer.Contracts
{
public interface IStoreNavExtension
{
string Partial { get; }
}
}

View File

@@ -41,7 +41,7 @@ namespace BTCPayServer.Controllers
{
var invoice = (await _InvoiceRepository.GetInvoices(new InvoiceQuery()
{
InvoiceId = id,
InvoiceId = new[] {id},
StoreId = new[] { HttpContext.GetStoreData().Id }
})).FirstOrDefault();
if (invoice == null)

View File

@@ -37,7 +37,7 @@ namespace BTCPayServer.Controllers
{
var invoice = (await _InvoiceRepository.GetInvoices(new InvoiceQuery()
{
InvoiceId = invoiceId,
InvoiceId = new[] {invoiceId},
UserId = GetUserId(),
IncludeAddresses = true,
IncludeEvents = true
@@ -582,7 +582,7 @@ namespace BTCPayServer.Controllers
{
var invoice = (await _InvoiceRepository.GetInvoices(new InvoiceQuery()
{
InvoiceId = invoiceId,
InvoiceId = new[] {invoiceId},
UserId = GetUserId()
})).FirstOrDefault();

View File

@@ -108,7 +108,7 @@ namespace BTCPayServer.Data
foreach (var strat in strategies.Properties())
{
var paymentMethodId = PaymentMethodId.Parse(strat.Name);
var network = networks.GetNetwork<BTCPayNetwork>(paymentMethodId.CryptoCode);
var network = networks.GetNetwork<BTCPayNetworkBase>(paymentMethodId.CryptoCode);
if (network != null)
{
if (network == networks.BTC && paymentMethodId.PaymentType == PaymentTypes.BTCLike && btcReturned)

View File

@@ -315,8 +315,9 @@ namespace BTCPayServer.HostedServices
var paymentData = payment.GetCryptoPaymentData();
if (paymentData is Payments.Bitcoin.BitcoinLikePaymentData onChainPaymentData)
{
var network = payment.Network as BTCPayNetwork;
// Do update if confirmation count in the paymentData is not up to date
if ((onChainPaymentData.ConfirmationCount < payment.Network.MaxTrackedConfirmation && payment.Accounted)
if ((onChainPaymentData.ConfirmationCount < network.MaxTrackedConfirmation && payment.Accounted)
&& (onChainPaymentData.Legacy || invoice.MonitoringExpiration < DateTimeOffset.UtcNow))
{
var transactionResult = await _ExplorerClientProvider.GetExplorerClient(payment.GetCryptoCode())?.GetTransactionAsync(onChainPaymentData.Outpoint.Hash);
@@ -325,7 +326,7 @@ namespace BTCPayServer.HostedServices
payment.SetCryptoPaymentData(onChainPaymentData);
// we want to extend invoice monitoring until we reach max confirmations on all onchain payment methods
if (confirmationCount < payment.Network.MaxTrackedConfirmation)
if (confirmationCount < network.MaxTrackedConfirmation)
extendInvoiceMonitoring = true;
return payment;

View File

@@ -59,7 +59,7 @@ namespace BTCPayServer.Payments.Bitcoin
public bool PaymentCompleted(PaymentEntity entity)
{
return ConfirmationCount >= Network.MaxTrackedConfirmation;
return ConfirmationCount >= ((BTCPayNetwork)Network).MaxTrackedConfirmation;
}
public bool PaymentConfirmed(PaymentEntity entity, SpeedPolicy speedPolicy)

View File

@@ -87,7 +87,9 @@ namespace BTCPayServer.Payments.Bitcoin
public override IEnumerable<PaymentMethodId> GetSupportedPaymentMethods()
{
return _networkProvider.GetAll()
return _networkProvider
.GetAll()
.OfType<BTCPayNetwork>()
.Select(network => new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike));
}

View File

@@ -149,7 +149,8 @@ namespace BTCPayServer.Payments.Bitcoin
foreach (var txCoin in evt.TransactionData.Transaction.Outputs.AsCoins()
.Where(o => o.ScriptPubKey == output.ScriptPubKey))
{
var invoice = await _InvoiceRepository.GetInvoiceFromScriptPubKey(output.ScriptPubKey, network.CryptoCode);
var key = output.ScriptPubKey.Hash + "#" + network.CryptoCode;
var invoice = (await _InvoiceRepository.GetInvoicesFromAddresses(new [] {key})).FirstOrDefault();
if (invoice != null)
{
var paymentData = new BitcoinLikePaymentData(txCoin, evt.TransactionData.Transaction.RBF);

View File

@@ -67,7 +67,7 @@ namespace BTCPayServer.Payments.Lightning
}
catch (OperationCanceledException) when (cts.IsCancellationRequested)
{
throw new PaymentMethodUnavailableException($"The lightning node did not reply in a timely maner");
throw new PaymentMethodUnavailableException($"The lightning node did not reply in a timely manner");
}
catch (Exception ex)
{
@@ -139,7 +139,10 @@ namespace BTCPayServer.Payments.Lightning
public override IEnumerable<PaymentMethodId> GetSupportedPaymentMethods()
{
return _networkProvider.GetAll()
return _networkProvider
.GetAll()
.OfType<BTCPayNetwork>()
.Where(network => network.NBitcoinNetwork.Consensus.SupportSegwit)
.Select(network => new PaymentMethodId(network.CryptoCode, PaymentTypes.LightningLike));
}

View File

@@ -461,7 +461,7 @@ namespace BTCPayServer.Services.Invoices
}
else if (paymentId.PaymentType == PaymentTypes.BTCLike)
{
var scheme = info.Network.UriScheme;
var scheme = ((BTCPayNetwork)info.Network).UriScheme;
var minerInfo = new MinerFeeInfo();
minerInfo.TotalFee = accounting.NetworkFee.Satoshi;
@@ -911,7 +911,7 @@ namespace BTCPayServer.Services.Invoices
{
[NotMapped]
[JsonIgnore]
public BTCPayNetwork Network { get; set; }
public BTCPayNetworkBase Network { get; set; }
public int Version { get; set; }
public DateTimeOffset ReceivedTime
{

View File

@@ -1,6 +1,7 @@
using DBriize;
using Microsoft.Extensions.Logging;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using NBitpayClient;
@@ -80,30 +81,31 @@ retry:
}
}
public async Task<InvoiceEntity> GetInvoiceFromScriptPubKey(Script scriptPubKey, string cryptoCode)
public async Task<IEnumerable<InvoiceEntity>> GetInvoicesFromAddresses(string[] addresses)
{
using (var db = _ContextFactory.CreateContext())
{
var key = scriptPubKey.Hash.ToString() + "#" + cryptoCode;
var result = (await db.AddressInvoices
return (await db.AddressInvoices
#pragma warning disable CS0618
.Where(a => a.Address == key)
.Where(a => addresses.Contains(a.Address))
#pragma warning restore CS0618
.Select(a => a.InvoiceData)
.Include(a => a.Payments)
.Include(a => a.RefundAddresses)
.ToListAsync()).FirstOrDefault();
if (result == null)
return null;
return ToEntity(result);
.Select(a => a.InvoiceData)
.Include(a => a.Payments)
.Include(a => a.RefundAddresses)
.ToListAsync()).Select(ToEntity);
}
}
public async Task<string[]> GetPendingInvoices()
public async Task<string[]> GetPendingInvoices(Func<IQueryable<PendingInvoiceData>, IQueryable<PendingInvoiceData>> filter = null )
{
using (var ctx = _ContextFactory.CreateContext())
{
return await ctx.PendingInvoices.Select(p => p.Id).ToArrayAsync();
var queryable = ctx.PendingInvoices.AsQueryable();
if (filter != null)
{
queryable = filter.Invoke(queryable);
}
return await queryable.Select(p => p.Id).ToArrayAsync();
}
}
@@ -239,7 +241,7 @@ retry:
return paymentMethod.GetPaymentMethodDetails().GetPaymentDestination();
}
public async Task<bool> NewAddress(string invoiceId, Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod paymentMethod, BTCPayNetworkBase network)
public async Task<bool> NewAddress(string invoiceId, IPaymentMethodDetails paymentMethod, BTCPayNetworkBase network)
{
using (var context = _ContextFactory.CreateContext())
{
@@ -252,7 +254,7 @@ retry:
if (currencyData == null)
return false;
var existingPaymentMethod = (Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod)currencyData.GetPaymentMethodDetails();
var existingPaymentMethod = currencyData.GetPaymentMethodDetails();
if (existingPaymentMethod.GetPaymentDestination() != null)
{
MarkUnassigned(invoiceId, invoiceEntity, context, currencyData.GetId());
@@ -441,7 +443,7 @@ retry:
entity.Payments = invoice.Payments.Select(p =>
{
var paymentEntity = ToObject<PaymentEntity>(p.Blob, null);
paymentEntity.Network = _Networks.GetNetwork<BTCPayNetwork>(paymentEntity.CryptoCode);
paymentEntity.Network = _Networks.GetNetwork<BTCPayNetworkBase>(paymentEntity.CryptoCode);
paymentEntity.Accounted = p.Accounted;
// PaymentEntity on version 0 does not have their own fee, because it was assumed that the payment method have fixed fee.
// We want to hide this legacy detail in InvoiceRepository, so we fetch the fee from the PaymentMethod and assign it to the PaymentEntity.
@@ -487,11 +489,12 @@ retry:
{
IQueryable<Data.InvoiceData> query = context.Invoices;
if (!string.IsNullOrEmpty(queryObject.InvoiceId))
if (queryObject.InvoiceId != null && queryObject.InvoiceId.Length > 0)
{
query = query.Where(i => i.Id == queryObject.InvoiceId);
var statusSet = queryObject.InvoiceId.ToHashSet();
query = query.Where(i => statusSet.Contains(i.Id));
}
if (queryObject.StoreId != null && queryObject.StoreId.Length > 0)
{
var stores = queryObject.StoreId.ToHashSet();
@@ -663,10 +666,10 @@ retry:
ReceivedTime = date.UtcDateTime,
Accounted = accounted,
NetworkFee = paymentMethodDetails.GetNextNetworkFee(),
Network = network as BTCPayNetwork
Network = network
};
entity.SetCryptoPaymentData(paymentData);
//TODO: abstract
if (paymentMethodDetails is Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod bitcoinPaymentMethod &&
bitcoinPaymentMethod.NetworkFeeMode == NetworkFeeMode.MultiplePaymentsOnly &&
bitcoinPaymentMethod.NextNetworkFee == Money.Zero)
@@ -811,7 +814,7 @@ retry:
get; set;
}
public string InvoiceId
public string[] InvoiceId
{
get;
set;

View File

@@ -12,9 +12,10 @@
m.DepositAddress = onChainPaymentData.GetDestination();
int confirmationCount = onChainPaymentData.ConfirmationCount;
if (confirmationCount >= payment.Network.MaxTrackedConfirmation)
var network = payment.Network as BTCPayNetwork;
if (confirmationCount >= network.MaxTrackedConfirmation)
{
m.Confirmations = "At least " + (payment.Network.MaxTrackedConfirmation);
m.Confirmations = "At least " + (network.MaxTrackedConfirmation);
}
else
{

View File

@@ -1,13 +1,18 @@
@{
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.ShowMenu = ViewBag.ShowMenu ?? true;
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.ShowMenu = ViewBag.ShowMenu ?? true;
if (!ViewData.ContainsKey("NavPartialName"))
{
ViewData["NavPartialName"] = "_Nav";
}
var title = $"{(ViewData.ContainsKey("MainTitle")? $"{ViewData["MainTitle"]}:" : String.Empty)} {ViewData["Title"]}";
}
<section>
<div class="container">
<div class="row">
<div class="col-lg-12">
<h4 class="section-heading">@ViewData["MainTitle"]: @ViewData["Title"]</h4>
<h4 class="section-heading">@title</h4>
<hr class="primary ml-0">
</div>
</div>
@@ -17,7 +22,7 @@ ViewBag.ShowMenu = ViewBag.ShowMenu ?? true;
<div class="col-md-3">
@if (ViewBag.ShowMenu)
{
@await Html.PartialAsync("_Nav")
@await Html.PartialAsync(ViewData["NavPartialName"].ToString())
}
</div>
<div class="col-md-9">
@@ -28,9 +33,9 @@ ViewBag.ShowMenu = ViewBag.ShowMenu ?? true;
</div>
</section>
@section HeadScripts {
@RenderSection("HeadScripts", required: false)
@RenderSection("HeadScripts", required: false)
}
@section Scripts {
@RenderSection("Scripts", required: false)
@RenderSection("Scripts", required: false)
}

View File

@@ -4,19 +4,6 @@
ViewData.SetActivePageAndTitle(StoreNavPages.Index, "Profile");
}
<style type="text/css">
.smMaxWidth {
max-width: 150px;
}
@@media (min-width: 768px) {
.smMaxWidth {
max-width: 300px;
}
}
</style>
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
<div class="row">

View File

@@ -5,5 +5,9 @@
<a id="@(nameof(StoreNavPages.Tokens))"class="nav-link @ViewData.IsActivePage(StoreNavPages.Tokens)" asp-action="ListTokens">Access Tokens</a>
<a id="@(nameof(StoreNavPages.Users))"class="nav-link @ViewData.IsActivePage(StoreNavPages.Users)" asp-action="StoreUsers">Users</a>
<a id="@(nameof(StoreNavPages.PayButton))"class="nav-link @ViewData.IsActivePage(StoreNavPages.PayButton)" asp-action="PayButton">Pay Button</a>
@inject IEnumerable<BTCPayServer.Contracts.IStoreNavExtension> Extensions;
@foreach (var extension in Extensions)
{
<partial name="@extension.Partial"/>
}
</div>

View File

@@ -118,4 +118,14 @@ a.nav-link {
.invoice-details a{
/* Prevent layout from breaking on hyperlinks with very long URLs as the visible text */
word-break: break-word;
}
}
.smMaxWidth {
max-width: 150px;
}
@media (min-width: 768px) {
.smMaxWidth {
max-width: 300px;
}
}