Commit d0e82faf authored by Jeremy Bokobza's avatar Jeremy Bokobza Committed by Dan Gershony

Notify wallet with new blocks (#12)

* The full is now able to notify the wallet with new blocks
Provided a temporary endpoint for demo purposes

* Updated to "Stratis.Bitcoin": "1.0.1.3-alpha"

* Update global.json
parent f6473308
{
{
"projects": [ "src" ]
}
{
"variables": [],
"info": {
"name": "Node",
"_postman_id": "28053655-d992-60bb-a476-0c83186f5674",
"description": "",
"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
},
"item": [
{
"name": "Connect full node",
"request": {
"url": "http://localhost:5000/api/node/connect",
"method": "GET",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{ \n\t\"password\": \"123456\",\n\t\"network\": \"Main\",\n\t\"folderPath\": \"Wallets\",\n\t\"name\": \"myFirstWallet\"\n}"
},
"description": ""
},
"response": []
},
{
"name": "Start syncing from hash",
"request": {
"url": "http://localhost:5000/api/v1/node/sync",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{ \n\t\"hash\": \"00000000770ebe897270ca5f6d539d8afb4ea4f4e757761a34ca82e17207d886\"\n}"
},
"description": "{ \n\t\"hash\": \"00000000770ebe897270ca5f6d539d8afb4ea4f4e757761a34ca82e17207d886\"\n}"
},
"response": []
}
]
}
\ No newline at end of file
using Microsoft.Extensions.DependencyInjection;
using Stratis.Bitcoin;
using Stratis.Bitcoin.Builder;
using Stratis.Bitcoin.Builder.Feature;
namespace Breeze.Api
{
/// <summary>
/// Provides an Api to the full node
/// </summary>
public class ApiFeature : FullNodeFeature
{
{
private readonly IFullNodeBuilder fullNodeBuilder;
private readonly FullNode fullNode;
public ApiFeature(IFullNodeBuilder fullNodeBuilder)
public ApiFeature(IFullNodeBuilder fullNodeBuilder, FullNode fullNode)
{
this.fullNodeBuilder = fullNodeBuilder;
this.fullNode = fullNode;
}
public override void Start()
{
Program.Initialize(this.fullNodeBuilder.Services);
Program.Initialize(this.fullNodeBuilder.Services, this.fullNode);
}
}
......
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using NBitcoin;
using Stratis.Bitcoin.Notifications;
namespace Breeze.Api.Controllers
{
{
[Route("api/v{version:apiVersion}/[controller]")]
public class NodeController : Controller
{
[HttpGet]
{
private readonly BlockNotification blockNotification;
public NodeController(BlockNotification blockNotification)
{
this.blockNotification = blockNotification;
}
[HttpGet]
[Route("status")]
public IActionResult Status()
{
return this.NotFound();
}
[HttpPost]
[Route("sync")]
public IActionResult Sync([FromBody] HashModel model)
{
if (!ModelState.IsValid)
{
return this.BadRequest();
}
this.blockNotification.SyncFrom(uint256.Parse(model.Hash));
return this.Ok();
}
}
public class HashModel
{
[Required(AllowEmptyStrings = false)]
public string Hash { get; set; }
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Stratis.Bitcoin;
namespace Breeze.Api
{
......@@ -12,7 +13,7 @@ namespace Breeze.Api
Initialize();
}
public static void Initialize(IEnumerable<ServiceDescriptor> services = null)
public static void Initialize(IEnumerable<ServiceDescriptor> services = null, FullNode fullNode = null)
{
var host = new WebHostBuilder()
.UseKestrel()
......@@ -20,20 +21,30 @@ namespace Breeze.Api
.UseIISIntegration()
.ConfigureServices(collection =>
{
if (services == null)
if (services == null || fullNode == null)
{
return;
}
// copies all the services defined for the full node to the Api.
// also copies over singleton instances already defined
foreach (var service in services)
{
collection.Add(service);
var obj = fullNode.Services.ServiceProvider.GetService(service.ServiceType);
if (obj != null && service.Lifetime == ServiceLifetime.Singleton && service.ImplementationInstance == null)
{
collection.AddSingleton(service.ServiceType, obj);
}
else
{
collection.Add(service);
}
}
})
.UseStartup<Startup>()
.Build();
host.Run();
host.Start();
}
}
}
......@@ -15,7 +15,7 @@
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.1",
"Microsoft.NETCore.App": "1.1.0",
"NBitcoin": "3.0.2.10",
"Stratis.Bitcoin": "1.0.1.2-alpha",
"Stratis.Bitcoin": "1.0.1.3-alpha",
"Swashbuckle.AspNetCore": "1.0.0-rc3",
"System.Reactive": "3.1.1",
"System.Runtime.Loader": "4.3.0"
......
using System.Threading;
using System;
using System.Threading;
using Breeze.Api;
using Microsoft.Extensions.Logging;
using Stratis.Bitcoin;
......@@ -6,6 +7,7 @@ using Stratis.Bitcoin.Builder;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Logging;
using Breeze.Wallet;
using Stratis.Bitcoin.Notifications;
namespace Breeze.Deamon
{
......@@ -19,30 +21,16 @@ namespace Breeze.Deamon
var node = (FullNode)new FullNodeBuilder()
.UseNodeSettings(nodeSettings)
.UseWallet()
.UseWallet()
.UseBlockNotification()
.UseApi()
//.UseBlockNotification()
.Build();
System.Console.WriteLine();
// == shut down thread ==
new Thread(() =>
{
System.Console.WriteLine("Press one key to stop");
System.Console.ReadLine();
node.Dispose();
})
{
IsBackground = true //so the process terminates
}.Start();
// start Full Node - this will also start the API
node.Start();
node.WaitDisposed();
Console.WriteLine("Press any key to stop");
Console.ReadLine();
node.Dispose();
}
}
}
......@@ -16,7 +16,7 @@
"type": "platform",
"version": "1.1.0"
},
"Stratis.Bitcoin": "1.0.1.2-alpha"
"Stratis.Bitcoin": "1.0.1.3-alpha"
},
"frameworks": {
......
using NBitcoin;
using Stratis.Bitcoin;
using Breeze.Wallet.Wrappers;
using Stratis.Bitcoin.Builder;
namespace Breeze.Wallet.Notifications
{
/// <summary>
/// Observer that receives notifications about the arrival of new <see cref="Block"/>s.
/// </summary>
public class BlockObserver : SignalObserver<Block>
{
private readonly ConcurrentChain chain;
private readonly ITrackerWrapper trackerWrapper;
public BlockObserver(ConcurrentChain chain, ITrackerWrapper trackerWrapper)
{
this.chain = chain;
this.trackerWrapper = trackerWrapper;
}
/// <summary>
/// Manages what happens when a new block is received.
/// </summary>
/// <param name="block">The new block</param>
protected override void OnNextCore(Block block)
{
var hash = block.Header.GetHash();
var height = this.chain.GetBlock(hash).Height;
this.trackerWrapper.NotifyAboutBlock(height, block);
}
}
}
using Stratis.Bitcoin;
using System;
using NBitcoin;
namespace Breeze.Wallet.Notifications
{
/// <summary>
/// Manages the subscription of the block observer to the block signaler.
/// </summary>
public class BlockSubscriber
{
private readonly ISignaler<Block> signaler;
private readonly BlockObserver observer;
public BlockSubscriber(ISignaler<Block> signaler, BlockObserver observer)
{
this.signaler = signaler;
this.observer = observer;
}
/// <summary>
/// Subscribes the block observer to the block signaler.
/// </summary>
/// <returns>An <see cref="IDisposable"/></returns>
public IDisposable Subscribe()
{
return this.signaler.Subscribe(this.observer);
}
}
}
using Stratis.Bitcoin.Builder.Feature;
using Breeze.Wallet.Controllers;
using Breeze.Wallet.Notifications;
using Breeze.Wallet.Wrappers;
using Microsoft.Extensions.DependencyInjection;
using NBitcoin;
using Stratis.Bitcoin;
using Stratis.Bitcoin.Builder;
namespace Breeze.Wallet
{
public class WalletFeature : FullNodeFeature
{
private readonly ITrackerWrapper trackerWrapper;
private readonly Signals signals;
private readonly ConcurrentChain chain;
public WalletFeature(ITrackerWrapper trackerWrapper, Signals signals, ConcurrentChain chain)
{
this.trackerWrapper = trackerWrapper;
this.signals = signals;
this.chain = chain;
}
public override void Start()
{
BlockSubscriber sub = new BlockSubscriber(signals.Blocks, new BlockObserver(chain, trackerWrapper));
sub.Subscribe();
}
}
......
......@@ -6,7 +6,7 @@
"Microsoft.AspNetCore.Mvc.Versioning": "1.0.3",
"NBitcoin": "3.0.2.10",
"NETStandard.Library": "1.6.1",
"Stratis.Bitcoin": "1.0.1.2-alpha"
"Stratis.Bitcoin": "1.0.1.3-alpha"
},
"frameworks": {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment