Skip to content

Commit

Permalink
Revert "Plugin unhandled exception (neo-project#3349)" (neo-project#3366
Browse files Browse the repository at this point in the history
)

This reverts commit b2f060f.

Co-authored-by: Christopher Schuchardt <[email protected]>
  • Loading branch information
vncoelho and cschuchardt88 authored Jul 17, 2024
1 parent 03fc303 commit f307a31
Show file tree
Hide file tree
Showing 26 changed files with 29 additions and 417 deletions.
66 changes: 2 additions & 64 deletions src/Neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,18 @@
using Akka.Actor;
using Akka.Configuration;
using Akka.IO;
using Akka.Util.Internal;
using Neo.IO.Actors;
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.Plugins;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace Neo.Ledger
{
Expand Down Expand Up @@ -472,10 +468,10 @@ private void Persist(Block block)
Context.System.EventStream.Publish(application_executed);
all_application_executed.Add(application_executed);
}
_ = InvokeCommittingAsync(system, block, snapshot, all_application_executed);
Committing?.Invoke(system, block, snapshot, all_application_executed);
snapshot.Commit();
}
_ = InvokeCommittedAsync(system, block);
Committed?.Invoke(system, block);
system.MemPool.UpdatePoolForBlockPersisted(block, system.StoreView);
extensibleWitnessWhiteList = null;
block_cache.Remove(block.PrevHash);
Expand All @@ -484,64 +480,6 @@ private void Persist(Block block)
Debug.Assert(header.Index == block.Index);
}

internal static async Task InvokeCommittingAsync(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList<ApplicationExecuted> applicationExecutedList)
{
await InvokeHandlersAsync(Committing?.GetInvocationList(), h => ((CommittingHandler)h)(system, block, snapshot, applicationExecutedList));
}

internal static async Task InvokeCommittedAsync(NeoSystem system, Block block)
{
await InvokeHandlersAsync(Committed?.GetInvocationList(), h => ((CommittedHandler)h)(system, block));
}

private static async Task InvokeHandlersAsync(Delegate[] handlers, Action<Delegate> handlerAction)
{
if (handlers == null) return;

var exceptions = new ConcurrentBag<Exception>();
var tasks = handlers.Select(handler => Task.Run(() =>
{
try
{
// skip stopped plugin.
if (handler.Target is Plugin { IsStopped: true })
{
return;
}
handlerAction(handler);
}
catch (Exception ex) when (handler.Target is Plugin plugin)
{
switch (plugin.ExceptionPolicy)
{
case UnhandledExceptionPolicy.StopNode:
exceptions.Add(ex);
throw;
case UnhandledExceptionPolicy.StopPlugin:
//Stop plugin on exception
plugin.IsStopped = true;
break;
case UnhandledExceptionPolicy.Ignore:
// Log the exception and continue with the next handler
break;
default:
throw new InvalidCastException($"The exception policy {plugin.ExceptionPolicy} is not valid.");
}
Utility.Log(nameof(plugin), LogLevel.Error, ex);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
})).ToList();

await Task.WhenAll(tasks);

exceptions.ForEach(e => throw e);
}

/// <summary>
/// Gets a <see cref="Akka.Actor.Props"/> object used for creating the <see cref="Blockchain"/> actor.
/// </summary>
Expand Down
56 changes: 6 additions & 50 deletions src/Neo/Plugins/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ public abstract class Plugin : IDisposable
/// <summary>
/// The directory containing the plugin folders. Files can be contained in any subdirectory.
/// </summary>
public static readonly string PluginsDirectory =
Combine(GetDirectoryName(System.AppContext.BaseDirectory), "Plugins");
public static readonly string PluginsDirectory = Combine(GetDirectoryName(System.AppContext.BaseDirectory), "Plugins");

private static readonly FileSystemWatcher configWatcher;

Expand Down Expand Up @@ -68,27 +67,14 @@ public abstract class Plugin : IDisposable
/// </summary>
public virtual Version Version => GetType().Assembly.GetName().Version;

/// <summary>
/// If the plugin should be stopped when an exception is thrown.
/// Default is <see langword="true"/>.
/// </summary>
protected internal virtual UnhandledExceptionPolicy ExceptionPolicy { get; init; } = UnhandledExceptionPolicy.StopNode;

/// <summary>
/// The plugin will be stopped if an exception is thrown.
/// But it also depends on <see cref="UnhandledExceptionPolicy"/>.
/// </summary>
internal bool IsStopped { get; set; }

static Plugin()
{
if (!Directory.Exists(PluginsDirectory)) return;
configWatcher = new FileSystemWatcher(PluginsDirectory)
{
EnableRaisingEvents = true,
IncludeSubdirectories = true,
NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.CreationTime |
NotifyFilters.LastWrite | NotifyFilters.Size,
NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.Size,
};
configWatcher.Changed += ConfigWatcher_Changed;
configWatcher.Created += ConfigWatcher_Changed;
Expand Down Expand Up @@ -120,8 +106,7 @@ private static void ConfigWatcher_Changed(object sender, FileSystemEventArgs e)
{
case ".json":
case ".dll":
Utility.Log(nameof(Plugin), LogLevel.Warning,
$"File {e.Name} is {e.ChangeType}, please restart node.");
Utility.Log(nameof(Plugin), LogLevel.Warning, $"File {e.Name} is {e.ChangeType}, please restart node.");
break;
}
}
Expand All @@ -134,8 +119,7 @@ private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEven
AssemblyName an = new(args.Name);

Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == args.Name) ??
AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == an.Name);
AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == an.Name);
if (assembly != null) return assembly;

string filename = an.Name + ".dll";
Expand Down Expand Up @@ -166,8 +150,7 @@ public virtual void Dispose()
/// <returns>The content of the configuration file read.</returns>
protected IConfigurationSection GetConfiguration()
{
return new ConfigurationBuilder().AddJsonFile(ConfigFile, optional: true).Build()
.GetSection("PluginConfiguration");
return new ConfigurationBuilder().AddJsonFile(ConfigFile, optional: true).Build().GetSection("PluginConfiguration");
}

private static void LoadPlugin(Assembly assembly)
Expand Down Expand Up @@ -204,7 +187,6 @@ internal static void LoadPlugins()
catch { }
}
}

foreach (Assembly assembly in assemblies)
{
LoadPlugin(assembly);
Expand Down Expand Up @@ -247,33 +229,7 @@ protected internal virtual void OnSystemLoaded(NeoSystem system)
/// <returns><see langword="true"/> if the <paramref name="message"/> is handled by a plugin; otherwise, <see langword="false"/>.</returns>
public static bool SendMessage(object message)
{

return Plugins.Any(plugin =>
{
try
{
return !plugin.IsStopped &&
plugin.OnMessage(message);
}
catch (Exception ex)
{
switch (plugin.ExceptionPolicy)
{
case UnhandledExceptionPolicy.StopNode:
throw;
case UnhandledExceptionPolicy.StopPlugin:
plugin.IsStopped = true;
break;
case UnhandledExceptionPolicy.Ignore:
break;
default:
throw new InvalidCastException($"The exception policy {plugin.ExceptionPolicy} is not valid.");
}
Utility.Log(nameof(Plugin), LogLevel.Error, ex);
return false;
}
}
);
return Plugins.Any(plugin => plugin.OnMessage(message));
}
}
}
33 changes: 0 additions & 33 deletions src/Neo/Plugins/PluginSettings.cs

This file was deleted.

20 changes: 0 additions & 20 deletions src/Neo/Plugins/UnhandledExceptionPolicy.cs

This file was deleted.

3 changes: 1 addition & 2 deletions src/Plugins/ApplicationLogs/ApplicationLogs.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
"Path": "ApplicationLogs_{0}",
"Network": 860833102,
"MaxStackSize": 65535,
"Debug": false,
"UnhandledExceptionPolicy": "StopPlugin"
"Debug": false
},
"Dependency": [
"RpcServer"
Expand Down
1 change: 0 additions & 1 deletion src/Plugins/ApplicationLogs/LogReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ public class LogReader : Plugin, ICommittingHandler, ICommittedHandler, ILogHand

public override string Name => "ApplicationLogs";
public override string Description => "Synchronizes smart contract VM executions and notifications (NotifyLog) on blockchain.";
protected override UnhandledExceptionPolicy ExceptionPolicy => Settings.Default.ExceptionPolicy;

#region Ctor

Expand Down
4 changes: 2 additions & 2 deletions src/Plugins/ApplicationLogs/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Neo.Plugins.ApplicationLogs
{
internal class Settings : PluginSettings
internal class Settings
{
public string Path { get; }
public uint Network { get; }
Expand All @@ -23,7 +23,7 @@ internal class Settings : PluginSettings

public static Settings Default { get; private set; }

private Settings(IConfigurationSection section) : base(section)
private Settings(IConfigurationSection section)
{
Path = section.GetValue("Path", "ApplicationLogs_{0}");
Network = section.GetValue("Network", 5195086u);
Expand Down
2 changes: 0 additions & 2 deletions src/Plugins/DBFTPlugin/DBFTPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ public class DBFTPlugin : Plugin, IServiceAddedHandler, IMessageReceivedHandler,

public override string ConfigFile => System.IO.Path.Combine(RootPath, "DBFTPlugin.json");

protected override UnhandledExceptionPolicy ExceptionPolicy => settings.ExceptionPolicy;

public DBFTPlugin()
{
RemoteNode.MessageReceived += ((IMessageReceivedHandler)this).RemoteNode_MessageReceived_Handler;
Expand Down
3 changes: 1 addition & 2 deletions src/Plugins/DBFTPlugin/DBFTPlugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"AutoStart": false,
"Network": 860833102,
"MaxBlockSize": 2097152,
"MaxBlockSystemFee": 150000000000,
"UnhandledExceptionPolicy": "StopNode"
"MaxBlockSystemFee": 150000000000
}
}
4 changes: 2 additions & 2 deletions src/Plugins/DBFTPlugin/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Neo.Plugins.DBFTPlugin
{
public class Settings : PluginSettings
public class Settings
{
public string RecoveryLogs { get; }
public bool IgnoreRecoveryLogs { get; }
Expand All @@ -22,7 +22,7 @@ public class Settings : PluginSettings
public uint MaxBlockSize { get; }
public long MaxBlockSystemFee { get; }

public Settings(IConfigurationSection section) : base(section)
public Settings(IConfigurationSection section)
{
RecoveryLogs = section.GetValue("RecoveryLogs", "ConsensusState");
IgnoreRecoveryLogs = section.GetValue("IgnoreRecoveryLogs", false);
Expand Down
2 changes: 0 additions & 2 deletions src/Plugins/OracleService/OracleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ public class OracleService : Plugin, ICommittingHandler, IServiceAddedHandler, I

public override string Description => "Built-in oracle plugin";

protected override UnhandledExceptionPolicy ExceptionPolicy => Settings.Default.ExceptionPolicy;

public override string ConfigFile => System.IO.Path.Combine(RootPath, "OracleService.json");

public OracleService()
Expand Down
1 change: 0 additions & 1 deletion src/Plugins/OracleService/OracleService.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"MaxOracleTimeout": 10000,
"AllowPrivateHost": false,
"AllowedContentTypes": [ "application/json" ],
"UnhandledExceptionPolicy": "Ignore",
"Https": {
"Timeout": 5000
},
Expand Down
4 changes: 2 additions & 2 deletions src/Plugins/OracleService/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public NeoFSSettings(IConfigurationSection section)
}
}

class Settings : PluginSettings
class Settings
{
public uint Network { get; }
public Uri[] Nodes { get; }
Expand All @@ -51,7 +51,7 @@ class Settings : PluginSettings

public static Settings Default { get; private set; }

private Settings(IConfigurationSection section) : base(section)
private Settings(IConfigurationSection section)
{
Network = section.GetValue("Network", 5195086u);
Nodes = section.GetSection("Nodes").GetChildren().Select(p => new Uri(p.Get<string>(), UriKind.Absolute)).ToArray();
Expand Down
1 change: 0 additions & 1 deletion src/Plugins/RpcServer/RpcServer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"PluginConfiguration": {
"UnhandledExceptionPolicy": "Ignore",
"Servers": [
{
"Network": 860833102,
Expand Down
1 change: 0 additions & 1 deletion src/Plugins/RpcServer/RpcServerPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public class RpcServerPlugin : Plugin
private static readonly Dictionary<uint, List<object>> handlers = new();

public override string ConfigFile => System.IO.Path.Combine(RootPath, "RpcServer.json");
protected override UnhandledExceptionPolicy ExceptionPolicy => settings.ExceptionPolicy;

protected override void Configure()
{
Expand Down
Loading

0 comments on commit f307a31

Please sign in to comment.