Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: enable command line command #3040

Merged
merged 26 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
26 changes: 26 additions & 0 deletions src/Neo.CLI/CLI/CommandLineOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2015-2023 The Neo Project.
//
// The Neo.Compiler.CSharp is free software distributed under the MIT
// software license, see the accompanying file LICENSE in the main directory
// of the project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

#nullable enable

namespace Neo.CLI
{
public class CommandLineOptions
{
public string? Config { get; init; }
public string? Network { get; init; }
public string? Wallet { get; init; }
public string? Password { get; init; }
public string[]? Plugins { get; set; }
public string? DBEngine { get; init; }
public string? DBPath { get; init; }
public bool? NoVerify { get; init; }
}
}
120 changes: 120 additions & 0 deletions src/Neo.CLI/CLI/MainService.CommandLine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright (C) 2016-2023 The Neo Project.
//
// The neo-cli is free software distributed under the MIT software
// license, see the accompanying file LICENSE in the main directory of
// the project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.CommandLine.NamingConventionBinder;
using System.Reflection;
using Microsoft.Extensions.Configuration;

namespace Neo.CLI
{
public partial class MainService
{
public int OnStartWithCommandLine(string[] args)
{
RootCommand rootCommand = new(Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyTitleAttribute>()!.Title)
{
new Option<string>(new[] { "-c", "--config","/config" }, "Specifies the config file."),
new Option<string>(new[] { "-n", "--network","/network" }, "Indicates the network of the chain [mainnet, testnet, privnet]."),
new Option<string>(new[] { "-w", "--wallet","/wallet" }, "The path of the neo3 wallet [*.json]."),
new Option<string>(new[] { "-p", "--password" ,"/password" }, "Password to decrypt the wallet, either from the command line or config file."),
new Option<string>(new[] { "--db-engine","/db-engine" }, "Specify the db engine."),
new Option<string>(new[] { "--db-path","/db-path" }, "Specify the db path."),
new Option<string>(new[] { "--noverify","/noverify" }, "Indicates whether the blocks need to be verified when importing."),
new Option<string[]>(new[] { "--plugins","/plugins" }, "The list of the plugins [plugin1 plugin2]."),
};

rootCommand.Handler = CommandHandler.Create<RootCommand, CommandLineOptions, InvocationContext>(Handle);
return rootCommand.Invoke(args);
}

private void Handle(RootCommand command, CommandLineOptions options, InvocationContext context)
{
Start(options);
}

private static void CustomProtocolSettings(CommandLineOptions options, ProtocolSettings settings)
{
uint network = settings.Network;
ProtocolSettings tempSetting = settings;
// if specified network without specifying config, then load the default config
if (!string.IsNullOrEmpty(options.Network))
{
if (!uint.TryParse(options.Network, out network))
{
network = options.Network switch
shargon marked this conversation as resolved.
Show resolved Hide resolved
{
"mainnet" => 860833102,
"testnet" => 894710606,
_ => throw new Exception("Invalid network")
};
}

// if also specified config, then load the config and check the network
if (!string.IsNullOrEmpty(options.Config))
{
tempSetting = ProtocolSettings.Load(options.Config);
// the network in config file must match the network from command line
if (network != tempSetting.Network) throw new ArgumentException($"Network mismatch {network} {tempSetting.Network}");
}
else // if the network if specified without config, then load the default config
{
tempSetting = ProtocolSettings.Load(network == 860833102 ? "config.mainnet.json" : "config.testnet.json");
}
}

ProtocolSettings customSetting = new ProtocolSettings
{
Network = network,
AddressVersion = tempSetting.AddressVersion,
StandbyCommittee = tempSetting.StandbyCommittee,
ValidatorsCount = tempSetting.ValidatorsCount,
SeedList = tempSetting.SeedList,
MillisecondsPerBlock = tempSetting.MillisecondsPerBlock,
MaxTransactionsPerBlock = tempSetting.MaxTransactionsPerBlock,
MemoryPoolMaxTransactions = tempSetting.MemoryPoolMaxTransactions,
MaxTraceableBlocks = tempSetting.MaxTraceableBlocks,
InitialGasDistribution = tempSetting.InitialGasDistribution,
Hardforks = tempSetting.Hardforks
};

if (!string.IsNullOrEmpty(options.Config) || !string.IsNullOrEmpty(options.Network)) ProtocolSettings.Custom = customSetting;
}

private static void CustomApplicationSettings(CommandLineOptions options, Settings settings)
{
Settings tempSetting = string.IsNullOrEmpty(options.Config) ? settings : new Settings(new ConfigurationBuilder().AddJsonFile(options.Config, optional: true).Build().GetSection("ApplicationConfiguration"));

Settings customSetting = new Settings
{
Logger = tempSetting.Logger,
Storage = new StorageSettings
{
Engine = options.DBEngine ?? tempSetting.Storage.Engine,
Path = options.DBPath ?? tempSetting.Storage.Path
},
P2P = tempSetting.P2P,
UnlockWallet = new UnlockWalletSettings
{
Path = options.Wallet ?? tempSetting.UnlockWallet.Path,
Password = options.Password ?? tempSetting.UnlockWallet.Password
}
};
if (!string.IsNullOrEmpty(options.Config)
|| !string.IsNullOrEmpty(options.Network)
|| !string.IsNullOrEmpty(options.DBEngine)
|| !string.IsNullOrEmpty(options.DBPath)
|| !string.IsNullOrEmpty(options.Wallet)
|| !string.IsNullOrEmpty(options.Password)) Settings.Custom = customSetting;
}
}
}
21 changes: 9 additions & 12 deletions src/Neo.CLI/CLI/MainService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,8 @@ private byte[] LoadUpdateScript(UInt160 scriptHash, string nefFilePath, string m
public override void OnStart(string[] args)
{
base.OnStart(args);
Start(args);
OnStartWithCommandLine(args);

}

public override void OnStop()
Expand All @@ -361,26 +362,22 @@ public void OpenWallet(string path, string password)
CurrentWallet = Wallet.Open(path, password, NeoSystem.Settings) ?? throw new NotSupportedException();
}

public async void Start(string[] args)
public async void Start(CommandLineOptions options)
{
if (NeoSystem != null) return;
bool verifyImport = true;
for (int i = 0; i < args.Length; i++)
switch (args[i])
{
case "/noverify":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be added back somehow.

case "--noverify":
verifyImport = false;
break;
}
bool verifyImport = options.NoVerify ?? true;
Jim8y marked this conversation as resolved.
Show resolved Hide resolved

ProtocolSettings protocol = ProtocolSettings.Load("config.json");

CustomProtocolSettings(options, protocol);
CustomApplicationSettings(options, Settings.Default);
NeoSystem = new NeoSystem(protocol, Settings.Default.Storage.Engine, string.Format(Settings.Default.Storage.Path, protocol.Network.ToString("X8")));
NeoSystem.AddService(this);

LocalNode = NeoSystem.LocalNode.Ask<LocalNode>(new LocalNode.GetInstance()).Result;

// installing plugins
options.Plugins?.Select(p => p).Where(p => !string.IsNullOrEmpty(p)).ToList().ForEach(async p => await InstallPluginAsync(p));
shargon marked this conversation as resolved.
Show resolved Hide resolved

foreach (var plugin in Plugin.Plugins)
{
// Register plugins commands
Expand Down
7 changes: 6 additions & 1 deletion src/Neo.CLI/Neo.CLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</ItemGroup>

<ItemGroup>
<None Update="config*.json">
<None Update="../../config/config*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
Expand All @@ -31,4 +31,9 @@
<ProjectReference Include="..\Neo\Neo.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta4.22272.1" />
</ItemGroup>

</Project>
39 changes: 26 additions & 13 deletions src/Neo.CLI/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ namespace Neo
{
public class Settings
{
public LoggerSettings Logger { get; }
public StorageSettings Storage { get; }
public P2PSettings P2P { get; }
public UnlockWalletSettings UnlockWallet { get; }
public LoggerSettings Logger { get; init; }
public StorageSettings Storage { get; init; }
public P2PSettings P2P { get; init; }
public UnlockWalletSettings UnlockWallet { get; init; }

static Settings? s_default;

Expand All @@ -44,25 +44,30 @@ public static Settings Default
var config = new ConfigurationBuilder().AddJsonFile("config.json", optional: true).Build();
Initialize(config);
}

return s_default!;
return Custom ?? s_default!;
}
}

public static Settings? Custom { get; set; }
shargon marked this conversation as resolved.
Show resolved Hide resolved
shargon marked this conversation as resolved.
Show resolved Hide resolved

public Settings(IConfigurationSection section)
{
this.Logger = new(section.GetSection("Logger"));
this.Storage = new(section.GetSection("Storage"));
this.P2P = new(section.GetSection("P2P"));
this.UnlockWallet = new(section.GetSection("UnlockWallet"));
}

public Settings()
{
}
}

public class LoggerSettings
{
public string Path { get; }
public bool ConsoleOutput { get; }
public bool Active { get; }
public string Path { get; init; }
public bool ConsoleOutput { get; init; }
public bool Active { get; init; }

public LoggerSettings(IConfigurationSection section)
{
Expand All @@ -74,14 +79,18 @@ public LoggerSettings(IConfigurationSection section)

public class StorageSettings
{
public string Engine { get; }
public string Path { get; }
public string Engine { get; init; }
public string Path { get; init; }

public StorageSettings(IConfigurationSection section)
{
this.Engine = section.GetValue("Engine", "LevelDBStore")!;
this.Path = section.GetValue("Path", "Data_LevelDB_{0}")!;
}

public StorageSettings()
{
}
}

public class P2PSettings
Expand All @@ -102,8 +111,8 @@ public P2PSettings(IConfigurationSection section)

public class UnlockWalletSettings
{
public string? Path { get; }
public string? Password { get; }
public string? Path { get; set; }
public string? Password { get; set; }
public bool IsActive { get; }

public UnlockWalletSettings(IConfigurationSection section)
Expand All @@ -115,5 +124,9 @@ public UnlockWalletSettings(IConfigurationSection section)
this.IsActive = bool.Parse(section.GetValue("IsActive", "false")!);
}
}

public UnlockWalletSettings()
{
}
}
}
2 changes: 1 addition & 1 deletion src/Neo.GUI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static void Main(string[] args)
return;
}
}
Service.Start(args);
Service.OnStartWithCommandLine(args);
Application.Run(MainForm = new MainForm(xdoc));
Service.Stop();
}
Expand Down
4 changes: 3 additions & 1 deletion src/Neo/ProtocolSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public record ProtocolSettings
/// <summary>
/// The default protocol settings for NEO MainNet.
/// </summary>
public static ProtocolSettings Default { get; } = new ProtocolSettings
public static ProtocolSettings Default { get; } = Custom ?? new ProtocolSettings
{
Network = 0u,
AddressVersion = 0x35,
Expand All @@ -118,6 +118,8 @@ public record ProtocolSettings
Hardforks = ImmutableDictionary<Hardfork, uint>.Empty
};

public static ProtocolSettings? Custom { get; set; }

/// <summary>
/// Loads the <see cref="ProtocolSettings"/> at the specified path.
/// </summary>
Expand Down