Removing http callback notification system

This commit is contained in:
nicolas.dorier 2018-01-07 21:48:00 +09:00
parent 6cb1649fc2
commit 80e878c2f5
11 changed files with 5 additions and 267 deletions

View file

@ -213,43 +213,6 @@ namespace BTCPayServer.Tests
}
}
/// <summary>
/// Simulating callback from NBXplorer. NBXplorer can't reach the host during tests as it is not running on localhost.
/// </summary>
/// <param name="address"></param>
public void SimulateCallback(BitcoinAddress address = null)
{
if (!FakeCallback) //The callback of NBXplorer should work
return;
var req = new MockHttpRequest(PayTester.ServerUri);
var controller = PayTester.GetController<CallbackController>();
if (address != null)
{
var match = new TransactionMatch();
match.Outputs.Add(new KeyPathInformation() { ScriptPubKey = address.ScriptPubKey });
var content = new StringContent(new NBXplorer.Serializer(Network).ToString(match), new UTF8Encoding(false), "application/json");
var uri = controller.GetCallbackUriAsync().GetAwaiter().GetResult();
HttpRequestMessage message = new HttpRequestMessage();
message.Method = HttpMethod.Post;
message.RequestUri = uri;
message.Content = content;
_Http.SendAsync(message).GetAwaiter().GetResult();
}
else
{
var uri = controller.GetCallbackBlockUriAsync().GetAwaiter().GetResult();
HttpRequestMessage message = new HttpRequestMessage();
message.Method = HttpMethod.Post;
message.RequestUri = uri;
_Http.SendAsync(message).GetAwaiter().GetResult();
}
}
public BTCPayServerTester PayTester
{

View file

@ -119,7 +119,6 @@ namespace BTCPayServer.Tests
Eventually(() =>
{
tester.SimulateCallback(url.Address);
var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
Assert.Equal("paid", localInvoice.Status);
Assert.True(localInvoice.Refundable);
@ -193,7 +192,6 @@ namespace BTCPayServer.Tests
BitcoinUrlBuilder url = new BitcoinUrlBuilder(invoice.PaymentUrls.BIP21);
tester.ExplorerNode.SendToAddress(url.Address, url.Amount);
Thread.Sleep(5000);
tester.SimulateCallback(url.Address);
callbackServer.ProcessNextRequest((ctx) =>
{
var ipn = new StreamReader(ctx.Request.Body).ReadToEnd();
@ -253,7 +251,6 @@ namespace BTCPayServer.Tests
Eventually(() =>
{
tester.SimulateCallback(invoiceAddress);
invoice = user.BitPay.GetInvoice(invoice.Id);
Assert.Equal(payment1, invoice.BtcPaid);
invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, tester.Network);
@ -274,7 +271,6 @@ namespace BTCPayServer.Tests
var test = tester.ExplorerClient.Sync(user.DerivationScheme, null);
Eventually(() =>
{
tester.SimulateCallback(invoiceAddress);
invoice = user.BitPay.GetInvoice(invoice.Id);
Assert.Equal(payment2, invoice.BtcPaid);
});
@ -366,7 +362,6 @@ namespace BTCPayServer.Tests
Eventually(() =>
{
tester.SimulateCallback(invoiceAddress);
var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
Assert.Equal("new", localInvoice.Status);
Assert.Equal(firstPayment, localInvoice.BtcPaid);
@ -389,7 +384,6 @@ namespace BTCPayServer.Tests
Eventually(() =>
{
tester.SimulateCallback(invoiceAddress);
var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
Assert.Equal("paid", localInvoice.Status);
Assert.Equal(firstPayment + secondPayment, localInvoice.BtcPaid);
@ -403,7 +397,6 @@ namespace BTCPayServer.Tests
Eventually(() =>
{
tester.SimulateCallback();
var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
Assert.Equal("confirmed", localInvoice.Status);
});
@ -412,7 +405,6 @@ namespace BTCPayServer.Tests
Eventually(() =>
{
tester.SimulateCallback();
var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
Assert.Equal("complete", localInvoice.Status);
Assert.NotEqual(0.0, localInvoice.Rate);
@ -435,7 +427,6 @@ namespace BTCPayServer.Tests
Eventually(() =>
{
tester.SimulateCallback(invoiceAddress);
var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
Assert.Equal("paid", localInvoice.Status);
Assert.Equal(Money.Zero, localInvoice.BtcDue);
@ -446,7 +437,6 @@ namespace BTCPayServer.Tests
Eventually(() =>
{
tester.SimulateCallback();
var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
Assert.Equal("confirmed", localInvoice.Status);
Assert.Equal(Money.Zero, localInvoice.BtcDue);

View file

@ -42,7 +42,7 @@ services:
# - eclair2
nbxplorer:
image: nicolasdorier/nbxplorer:1.0.0.34
image: nicolasdorier/nbxplorer:1.0.0.35
ports:
- "32838:32838"
expose:

View file

@ -21,10 +21,10 @@
<PackageReference Include="Hangfire.MemoryStorage" Version="1.5.2" />
<PackageReference Include="Hangfire.PostgreSql" Version="1.4.8.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" />
<PackageReference Include="NBitcoin" Version="4.0.0.50" />
<PackageReference Include="NBitcoin" Version="4.0.0.51" />
<PackageReference Include="NBitpayClient" Version="1.0.0.13" />
<PackageReference Include="DBreeze" Version="1.87.0" />
<PackageReference Include="NBXplorer.Client" Version="1.0.0.22" />
<PackageReference Include="NBXplorer.Client" Version="1.0.0.23" />
<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

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BTCPayServer
{
public class CompositeDisposable : IDisposable
{
List<IDisposable> _Disposables = new List<IDisposable>();
public void Add(IDisposable disposable) { _Disposables.Add(disposable); }
public void Dispose()
{
foreach (var d in _Disposables)
d.Dispose();
_Disposables.Clear();
}
}
}

View file

@ -1,143 +0,0 @@
using BTCPayServer.Logging;
using BTCPayServer.Services.Invoices;
using BTCPayServer.Services;
using BTCPayServer.Services.Wallets;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NBitcoin;
using NBXplorer;
using Microsoft.Extensions.Logging;
using NBXplorer.DerivationStrategy;
using NBXplorer.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BTCPayServer.Configuration;
using BTCPayServer.Events;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Hosting.Server;
namespace BTCPayServer.Controllers
{
public class CallbackController : Controller
{
public class CallbackSettings
{
public string Token
{
get; set;
}
}
SettingsRepository _Settings;
Network _Network;
ExplorerClient _Explorer;
BTCPayServerOptions _Options;
EventAggregator _EventAggregator;
IServer _Server;
public CallbackController(SettingsRepository repo,
ExplorerClient explorer,
EventAggregator eventAggregator,
BTCPayServerOptions options,
IServer server,
BTCPayNetworkProvider networkProvider)
{
_Settings = repo;
_Network = networkProvider.GetNetwork("BTC").NBitcoinNetwork;
_Explorer = explorer;
_Options = options;
_EventAggregator = eventAggregator;
_Server = server;
}
[Route("callbacks/transactions")]
[HttpPost]
public async Task NewTransaction(string token)
{
await AssertToken(token);
//We don't want to register all the json converter at MVC level, so we parse here
var serializer = new NBXplorer.Serializer(_Network);
var content = await new StreamReader(Request.Body, new UTF8Encoding(false), false, 1024, true).ReadToEndAsync();
var match = serializer.ToObject<TransactionMatch>(content);
foreach (var output in match.Outputs)
{
var evt = new TxOutReceivedEvent();
evt.ScriptPubKey = output.ScriptPubKey;
evt.Address = output.ScriptPubKey.GetDestinationAddress(_Network);
_EventAggregator.Publish(evt);
}
}
[Route("callbacks/blocks")]
[HttpPost]
public async Task NewBlock(string token)
{
await AssertToken(token);
_EventAggregator.Publish(new Events.NewBlockEvent());
}
private async Task AssertToken(string token)
{
var callback = await _Settings.GetSettingAsync<CallbackSettings>();
if (await GetToken() != token)
throw new BTCPayServer.BitpayHttpException(400, "invalid-callback-token");
}
public async Task<Uri> GetCallbackUriAsync()
{
string token = await GetToken();
return BuildCallbackUri("callbacks/transactions?token=" + token);
}
public async Task RegisterCallbackUriAsync(DerivationStrategyBase derivationScheme)
{
var uri = await GetCallbackUriAsync();
await _Explorer.SubscribeToWalletAsync(uri, derivationScheme);
}
private async Task<string> GetToken()
{
var callback = await _Settings.GetSettingAsync<CallbackSettings>();
if (callback == null)
{
callback = new CallbackSettings() { Token = Guid.NewGuid().ToString() };
await _Settings.UpdateSetting(callback);
}
var token = callback.Token;
return token;
}
public async Task<Uri> GetCallbackBlockUriAsync()
{
string token = await GetToken();
return BuildCallbackUri("callbacks/blocks?token=" + token);
}
private Uri BuildCallbackUri(string callbackPath)
{
var address = _Server.Features.Get<IServerAddressesFeature>().Addresses
.Select(c => new Uri(TransformToRoutable(c)))
.First();
var baseUrl = _Options.InternalUrl == null ? address.AbsoluteUri : _Options.InternalUrl.AbsoluteUri;
baseUrl = baseUrl.WithTrailingSlash();
return new Uri(baseUrl + callbackPath);
}
private string TransformToRoutable(string host)
{
if (host.StartsWith("http://0.0.0.0"))
host = host.Replace("http://0.0.0.0", "http://127.0.0.1");
return host;
}
public async Task<Uri> RegisterCallbackBlockUriAsync(Uri uri)
{
await _Explorer.SubscribeToBlocksAsync(uri);
return uri;
}
}
}

View file

@ -19,6 +19,7 @@ using BTCPayServer.Services.Rates;
using System.Net.WebSockets;
using System.Threading;
using BTCPayServer.Events;
using NBXplorer;
namespace BTCPayServer.Controllers
{

View file

@ -30,7 +30,6 @@ namespace BTCPayServer.Controllers
public StoresController(
StoreRepository repo,
TokenRepository tokenRepo,
CallbackController callbackController,
UserManager<ApplicationUser> userManager,
AccessTokenController tokenController,
BTCPayWallet wallet,
@ -44,11 +43,9 @@ namespace BTCPayServer.Controllers
_Wallet = wallet;
_Env = env;
_NetworkProvider = networkProvider;
_CallbackController = callbackController;
}
BTCPayNetworkProvider _NetworkProvider;
CallbackController _CallbackController;
BTCPayWallet _Wallet;
AccessTokenController _TokenController;
StoreRepository _Repo;
@ -203,7 +200,6 @@ namespace BTCPayServer.Controllers
{
var strategy = ParseDerivationStrategy(model.DerivationScheme, model.DerivationSchemeFormat, _NetworkProvider.BTC);
await _Wallet.TrackAsync(strategy);
await _CallbackController.RegisterCallbackUriAsync(strategy.DerivationStrategyBase);
model.DerivationScheme = strategy.ToString();
}
store.DerivationStrategy = model.DerivationScheme;

View file

@ -168,11 +168,9 @@ namespace BTCPayServer.Hosting
services.TryAddSingleton<InvoiceWatcherAccessor>();
services.AddSingleton<IHostedService, InvoiceWatcher>();
services.TryAddSingleton<Initializer>();
services.TryAddScoped<IHttpContextAccessor, HttpContextAccessor>();
services.TryAddSingleton<IAuthorizationHandler, OwnStoreHandler>();
services.AddTransient<AccessTokenController>();
services.AddTransient<CallbackController>();
services.AddTransient<InvoiceController>();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
@ -204,10 +202,6 @@ namespace BTCPayServer.Hosting
});
}
var initialize = app.ApplicationServices.GetService<Initializer>();
initialize.Init();
app.UseMiddleware<BTCPayMiddleware>();
return app;
}

View file

@ -1,45 +0,0 @@
using System;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Controllers;
using BTCPayServer.Logging;
using BTCPayServer.Events;
namespace BTCPayServer
{
public class Initializer
{
EventAggregator _Aggregator;
CallbackController _CallbackController;
public Initializer(EventAggregator aggregator,
CallbackController callbackController
)
{
_Aggregator = aggregator;
_CallbackController = callbackController;
}
public void Init()
{
_Aggregator.Subscribe<NBXplorerStateChangedEvent>(async (s, evt) =>
{
if (evt.NewState == NBXplorerState.Ready)
{
s.Unsubscribe();
try
{
var callback = await _CallbackController.GetCallbackBlockUriAsync();
await _CallbackController.RegisterCallbackBlockUriAsync(callback);
Logs.PayServer.LogInformation($"Registering block callback to " + callback);
}
catch (Exception ex)
{
Logs.PayServer.LogError(ex, "Could not register block callback");
s.Resubscribe();
}
}
});
}
}
}

View file

@ -17,6 +17,7 @@ using Newtonsoft.Json;
using System.Collections.Concurrent;
using Microsoft.Extensions.Hosting;
using BTCPayServer.Events;
using NBXplorer;
namespace BTCPayServer.Services.Invoices
{