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" ] "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 Microsoft.Extensions.DependencyInjection;
using Stratis.Bitcoin;
using Stratis.Bitcoin.Builder; using Stratis.Bitcoin.Builder;
using Stratis.Bitcoin.Builder.Feature; using Stratis.Bitcoin.Builder.Feature;
namespace Breeze.Api namespace Breeze.Api
{ {
/// <summary>
/// Provides an Api to the full node
/// </summary>
public class ApiFeature : FullNodeFeature public class ApiFeature : FullNodeFeature
{ {
private readonly IFullNodeBuilder fullNodeBuilder; private readonly IFullNodeBuilder fullNodeBuilder;
private readonly FullNode fullNode;
public ApiFeature(IFullNodeBuilder fullNodeBuilder) public ApiFeature(IFullNodeBuilder fullNodeBuilder, FullNode fullNode)
{ {
this.fullNodeBuilder = fullNodeBuilder; this.fullNodeBuilder = fullNodeBuilder;
this.fullNode = fullNode;
} }
public override void Start() 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 namespace Breeze.Api.Controllers
{ {
[Route("api/v{version:apiVersion}/[controller]")] [Route("api/v{version:apiVersion}/[controller]")]
public class NodeController : Controller public class NodeController : Controller
{ {
private readonly BlockNotification blockNotification;
public NodeController(BlockNotification blockNotification)
{
this.blockNotification = blockNotification;
}
[HttpGet] [HttpGet]
[Route("status")] [Route("status")]
public IActionResult Status() public IActionResult Status()
{ {
return this.NotFound(); 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 @@ ...@@ -2,6 +2,7 @@
using System.IO; using System.IO;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Stratis.Bitcoin;
namespace Breeze.Api namespace Breeze.Api
{ {
...@@ -12,7 +13,7 @@ namespace Breeze.Api ...@@ -12,7 +13,7 @@ namespace Breeze.Api
Initialize(); Initialize();
} }
public static void Initialize(IEnumerable<ServiceDescriptor> services = null) public static void Initialize(IEnumerable<ServiceDescriptor> services = null, FullNode fullNode = null)
{ {
var host = new WebHostBuilder() var host = new WebHostBuilder()
.UseKestrel() .UseKestrel()
...@@ -20,20 +21,30 @@ namespace Breeze.Api ...@@ -20,20 +21,30 @@ namespace Breeze.Api
.UseIISIntegration() .UseIISIntegration()
.ConfigureServices(collection => .ConfigureServices(collection =>
{ {
if (services == null) if (services == null || fullNode == null)
{ {
return; 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) foreach (var service in services)
{
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); collection.Add(service);
} }
}
}) })
.UseStartup<Startup>() .UseStartup<Startup>()
.Build(); .Build();
host.Run(); host.Start();
} }
} }
} }
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.1", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.1",
"Microsoft.NETCore.App": "1.1.0", "Microsoft.NETCore.App": "1.1.0",
"NBitcoin": "3.0.2.10", "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", "Swashbuckle.AspNetCore": "1.0.0-rc3",
"System.Reactive": "3.1.1", "System.Reactive": "3.1.1",
"System.Runtime.Loader": "4.3.0" "System.Runtime.Loader": "4.3.0"
......
using System.Threading; using System;
using System.Threading;
using Breeze.Api; using Breeze.Api;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Stratis.Bitcoin; using Stratis.Bitcoin;
...@@ -6,6 +7,7 @@ using Stratis.Bitcoin.Builder; ...@@ -6,6 +7,7 @@ using Stratis.Bitcoin.Builder;
using Stratis.Bitcoin.Configuration; using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Logging; using Stratis.Bitcoin.Logging;
using Breeze.Wallet; using Breeze.Wallet;
using Stratis.Bitcoin.Notifications;
namespace Breeze.Deamon namespace Breeze.Deamon
{ {
...@@ -20,29 +22,15 @@ namespace Breeze.Deamon ...@@ -20,29 +22,15 @@ namespace Breeze.Deamon
var node = (FullNode)new FullNodeBuilder() var node = (FullNode)new FullNodeBuilder()
.UseNodeSettings(nodeSettings) .UseNodeSettings(nodeSettings)
.UseWallet() .UseWallet()
.UseBlockNotification()
.UseApi() .UseApi()
//.UseBlockNotification()
.Build(); .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 // start Full Node - this will also start the API
node.Start(); node.Start();
node.WaitDisposed(); Console.WriteLine("Press any key to stop");
Console.ReadLine();
node.Dispose(); node.Dispose();
} }
} }
} }
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
"type": "platform", "type": "platform",
"version": "1.1.0" "version": "1.1.0"
}, },
"Stratis.Bitcoin": "1.0.1.2-alpha" "Stratis.Bitcoin": "1.0.1.3-alpha"
}, },
"frameworks": { "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 Stratis.Bitcoin.Builder.Feature;
using Breeze.Wallet.Controllers; using Breeze.Wallet.Controllers;
using Breeze.Wallet.Notifications;
using Breeze.Wallet.Wrappers; using Breeze.Wallet.Wrappers;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using NBitcoin;
using Stratis.Bitcoin;
using Stratis.Bitcoin.Builder; using Stratis.Bitcoin.Builder;
namespace Breeze.Wallet namespace Breeze.Wallet
{ {
public class WalletFeature : FullNodeFeature 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() public override void Start()
{ {
BlockSubscriber sub = new BlockSubscriber(signals.Blocks, new BlockObserver(chain, trackerWrapper));
sub.Subscribe();
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
"Microsoft.AspNetCore.Mvc.Versioning": "1.0.3", "Microsoft.AspNetCore.Mvc.Versioning": "1.0.3",
"NBitcoin": "3.0.2.10", "NBitcoin": "3.0.2.10",
"NETStandard.Library": "1.6.1", "NETStandard.Library": "1.6.1",
"Stratis.Bitcoin": "1.0.1.2-alpha" "Stratis.Bitcoin": "1.0.1.3-alpha"
}, },
"frameworks": { "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