Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

node: Mode system #853

Open
wants to merge 83 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
d1bc7d1
neo-cli: tune MaxTransactionsPerBlock for testnet (#850)
roman-khimov Feb 10, 2022
35269f6
set new network id for testnet
superboyiii Mar 28, 2022
51b5514
revert
superboyiii Mar 28, 2022
2ad44ef
Add new testnet network id (#852)
superboyiii Mar 29, 2022
ab5447d
typo, comment (#847)
Jim8y Mar 31, 2022
8cac90f
create mode folders
Jim8y Apr 3, 2022
c9c3392
privatenet config and commands
Jim8y Apr 3, 2022
029ac42
load mode
Jim8y Apr 7, 2022
d4bb9e4
list mode
Jim8y Apr 7, 2022
11dabc8
delete mode
Jim8y Apr 7, 2022
e86ab46
save mode
Jim8y Apr 7, 2022
c73623b
optimise code
Jim8y Apr 7, 2022
2564839
done with the mode system and added an icon for neo-cli
Jim8y Apr 7, 2022
cbd62b3
fix format
Jim8y Apr 7, 2022
fd1ec20
fix format....well, no idea where the format issue is
Jim8y Apr 7, 2022
7d5ed7f
remove mode file
Jim8y Apr 8, 2022
6427f54
update wallet file
Jim8y Apr 8, 2022
01daf77
save config files in a same folder
Jim8y Apr 8, 2022
8536ff9
code optimise
Jim8y Apr 8, 2022
4f62c33
fix logic
Jim8y Apr 8, 2022
f41de1a
fix format
Jim8y Apr 8, 2022
de3ccd8
optimise code and solve delete issue
Jim8y Apr 8, 2022
6dd88ef
when user install plugin, save the config to the current mode
Jim8y Apr 8, 2022
dd130bb
copy plugin config.json to all modes
Jim8y Apr 9, 2022
27ea359
Update neo-cli/CLI/MainService.Mode.cs
Jim8y Apr 9, 2022
5e0e7f8
Merge branch 'develop' into mode-system
Jim8y Apr 19, 2022
d0c0f30
update mode system
Jim8y May 18, 2022
a89a910
Merge branch 'master' into mode-system
Jim8y May 25, 2022
04c2d42
Merge branch 'master' into mode-system
Jim8y Jun 25, 2022
fedde51
merge master
Jim8y Jul 3, 2022
7aac009
Update neo-cli/CLI/MainService.Mode.cs
Jim8y Jul 14, 2022
817bae6
fix issues as nico comments
Jim8y Jul 14, 2022
7745c8d
minor update
Jim8y Jul 14, 2022
f921835
fix plugin delete issue
Jim8y Jul 15, 2022
e6e225e
Update neo-cli/CLI/MainService.Mode.cs
Jim8y Jul 18, 2022
f3fd7aa
fix path issue
Jim8y Jul 18, 2022
91eb460
fix format
Jim8y Jul 18, 2022
fd9203f
fix plugin name issue
Jim8y Jul 18, 2022
87feb0f
fix config issue while install plugin from the mode
Jim8y Jul 20, 2022
092d546
Merge branch 'master' into mode-system
Jim8y Jul 26, 2022
d30b8d1
add warning info
Jim8y Jul 28, 2022
5894885
stop the node
Jim8y Jul 28, 2022
7e6919c
Merge branch 'master' into mode-system
Jim8y Jul 28, 2022
f83ab4f
rename and remove
Jim8y Jul 28, 2022
9af9e0c
fix async issue
Jim8y Aug 2, 2022
3d44018
Merge branch 'master' into mode-system
Jim8y Aug 9, 2022
13697d7
Merge branch 'master' into mode-system
Jim8y Aug 10, 2022
d38e39e
in case of duplicly install plugin while loading mode
Jim8y Aug 10, 2022
6a1b2ba
Merge branch 'master' into mode-system
Jim8y Aug 18, 2022
dd69999
fix case in path
Jim8y Sep 8, 2022
6a4df34
add plugin file
Jim8y Sep 8, 2022
2a98ccb
on create new mode
Jim8y Sep 8, 2022
f5f6b8a
add oracle mode
Jim8y Sep 8, 2022
e73a42c
try to fix cpytofolder
Jim8y Sep 8, 2022
ef18644
fix mode load issue
Jim8y Sep 8, 2022
ced9cc3
udpate the expect
Jim8y Sep 8, 2022
1056ec2
Revert "udpate the expect"
Jim8y Sep 8, 2022
e33c868
fix plugin name case issue
Jim8y Sep 15, 2022
5dad265
fix plugin name case issue and remove oracle mode
Jim8y Sep 21, 2022
009f802
format check
Jim8y Sep 22, 2022
e79bde9
1. config exists in mode and in mode => move config from mode to plugin
Jim8y Sep 22, 2022
bcad2a0
config.json
Jim8y Sep 22, 2022
86a7174
fix format
Jim8y Oct 10, 2022
0bd73ce
fix expect test
Jim8y Oct 26, 2022
842fc07
fix path issue
Jim8y Oct 26, 2022
3d06822
fix path
Jim8y Oct 27, 2022
2a3e53e
fix privatenet wallet path
Jim8y Oct 27, 2022
f1977f0
fix expect
Jim8y Oct 27, 2022
e12ad2d
Update neo-cli/Modes/privatenet/config.json
Jim8y Oct 27, 2022
6cf1de2
Merge branch 'master' into mode-system
Jim8y Oct 27, 2022
17e009c
Merge branch 'master' into mode-system
Jim8y Oct 27, 2022
cb96042
Update neo-cli/CLI/MainService.Plugins.cs
Jim8y Oct 31, 2022
858a922
Update neo-cli/CLI/MainService.Plugins.cs
Jim8y Oct 31, 2022
9cdedc8
Merge branch 'master' into mode-system
Jim8y Dec 8, 2022
305ab79
Update Helper.cs
shargon Dec 12, 2022
c0cb778
Merge branch 'master' into mode-system
superboyiii Jan 11, 2023
456afc9
Merge branch 'mode-system' of github.com:Liaojinghui/neo-node into mo…
Jim8y Jan 30, 2023
fc27b27
Merge branch 'master' into mode-system
Jim8y Feb 2, 2023
374acf6
Merge branch 'mode-system' of github.com:Liaojinghui/neo-node into mo…
Jim8y Feb 2, 2023
2e07919
update format
Jim8y Feb 2, 2023
9445883
Merge branch 'master' into mode-system
vncoelho Feb 23, 2023
892f2cd
Merge branch 'master' into mode-system
Jim8y Feb 27, 2023
5faefae
Merge branch 'master' into mode-system
Jim8y Aug 10, 2023
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
4 changes: 4 additions & 0 deletions .github/workflows/test-neo-cli.expect
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ expect {
timeout { exit 1 }
}

sleep 5
Copy link
Member

Choose a reason for hiding this comment

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

5 seconds is required?

Copy link
Contributor Author

@Jim8y Jim8y Dec 14, 2022

Choose a reason for hiding this comment

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

Yes, has to wait for 5 seconds, at least


spawn dotnet out/neo-cli.dll

#
# Test 'create wallet'
#
Expand Down
9 changes: 8 additions & 1 deletion Neo.ConsoleService/ConsoleServiceBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,14 @@ public virtual void OnStart(string[] args)

public virtual void OnStop()
{
_shutdownAcknowledged.Signal();
try
{
_shutdownAcknowledged.Signal();
}
catch
{
// ignore
}
}

public string ReadUserInput(string prompt, bool password = false)
Expand Down
209 changes: 209 additions & 0 deletions neo-cli/CLI/MainService.Mode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Copyright (C) 2016-2022 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.IO;
using System.Linq;
using System.Threading.Tasks;
using Akka.Util.Internal;
using Neo.ConsoleService;
namespace Neo.CLI;

partial class MainService
{
/// <summary>
/// Process "mode list" command.
/// </summary>
[ConsoleCommand("mode list", Category = "Mode Commands")]
private void OnListModes()
{
try
{
Directory.GetDirectories(ModePath).ForEach(p => ConsoleHelper.Info(p));
}
catch (IOException)
{
}
}

/// <summary>
/// Process "mode save" command
/// <param name="modeName">Mode name</param>
/// </summary>
[ConsoleCommand("mode save", Category = "Mode Commands")]
private void OnSaveMode(string modeName)
{
// if no mode name assigned
if (modeName is null)
{
ConsoleHelper.Error("No mode name assigned.");
return;
}
modeName = modeName.ToLower();
try
{
var targetMode = new DirectoryInfo($"{ModePath}/{modeName}");
// Create the mode if it does not exist
if (!targetMode.Exists) Directory.CreateDirectory(targetMode.FullName);
// Get the config files of the node
MoveModeConfig(modeName.ToLower());
var plugins = new DirectoryInfo(PluginPath);
// Cache directories before we start copying
var dirs = plugins.GetDirectories();
// Create an empty .PLUGINS file
File.Create($"{ModePath}/{modeName}/.PLUGINS").Close();
// Save the Plugin files
foreach (var plugin in dirs)
{
foreach (var file in plugin.GetFiles().Where(p => p.Extension == ".json"))
{
file.CopyTo($"{ModePath}/{modeName}/{plugin.Name}.json", true);
}
AddPluginToMode(plugin.Name, modeName);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

/// <summary>
/// Process "mode delete" command
/// <param name="modeName">Mode name</param>
/// </summary>
[ConsoleCommand("mode delete", Category = "Mode Commands")]
private void OnDeleteMode(string modeName)
{
try
{
var dir = new DirectoryInfo($"{ModePath}/{modeName.ToLower()}");
if (!dir.Exists)
return;
Directory.Delete(dir.FullName, true);
ConsoleHelper.Info("Mode ", modeName, " was deleted.");
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

/// <summary>
/// Load the target mode, plugin should be according to the mode,
/// if the mode contains the plugin, install the plugin, otherwise delete the plugin
/// </summary>
/// <param name="mode"> name of the mode</param>
/// <exception cref="DirectoryNotFoundException"> if the mode is not found</exception>
private async Task LoadMode(string mode)
{
try
{
mode = mode.ToLower();
var dir = new DirectoryInfo($"{ModePath}/{mode}");
if (!dir.Exists)
throw new DirectoryNotFoundException($"Mode not found: {dir.FullName}");
// Process the plugin
var modePlugins = File.ReadAllLines($"{ModePath}/{_currentMode}/.PLUGINS");
// loop modePlugins
foreach (var pluginName in modePlugins)
{
// if the plugin is not installed, install it
if (!Directory.Exists($"{PluginPath}/{pluginName}/"))
{
await InstallPluginAsync(pluginName, overWrite: true, saveConfig: false);
_needRestart = true;
}
// if the mode has the plugin config, load the config from the mode
if (File.Exists($"{ModePath}/{mode}/{pluginName}.json"))
File.Copy($"{ModePath}/{mode}/{pluginName}.json",
$"{PluginPath}/{pluginName}/config.json", true);
}
// get the system config file from the mode
MoveModeConfig(mode, false);

// Get existing plugins and delete them if they are not in the mode
new DirectoryInfo($"{PluginPath}/").GetDirectories().ForEach(p =>
{
if (modePlugins.Any(k => string.Compare(Path.GetFileNameWithoutExtension(k), p.Name, StringComparison.OrdinalIgnoreCase) == 0)
|| !File.Exists($"{PluginPath}/{p.Name}/config.json")) return;
try
{
ConsoleHelper.Info("Removing plugin ", p.Name);
Directory.Delete($"{PluginPath}/{p.Name}", true);
_needRestart = true;
}
catch
{
// ignored
}
});
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

/// save config.json and config.fs.json to the mode directory
/// <param name="mode"> name of the mode</param>
/// <param name="toMode"></param>
/// <exception cref="DirectoryNotFoundException"> if the mode is not found</exception>
private static void MoveModeConfig(string mode, bool toMode = true)
{
var modeDir = new DirectoryInfo($"{ModePath}/{mode.ToLower()}");
var configDir = new DirectoryInfo($"{StrExeFilePath}");
if (!modeDir.Exists)
throw new DirectoryNotFoundException($"Mode not found: {modeDir.FullName}");
try
{
if (toMode)
{
File.Copy(configDir.FullName + "/config.json",
modeDir.FullName + "/config.json", true);
File.Copy(configDir.FullName + "/config.fs.json",
modeDir.FullName + "/config.fs.json", true);
}
else
{
File.Copy(modeDir.FullName + "/config.json",
configDir.FullName + "/config.json", true);
File.Copy(modeDir.FullName + "/config.fs.json",
configDir.FullName + "/config.fs.json", true);
}
Jim8y marked this conversation as resolved.
Show resolved Hide resolved
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

// Add plugin to .PLUGINS file
private static void AddPluginToMode(string pluginName, string modeName)
{
var plugins = File.ReadAllLines($"{ModePath}/{modeName}/.PLUGINS");
if (plugins.Contains(pluginName)) return;
var newPlugins = plugins.Append(pluginName).ToArray();
File.WriteAllLines($"{ModePath}/{modeName}/.PLUGINS", newPlugins);
}

// Remove plugin from .PLUGINS file
private static void RemovePluginFromMode(string pluginName, string modeName)
{
var plugins = File.ReadAllLines($"{ModePath}/{modeName}/.PLUGINS");
// if (plugins.All(p => !string.Equals(p, pluginName, StringComparison.CurrentCultureIgnoreCase))) return;
var newPlugins = plugins.Where(p => !string.Equals(p, pluginName, StringComparison.CurrentCultureIgnoreCase)).ToArray();
File.WriteAllLines($"{ModePath}/{modeName}/.PLUGINS", newPlugins);
}
}
68 changes: 60 additions & 8 deletions neo-cli/CLI/MainService.Plugins.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 2016-2022 The Neo Project.
// The neo-cli is free software distributed under the MIT software
// 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.
Expand Down Expand Up @@ -34,7 +34,7 @@ private async Task OnInstallCommandAsync(string pluginName)
{
if (PluginExists(pluginName))
{
ConsoleHelper.Warning($"Plugin already exist.");
ConsoleHelper.Warning("Plugin already exist.");
return;
}

Expand Down Expand Up @@ -119,9 +119,11 @@ private async Task<MemoryStream> DownloadPluginAsync(string pluginName)
/// Install plugin from stream
/// </summary>
/// <param name="pluginName">name of the plugin</param>
/// <param name="installed">installed dependency</param>
/// <param name="overWrite">Install by force for `update`</param>
/// <param name="saveConfig">Need to save the config file to the mode</param>
private async Task InstallPluginAsync(string pluginName, HashSet<string> installed = null,
bool overWrite = false)
bool overWrite = false, bool saveConfig = true)
{
installed ??= new HashSet<string>();
if (!installed.Add(pluginName)) return;
Expand All @@ -140,7 +142,40 @@ private async Task InstallPluginAsync(string pluginName, HashSet<string> install
await using Stream es = entry.Open();
await InstallDependenciesAsync(es, installed);
}
zip.ExtractToDirectory("./", true);
if (!Directory.Exists($"{StrExeFilePath}/Plugins"))
{
Directory.CreateDirectory($"{StrExeFilePath}/Plugins");
}
zip.ExtractToDirectory($"{StrExeFilePath}", true);
Console.WriteLine();

if (!saveConfig) return;
// Save the config.json to current mode
try
{
var pluginActualName = GetPluginActualName(pluginName);
if (File.Exists($"{ModePath}/{_currentMode}/{pluginActualName}.json"))
{
if (File.Exists($"{PluginPath}/{pluginActualName}/config.json"))
// plugin contains config.json && mode contains plugin.json
// replace the config.json with plugin.json from mode
File.Copy($"{ModePath}/{_currentMode}/{pluginActualName}.json", $"{PluginPath}/{pluginActualName}/config.json", true);
else
// plugin doesn't contain config.json && mode contains plugin.json
// delete the plugin.json from mode
File.Delete($"{ModePath}/{_currentMode}/{pluginActualName}.json");
}
else if (File.Exists($"{PluginPath}/{pluginActualName}/config.json"))
// plugin contains config.json && mode doesn't contain plugin.json
// copy the config.json to mode
File.Copy($"{PluginPath}/{pluginActualName}/config.json", $"{ModePath}/{_currentMode}/{pluginActualName}.json", false);
AddPluginToMode(pluginActualName, _currentMode);
}
catch (Exception e)
{
// ignored
Console.WriteLine(e.Message);
}
}

/// <summary>
Expand Down Expand Up @@ -173,7 +208,8 @@ private async Task InstallDependenciesAsync(Stream config, HashSet<string> insta
/// <returns></returns>
private static bool PluginExists(string pluginName)
{
return Plugin.Plugins.Any(p => p.Name.Equals(pluginName, StringComparison.InvariantCultureIgnoreCase));
return Plugin.Plugins.Any(p => p.Name.Equals(pluginName, StringComparison.InvariantCultureIgnoreCase)) ||
new DirectoryInfo($"{StrExeFilePath}/Plugins").GetDirectories().Any(p => p.Name.Equals(pluginName, StringComparison.InvariantCultureIgnoreCase));
}

/// <summary>
Expand All @@ -188,12 +224,12 @@ private void OnUnInstallCommand(string pluginName)
ConsoleHelper.Warning("Plugin not found");
return;
}

pluginName = GetPluginActualName(pluginName);
foreach (var p in Plugin.Plugins)
{
try
{
using var reader = File.OpenRead($"./Plugins/{p.Name}/config.json");
using var reader = File.OpenRead($"{PluginPath}/{p.Name}/config.json");
if (new ConfigurationBuilder()
.AddJsonStream(reader)
.Build()
Expand All @@ -214,7 +250,11 @@ private void OnUnInstallCommand(string pluginName)
}
try
{
Directory.Delete($"Plugins/{pluginName}", true);
Directory.Delete($"{PluginPath}/{pluginName}", true);
var config = $"{ModePath}/{_currentMode}/{pluginName}.json";
if (File.Exists(config))
File.Delete(config);
RemovePluginFromMode(pluginName, _currentMode);
}
catch (IOException) { }
ConsoleHelper.Info("Uninstall successful, please restart neo-cli.");
Expand All @@ -240,5 +280,17 @@ private void OnPluginsCommand()
ConsoleHelper.Warning("No loaded plugins");
}
}

private static string GetPluginActualName(string pluginName)
{
var pluginActualName = "";
foreach (var plugin in new DirectoryInfo($"{PluginPath}").GetDirectories())
{
if (!string.Equals(plugin.Name, pluginName, StringComparison.CurrentCultureIgnoreCase)) continue;
pluginActualName = plugin.Name;
break;
}
return pluginActualName;
}
}
}
Loading