diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index 0344f39541..3add07d724 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -274,7 +274,16 @@ protected static void OnSysCall(ExecutionEngine engine, Instruction instruction) { if (engine is ApplicationEngine app) { - app.OnSysCall(GetInteropDescriptor(instruction.TokenU32)); + var interop = GetInteropDescriptor(instruction.TokenU32); + + if (interop?.Hardfork != null && !app.IsHardforkEnabled(interop.Hardfork.Value)) + { + // The syscall is not active + + throw new KeyNotFoundException(); + } + + app.OnSysCall(interop); } else { @@ -691,19 +700,20 @@ private static Block CreateDummyBlock(IReadOnlyStore snapshot, ProtocolSettings }; } - private static InteropDescriptor Register(string name, string handler, long fixedPrice, CallFlags requiredCallFlags) + private static InteropDescriptor Register(string name, string handler, long fixedPrice, CallFlags requiredCallFlags, Hardfork? hardfork = null) { var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; - MethodInfo method = typeof(ApplicationEngine).GetMethod(handler, flags) + var method = typeof(ApplicationEngine).GetMethod(handler, flags) ?? typeof(ApplicationEngine).GetProperty(handler, flags).GetMethod; - InteropDescriptor descriptor = new() + var descriptor = new InteropDescriptor() { Name = name, Handler = method, + Hardfork = hardfork, FixedPrice = fixedPrice, RequiredCallFlags = requiredCallFlags }; - services ??= new Dictionary(); + services ??= []; services.Add(descriptor.Hash, descriptor); return descriptor; } diff --git a/src/Neo/SmartContract/InteropDescriptor.cs b/src/Neo/SmartContract/InteropDescriptor.cs index e0bdab8c16..172dcfda12 100644 --- a/src/Neo/SmartContract/InteropDescriptor.cs +++ b/src/Neo/SmartContract/InteropDescriptor.cs @@ -58,6 +58,11 @@ public uint Hash /// public long FixedPrice { get; init; } + /// + /// Required Hardfork to be active. + /// + public Hardfork? Hardfork { get; init; } + /// /// The required for the interoperable service. ///