Skip to content

Commit

Permalink
Adding Rutanio Network (RUTA) (#161)
Browse files Browse the repository at this point in the history
* Add access to hashkey to use a dynamic string

* Add Rutanio networks

* Add Rutanio.Node

* Add Rutanio to NetworkSelector node and use a custom agent (Blockcore-Ruta)

* Use ContenType as a configuration parameter to allow connections with differents daemons (i.e: ElectrumX)

* Add node agent instead of Swagger title

* Update favicon to use with Rutanio

* Update Rutanio nodeBuilder to use same order then Blockcore.Node

* RUTA will fall through last case option (XDS)

* Introduce network-specific standard script

* Framework props were removed; they are global prop

* MaxTxFee added. Use the new rules for coindb

* favicon feature was removed (for later release)

* BIP9 Deployment on place

* API title use now Blockcore + coin ticker

* ApiTitle more readable

* Indentation line to solve PR conflicts

Co-authored-by: checho1989 <cheverdolaga@hotmail.com>
  • Loading branch information
turcol and checho1989 authored Jun 24, 2020
1 parent 29194d6 commit 6dac1ff
Show file tree
Hide file tree
Showing 30 changed files with 1,229 additions and 8 deletions.
Empty file modified README.md
100755 → 100644
Empty file.
17 changes: 17 additions & 0 deletions src/Blockcore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Node", "Node", "{8820C3A5-7
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blockcore.Node", "Node\Blockcore.Node\Blockcore.Node.csproj", "{D0A183FE-C913-4F8F-92EC-BD4502745140}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Rutanio", "Rutanio", "{50759380-AF62-11EA-BC6D-7563ABA8C5CA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rutanio.Node", "Networks\Rutanio\Rutanio.Node\Rutanio.Node.csproj", "{EECEF785-EC8C-4037-9BF9-1DACABDE0E3D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rutanio", "Networks\Rutanio\Rutanio\Rutanio.csproj", "{271E03B3-5DD6-4A16-A54A-1E72AF9B4902}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -296,11 +302,20 @@ Global
{D0A183FE-C913-4F8F-92EC-BD4502745140}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0A183FE-C913-4F8F-92EC-BD4502745140}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0A183FE-C913-4F8F-92EC-BD4502745140}.Release|Any CPU.Build.0 = Release|Any CPU
{EECEF785-EC8C-4037-9BF9-1DACABDE0E3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EECEF785-EC8C-4037-9BF9-1DACABDE0E3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EECEF785-EC8C-4037-9BF9-1DACABDE0E3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EECEF785-EC8C-4037-9BF9-1DACABDE0E3D}.Release|Any CPU.Build.0 = Release|Any CPU
{271E03B3-5DD6-4A16-A54A-1E72AF9B4902}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{271E03B3-5DD6-4A16-A54A-1E72AF9B4902}.Debug|Any CPU.Build.0 = Debug|Any CPU
{271E03B3-5DD6-4A16-A54A-1E72AF9B4902}.Release|Any CPU.ActiveCfg = Release|Any CPU
{271E03B3-5DD6-4A16-A54A-1E72AF9B4902}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{50759380-AF62-11EA-BC6D-7563ABA8C5CA} = {3B56C02B-4468-4268-B797-851562789FCC}
{800A5906-C050-4E75-9D7C-0CB1C404A0F8} = {EAE139C2-B19C-4905-9117-8A4068ABD3D2}
{94FEB14E-D123-486D-A24D-D2BE725D96E3} = {EAE139C2-B19C-4905-9117-8A4068ABD3D2}
{E538B76A-513F-46D5-9F14-E35E79B484CA} = {EAE139C2-B19C-4905-9117-8A4068ABD3D2}
Expand Down Expand Up @@ -348,6 +363,8 @@ Global
{36CE71D7-812A-40D7-96B7-8220E8E86643} = {88A9A633-DA22-412B-A04C-2A3405D3E2C8}
{8E17F166-F15A-42F7-9407-06CE2A4AA0AF} = {88A9A633-DA22-412B-A04C-2A3405D3E2C8}
{D0A183FE-C913-4F8F-92EC-BD4502745140} = {8820C3A5-74B4-45AB-B80C-2495DFBA4A2B}
{EECEF785-EC8C-4037-9BF9-1DACABDE0E3D} = {50759380-AF62-11EA-BC6D-7563ABA8C5CA}
{271E03B3-5DD6-4A16-A54A-1E72AF9B4902} = {50759380-AF62-11EA-BC6D-7563ABA8C5CA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6C780ABA-5872-4B83-AD3F-A5BD423AD907}
Expand Down
7 changes: 6 additions & 1 deletion src/External/NBitcoin/BIP32/ExtKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ public static ExtKey Parse(string wif, Network expectedNetwork = null)
private byte nDepth;
private byte[] vchFingerprint = new byte[FingerprintLength];

private static readonly byte[] hashkey = Encoders.ASCII.DecodeData("Bitcoin seed");
private static byte[] hashkey = Encoders.ASCII.DecodeData("Bitcoin seed");

public static void OverrideHashKey(byte[] newHashkey)
{
hashkey = newHashkey;
}

/// <summary>
/// Gets the depth of this extended key from the root key.
Expand Down
5 changes: 5 additions & 0 deletions src/Features/Blockcore.Features.NodeHost/NodeHostSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public class NodeHostSettings
/// <summary>Use HTTPS or not.</summary>
public bool UseHttps { get; set; }

/// <summary>Use title from agent</summary>
public string ApiTitle { get; set; }

/// <summary>
/// Initializes an instance of the object from the node configuration.
/// </summary>
Expand All @@ -62,6 +65,8 @@ public NodeHostSettings(NodeSettings nodeSettings)

this.logger = nodeSettings.LoggerFactory.CreateLogger(typeof(NodeHostSettings).FullName);

this.ApiTitle = "Blockcore-" + nodeSettings.Network.CoinTicker;

TextFileConfiguration config = nodeSettings.ConfigReader;

this.UseHttps = config.GetOrDefault("usehttps", false);
Expand Down
2 changes: 1 addition & 1 deletion src/Features/Blockcore.Features.NodeHost/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public void ConfigureServices(IServiceCollection services)
options.SwaggerDoc("node",
new OpenApiInfo
{
Title = "Blockcore Node API",
Title = hostSettings.ApiTitle + " Node API",
Version = assemblyVersion,
Description = "Access to the Blockcore Node features.",
Contact = new OpenApiContact
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@page "/"
@inject NBitcoin.Network Network
@namespace Blockcore.Features.NodeHost.UI.Pages
@inject NBitcoin.Network Network
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Expand Down Expand Up @@ -44,7 +45,6 @@
alert(error);
});
}
};
</script>
};</script>
</body>
</html>
Binary file not shown.
3 changes: 3 additions & 0 deletions src/Features/Blockcore.Features.RPC/RPCFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public static void BuildDefaultConfigurationFile(StringBuilder builder, Network
builder.AppendLine("#rpcbind=127.0.0.1");
builder.AppendLine("#Ip address allowed to connect to RPC (default all: 0.0.0.0 and ::)");
builder.AppendLine("#rpcallowip=127.0.0.1");
builder.AppendLine("#Can load the RPCContentType with or without charset. (default: application/json; chartset=utf-8)");
builder.AppendLine("#rpccontenttype=application/json");

}

public override Task InitializeAsync()
Expand Down
13 changes: 10 additions & 3 deletions src/Features/Blockcore.Features.RPC/RPCMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ public class RPCMiddleware
private readonly IHttpContextFactory httpContextFactory;
private readonly DataFolder dataFolder;

public const string ContentType = "application/json; charset=utf-8";

public RPCMiddleware(RequestDelegate next, IRPCAuthorization authorization, ILoggerFactory loggerFactory, IHttpContextFactory httpContextFactory, DataFolder dataFolder)
public readonly string ContentType;

public RPCMiddleware(
RequestDelegate next,
IRPCAuthorization authorization,
ILoggerFactory loggerFactory,
IHttpContextFactory httpContextFactory,
DataFolder dataFolder,
string contentType = "application/json; charset=utf-8")
{
Guard.NotNull(next, nameof(next));
Guard.NotNull(authorization, nameof(authorization));
Expand All @@ -40,6 +46,7 @@ public RPCMiddleware(RequestDelegate next, IRPCAuthorization authorization, ILog
this.logger = loggerFactory.CreateLogger(this.GetType().FullName);
this.httpContextFactory = httpContextFactory;
this.dataFolder = dataFolder;
this.ContentType = contentType;
}

public async Task InvokeAsync(HttpContext httpContext)
Expand Down
5 changes: 5 additions & 0 deletions src/Features/Blockcore.Features.RPC/RpcSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public class RpcSettings
/// <summary>List of IP addresses that are allowed to connect to RPC interfaces.</summary>
public List<IPAddressBlock> AllowIp { get; set; }

/// <summary>Can load the RPCContentType with or without charset.</summary>
public string RPCContentType { get; set; }

/// <summary>
/// Initializes an instance of the object from the node configuration.
/// </summary>
Expand Down Expand Up @@ -71,6 +74,7 @@ private void LoadSettingsFromConfig(NodeSettings nodeSettings)

this.Server = config.GetOrDefault<bool>("server", false, this.logger);
this.RPCPort = config.GetOrDefault<int>("rpcport", nodeSettings.Network.DefaultRPCPort, this.logger);
this.RPCContentType = config.GetOrDefault("rpccontenttype", "application/json; charset=utf-8", this.logger);

if (this.Server)
{
Expand Down Expand Up @@ -157,6 +161,7 @@ public static void PrintHelp(Network network)
builder.AppendLine($"-rpcport=<0-65535> Listen for JSON-RPC connections on <port>. Default: {network.DefaultRPCPort}");
builder.AppendLine($"-rpcbind=<ip:port> Bind to given address to listen for JSON-RPC connections. This option can be specified multiple times. Default: bind to all interfaces");
builder.AppendLine($"-rpcallowip=<ip> Allow JSON-RPC connections from specified source. This option can be specified multiple times.");
builder.AppendLine($"-rpccontentype=<string> Use application/json to connect with other daemons like ElectrumX");

defaults.Logger.LogInformation(builder.ToString());
}
Expand Down
2 changes: 1 addition & 1 deletion src/Features/Blockcore.Features.RPC/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env,

MvcNewtonsoftJsonOptions options = GetMVCOptions(serviceProvider);
Serializer.RegisterFrontConverters(options.SerializerSettings, fullNode.Network);
app.UseMiddleware(typeof(RPCMiddleware), authorizedAccess);
app.UseMiddleware(typeof(RPCMiddleware), authorizedAccess, rpcSettings.RPCContentType);
app.UseRPC();
}

Expand Down
49 changes: 49 additions & 0 deletions src/Networks/Rutanio/Rutanio.Node/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Threading.Tasks;
using Blockcore;
using Blockcore.Builder;
using Blockcore.Configuration;
using Blockcore.Features.NodeHost;
using Blockcore.Features.BlockStore;
using Blockcore.Features.ColdStaking;
using Blockcore.Features.Consensus;
using Blockcore.Features.Diagnostic;
using Blockcore.Features.MemoryPool;
using Blockcore.Features.Miner;
using Blockcore.Features.RPC;
using Blockcore.Utilities;
using NBitcoin.Protocol;

namespace Rutanio.Daemon
{
public class Program
{
public static async Task Main(string[] args)
{
try
{
var nodeSettings = new NodeSettings(networksSelector: Networks.Networks.Rutanio, args: args, agent: "Blockcore-RUTA");

IFullNodeBuilder nodeBuilder = new FullNodeBuilder()
.UseNodeSettings(nodeSettings)
.UseBlockStore()
.UseMempool()
.UseNodeHost()
.AddRPC()
.UseDiagnosticFeature()
.UsePosConsensus()
.AddPowPosMining()
.UseColdStakingWallet();

IFullNode node = nodeBuilder.Build();

if (node != null)
await node.RunAsync();
}
catch (Exception ex)
{
Console.WriteLine("There was a problem initializing the node. Details: '{0}'", ex);
}
}
}
}
39 changes: 39 additions & 0 deletions src/Networks/Rutanio/Rutanio.Node/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"profiles": {
"Rutanio (MAIN)": {
"commandName": "Project"
},
"Rutanio (TEST)": {
"commandName": "Project",
"commandLineArgs": "-testnet"
},
"Rutanio (MAIN/RPC)": {
"commandName": "Project",
"commandLineArgs": "-server -rpcallowip=127.0.0.1 -rpcbind=127.0.0.1 -rpcpassword=rpcpassword -rpcuser=rpcuser"
},
"Rutanio (TEST/RPC)": {
"commandName": "Project",
"commandLineArgs": "-server -rpcallowip=127.0.0.1 -rpcbind=127.0.0.1 -rpcpassword=rpcpassword -rpcuser=rpcuser -testnet"
},
"Rutanio (MAIN/LOCAL/RPC)": {
"commandName": "Project",
"commandLineArgs": "-server -rpcallowip=127.0.0.1 -rpcbind=127.0.0.1 -rpcpassword=rpcpassword -rpcuser=rpcuser -datadir=nodedata"
},
"Rutanio (TEST/LOCAL/RPC)": {
"commandName": "Project",
"commandLineArgs": "-server -rpcallowip=127.0.0.1 -rpcbind=127.0.0.1 -rpcpassword=rpcpassword -rpcuser=rpcuser -datadir=nodedata -testnet"
},
"Rutanio (MAIN/LOCAL/RPC/DEFAULT)": {
"commandName": "Project",
"commandLineArgs": "-server -rpcallowip=127.0.0.1 -rpcbind=127.0.0.1 -rpcpassword=rpcpassword -rpcuser=rpcuser -datadir=nodedata -defaultwalletname=default -defaultwalletpassword=default -unlockdefaultwallet -server"
},
"Rutanio (TEST/LOCAL/RPC/DEFAULT)": {
"commandName": "Project",
"commandLineArgs": "-server -rpcallowip=127.0.0.1 -rpcbind=127.0.0.1 -rpcpassword=rpcpassword -rpcuser=rpcuser -datadir=nodedata -defaultwalletname=default -defaultwalletpassword=default -unlockdefaultwallet -server -testnet"
},
"Rutanio (TEST/NO ASSUME VALID)": {
"commandName": "Project",
"commandLineArgs": "-testnet -assumevalid=0 -checkpoints=false"
}
}
}
29 changes: 29 additions & 0 deletions src/Networks/Rutanio/Rutanio.Node/Rutanio.Node.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<AssemblyName>Rutanio.Node</AssemblyName>
<OutputType>Exe</OutputType>
<Authors>Blockcore</Authors>
</PropertyGroup>

<PropertyGroup>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\External\NBitcoin\NBitcoin.csproj" />
<ProjectReference Include="..\..\..\Features\Blockcore.Features.NodeHost\Blockcore.Features.NodeHost.csproj" />
<ProjectReference Include="..\..\..\Features\Blockcore.Features.BlockStore\Blockcore.Features.BlockStore.csproj" />
<ProjectReference Include="..\..\..\Features\Blockcore.Features.ColdStaking\Blockcore.Features.ColdStaking.csproj" />
<ProjectReference Include="..\..\..\Features\Blockcore.Features.Consensus\Blockcore.Features.Consensus.csproj" />
<ProjectReference Include="..\..\..\Features\Blockcore.Features.Diagnostic\Blockcore.Features.Diagnostic.csproj" />
<ProjectReference Include="..\..\..\Features\Blockcore.Features.MemoryPool\Blockcore.Features.MemoryPool.csproj" />
<ProjectReference Include="..\..\..\Features\Blockcore.Features.Miner\Blockcore.Features.Miner.csproj" />
<ProjectReference Include="..\..\..\Features\Blockcore.Features.RPC\Blockcore.Features.RPC.csproj" />
<ProjectReference Include="..\..\..\Features\Blockcore.Features.Wallet\Blockcore.Features.Wallet.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Rutanio\Rutanio.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using NBitcoin;

namespace Rutanio.Networks.Consensus
{
/// <inheritdoc />
public class RutanioPosConsensusOptions : PosConsensusOptions
{
/// <inheritdoc />
public override int GetStakeMinConfirmations(int height, Network network)
{
// StakeMinConfirmations must equal MaxReorgLength so that nobody can stake in isolation and then force a reorg
return (int)network.Consensus.MaxReorgLength;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using NBitcoin;
namespace Rutanio.Networks.Deployments
{
/// <summary>
/// BIP9 deployments for the Blockcore sample coin network.
/// </summary>
public class RutanioBIP9Deployments : BIP9DeploymentsArray
{
// The position of each deployment in the deployments array. Note that this is decoupled from the actual position of the flag bit for the deployment in the block version.
public const int TestDummy = 0;
public const int CSV = 1;
public const int Segwit = 2;
public const int ColdStaking = 3;

// The number of deployments.
public const int NumberOfDeployments = 4;

/// <summary>
/// Constructs the BIP9 deployments array.
/// </summary>
public RutanioBIP9Deployments() : base(NumberOfDeployments)
{
}

/// <summary>
/// Gets the deployment flags to set when the deployment activates.
/// </summary>
/// <param name="deployment">The deployment number.</param>
/// <returns>The deployment flags.</returns>
public override BIP9DeploymentFlags GetFlags(int deployment)
{
var flags = new BIP9DeploymentFlags();

switch (deployment)
{
case ColdStaking:
flags.ScriptFlags |= ScriptVerify.CheckColdStakeVerify;
break;

case CSV:
// Start enforcing BIP68 (sequence locks), BIP112 (CHECKSEQUENCEVERIFY) and BIP113 (Median Time Past) using versionbits logic.
flags.ScriptFlags = ScriptVerify.CheckSequenceVerify;
flags.LockTimeFlags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast;
break;

case Segwit:
// Start enforcing WITNESS rules using versionbits logic.
flags.ScriptFlags = ScriptVerify.Witness;
break;
}

return flags;
}
}
}
15 changes: 15 additions & 0 deletions src/Networks/Rutanio/Rutanio/Networks/Networks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using NBitcoin;

namespace Rutanio.Networks
{
public static class Networks
{
public static NetworksSelector Rutanio
{
get
{
return new NetworksSelector(() => new RutanioMain(), () => new RutanioTest(), () => new RutanioRegTest());
}
}
}
}
Loading

0 comments on commit 6dac1ff

Please sign in to comment.