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 18 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
36 changes: 36 additions & 0 deletions src/Neo.CLI/CLI/CommandLineOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// CommandLineOption.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository 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.

namespace Neo.CLI
{
public class CommandLineOptions
{
public string? Config { 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; }

/// <summary>
/// Check if CommandLineOptions was configured
/// </summary>
public bool IsValid =>
!string.IsNullOrEmpty(Config) ||
!string.IsNullOrEmpty(Wallet) ||
!string.IsNullOrEmpty(Password) ||
!string.IsNullOrEmpty(DBEngine) ||
!string.IsNullOrEmpty(DBPath) ||
(Plugins?.Length > 0) ||
NoVerify is not null;
}
}
93 changes: 93 additions & 0 deletions src/Neo.CLI/CLI/MainService.CommandLine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// MainService.CommandLine.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository 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 Microsoft.Extensions.Configuration;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.CommandLine.NamingConventionBinder;
using System.Reflection;

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[] { "-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 plugins, if not present, will be installed [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)
{
var tempSetting = settings;
// if specified config, then load the config and check the network
if (!string.IsNullOrEmpty(options.Config))
{
tempSetting = ProtocolSettings.Load(options.Config);
}

var customSetting = new ProtocolSettings
{
Network = tempSetting.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)) ProtocolSettings.Custom = customSetting;
}

private static void CustomApplicationSettings(CommandLineOptions options, Settings settings)
{
var tempSetting = string.IsNullOrEmpty(options.Config) ? settings : new Settings(new ConfigurationBuilder().AddJsonFile(options.Config, optional: true).Build().GetSection("ApplicationConfiguration"));
var 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
},
Contracts = tempSetting.Contracts
};
if (options.IsValid) 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 @@ -347,7 +347,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 @@ -366,26 +367,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
5 changes: 5 additions & 0 deletions src/Neo.CLI/Neo.CLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,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>
47 changes: 32 additions & 15 deletions src/Neo.CLI/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ namespace Neo
{
public class Settings
{
public LoggerSettings Logger { get; }
public StorageSettings Storage { get; }
public P2PSettings P2P { get; }
public UnlockWalletSettings UnlockWallet { get; }
public ContractsSettings Contracts { get; }
public LoggerSettings Logger { get; init; }
public StorageSettings Storage { get; init; }
public P2PSettings P2P { get; init; }
public UnlockWalletSettings UnlockWallet { get; init; }
public ContractsSettings Contracts { get; init; }

static Settings? s_default;

Expand All @@ -46,11 +46,12 @@ 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)
{
Contracts = new(section.GetSection(nameof(Contracts)));
Expand All @@ -59,32 +60,44 @@ public Settings(IConfigurationSection section)
P2P = new(section.GetSection(nameof(P2P)));
UnlockWallet = new(section.GetSection(nameof(UnlockWallet)));
}

public Settings()
{
Logger = new LoggerSettings();
shargon marked this conversation as resolved.
Show resolved Hide resolved
Storage = new StorageSettings();
P2P = new P2PSettings();
UnlockWallet = new UnlockWalletSettings();
}
}

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

public LoggerSettings(IConfigurationSection section)
{
Path = section.GetValue(nameof(Path), "Logs")!;
ConsoleOutput = section.GetValue(nameof(ConsoleOutput), false);
Active = section.GetValue(nameof(Active), false);
}

public LoggerSettings() { }
}

public class StorageSettings
{
public string Engine { get; } = string.Empty;
public string Path { get; } = string.Empty;
public string Engine { get; init; } = string.Empty;
public string Path { get; init; } = string.Empty;

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

public StorageSettings() { }
}

public class P2PSettings
Expand All @@ -101,13 +114,15 @@ public P2PSettings(IConfigurationSection section)
MaxConnections = section.GetValue(nameof(MaxConnections), Peer.DefaultMaxConnections);
MaxConnectionsPerAddress = section.GetValue(nameof(MaxConnectionsPerAddress), 3);
}

public P2PSettings() { }
}

public class UnlockWalletSettings
{
public string Path { get; } = string.Empty;
public string Password { get; } = string.Empty;
public bool IsActive { get; } = false;
public string? Path { get; init; } = string.Empty;
public string? Password { get; init; } = string.Empty;
public bool IsActive { get; init; } = false;

public UnlockWalletSettings(IConfigurationSection section)
{
Expand All @@ -118,6 +133,8 @@ public UnlockWalletSettings(IConfigurationSection section)
IsActive = section.GetValue(nameof(IsActive), false);
}
}

public UnlockWalletSettings() { }
}

public class ContractsSettings
Expand Down
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