Skip to content
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

NeoVM integration #2970

Merged
merged 1 commit into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
101 changes: 101 additions & 0 deletions benchmarks/Neo.VM.Benchmarks/Benchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using System.Diagnostics;

namespace Neo.VM
{
public static class Benchmarks
{
public static void NeoIssue2528()
{
// https://github.com/neo-project/neo/issues/2528
// L01: INITSLOT 1, 0
// L02: NEWARRAY0
// L03: DUP
// L04: DUP
// L05: PUSHINT16 2043
// L06: STLOC 0
// L07: PUSH1
// L08: PACK
// L09: LDLOC 0
// L10: DEC
// L11: STLOC 0
// L12: LDLOC 0
// L13: JMPIF_L L07
// L14: PUSH1
// L15: PACK
// L16: APPEND
// L17: PUSHINT32 38000
// L18: STLOC 0
// L19: PUSH0
// L20: PICKITEM
// L21: LDLOC 0
// L22: DEC
// L23: STLOC 0
// L24: LDLOC 0
// L25: JMPIF_L L19
// L26: DROP
Run(nameof(NeoIssue2528), "VwEAwkpKAfsHdwARwG8AnXcAbwAl9////xHAzwJwlAAAdwAQzm8AnXcAbwAl9////0U=");
}

public static void NeoVMIssue418()
{
// https://github.com/neo-project/neo-vm/issues/418
// L00: NEWARRAY0
// L01: PUSH0
// L02: PICK
// L03: PUSH1
// L04: PACK
// L05: PUSH1
// L06: PICK
// L07: PUSH1
// L08: PACK
// L09: INITSSLOT 1
// L10: PUSHINT16 510
// L11: DEC
// L12: STSFLD0
// L13: PUSH1
// L14: PICK
// L15: PUSH1
// L16: PICK
// L17: PUSH2
// L18: PACK
// L19: REVERSE3
// L20: PUSH2
// L21: PACK
// L22: LDSFLD0
// L23: DUP
// L24: JMPIF L11
// L25: DROP
// L26: ROT
// L27: DROP
Run(nameof(NeoVMIssue418), "whBNEcARTRHAVgEB/gGdYBFNEU0SwFMSwFhKJPNFUUU=");
}

public static void NeoIssue2723()
{
// L00: INITSSLOT 1
// L01: PUSHINT32 130000
// L02: STSFLD 0
// L03: PUSHINT32 1048576
// L04: NEWBUFFER
// L05: DROP
// L06: LDSFLD 0
// L07: DEC
// L08: DUP
// L09: STSFLD 0
// L10: JMPIF L03
Run(nameof(NeoIssue2723), "VgEC0PsBAGcAAgAAEACIRV8AnUpnACTz");
}

private static void Run(string name, string poc)
{
byte[] script = Convert.FromBase64String(poc);
using ExecutionEngine engine = new();
engine.LoadScript(script);
Stopwatch stopwatch = Stopwatch.StartNew();
engine.Execute();
stopwatch.Stop();
Debug.Assert(engine.State == VMState.HALT);
Console.WriteLine($"Benchmark: {name},\tTime: {stopwatch.Elapsed}");
}
}
}
16 changes: 16 additions & 0 deletions benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>Neo.VM</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Neo.VM\Neo.VM.csproj" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions benchmarks/Neo.VM.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Neo.VM;
using System.Reflection;

foreach (var method in typeof(Benchmarks).GetMethods(BindingFlags.Public | BindingFlags.Static))
{
method.CreateDelegate<Action>().Invoke();
}
23 changes: 22 additions & 1 deletion neo.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Json", "src\Neo.Json\Ne
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.UnitTests", "tests\Neo.UnitTests\Neo.UnitTests.csproj", "{5B783B30-B422-4C2F-AC22-187A8D1993F4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Json.UnitTests", "tests\Neo.Json.UnitTests\Neo.Json.UnitTests.csproj", "{AE6C32EE-8447-4E01-8187-2AE02BB64251}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Json.UnitTests", "tests\Neo.Json.UnitTests\Neo.Json.UnitTests.csproj", "{AE6C32EE-8447-4E01-8187-2AE02BB64251}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Benchmarks", "benchmarks\Neo.Benchmarks\Neo.Benchmarks.csproj", "{BCD03521-5F8F-4775-9ADF-FA361480804F}"
EndProject
Expand All @@ -18,6 +18,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{EDE05FA8
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{C25EB0B0-0CAC-4CC1-8F36-F9229EFB99EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.VM.Benchmarks", "benchmarks\Neo.VM.Benchmarks\Neo.VM.Benchmarks.csproj", "{E83633BA-FCF0-4A1A-B5BC-42000E24D437}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.VM", "src\Neo.VM\Neo.VM.csproj", "{0603710E-E0BA-494C-AA0F-6FB0C8A8C754}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.VM.Tests", "tests\Neo.VM.Tests\Neo.VM.Tests.csproj", "{005F84EB-EA2E-449F-930A-7B4173DDC7EC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -44,6 +50,18 @@ Global
{BCD03521-5F8F-4775-9ADF-FA361480804F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|Any CPU.Build.0 = Release|Any CPU
{E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Release|Any CPU.Build.0 = Release|Any CPU
{0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Release|Any CPU.Build.0 = Release|Any CPU
{005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -54,6 +72,9 @@ Global
{5B783B30-B422-4C2F-AC22-187A8D1993F4} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
{AE6C32EE-8447-4E01-8187-2AE02BB64251} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
{BCD03521-5F8F-4775-9ADF-FA361480804F} = {C25EB0B0-0CAC-4CC1-8F36-F9229EFB99EC}
{E83633BA-FCF0-4A1A-B5BC-42000E24D437} = {C25EB0B0-0CAC-4CC1-8F36-F9229EFB99EC}
{0603710E-E0BA-494C-AA0F-6FB0C8A8C754} = {B5339DF7-5D1D-43BA-B332-74B825E1770E}
{005F84EB-EA2E-449F-930A-7B4173DDC7EC} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BCBA19D9-F868-4C6D-8061-A2B91E06E3EC}
Expand Down
31 changes: 31 additions & 0 deletions src/Neo.VM/BadScriptException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (C) 2016-2023 The Neo Project.
//
// The neo-vm 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;

namespace Neo.VM
{
/// <summary>
/// Represents the exception thrown when the bad script is parsed.
/// </summary>
public class BadScriptException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="BadScriptException"/> class.
/// </summary>
public BadScriptException() { }

/// <summary>
/// Initializes a new instance of the <see cref="BadScriptException"/> class with a specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public BadScriptException(string message) : base(message) { }
}
}
21 changes: 21 additions & 0 deletions src/Neo.VM/CatchableException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2016-2023 The Neo Project.
//
// The neo-vm 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;

namespace Neo.VM
{
public class CatchableException : Exception
{
public CatchableException(string message) : base(message)
{
}
}
}
129 changes: 129 additions & 0 deletions src/Neo.VM/Collections/OrderedDictionary.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright (C) 2016-2023 The Neo Project.
//
// The neo-vm 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.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

namespace Neo.VM.Collections
{
internal class OrderedDictionary<TKey, TValue> : IDictionary<TKey, TValue>
where TKey : notnull
{
private class TItem
{
public readonly TKey Key;
public TValue Value;

public TItem(TKey key, TValue value)
{
this.Key = key;
this.Value = value;
}
}

private class InternalCollection : KeyedCollection<TKey, TItem>
{
protected override TKey GetKeyForItem(TItem item)
{
return item.Key;
}
}

private readonly InternalCollection collection = new();

public int Count => collection.Count;
public bool IsReadOnly => false;
public ICollection<TKey> Keys => collection.Select(p => p.Key).ToArray();
public ICollection<TValue> Values => collection.Select(p => p.Value).ToArray();

public TValue this[TKey key]
{
get
{
return collection[key].Value;
}
set
{
if (collection.TryGetValue(key, out var entry))
entry.Value = value;
else
Add(key, value);
}
}

public void Add(TKey key, TValue value)
{
collection.Add(new TItem(key, value));
}

public bool ContainsKey(TKey key)
{
return collection.Contains(key);
}

public bool Remove(TKey key)
{
return collection.Remove(key);
}

// supress warning of value parameter nullability mismatch
#pragma warning disable CS8767
public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
#pragma warning restore CS8767
{
if (collection.TryGetValue(key, out var entry))
{
value = entry.Value;
return true;
}
value = default;
return false;
}

void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
Add(item.Key, item.Value);
}

public void Clear()
{
collection.Clear();
}

bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
{
return collection.Contains(item.Key);
}

void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
for (int i = 0; i < collection.Count; i++)
array[i + arrayIndex] = new KeyValuePair<TKey, TValue>(collection[i].Key, collection[i].Value);
}

bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
return collection.Remove(item.Key);
}

IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
return collection.Select(p => new KeyValuePair<TKey, TValue>(p.Key, p.Value)).GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return collection.Select(p => new KeyValuePair<TKey, TValue>(p.Key, p.Value)).GetEnumerator();
}
}
}
27 changes: 27 additions & 0 deletions src/Neo.VM/Cryptography/BitOperations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2016-2023 The Neo Project.
//
// The neo-vm 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.Runtime.CompilerServices;

namespace Neo.VM.Cryptography
{
#if !NET5_0_OR_GREATER
static class BitOperations
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint RotateLeft(uint value, int offset)
=> (value << offset) | (value >> (32 - offset));

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong RotateLeft(ulong value, int offset)
=> (value << offset) | (value >> (64 - offset));
}
#endif
}
Loading