Skip to content

Commit

Permalink
Merge branch 'develop' into 'master'
Browse files Browse the repository at this point in the history
Develop

See merge request company-projects/Meadow!36
  • Loading branch information
zone117x committed Oct 4, 2018
2 parents 3dab538 + fca413c commit f85b168
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/Meadow.Cli/Commands/StartTestServerCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protected override void EndProcessing()

var config = this.ReadConfig();

var testNodeServer = new TestNodeServer((int)config.NetworkPort, new AccountConfiguration
var testNodeServer = new TestNodeServer(port: (int)config.NetworkPort, accountConfig: new AccountConfiguration
{
AccountGenerationCount = config.AccountCount,
DefaultAccountEtherBalance = config.AccountBalance
Expand Down
5 changes: 3 additions & 2 deletions src/Meadow.JsonRpc.Server.Proxy/RpcServerProxy.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Meadow.Core.EthTypes;
Expand All @@ -21,10 +22,10 @@ public class RpcServerProxy : IRpcController, IDisposable

public IWebHost WebHost => _httpServer.WebHost;

public RpcServerProxy(Uri targetHost, int? proxyServerPort = null)
public RpcServerProxy(Uri targetHost, int? proxyServerPort = null, IPAddress address = null)
{
_proxyClient = JsonRpcClient.Create(targetHost, ArbitraryDefaults.DEFAULT_GAS_LIMIT, ArbitraryDefaults.DEFAULT_GAS_PRICE);
_httpServer = new JsonRpcHttpServer(_proxyClient, ConfigureWebHost, proxyServerPort);
_httpServer = new JsonRpcHttpServer(_proxyClient, ConfigureWebHost, proxyServerPort, address);

//var undefinedRpcMethods = this.GetUndefinedRpcMethods();
//Console.WriteLine("Warning: following RPC methods are not defined: \n" + string.Join(", ", undefinedRpcMethods.Select(r => r.Value())));
Expand Down
17 changes: 10 additions & 7 deletions src/Meadow.JsonRpc.Server/JsonRpcHttpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class JsonRpcHttpServer : IDisposable
public string[] ServerAddresses => _serverAddressFeature().Addresses.ToArray();

public int ServerPort => GetServerPort();
public Uri ServerAddress => GetServerHostAddress();

Func<IServerAddressesFeature> _serverAddressFeature;
IRpcController _serverHandler;
Expand All @@ -55,7 +56,7 @@ public RpcRequestItem(JObject requestMessage)


/// <param name="port">If null or unspecified the http server binds to a random port.</param>
public JsonRpcHttpServer(IRpcController serverHandler, Func<IWebHostBuilder, IWebHostBuilder> configure = null, int? port = null)
public JsonRpcHttpServer(IRpcController serverHandler, Func<IWebHostBuilder, IWebHostBuilder> configure = null, int? port = null, IPAddress address = null)
{
_serverHandler = serverHandler;
var webHostBuilder = new WebHostBuilder()
Expand All @@ -68,7 +69,7 @@ public JsonRpcHttpServer(IRpcController serverHandler, Func<IWebHostBuilder, IWe
.UseSockets()
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, port ?? 0);
options.Listen(address ?? IPAddress.Loopback, port ?? 0);
//options.Listen(port ?? 0);
});

Expand Down Expand Up @@ -99,8 +100,7 @@ public JsonRpcHttpServer(IRpcController serverHandler, Func<IWebHostBuilder, IWe

public void Stop() => WebHost.StopAsync().GetAwaiter().GetResult();


int GetServerPort()
Uri GetServerHostAddress()
{
var addrs = ServerAddresses;
if (addrs.Length == 0)
Expand All @@ -109,9 +109,12 @@ int GetServerPort()
}

var httpAddr = addrs.FirstOrDefault(addr => addr.StartsWith("http://", StringComparison.OrdinalIgnoreCase));
var addrParts = httpAddr.Split(':')[2];
var port = int.Parse(addrParts, CultureInfo.InvariantCulture);
return port;
return new Uri(httpAddr);
}

int GetServerPort()
{
return GetServerHostAddress().Port;
}

async Task Handle(HttpContext context, Func<Task> next)
Expand Down
21 changes: 21 additions & 0 deletions src/Meadow.TestNode.Host/Meadow.TestNode.Host.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<GeneratePackageOnBuild Condition="'$(Configuration)' == 'Release'">true</GeneratePackageOnBuild>
<PackAsTool>true</PackAsTool>
<ToolCommandName>meadow-testnode</ToolCommandName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.2.5" />
<PackageReference Include="Secp256k1.Native" Version="0.1.18" ExcludeAssets="native" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Meadow.JsonRpc.Server.Proxy\Meadow.JsonRpc.Server.Proxy.csproj" />
<ProjectReference Include="..\Meadow.TestNode\Meadow.TestNode.csproj" />
</ItemGroup>

</Project>
35 changes: 35 additions & 0 deletions src/Meadow.TestNode.Host/ProcessArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using McMaster.Extensions.CommandLineUtils;

namespace Meadow.TestNode.Host
{

class ProcessArgs
{
[Option("-p|--port", "TODO.", CommandOptionType.SingleValue)]
public uint? Port { get; }

[Option("-h|--host", "TODO", CommandOptionType.SingleValue)]
public string Host { get; }

[Option("-a|--account_count", "TODO", CommandOptionType.SingleValue)]
public uint? AccountCount { get; }

[Option("-b|--account_balance", "TODO", CommandOptionType.SingleValue)]
public uint? AccountBalance { get; }

[Option("-m|--mnemonic", "TODO", CommandOptionType.SingleValue)]
public string Mnemonic { get; }

[Option("--proxy_node", "TODO", CommandOptionType.SingleValue)]
public string Proxy { get; }

public static ProcessArgs Parse(string[] args)
{
var app = new CommandLineApplication<ProcessArgs>(throwOnUnexpectedArg: true);
app.Conventions.UseDefaultConventions();
app.Parse(args);
return app.Model;
}
}

}
93 changes: 93 additions & 0 deletions src/Meadow.TestNode.Host/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using Meadow.Core.AccountDerivation;
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow.TestNode.Host
{
class Program
{

static async Task Main(string[] args)
{
var opts = ProcessArgs.Parse(args);

if (!string.IsNullOrWhiteSpace(opts.Proxy))
{
// TODO: testnode.host proxy support
throw new NotImplementedException();
}

IPAddress host;
if (string.IsNullOrWhiteSpace(opts.Host) || opts.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
host = IPAddress.Loopback;
}
else if (opts.Host == "*")
{
host = IPAddress.Any;
}
else if (IPAddress.TryParse(opts.Host, out var addr))
{
host = addr;
}
else
{
var entry = await Dns.GetHostEntryAsync(opts.Host);
host = entry.AddressList[0];
}

// Setup account derivation / keys
IAccountDerivation accountDerivation;
if (string.IsNullOrWhiteSpace(opts.Mnemonic))
{
var hdWalletAccountDerivation = HDAccountDerivation.Create();
accountDerivation = hdWalletAccountDerivation;
Console.WriteLine($"Using mnemonic phrase: '{hdWalletAccountDerivation.MnemonicPhrase}'");
Console.WriteLine("Warning: this private key generation is not secure and should not be used in production.");
}
else
{
accountDerivation = new HDAccountDerivation(opts.Mnemonic);
}


var accountConfig = new AccountConfiguration
{
AccountGenerationCount = (int)(opts.AccountCount ?? 100),
DefaultAccountEtherBalance = opts.AccountBalance ?? 1000,
AccountDerivationMethod = accountDerivation
};

// Create our local test node.
using (var testNodeServer = new TestNodeServer(
port: (int)opts.Port.GetValueOrDefault(),
address: host,
accountConfig: accountConfig))
{
Console.WriteLine("Starting server...");

// Start our local test node.
await testNodeServer.RpcServer.StartAsync();

// Create an RPC client for our local test node.
var serverAddresses = string.Join(", ", testNodeServer.RpcServer.ServerAddresses);
Console.WriteLine($"Test node server listening on: {serverAddresses}");

// Listen for exit request.
var exitEvent = new SemaphoreSlim(0, 1);
Console.CancelKeyPress += (s, e) =>
{
exitEvent.Release();
e.Cancel = true;
};

// Shutdown.
await exitEvent.WaitAsync();
Console.WriteLine("Stopping server and exiting...");
await testNodeServer.RpcServer.StopAsync();
}
}
}
}
3 changes: 1 addition & 2 deletions src/Meadow.TestNode/AccountConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ public class AccountConfiguration
/// <summary>
/// The specification/format to use for generating accounts from the seed.
/// Defaults to <see cref="Bip44AccountDerivation"/>
/// TODO: Currently defaults to the C# rng with fixed seed until bip44 is implemented.
/// </summary>
public IAccountDerivation AccountDerivationMethod { get; set; } = new SystemRandomAccountDerivation(1234);
public IAccountDerivation AccountDerivationMethod { get; set; }

}
}
10 changes: 7 additions & 3 deletions src/Meadow.TestNode/TestNodeServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
using Meadow.Core.Cryptography.Ecdsa;
using Meadow.Core.Cryptography;
using Meadow.Core.RlpEncoding;
using System.Net;
using Meadow.Core.AccountDerivation;

namespace Meadow.TestNode
{
Expand Down Expand Up @@ -54,10 +56,10 @@ static TestNodeServer()
#region Constructor
/// <param name="port">If null or unspecified the http server binds to a random port.</param>
/// <param name="accountConfig">Configure number of accounts to generate, ether balance, wallet derivation method.</param>
public TestNodeServer(int? port = null, AccountConfiguration accountConfig = null)
public TestNodeServer(int? port = null, IPAddress address = null, AccountConfiguration accountConfig = null)
{
// Initialize our basic components.
RpcServer = new JsonRpcHttpServer(this, ConfigureWebHost, port);
RpcServer = new JsonRpcHttpServer(this, ConfigureWebHost, port, address);
AccountKeys = new List<Address>();
AccountDictionary = new Dictionary<Address, EthereumEcdsa>();
Snapshots = new Dictionary<ulong, (StateSnapshot snapshot, TimeSpan timeStampOffset)>();
Expand All @@ -70,8 +72,10 @@ public TestNodeServer(int? port = null, AccountConfiguration accountConfig = nul
accountConfig = (accountConfig ?? new AccountConfiguration());
BigInteger initialAccountBalance = new BigInteger(1e18M * accountConfig.DefaultAccountEtherBalance);

var accountDerivation = accountConfig.AccountDerivationMethod ?? HDAccountDerivation.Create();

// Generate a keypairs
foreach (var keypair in EthereumEcdsa.Generate(accountConfig.AccountGenerationCount, accountConfig.AccountDerivationMethod))
foreach (var keypair in EthereumEcdsa.Generate(accountConfig.AccountGenerationCount, accountDerivation))
{
// Get an account from the public key hash.
Meadow.EVM.Data_Types.Addressing.Address account = new Meadow.EVM.Data_Types.Addressing.Address(keypair.GetPublicKeyHash());
Expand Down
23 changes: 22 additions & 1 deletion src/Meadow.UnitTestTemplate/Global.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Meadow.Contract;
using Meadow.Core.AccountDerivation;
using Meadow.Core.Utils;
using Meadow.CoverageReport;
using Meadow.CoverageReport.Debugging;
Expand Down Expand Up @@ -73,6 +74,14 @@ public static class Global
[System.ComponentModel.Description("TODO")]
public static long? AccountBalance { get; set; }

/// <summary>
/// Initially populated by app.config (if set).
/// Defaults to a randomly generated mnemonic if not set.
/// </summary>
[DefaultValue(null), DisplayName("AccountMnemonic")]
[System.ComponentModel.Description("TODO")]
public static string AccountMnemonic { get; set; }

/// <summary>
/// Initially populated by app.config (if set). Describes the endpoint of an external node
/// to connect to and tests against.
Expand Down Expand Up @@ -201,6 +210,11 @@ static void ParseAppConfigSettings(Assembly callingAssembly)
() => AccountBalance,
str => int.Parse(str, NumberStyles.AllowThousands, CultureInfo.InvariantCulture));

SetupConfigValue(
configValueList,
() => AccountMnemonic,
str => str);

SetupConfigValue(
configValueList,
() => SolcVersion,
Expand Down Expand Up @@ -319,11 +333,18 @@ static bool TryGetAppConfigValue(string key, out string value)

public static async Task<TestServices> CreateTestServicesInstance()
{
// Setup account derivation / keys.
var mnemonic = AccountMnemonic ?? AttributeHelper.GetDefault(() => AccountMnemonic);
var accountDerivation = string.IsNullOrWhiteSpace(mnemonic)
? HDAccountDerivation.Create()
: new HDAccountDerivation(mnemonic);

// Create our local test node.
var accountConfig = new AccountConfiguration
{
AccountGenerationCount = AccountCount ?? AttributeHelper.GetDefault(() => AccountCount),
DefaultAccountEtherBalance = AccountBalance ?? AttributeHelper.GetDefault(() => AccountBalance)
DefaultAccountEtherBalance = AccountBalance ?? AttributeHelper.GetDefault(() => AccountBalance),
AccountDerivationMethod = accountDerivation
};

var testNodeServer = new TestNodeServer(accountConfig: accountConfig);
Expand Down
1 change: 1 addition & 0 deletions src/Meadow.UnitTestTemplate/MeadowTestMethodAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public static TestResult[] Execute(ITestMethod testMethod)
}

}

// Test only has description, use in display name
else if (desc != null)
{
Expand Down
8 changes: 7 additions & 1 deletion src/Meadow.sln
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.SolCodeGen.Test", "M
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.CoverageReport", "Meadow.CoverageReport\Meadow.CoverageReport.csproj", "{4370F8AB-A419-4872-82A9-15CAEEAFE159}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meadow.UnitTestTemplate", "Meadow.UnitTestTemplate\Meadow.UnitTestTemplate.csproj", "{5D042EFF-7CB7-4DD4-81FF-D704E1C9D44D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.UnitTestTemplate", "Meadow.UnitTestTemplate\Meadow.UnitTestTemplate.csproj", "{5D042EFF-7CB7-4DD4-81FF-D704E1C9D44D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.UnitTestTemplate.Test", "Meadow.UnitTestTemplate.Test\Meadow.UnitTestTemplate.Test.csproj", "{26C69B00-BB7D-4655-A4B3-B30DC848517F}"
EndProject
Expand Down Expand Up @@ -91,6 +91,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.DebugAdapterServer",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.DebugExampleTests", "Meadow.DebugExampleTests\Meadow.DebugExampleTests.csproj", "{FA7D8150-CDC0-4FFF-AA14-B76A8470B60E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meadow.TestNode.Host", "Meadow.TestNode.Host\Meadow.TestNode.Host.csproj", "{09716096-0171-490F-A53B-16FA61FB5232}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -213,6 +215,10 @@ Global
{FA7D8150-CDC0-4FFF-AA14-B76A8470B60E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA7D8150-CDC0-4FFF-AA14-B76A8470B60E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA7D8150-CDC0-4FFF-AA14-B76A8470B60E}.Release|Any CPU.Build.0 = Release|Any CPU
{09716096-0171-490F-A53B-16FA61FB5232}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09716096-0171-490F-A53B-16FA61FB5232}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09716096-0171-490F-A53B-16FA61FB5232}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09716096-0171-490F-A53B-16FA61FB5232}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit f85b168

Please sign in to comment.