-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Fix plugin exception #3426
Fix plugin exception #3426
Changes from 11 commits
a7f39ef
ffcd7ce
a4cade1
5ebdfd4
82fcfb6
da31567
ba3e748
0a41a97
b76adb9
5a7443f
c9e6dd4
3944f42
79d597c
5034e7f
b384811
2ecf454
1a80344
e4b10cb
07906b2
eb0c6b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ | |
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; | ||
|
@@ -24,6 +25,7 @@ | |
using System.Collections.Immutable; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Runtime.CompilerServices; | ||
|
||
namespace Neo.Ledger | ||
{ | ||
|
@@ -468,10 +470,10 @@ private void Persist(Block block) | |
Context.System.EventStream.Publish(application_executed); | ||
all_application_executed.Add(application_executed); | ||
} | ||
Committing?.Invoke(system, block, snapshot, all_application_executed); | ||
InvokeCommitting(system, block, snapshot, all_application_executed); | ||
snapshot.Commit(); | ||
} | ||
Committed?.Invoke(system, block); | ||
InvokeCommitted(system, block); | ||
system.MemPool.UpdatePoolForBlockPersisted(block, system.StoreView); | ||
extensibleWitnessWhiteList = null; | ||
block_cache.Remove(block.PrevHash); | ||
|
@@ -480,6 +482,56 @@ private void Persist(Block block) | |
Debug.Assert(header.Index == block.Index); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
internal static void InvokeCommitting(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList<ApplicationExecuted> applicationExecutedList) | ||
{ | ||
InvokeHandlers(Committing?.GetInvocationList(), h => ((CommittingHandler)h)(system, block, snapshot, applicationExecutedList)); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
internal static void InvokeCommitted(NeoSystem system, Block block) | ||
{ | ||
InvokeHandlers(Committed?.GetInvocationList(), h => ((CommittedHandler)h)(system, block)); | ||
} | ||
|
||
private static void InvokeHandlers(Delegate[] handlers, Action<Delegate> handlerAction) | ||
{ | ||
if (handlers == null) return; | ||
|
||
foreach (var handler in handlers) | ||
{ | ||
try | ||
{ | ||
// skip stopped plugin. | ||
if (handler.Target is Plugin { IsStopped: true }) | ||
{ | ||
continue; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the stopped plugin keep crashing nothing will be reported? |
||
} | ||
|
||
handlerAction(handler); | ||
} | ||
catch (Exception ex) when (handler.Target is Plugin plugin) | ||
{ | ||
Utility.Log(nameof(plugin), LogLevel.Error, ex); | ||
switch (plugin.ExceptionPolicy) | ||
{ | ||
case UnhandledExceptionPolicy.StopNode: | ||
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."); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets a <see cref="Akka.Actor.Props"/> object used for creating the <see cref="Blockchain"/> actor. | ||
/// </summary> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright (C) 2015-2024 The Neo Project. | ||
// | ||
// PluginSettings.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 Org.BouncyCastle.Security; | ||
using System; | ||
|
||
namespace Neo.Plugins; | ||
|
||
public abstract class PluginSettings(IConfigurationSection section) | ||
{ | ||
public UnhandledExceptionPolicy ExceptionPolicy | ||
{ | ||
get | ||
{ | ||
var policyString = section.GetValue(nameof(UnhandledExceptionPolicy), nameof(UnhandledExceptionPolicy.StopNode)); | ||
if (Enum.TryParse(policyString, true, out UnhandledExceptionPolicy policy)) | ||
{ | ||
return policy; | ||
} | ||
|
||
throw new InvalidParameterException($"{policyString} is not a valid UnhandledExceptionPolicy"); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright (C) 2015-2024 The Neo Project. | ||
// | ||
// UnhandledExceptionPolicy.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.Plugins | ||
{ | ||
public enum UnhandledExceptionPolicy : byte | ||
{ | ||
Ignore = 0, | ||
StopPlugin = 1, | ||
StopNode = 2, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,8 @@ | |
"Path": "ApplicationLogs_{0}", | ||
"Network": 860833102, | ||
"MaxStackSize": 65535, | ||
"Debug": false | ||
"Debug": false, | ||
"UnhandledExceptionPolicy": "StopPlugin" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's better in almost all of them There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nothoing was changed since the last review but the deledage invoke. Different plugin has different behavior on unhandled exception that are precisely set by superboy. Default behavior means nothing here. |
||
}, | ||
"Dependency": [ | ||
"RpcServer" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
{ | ||
"PluginConfiguration": { | ||
"UnhandledExceptionPolicy": "Ignore", | ||
"Servers": [ | ||
{ | ||
"Network": 860833102, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What we have this requirement added?