Skip to content

Commit

Permalink
Migrating Neo VM
Browse files Browse the repository at this point in the history
  • Loading branch information
lock9 committed Nov 16, 2023
1 parent 61a0665 commit d315686
Show file tree
Hide file tree
Showing 239 changed files with 49,296 additions and 2 deletions.
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

0 comments on commit d315686

Please sign in to comment.