diff --git a/CHANGELOG.md b/CHANGELOG.md
index aa05d4e92..d12ec0cc7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,14 @@
# Changelog
All notable changes to this project will be documented in this file.
+## [3.2.1]
+
+### Changed
+- ([#807](/~https://github.com/neo-project/neo-node/pull/807/)) Install plugin and dependencies
+- ([#850](/~https://github.com/neo-project/neo-node/pull/850/)) Modify MaxTransactionsPerBlock for testnet
+- ([#852](/~https://github.com/neo-project/neo-node/pull/852/)) Add new testnet network id
+- ([#847](/~https://github.com/neo-project/neo-node/pull/847/)) typo, comment
+
## [3.1.0]
### Changed
diff --git a/Neo.ConsoleService/CommandToken.cs b/Neo.ConsoleService/CommandToken.cs
index fedb601b2..f3bf1fa64 100644
--- a/Neo.ConsoleService/CommandToken.cs
+++ b/Neo.ConsoleService/CommandToken.cs
@@ -29,7 +29,7 @@ internal abstract class CommandToken
///
/// Value
///
- public string Value { get; protected set; }
+ public string Value { get; protected init; }
///
/// Constructor
@@ -152,7 +152,7 @@ public static void Trim(List args)
// Trim end
- while (args.Count > 0 && args[args.Count - 1].Type == CommandTokenType.Space)
+ while (args.Count > 0 && args[^1].Type == CommandTokenType.Space)
{
args.RemoveAt(args.Count - 1);
}
diff --git a/Neo.ConsoleService/ConsoleCommandMethod.cs b/Neo.ConsoleService/ConsoleCommandMethod.cs
index d0949a68f..df241ce5f 100644
--- a/Neo.ConsoleService/ConsoleCommandMethod.cs
+++ b/Neo.ConsoleService/ConsoleCommandMethod.cs
@@ -52,7 +52,7 @@ internal class ConsoleCommandMethod
///
/// Instance
/// Method
- /// Verbs
+ /// Attribute
public ConsoleCommandMethod(object instance, MethodInfo method, ConsoleCommandAttribute attribute)
{
Method = method;
diff --git a/Neo.ConsoleService/ConsoleServiceBase.cs b/Neo.ConsoleService/ConsoleServiceBase.cs
index bffa0ef7d..cb62382ba 100644
--- a/Neo.ConsoleService/ConsoleServiceBase.cs
+++ b/Neo.ConsoleService/ConsoleServiceBase.cs
@@ -35,11 +35,11 @@ public abstract class ConsoleServiceBase
public bool ReadingPassword { get; set; } = false;
private bool _running;
- private readonly CancellationTokenSource _shutdownTokenSource = new CancellationTokenSource();
- private readonly CountdownEvent _shutdownAcknowledged = new CountdownEvent(1);
- private readonly Dictionary> _verbs = new Dictionary>();
- private readonly Dictionary _instances = new Dictionary();
- private readonly Dictionary, bool, object>> _handlers = new Dictionary, bool, object>>();
+ private readonly CancellationTokenSource _shutdownTokenSource = new();
+ private readonly CountdownEvent _shutdownAcknowledged = new(1);
+ private readonly Dictionary> _verbs = new();
+ private readonly Dictionary _instances = new();
+ private readonly Dictionary, bool, object>> _handlers = new();
private bool OnCommand(string commandLine)
{
@@ -188,10 +188,10 @@ protected void OnHelpCommand(string key)
withHelp.Sort((a, b) =>
{
- var cate = a.HelpCategory.CompareTo(b.HelpCategory);
+ var cate = string.Compare(a.HelpCategory, b.HelpCategory, StringComparison.Ordinal);
if (cate == 0)
{
- cate = a.Key.CompareTo(b.Key);
+ cate = string.Compare(a.Key, b.Key, StringComparison.Ordinal);
}
return cate;
});
@@ -234,7 +234,7 @@ protected void OnHelpCommand(string key)
if (lastKey != command.Key)
{
- Console.WriteLine($"You can call this command like this:");
+ Console.WriteLine("You can call this command like this:");
lastKey = command.Key;
}
@@ -247,7 +247,7 @@ protected void OnHelpCommand(string key)
if (!found)
{
- throw new ArgumentException($"Command not found.");
+ throw new ArgumentException("Command not found.");
}
}
}
@@ -297,8 +297,7 @@ public virtual void OnStop()
public string ReadUserInput(string prompt, bool password = false)
{
const string t = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
- StringBuilder sb = new StringBuilder();
- ConsoleKeyInfo key;
+ var sb = new StringBuilder();
if (!string.IsNullOrEmpty(prompt))
{
@@ -316,6 +315,7 @@ public string ReadUserInput(string prompt, bool password = false)
}
else
{
+ ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
@@ -323,14 +323,7 @@ public string ReadUserInput(string prompt, bool password = false)
if (t.IndexOf(key.KeyChar) != -1)
{
sb.Append(key.KeyChar);
- if (password)
- {
- Console.Write('*');
- }
- else
- {
- Console.Write(key.KeyChar);
- }
+ Console.Write(password ? '*' : key.KeyChar);
}
else if (key.Key == ConsoleKey.Backspace && sb.Length > 0)
{
@@ -411,30 +404,25 @@ protected ConsoleServiceBase()
{
// Register self commands
- RegisterCommandHander((args, canConsumeAll) =>
- {
- return CommandToken.ReadString(args, canConsumeAll);
- });
+ RegisterCommandHandler(CommandToken.ReadString);
- RegisterCommandHander((args, canConsumeAll) =>
+ RegisterCommandHandler((args, canConsumeAll) =>
{
if (canConsumeAll)
{
var ret = CommandToken.ToString(args);
args.Clear();
- return ret.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
- }
- else
- {
- return CommandToken.ReadString(args, false).Split(',', ' ');
+ return ret.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
}
+
+ return CommandToken.ReadString(args, false).Split(',', ' ');
});
- RegisterCommandHander(false, (str) => byte.Parse(str));
- RegisterCommandHander(false, (str) => str == "1" || str == "yes" || str == "y" || bool.Parse(str));
- RegisterCommandHander(false, (str) => ushort.Parse(str));
- RegisterCommandHander(false, (str) => uint.Parse(str));
- RegisterCommandHander(false, (str) => IPAddress.Parse(str));
+ RegisterCommandHandler(false, str => byte.Parse(str));
+ RegisterCommandHandler(false, str => str == "1" || str == "yes" || str == "y" || bool.Parse(str));
+ RegisterCommandHandler(false, str => ushort.Parse(str));
+ RegisterCommandHandler(false, str => uint.Parse(str));
+ RegisterCommandHandler(false, IPAddress.Parse);
}
///
@@ -442,7 +430,7 @@ protected ConsoleServiceBase()
///
/// Return type
/// Handler
- private void RegisterCommandHander(Func, bool, object> handler)
+ private void RegisterCommandHandler(Func, bool, object> handler)
{
_handlers[typeof(TRet)] = handler;
}
@@ -454,9 +442,9 @@ private void RegisterCommandHander(Func, bool, object>
/// Return type
/// Can consume all
/// Handler
- public void RegisterCommandHander(bool canConsumeAll, Func handler)
+ public void RegisterCommandHandler(bool canConsumeAll, Func handler)
{
- _handlers[typeof(TRet)] = (args, cosumeAll) =>
+ _handlers[typeof(TRet)] = (args, _) =>
{
var value = (T)_handlers[typeof(T)](args, canConsumeAll);
return handler(value);
@@ -469,11 +457,11 @@ public void RegisterCommandHander(bool canConsumeAll, Func h
/// Base type
/// Return type
/// Handler
- public void RegisterCommandHander(Func handler)
+ public void RegisterCommandHandler(Func handler)
{
- _handlers[typeof(TRet)] = (args, cosumeAll) =>
+ _handlers[typeof(TRet)] = (args, consumeAll) =>
{
- var value = (T)_handlers[typeof(T)](args, cosumeAll);
+ var value = (T)_handlers[typeof(T)](args, consumeAll);
return handler(value);
};
}
@@ -498,7 +486,7 @@ public void RegisterCommand(object instance, string name = null)
if (!method.GetParameters().All(u => u.ParameterType.IsEnum || _handlers.ContainsKey(u.ParameterType)))
{
- throw new ArgumentException("Handler not found for the command: " + method.ToString());
+ throw new ArgumentException("Handler not found for the command: " + method);
}
// Add command
@@ -576,7 +564,7 @@ public void Run(string[] args)
protected string ReadLine()
{
- Task readLineTask = Task.Run(() => Console.ReadLine());
+ Task readLineTask = Task.Run(Console.ReadLine);
try
{
@@ -623,7 +611,7 @@ public virtual void RunConsole()
ConsoleHelper.Error("Command not found");
}
}
- catch (TargetInvocationException ex)
+ catch (TargetInvocationException ex) when (ex.InnerException is not null)
{
ConsoleHelper.Error(ex.InnerException.Message);
}
diff --git a/Neo.ConsoleService/ServiceProxy.cs b/Neo.ConsoleService/ServiceProxy.cs
index a6fac7ebd..e3a8a982f 100644
--- a/Neo.ConsoleService/ServiceProxy.cs
+++ b/Neo.ConsoleService/ServiceProxy.cs
@@ -14,21 +14,21 @@ namespace Neo.ConsoleService
{
internal class ServiceProxy : ServiceBase
{
- private readonly ConsoleServiceBase service;
+ private readonly ConsoleServiceBase _service;
public ServiceProxy(ConsoleServiceBase service)
{
- this.service = service;
+ this._service = service;
}
protected override void OnStart(string[] args)
{
- service.OnStart(args);
+ _service.OnStart(args);
}
protected override void OnStop()
{
- service.OnStop();
+ _service.OnStop();
}
}
}
diff --git a/neo-cli/CLI/ConsolePercent.cs b/neo-cli/CLI/ConsolePercent.cs
index cd9f36f15..364e67221 100644
--- a/neo-cli/CLI/ConsolePercent.cs
+++ b/neo-cli/CLI/ConsolePercent.cs
@@ -16,7 +16,8 @@ public class ConsolePercent : IDisposable
{
#region Variables
- private long _maxValue, _value;
+ private readonly long _maxValue;
+ private long _value;
private decimal _lastFactor;
private string _lastPercent;
@@ -33,7 +34,7 @@ public class ConsolePercent : IDisposable
///
public long Value
{
- get { return _value; }
+ get => _value;
set
{
if (value == _value) return;
@@ -48,8 +49,8 @@ public long Value
///
public long MaxValue
{
- get { return _maxValue; }
- set
+ get => _maxValue;
+ init
{
if (value == _maxValue) return;
diff --git a/neo-cli/CLI/MainService.Contracts.cs b/neo-cli/CLI/MainService.Contracts.cs
index 1a32e3f5c..74ac577e6 100644
--- a/neo-cli/CLI/MainService.Contracts.cs
+++ b/neo-cli/CLI/MainService.Contracts.cs
@@ -26,6 +26,7 @@ partial class MainService
///
/// File path
/// Manifest path
+ /// Extra data for deploy
[ConsoleCommand("deploy", Category = "Contract Commands")]
private void OnDeployCommand(string filePath, string manifestPath = null, JObject data = null)
{
@@ -57,8 +58,12 @@ private void OnDeployCommand(string filePath, string manifestPath = null, JObjec
///
/// Process "update" command
///
+ /// Script hash
/// File path
/// Manifest path
+ /// Sender
+ /// Signer Accounts
+ /// Extra data for update
[ConsoleCommand("update", Category = "Contract Commands")]
private void OnUpdateCommand(UInt160 scriptHash, string filePath, string manifestPath, UInt160 sender, UInt160[] signerAccounts = null, JObject data = null)
{
@@ -68,7 +73,7 @@ private void OnUpdateCommand(UInt160 scriptHash, string filePath, string manifes
if (sender != null)
{
if (signerAccounts == null)
- signerAccounts = new UInt160[1] { sender };
+ signerAccounts = new[] { sender };
else if (signerAccounts.Contains(sender) && signerAccounts[0] != sender)
{
var signersList = signerAccounts.ToList();
@@ -82,13 +87,7 @@ private void OnUpdateCommand(UInt160 scriptHash, string filePath, string manifes
signers = signerAccounts.Select(p => new Signer() { Account = p, Scopes = WitnessScope.CalledByEntry }).ToArray();
}
- Transaction tx = new Transaction
- {
- Signers = signers,
- Attributes = Array.Empty(),
- Witnesses = Array.Empty()
- };
-
+ Transaction tx;
try
{
byte[] script = LoadUpdateScript(scriptHash, filePath, manifestPath, data, out var nef, out var manifest);
@@ -127,7 +126,7 @@ private void OnUpdateCommand(UInt160 scriptHash, string filePath, string manifes
/// Contract parameters
/// Transaction's sender
/// Signer's accounts
- /// Max fee for running the script
+ /// Max fee for running the script
[ConsoleCommand("invoke", Category = "Contract Commands")]
private void OnInvokeCommand(UInt160 scriptHash, string operation, JArray contractParameters = null, UInt160 sender = null, UInt160[] signerAccounts = null, decimal maxGas = 20)
{
diff --git a/neo-cli/CLI/MainService.NEP17.cs b/neo-cli/CLI/MainService.NEP17.cs
index 8cce43dbf..ff06974bf 100644
--- a/neo-cli/CLI/MainService.NEP17.cs
+++ b/neo-cli/CLI/MainService.NEP17.cs
@@ -16,7 +16,9 @@
using Neo.VM.Types;
using Neo.Wallets;
using System;
+using System.Collections.Generic;
using System.Linq;
+using Array = System.Array;
namespace Neo.CLI
{
@@ -27,7 +29,7 @@ partial class MainService
///
/// Script hash
/// To
- /// Ammount
+ /// Amount
/// From
/// Data
/// Signer's accounts
@@ -58,7 +60,7 @@ private void OnTransferCommand(UInt160 tokenHash, UInt160 to, decimal amount, UI
Scopes = WitnessScope.CalledByEntry,
Account = p
})
- .ToArray() ?? new Signer[0]);
+ .ToArray() ?? Array.Empty());
}
catch (InvalidOperationException e)
{
@@ -80,9 +82,11 @@ private void OnTransferCommand(UInt160 tokenHash, UInt160 to, decimal amount, UI
[ConsoleCommand("balanceOf", Category = "NEP17 Commands")]
private void OnBalanceOfCommand(UInt160 tokenHash, UInt160 address)
{
- var arg = new JObject();
- arg["type"] = "Hash160";
- arg["value"] = address.ToString();
+ var arg = new JObject
+ {
+ ["type"] = "Hash160",
+ ["value"] = address.ToString()
+ };
var asset = new AssetDescriptor(NeoSystem.StoreView, NeoSystem.Settings, tokenHash);
@@ -113,7 +117,7 @@ private void OnNameCommand(UInt160 tokenHash)
[ConsoleCommand("decimals", Category = "NEP17 Commands")]
private void OnDecimalsCommand(UInt160 tokenHash)
{
- if (!OnInvokeWithResult(tokenHash, "decimals", out StackItem result, null)) return;
+ if (!OnInvokeWithResult(tokenHash, "decimals", out StackItem result)) return;
ConsoleHelper.Info("Result: ", $"{((PrimitiveType)result).GetInteger()}");
}
@@ -125,7 +129,7 @@ private void OnDecimalsCommand(UInt160 tokenHash)
[ConsoleCommand("totalSupply", Category = "NEP17 Commands")]
private void OnTotalSupplyCommand(UInt160 tokenHash)
{
- if (!OnInvokeWithResult(tokenHash, "totalSupply", out StackItem result, null)) return;
+ if (!OnInvokeWithResult(tokenHash, "totalSupply", out StackItem result)) return;
var asset = new AssetDescriptor(NeoSystem.StoreView, NeoSystem.Settings, tokenHash);
var totalSupply = new BigDecimal(((PrimitiveType)result).GetInteger(), asset.Decimals);
diff --git a/neo-cli/CLI/MainService.Plugins.cs b/neo-cli/CLI/MainService.Plugins.cs
index f61117682..9347366f8 100644
--- a/neo-cli/CLI/MainService.Plugins.cs
+++ b/neo-cli/CLI/MainService.Plugins.cs
@@ -8,15 +8,18 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
+using Microsoft.Extensions.Configuration;
using Neo.ConsoleService;
using Neo.IO.Json;
using Neo.Plugins;
using System;
+using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
+using System.Security.Cryptography;
using System.Threading.Tasks;
namespace Neo.CLI
@@ -30,16 +33,53 @@ partial class MainService
[ConsoleCommand("install", Category = "Plugin Commands")]
private async Task OnInstallCommandAsync(string pluginName)
{
+ if (PluginExists(pluginName))
+ {
+ ConsoleHelper.Warning($"Plugin already exist.");
+ return;
+ }
+
+ await InstallPluginAsync(pluginName);
+ ConsoleHelper.Warning("Install successful, please restart neo-cli.");
+ }
+
+ ///
+ /// Force to install a plugin again. This will overwrite
+ /// existing plugin files, in case of any file missing or
+ /// damage to the old version.
+ ///
+ /// name of the plugin
+ [ConsoleCommand("reinstall", Category = "Plugin Commands", Description = "Overwrite existing plugin by force.")]
+ private async Task OnReinstallCommand(string pluginName)
+ {
+ await InstallPluginAsync(pluginName, overWrite: true);
+ ConsoleHelper.Warning("Reinstall successful, please restart neo-cli.");
+ }
+
+ ///
+ /// Download plugin from github release
+ /// The function of download and install are divided
+ /// for the consideration of `update` command that
+ /// might be added in the future.
+ ///
+ /// name of the plugin
+ /// Downloaded content
+ private async Task DownloadPluginAsync(string pluginName)
+ {
+ var url =
+ $"/~https://github.com/neo-project/neo-modules/releases/download/v{typeof(Plugin).Assembly.GetVersion()}/{pluginName}.zip";
using HttpClient http = new();
- HttpResponseMessage response = await http.GetAsync($"/~https://github.com/neo-project/neo-modules/releases/download/v{typeof(Plugin).Assembly.GetVersion()}/{pluginName}.zip");
+ HttpResponseMessage response = await http.GetAsync(url);
if (response.StatusCode == HttpStatusCode.NotFound)
{
response.Dispose();
- Version version_core = typeof(Plugin).Assembly.GetName().Version;
- HttpRequestMessage request = new(HttpMethod.Get, "https://api.github.com/repos/neo-project/neo-modules/releases");
- request.Headers.UserAgent.ParseAdd($"{GetType().Assembly.GetName().Name}/{GetType().Assembly.GetVersion()}");
- using HttpResponseMessage response_api = await http.SendAsync(request);
- byte[] buffer = await response_api.Content.ReadAsByteArrayAsync();
+ Version versionCore = typeof(Plugin).Assembly.GetName().Version;
+ HttpRequestMessage request = new(HttpMethod.Get,
+ "https://api.github.com/repos/neo-project/neo-modules/releases");
+ request.Headers.UserAgent.ParseAdd(
+ $"{GetType().Assembly.GetName().Name}/{GetType().Assembly.GetVersion()}");
+ using HttpResponseMessage responseApi = await http.SendAsync(request);
+ byte[] buffer = await responseApi.Content.ReadAsByteArrayAsync();
JObject releases = JObject.Parse(buffer);
JObject asset = releases.GetArray()
.Where(p => !p["tag_name"].GetString().Contains('-'))
@@ -49,25 +89,92 @@ private async Task OnInstallCommandAsync(string pluginName)
Assets = p["assets"].GetArray()
})
.OrderByDescending(p => p.Version)
- .First(p => p.Version <= version_core).Assets
+ .First(p => p.Version <= versionCore).Assets
.FirstOrDefault(p => p["name"].GetString() == $"{pluginName}.zip");
if (asset is null) throw new Exception("Plugin doesn't exist.");
response = await http.GetAsync(asset["browser_download_url"].GetString());
}
+
using (response)
{
- using Stream stream = await response.Content.ReadAsStreamAsync();
- using ZipArchive zip = new(stream, ZipArchiveMode.Read);
- try
- {
- zip.ExtractToDirectory(".");
- ConsoleHelper.Info("Install successful, please restart neo-cli.");
- }
- catch (IOException)
+ var totalRead = 0L;
+ byte[] buffer = new byte[1024];
+ int read;
+ await using Stream stream = await response.Content.ReadAsStreamAsync();
+ ConsoleHelper.Info("From ", $"{url}");
+ var output = new MemoryStream();
+ while ((read = await stream.ReadAsync(buffer)) > 0)
{
- ConsoleHelper.Warning($"Plugin already exist.");
+ output.Write(buffer, 0, read);
+ totalRead += read;
+ Console.Write(
+ $"\rDownloading {pluginName}.zip {totalRead / 1024}KB/{response.Content.Headers.ContentLength / 1024}KB {(totalRead * 100) / response.Content.Headers.ContentLength}%");
}
+
+ Console.WriteLine();
+ return output;
+ }
+ }
+
+ ///
+ /// Install plugin from stream
+ ///
+ /// name of the plugin
+ /// Install by force for `update`
+ private async Task InstallPluginAsync(string pluginName, HashSet installed = null,
+ bool overWrite = false)
+ {
+ installed ??= new HashSet();
+ if (!installed.Add(pluginName)) return;
+ if (!overWrite && PluginExists(pluginName)) return;
+
+ await using MemoryStream stream = await DownloadPluginAsync(pluginName);
+ using (SHA256 sha256 = SHA256.Create())
+ {
+ ConsoleHelper.Info("SHA256: ", $"{sha256.ComputeHash(stream.ToArray()).ToHexString()}");
}
+
+ using ZipArchive zip = new(stream, ZipArchiveMode.Read);
+ ZipArchiveEntry entry = zip.Entries.FirstOrDefault(p => p.Name == "config.json");
+ if (entry is not null)
+ {
+ await using Stream es = entry.Open();
+ await InstallDependenciesAsync(es, installed);
+ }
+ zip.ExtractToDirectory("./", true);
+ }
+
+ ///
+ /// Install the dependency of the plugin
+ ///
+ /// plugin config path in temp
+ /// Dependency set
+ private async Task InstallDependenciesAsync(Stream config, HashSet installed)
+ {
+ IConfigurationSection dependency = new ConfigurationBuilder()
+ .AddJsonStream(config)
+ .Build()
+ .GetSection("Dependency");
+
+ if (!dependency.Exists()) return;
+ var dependencies = dependency.GetChildren().Select(p => p.Get()).ToArray();
+ if (dependencies.Length == 0) return;
+
+ foreach (string plugin in dependencies.Where(p => !PluginExists(p)))
+ {
+ ConsoleHelper.Info($"Installing dependency: {plugin}");
+ await InstallPluginAsync(plugin, installed);
+ }
+ }
+
+ ///
+ /// Check that the plugin has all necessary files
+ ///
+ /// Name of the plugin
+ ///
+ private static bool PluginExists(string pluginName)
+ {
+ return File.Exists($"Plugins/{pluginName}.dll");
}
///
@@ -77,30 +184,77 @@ private async Task OnInstallCommandAsync(string pluginName)
[ConsoleCommand("uninstall", Category = "Plugin Commands")]
private void OnUnInstallCommand(string pluginName)
{
- var plugin = Plugin.Plugins.FirstOrDefault(p => p.Name == pluginName);
- if (plugin is null)
+ if (!PluginExists(pluginName))
{
ConsoleHelper.Warning("Plugin not found");
return;
}
- if (plugin is Logger)
+
+ var plugin = Plugin.Plugins.FirstOrDefault(p => p.Name == pluginName);
+ if (plugin is not null)
{
- ConsoleHelper.Warning("You cannot uninstall a built-in plugin.");
- return;
+ if (plugin is Logger)
+ {
+ ConsoleHelper.Warning("You cannot uninstall a built-in plugin.");
+ return;
+ }
+
+ Plugin.Plugins.Remove(plugin);
+ }
+
+ foreach (var p in Plugin.Plugins)
+ {
+ try
+ {
+ using var reader = File.OpenRead($"./Plugins/{p.Name}/config.json");
+ if (new ConfigurationBuilder()
+ .AddJsonStream(reader)
+ .Build()
+ .GetSection("Dependency")
+ .GetChildren()
+ .Select(d => d.Get())
+ .Any(v => v == pluginName))
+ {
+ ConsoleHelper.Error(
+ $"Can not uninstall. Other plugins depend on this plugin, try `reinstall {pluginName}` if the plugin is broken.");
+ return;
+ }
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
}
- File.Delete(plugin.Path);
- File.Delete(plugin.ConfigFile);
try
{
- Directory.Delete(Path.GetDirectoryName(plugin.ConfigFile), false);
+ DeleteFiles(new[] { $"Plugins/{pluginName}.dll", $"Plugins/{pluginName}/config.json" });
+ Directory.Delete($"Plugins/{pluginName}", false);
}
catch (IOException)
{
}
+
ConsoleHelper.Info("Uninstall successful, please restart neo-cli.");
}
+ private static void DeleteFiles(IEnumerable list)
+ {
+ foreach (var file in list)
+ {
+ try
+ {
+ if (!File.Exists(file)) continue;
+ ConsoleHelper.Info("Deleting ", file);
+ File.Delete(file);
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ }
+ }
+
///
/// Process "plugins" command
///
@@ -113,7 +267,8 @@ private void OnPluginsCommand()
foreach (Plugin plugin in Plugin.Plugins)
{
if (plugin is Logger) continue;
- ConsoleHelper.Info($"\t{plugin.Name,-20}", plugin.Description);
+ var name = $"{plugin.Name}@{plugin.Version}";
+ Console.WriteLine($"\t{name,-25}{plugin.Description}");
}
}
else
diff --git a/neo-cli/CLI/MainService.Tools.cs b/neo-cli/CLI/MainService.Tools.cs
index 05d6df487..f5be9a648 100644
--- a/neo-cli/CLI/MainService.Tools.cs
+++ b/neo-cli/CLI/MainService.Tools.cs
@@ -80,13 +80,7 @@ private string HexToString(string hexString)
var clearHexString = ClearHexString(hexString);
var bytes = clearHexString.HexToBytes();
var utf8String = Utility.StrictUTF8.GetString(bytes);
-
- if (!IsPrintable(utf8String))
- {
- return null;
- }
-
- return utf8String;
+ return IsPrintable(utf8String) ? utf8String : null;
}
catch
{
@@ -416,14 +410,8 @@ private string Base64ToString(string bytearray)
try
{
byte[] result = Convert.FromBase64String(bytearray);
- string utf8string = Utility.StrictUTF8.GetString(result);
-
- if (!IsPrintable(utf8string))
- {
- return null;
- }
-
- return utf8string;
+ string utf8String = Utility.StrictUTF8.GetString(result);
+ return IsPrintable(utf8String) ? utf8String : null;
}
catch
{
diff --git a/neo-cli/CLI/MainService.Vote.cs b/neo-cli/CLI/MainService.Vote.cs
index b8ffdb988..da9be9953 100644
--- a/neo-cli/CLI/MainService.Vote.cs
+++ b/neo-cli/CLI/MainService.Vote.cs
@@ -17,6 +17,7 @@
using Neo.VM.Types;
using Neo.Wallets;
using System;
+using System.Linq;
using System.Numerics;
namespace Neo.CLI
@@ -27,7 +28,6 @@ partial class MainService
/// Process "register candidate" command
///
/// register account scriptHash
- /// Max fee for running the script
[ConsoleCommand("register candidate", Category = "Vote Commands")]
private void OnRegisterCandidateCommand(UInt160 account)
{
@@ -49,7 +49,7 @@ private void OnRegisterCandidateCommand(UInt160 account)
}
}
- ECPoint publicKey = currentAccount?.GetKey()?.PublicKey;
+ ECPoint publicKey = currentAccount.GetKey()?.PublicKey;
byte[] script;
using (ScriptBuilder scriptBuilder = new ScriptBuilder())
{
@@ -63,7 +63,7 @@ private void OnRegisterCandidateCommand(UInt160 account)
///
/// Process "unregister candidate" command
///
- /// unregister account scriptHash
+ /// unregister account scriptHash
[ConsoleCommand("unregister candidate", Category = "Vote Commands")]
private void OnUnregisterCandidateCommand(UInt160 account)
{
@@ -208,9 +208,11 @@ private void OnGetNextBlockValidatorsCommand()
private void OnGetAccountState(UInt160 address)
{
string notice = "No vote record!";
- var arg = new JObject();
- arg["type"] = "Hash160";
- arg["value"] = address.ToString();
+ var arg = new JObject
+ {
+ ["type"] = "Hash160",
+ ["value"] = address.ToString()
+ };
if (!OnInvokeWithResult(NativeContract.NEO.Hash, "getAccountState", out StackItem result, null, new JArray(arg))) return;
Console.WriteLine();
diff --git a/neo-cli/CLI/MainService.Wallet.cs b/neo-cli/CLI/MainService.Wallet.cs
index 0db3eb313..f56a759ff 100644
--- a/neo-cli/CLI/MainService.Wallet.cs
+++ b/neo-cli/CLI/MainService.Wallet.cs
@@ -90,14 +90,14 @@ private void OnUpgradeWalletCommand(string path)
ConsoleHelper.Info("Cancelled");
return;
}
- string path_new = Path.ChangeExtension(path, ".json");
- if (File.Exists(path_new))
+ string pathNew = Path.ChangeExtension(path, ".json");
+ if (File.Exists(pathNew))
{
- ConsoleHelper.Warning($"File '{path_new}' already exists");
+ ConsoleHelper.Warning($"File '{pathNew}' already exists");
return;
}
- NEP6Wallet.Migrate(path_new, path, password, NeoSystem.Settings).Save();
- Console.WriteLine($"Wallet file upgrade complete. New wallet file has been auto-saved at: {path_new}");
+ NEP6Wallet.Migrate(pathNew, path, password, NeoSystem.Settings).Save();
+ Console.WriteLine($"Wallet file upgrade complete. New wallet file has been auto-saved at: {pathNew}");
}
///
@@ -252,7 +252,7 @@ private void OnImportMultisigAddress(ushort m, ECPoint[] publicKeys)
Contract multiSignContract = Contract.CreateMultiSigContract(m, publicKeys);
KeyPair keyPair = CurrentWallet.GetAccounts().FirstOrDefault(p => p.HasKey && publicKeys.Contains(p.GetKey().PublicKey))?.GetKey();
- WalletAccount account = CurrentWallet.CreateAccount(multiSignContract, keyPair);
+ CurrentWallet.CreateAccount(multiSignContract, keyPair);
if (CurrentWallet is NEP6Wallet wallet)
wallet.Save();
@@ -466,7 +466,7 @@ private void OnSignCommand(JObject jsonObjectToSign)
{
var snapshot = NeoSystem.StoreView;
ContractParametersContext context = ContractParametersContext.Parse(jsonObjectToSign.ToString(), snapshot);
- if (context.Network != neoSystem.Settings.Network)
+ if (context.Network != _neoSystem.Settings.Network)
{
ConsoleHelper.Warning("Network mismatch.");
return;
@@ -636,7 +636,7 @@ private void SignAndSendTx(DataCache snapshot, Transaction tx)
ContractParametersContext context;
try
{
- context = new ContractParametersContext(snapshot, tx, neoSystem.Settings.Network);
+ context = new ContractParametersContext(snapshot, tx, _neoSystem.Settings.Network);
}
catch (InvalidOperationException e)
{
diff --git a/neo-cli/CLI/MainService.cs b/neo-cli/CLI/MainService.cs
index 6fa7853e8..89493e03d 100644
--- a/neo-cli/CLI/MainService.cs
+++ b/neo-cli/CLI/MainService.cs
@@ -36,6 +36,7 @@
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
+using Array = System.Array;
namespace Neo.CLI
{
@@ -45,33 +46,24 @@ public partial class MainService : ConsoleServiceBase, IWalletProvider
public const long TestModeGas = 20_00000000;
- private Wallet currentWallet;
+ private Wallet _currentWallet;
public LocalNode LocalNode;
public Wallet CurrentWallet
{
- get
- {
- return currentWallet;
- }
+ get => _currentWallet;
private set
{
- currentWallet = value;
+ _currentWallet = value;
WalletChanged?.Invoke(this, value);
}
}
- private NeoSystem neoSystem;
+ private NeoSystem _neoSystem;
public NeoSystem NeoSystem
{
- get
- {
- return neoSystem;
- }
- private set
- {
- neoSystem = value;
- }
+ get => _neoSystem;
+ private set => _neoSystem = value;
}
protected override string Prompt => "neo";
@@ -82,15 +74,15 @@ private set
///
public MainService() : base()
{
- RegisterCommandHander(false, (str) => StringToAddress(str, NeoSystem.Settings.AddressVersion));
- RegisterCommandHander(false, (str) => UInt256.Parse(str));
- RegisterCommandHander((str) => str.Select(u => UInt256.Parse(u.Trim())).ToArray());
- RegisterCommandHander((arr) => arr.Select(str => StringToAddress(str, NeoSystem.Settings.AddressVersion)).ToArray());
- RegisterCommandHander((str) => ECPoint.Parse(str.Trim(), ECCurve.Secp256r1));
- RegisterCommandHander((str) => str.Select(u => ECPoint.Parse(u.Trim(), ECCurve.Secp256r1)).ToArray());
- RegisterCommandHander((str) => JObject.Parse(str));
- RegisterCommandHander((str) => decimal.Parse(str, CultureInfo.InvariantCulture));
- RegisterCommandHander((obj) => (JArray)obj);
+ RegisterCommandHandler(false, str => StringToAddress(str, NeoSystem.Settings.AddressVersion));
+ RegisterCommandHandler(false, UInt256.Parse);
+ RegisterCommandHandler(str => str.Select(u => UInt256.Parse(u.Trim())).ToArray());
+ RegisterCommandHandler(arr => arr.Select(str => StringToAddress(str, NeoSystem.Settings.AddressVersion)).ToArray());
+ RegisterCommandHandler(str => ECPoint.Parse(str.Trim(), ECCurve.Secp256r1));
+ RegisterCommandHandler(str => str.Select(u => ECPoint.Parse(u.Trim(), ECCurve.Secp256r1)).ToArray());
+ RegisterCommandHandler(str => JObject.Parse(str));
+ RegisterCommandHandler(str => decimal.Parse(str, CultureInfo.InvariantCulture));
+ RegisterCommandHandler(obj => (JArray)obj);
RegisterCommand(this);
}
@@ -483,7 +475,7 @@ public async void Start(string[] args)
public void Stop()
{
- Interlocked.Exchange(ref neoSystem, null)?.Dispose();
+ Interlocked.Exchange(ref _neoSystem, null)?.Dispose();
}
private void WriteBlocks(uint start, uint count, string path, bool writeStart)
@@ -548,14 +540,14 @@ private static void WriteLineWithoutFlicker(string message = "", int maxWidth =
/// Max fee for running the script
private void SendTransaction(byte[] script, UInt160 account = null, long gas = TestModeGas)
{
- Signer[] signers = System.Array.Empty();
+ Signer[] signers = Array.Empty();
var snapshot = NeoSystem.StoreView;
if (account != null)
{
signers = CurrentWallet.GetAccounts()
.Where(p => !p.Lock && !p.WatchOnly && p.ScriptHash == account && NativeContract.GAS.BalanceOf(snapshot, p.ScriptHash).Sign > 0)
- .Select(p => new Signer() { Account = p.ScriptHash, Scopes = WitnessScope.CalledByEntry })
+ .Select(p => new Signer { Account = p.ScriptHash, Scopes = WitnessScope.CalledByEntry })
.ToArray();
}
@@ -580,10 +572,7 @@ private void SendTransaction(byte[] script, UInt160 account = null, long gas = T
catch (InvalidOperationException e)
{
ConsoleHelper.Error(GetExceptionMessage(e));
- return;
}
-
- return;
}
///
@@ -592,12 +581,12 @@ private void SendTransaction(byte[] script, UInt160 account = null, long gas = T
/// Script hash
/// Operation
/// Result
- /// Transaction
+ /// Transaction
/// Contract parameters
/// Show result stack if it is true
/// Max fee for running the script
/// Return true if it was successful
- private bool OnInvokeWithResult(UInt160 scriptHash, string operation, out StackItem result, IVerifiable verificable = null, JArray contractParameters = null, bool showStack = true, long gas = TestModeGas)
+ private bool OnInvokeWithResult(UInt160 scriptHash, string operation, out StackItem result, IVerifiable verifiable = null, JArray contractParameters = null, bool showStack = true, long gas = TestModeGas)
{
List parameters = new List();
@@ -635,12 +624,12 @@ private bool OnInvokeWithResult(UInt160 scriptHash, string operation, out StackI
ConsoleHelper.Info("Invoking script with: ", $"'{script.ToBase64String()}'");
}
- if (verificable is Transaction tx)
+ if (verifiable is Transaction tx)
{
tx.Script = script;
}
- using ApplicationEngine engine = ApplicationEngine.Run(script, NeoSystem.StoreView, container: verificable, settings: NeoSystem.Settings, gas: gas);
+ using ApplicationEngine engine = ApplicationEngine.Run(script, NeoSystem.StoreView, container: verifiable, settings: NeoSystem.Settings, gas: gas);
PrintExecutionOutput(engine, showStack);
result = engine.State == VMState.FAULT ? null : engine.ResultStack.Peek();
return engine.State != VMState.FAULT;
diff --git a/neo-cli/config.testnet.json b/neo-cli/config.testnet.json
index f151c2625..7ee048897 100644
--- a/neo-cli/config.testnet.json
+++ b/neo-cli/config.testnet.json
@@ -23,10 +23,10 @@
}
},
"ProtocolConfiguration": {
- "Network": 877933390,
+ "Network": 894710606,
"AddressVersion": 53,
"MillisecondsPerBlock": 15000,
- "MaxTransactionsPerBlock": 512,
+ "MaxTransactionsPerBlock": 5000,
"MemoryPoolMaxTransactions": 50000,
"MaxTraceableBlocks": 2102400,
"InitialGasDistribution": 5200000000000000,
@@ -55,11 +55,11 @@
"03184b018d6b2bc093e535519732b3fd3f7551c8cffaf4621dd5a0b89482ca66c9"
],
"SeedList": [
- "seed1t4.neo.org:20333",
- "seed2t4.neo.org:20333",
- "seed3t4.neo.org:20333",
- "seed4t4.neo.org:20333",
- "seed5t4.neo.org:20333"
+ "seed1t5.neo.org:20333",
+ "seed2t5.neo.org:20333",
+ "seed3t5.neo.org:20333",
+ "seed4t5.neo.org:20333",
+ "seed5t5.neo.org:20333"
]
}
}
diff --git a/neo-cli/neo-cli.csproj b/neo-cli/neo-cli.csproj
index 208fd90e4..9993e5ef9 100644
--- a/neo-cli/neo-cli.csproj
+++ b/neo-cli/neo-cli.csproj
@@ -1,9 +1,9 @@
- 2016-2021 The Neo Project
+ 2016-2022 The Neo Project
Neo.CLI
- 3.1.0
+ 3.2.1
The Neo Project
net6.0
neo-cli
@@ -23,7 +23,7 @@
-
+
diff --git a/neo-gui/neo-gui.csproj b/neo-gui/neo-gui.csproj
index 13a14e02b..94a56ec90 100644
--- a/neo-gui/neo-gui.csproj
+++ b/neo-gui/neo-gui.csproj
@@ -1,9 +1,9 @@
- 2016-2021 The Neo Project
+ 2016-2022 The Neo Project
Neo.GUI
- 3.1.0
+ 3.2.1
The Neo Project
WinExe
net6.0-windows
diff --git a/tests/Neo.ConsoleService.Tests/Neo.ConsoleService.Tests.csproj b/tests/Neo.ConsoleService.Tests/Neo.ConsoleService.Tests.csproj
index 0e94b37d0..48273aad7 100644
--- a/tests/Neo.ConsoleService.Tests/Neo.ConsoleService.Tests.csproj
+++ b/tests/Neo.ConsoleService.Tests/Neo.ConsoleService.Tests.csproj
@@ -6,9 +6,9 @@
-
-
-
+
+
+