diff --git a/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md b/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md index 9b98d24f99..4c2e7a8977 100644 --- a/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md +++ b/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md @@ -12,6 +12,10 @@ A summary of the problem you want to solve or metric you want to improve **Do you have any solution you want to propose?** A clear and concise description of what you expect with this change. +**Neo Version** +- Neo 2 +- Neo 3 + **Where in the software does this update applies to?** - Compiler - Consensus diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml new file mode 100644 index 0000000000..2aae8920e8 --- /dev/null +++ b/.github/workflows/dotnetcore.yml @@ -0,0 +1,73 @@ +name: .NET Core Test and Publish + +on: + push: + branches: master + pull_request: + +env: + DOTNET_VERSION: 3.0.100 + +jobs: + + Test: + runs-on: ubuntu-latest + steps: + - name: Chectout + uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + - name: Check format + run: | + dotnet tool install --tool-path ./ dotnet-format + ./dotnet-format --check --dry-run -v diagnostic + - name: Test + run: | + find tests -name *.csproj | xargs -I % dotnet add % package coverlet.msbuild + dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=${GITHUB_WORKSPACE}/coverage/lcov + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + PublishGithub: + if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/') + needs: Test + runs-on: ubuntu-latest + steps: + - name: Chectout + uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + - name: Setup NuGet.exe for use with actions + uses: NuGet/setup-nuget@v1 + - name: Pack with dotnet + run: git rev-list --count HEAD |xargs printf "CI%05d" |xargs dotnet pack -c Debug -o out --include-source --version-suffix + - name: Publish to Github Packages + run: | + nuget source Add -Name "GitHub" -Source "https://nuget.pkg.github.com/neo-project/index.json" -UserName neo-project -Password ${GITHUB_TOKEN} + nuget push out/*.nupkg -Source "GitHub" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + PublishMyGet: + if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/') + needs: Test + runs-on: ubuntu-latest + steps: + - name: Chectout + uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + - name: Pack with dotnet + run: git rev-list --count HEAD |xargs printf "CI%05d" |xargs dotnet pack -c Debug -o out --include-source --version-suffix + - name: Publish to MyGet + run: dotnet nuget push out/*.nupkg -s https://www.myget.org/F/neo/api/v2/package -k ${MYGET_TOKEN} -ss https://www.myget.org/F/neo/symbols/api/v2/package -sk ${MYGET_TOKEN} + env: + MYGET_TOKEN: ${{ secrets.MYGET_TOKEN }} diff --git a/.gitignore b/.gitignore index 88426a8e9b..cb49b769de 100644 --- a/.gitignore +++ b/.gitignore @@ -255,3 +255,4 @@ paket-files/ *.sln.iml PublishProfiles +/.vscode diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 59b745ca31..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,47 +0,0 @@ -language: csharp - -os: - - linux - - osx - -dist: bionic -osx_image: xcode9.1 - -mono: none -dotnet: 2.2.402 - -env: - - TEST_SUITE="without-cultures" - - TEST_SUITE="cultures" - -before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ulimit -n 2048; fi -install: - - dotnet tool install -g dotnet-format --version 4.0.40103 --add-source https://dotnet.myget.org/F/format/api/v3/index.json - - export PATH="$PATH:$HOME/.dotnet/tools" - - dotnet-format --version -before_script: - - echo "Checking format..." - - dotnet format --check --dry-run -w . -v diagnostic # check C# formatting for neo.sln - - cd neo.UnitTests -script: | - if [[ "$TEST_SUITE" == "cultures" ]]; then - dotnet test -v m --filter FullyQualifiedName=Neo.UnitTests.UT_Culture.All_Tests_Cultures - else - if [[ "$TEST_SUITE" == "without-cultures" && "$TRAVIS_OS_NAME" == "linux" ]]; then - # Test & Calculate coverage - find * -name *.csproj | xargs -I % dotnet add % package coverlet.msbuild - dotnet test -v m --filter FullyQualifiedName!=Neo.UnitTests.UT_Culture.All_Tests_Cultures /p:CollectCoverage=true /p:CoverletOutputFormat=opencover - else - # Only test - dotnet test -v m --filter FullyQualifiedName!=Neo.UnitTests.UT_Culture.All_Tests_Cultures - fi - fi -after_success: | - if [[ "$TEST_SUITE" == "without-cultures" && "$TRAVIS_OS_NAME" == "linux" ]]; then - # Send coverage - echo "Test Success - Branch($TRAVIS_BRANCH) Pull Request($TRAVIS_PULL_REQUEST) Tag($TRAVIS_TAG)" - bash <(curl -s https://codecov.io/bash) -v - fi - - diff --git a/README.md b/README.md index ac251a7a77..d567717e71 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ Current neo version. - - Current Coverage Status. + + Coverage Status License. diff --git a/neo.UnitTests/Cryptography/UT_Base58.cs b/neo.UnitTests/Cryptography/UT_Base58.cs deleted file mode 100644 index 5f2d750382..0000000000 --- a/neo.UnitTests/Cryptography/UT_Base58.cs +++ /dev/null @@ -1,31 +0,0 @@ -using FluentAssertions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.Cryptography; -using System; - -namespace Neo.UnitTests.Cryptography -{ - [TestClass] - public class UT_Base58 - { - byte[] decoded1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - string encoded1 = "1kA3B2yGe2z4"; - byte[] decoded2 = { 0, 0, 0, 0, 0 }; - string encoded2 = "1111"; - - [TestMethod] - public void TestEncode() - { - Base58.Encode(decoded1).Should().Be(encoded1); - } - - [TestMethod] - public void TestDecode() - { - Base58.Decode(encoded1).Should().BeEquivalentTo(decoded1); - Base58.Decode(encoded2).Should().BeEquivalentTo(decoded2); - Action action = () => Base58.Decode(encoded1 + "l").Should().BeEquivalentTo(decoded1); - action.Should().Throw(); - } - } -} diff --git a/neo.UnitTests/IO/Caching/UT_ReflectionCache.cs b/neo.UnitTests/IO/Caching/UT_ReflectionCache.cs deleted file mode 100644 index 4e1fcce634..0000000000 --- a/neo.UnitTests/IO/Caching/UT_ReflectionCache.cs +++ /dev/null @@ -1,80 +0,0 @@ -using FluentAssertions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.IO.Caching; -using System; - -namespace Neo.UnitTests.IO.Caching -{ - public class TestItem { } - - public class TestItem1 : TestItem { } - - public class TestItem2 : TestItem { } - - public enum MyTestEnum : byte - { - [ReflectionCache(typeof(TestItem1))] - Item1 = 0x00, - - [ReflectionCache(typeof(TestItem2))] - Item2 = 0x01, - } - - public enum MyEmptyEnum : byte { } - - [TestClass] - public class UT_ReflectionCache - { - ReflectionCache reflectionCache; - - [TestInitialize] - public void SetUp() - { - reflectionCache = ReflectionCache.CreateFromEnum(); - } - - [TestMethod] - public void TestCreateFromEnum() - { - reflectionCache.Should().NotBeNull(); - } - - [TestMethod] - public void TestCreateFromObjectNotEnum() - { - Action action = () => ReflectionCache.CreateFromEnum(); - action.Should().Throw(); - } - - [TestMethod] - public void TestCreateFromEmptyEnum() - { - reflectionCache = ReflectionCache.CreateFromEnum(); - reflectionCache.Count.Should().Be(0); - } - - [TestMethod] - public void TestCreateInstance() - { - object item1 = reflectionCache.CreateInstance((byte)MyTestEnum.Item1, null); - (item1 is TestItem1).Should().BeTrue(); - - object item2 = reflectionCache.CreateInstance((byte)MyTestEnum.Item2, null); - (item2 is TestItem2).Should().BeTrue(); - - object item3 = reflectionCache.CreateInstance(0x02, null); - item3.Should().BeNull(); - } - - [TestMethod] - public void TestCreateInstance2() - { - TestItem defaultItem = new TestItem1(); - object item2 = reflectionCache.CreateInstance((byte)MyTestEnum.Item2, defaultItem); - (item2 is TestItem2).Should().BeTrue(); - - object item1 = reflectionCache.CreateInstance(0x02, new TestItem1()); - (item1 is TestItem1).Should().BeTrue(); - } - } -} diff --git a/neo.sln b/neo.sln index fd72762fc2..79e13f0185 100644 --- a/neo.sln +++ b/neo.sln @@ -1,11 +1,14 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26430.15 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29519.87 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "neo", "neo\neo.csproj", "{36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "neo", "src\neo\neo.csproj", "{36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "neo.UnitTests", "neo.UnitTests\neo.UnitTests.csproj", "{5B783B30-B422-4C2F-AC22-187A8D1993F4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "neo.UnitTests", "tests\neo.UnitTests\neo.UnitTests.csproj", "{5B783B30-B422-4C2F-AC22-187A8D1993F4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B5339DF7-5D1D-43BA-B332-74B825E1770E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{EDE05FA8-8E73-4924-BC63-DD117127EEE1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -25,4 +28,11 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC} = {B5339DF7-5D1D-43BA-B332-74B825E1770E} + {5B783B30-B422-4C2F-AC22-187A8D1993F4} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BCBA19D9-F868-4C6D-8061-A2B91E06E3EC} + EndGlobalSection EndGlobal diff --git a/neo/Cryptography/Base58.cs b/neo/Cryptography/Base58.cs deleted file mode 100644 index b64f12216b..0000000000 --- a/neo/Cryptography/Base58.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Linq; -using System.Numerics; -using System.Text; - -namespace Neo.Cryptography -{ - public static class Base58 - { - public const string Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; - - public static byte[] Decode(string input) - { - BigInteger bi = BigInteger.Zero; - for (int i = input.Length - 1; i >= 0; i--) - { - int index = Alphabet.IndexOf(input[i]); - if (index == -1) - throw new FormatException(); - bi += index * BigInteger.Pow(58, input.Length - 1 - i); - } - byte[] bytes = bi.ToByteArray(); - Array.Reverse(bytes); - bool stripSignByte = bytes.Length > 1 && bytes[0] == 0 && bytes[1] >= 0x80; - int leadingZeros = 0; - for (int i = 0; i < input.Length && input[i] == Alphabet[0]; i++) - { - leadingZeros++; - } - byte[] tmp = new byte[bytes.Length - (stripSignByte ? 1 : 0) + leadingZeros]; - Array.Copy(bytes, stripSignByte ? 1 : 0, tmp, leadingZeros, tmp.Length - leadingZeros); - Array.Clear(bytes, 0, bytes.Length); - return tmp; - } - - public static string Encode(byte[] input) - { - BigInteger value = new BigInteger(new byte[1].Concat(input).Reverse().ToArray()); - StringBuilder sb = new StringBuilder(); - while (value >= 58) - { - BigInteger mod = value % 58; - sb.Insert(0, Alphabet[(int)mod]); - value /= 58; - } - sb.Insert(0, Alphabet[(int)value]); - foreach (byte b in input) - { - if (b == 0) - sb.Insert(0, Alphabet[0]); - else - break; - } - return sb.ToString(); - } - } -} diff --git a/neo/IO/Caching/ReflectionCache.cs b/neo/IO/Caching/ReflectionCache.cs deleted file mode 100644 index 452856698c..0000000000 --- a/neo/IO/Caching/ReflectionCache.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; - -namespace Neo.IO.Caching -{ - public class ReflectionCache : Dictionary - { - /// - /// Constructor - /// - public ReflectionCache() { } - /// - /// Constructor - /// - /// Enum type - public static ReflectionCache CreateFromEnum() where EnumType : struct, IConvertible - { - Type enumType = typeof(EnumType); - - if (!enumType.GetTypeInfo().IsEnum) - throw new ArgumentException("K must be an enumerated type"); - - // Cache all types - ReflectionCache r = new ReflectionCache(); - - foreach (object t in Enum.GetValues(enumType)) - { - // Get enumn member - MemberInfo[] memInfo = enumType.GetMember(t.ToString()); - if (memInfo == null || memInfo.Length != 1) - throw (new FormatException()); - - // Get attribute - ReflectionCacheAttribute attribute = memInfo[0].GetCustomAttributes(typeof(ReflectionCacheAttribute), false) - .Cast() - .FirstOrDefault(); - - if (attribute == null) - throw (new FormatException()); - - // Append to cache - r.Add((T)t, attribute.Type); - } - return r; - } - /// - /// Create object from key - /// - /// Key - /// Default value - public object CreateInstance(T key, object def = null) - { - Type tp; - - // Get Type from cache - if (TryGetValue(key, out tp)) return Activator.CreateInstance(tp); - - // return null - return def; - } - /// - /// Create object from key - /// - /// Type - /// Key - /// Default value - public K CreateInstance(T key, K def = default(K)) - { - Type tp; - - // Get Type from cache - if (TryGetValue(key, out tp)) return (K)Activator.CreateInstance(tp); - - // return null - return def; - } - } -} diff --git a/neo/Network/P2P/MessageCommand.cs b/neo/Network/P2P/MessageCommand.cs deleted file mode 100644 index d1f2befc67..0000000000 --- a/neo/Network/P2P/MessageCommand.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Neo.Network.P2P -{ - public enum MessageCommand : byte - { - //handshaking - Version = 0x00, - Verack = 0x01, - - //connectivity - GetAddr = 0x10, - Addr = 0x11, - Ping = 0x18, - Pong = 0x19, - - //synchronization - GetHeaders = 0x20, - Headers = 0x21, - GetBlocks = 0x24, - Mempool = 0x25, - Inv = 0x27, - GetData = 0x28, - GetBlockData = 0x29, - NotFound = 0x2a, - Transaction = 0x2b, - Block = 0x2c, - Consensus = 0x2d, - Reject = 0x2f, - - //SPV protocol - FilterLoad = 0x30, - FilterAdd = 0x31, - FilterClear = 0x32, - MerkleBlock = 0x38, - - //others - Alert = 0x40, - } -} diff --git a/neo/BigDecimal.cs b/src/neo/BigDecimal.cs similarity index 100% rename from neo/BigDecimal.cs rename to src/neo/BigDecimal.cs diff --git a/neo/Consensus/ChangeView.cs b/src/neo/Consensus/ChangeView.cs similarity index 100% rename from neo/Consensus/ChangeView.cs rename to src/neo/Consensus/ChangeView.cs diff --git a/neo/Consensus/ChangeViewReason.cs b/src/neo/Consensus/ChangeViewReason.cs similarity index 100% rename from neo/Consensus/ChangeViewReason.cs rename to src/neo/Consensus/ChangeViewReason.cs diff --git a/neo/Consensus/Commit.cs b/src/neo/Consensus/Commit.cs similarity index 100% rename from neo/Consensus/Commit.cs rename to src/neo/Consensus/Commit.cs diff --git a/neo/Consensus/ConsensusContext.cs b/src/neo/Consensus/ConsensusContext.cs similarity index 99% rename from neo/Consensus/ConsensusContext.cs rename to src/neo/Consensus/ConsensusContext.cs index e7c2649782..d05b4a64ea 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/src/neo/Consensus/ConsensusContext.cs @@ -82,6 +82,7 @@ public ConsensusContext(Wallet wallet, Store store) public Block CreateBlock() { + EnsureHeader(); Contract contract = Contract.CreateMultiSigContract(M, Validators); ContractParametersContext sc = new ContractParametersContext(Block); for (int i = 0, j = 0; i < Validators.Length && j < M; i++) diff --git a/neo/Consensus/ConsensusMessage.cs b/src/neo/Consensus/ConsensusMessage.cs similarity index 60% rename from neo/Consensus/ConsensusMessage.cs rename to src/neo/Consensus/ConsensusMessage.cs index af16db03e3..0bca5534e1 100644 --- a/neo/Consensus/ConsensusMessage.cs +++ b/src/neo/Consensus/ConsensusMessage.cs @@ -7,11 +7,6 @@ namespace Neo.Consensus { public abstract class ConsensusMessage : ISerializable { - /// - /// Reflection cache for ConsensusMessageType - /// - private static ReflectionCache ReflectionCache = ReflectionCache.CreateFromEnum(); - public readonly ConsensusMessageType Type; public byte ViewNumber; @@ -31,15 +26,10 @@ public virtual void Deserialize(BinaryReader reader) public static ConsensusMessage DeserializeFrom(byte[] data) { - ConsensusMessage message = ReflectionCache.CreateInstance(data[0]); - if (message == null) throw new FormatException(); - - using (MemoryStream ms = new MemoryStream(data, false)) - using (BinaryReader r = new BinaryReader(ms)) - { - message.Deserialize(r); - } - return message; + ConsensusMessageType type = (ConsensusMessageType)data[0]; + ISerializable message = ReflectionCache.CreateSerializable(type, data); + if (message is null) throw new FormatException(); + return (ConsensusMessage)message; } public virtual void Serialize(BinaryWriter writer) diff --git a/neo/Consensus/ConsensusMessageType.cs b/src/neo/Consensus/ConsensusMessageType.cs similarity index 100% rename from neo/Consensus/ConsensusMessageType.cs rename to src/neo/Consensus/ConsensusMessageType.cs diff --git a/neo/Consensus/ConsensusService.cs b/src/neo/Consensus/ConsensusService.cs similarity index 99% rename from neo/Consensus/ConsensusService.cs rename to src/neo/Consensus/ConsensusService.cs index 574082043a..9d0bd5a343 100644 --- a/neo/Consensus/ConsensusService.cs +++ b/src/neo/Consensus/ConsensusService.cs @@ -405,7 +405,7 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m if (context.RequestSentOrReceived || context.NotAcceptingPayloadsDueToViewChanging) return; if (payload.ValidatorIndex != context.Block.ConsensusData.PrimaryIndex || message.ViewNumber != context.ViewNumber) return; Log($"{nameof(OnPrepareRequestReceived)}: height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex} tx={message.TransactionHashes.Length}"); - if (message.Timestamp <= context.PrevHeader.Timestamp || message.Timestamp > TimeProvider.Current.UtcNow.AddMinutes(10).ToTimestampMS()) + if (message.Timestamp <= context.PrevHeader.Timestamp || message.Timestamp > TimeProvider.Current.UtcNow.AddMilliseconds(8 * Blockchain.MillisecondsPerBlock).ToTimestampMS()) { Log($"Timestamp incorrect: {message.Timestamp}", LogLevel.Warning); return; diff --git a/neo/Consensus/PrepareRequest.cs b/src/neo/Consensus/PrepareRequest.cs similarity index 100% rename from neo/Consensus/PrepareRequest.cs rename to src/neo/Consensus/PrepareRequest.cs diff --git a/neo/Consensus/PrepareResponse.cs b/src/neo/Consensus/PrepareResponse.cs similarity index 100% rename from neo/Consensus/PrepareResponse.cs rename to src/neo/Consensus/PrepareResponse.cs diff --git a/neo/Consensus/RecoveryMessage.ChangeViewPayloadCompact.cs b/src/neo/Consensus/RecoveryMessage.ChangeViewPayloadCompact.cs similarity index 100% rename from neo/Consensus/RecoveryMessage.ChangeViewPayloadCompact.cs rename to src/neo/Consensus/RecoveryMessage.ChangeViewPayloadCompact.cs diff --git a/neo/Consensus/RecoveryMessage.CommitPayloadCompact.cs b/src/neo/Consensus/RecoveryMessage.CommitPayloadCompact.cs similarity index 100% rename from neo/Consensus/RecoveryMessage.CommitPayloadCompact.cs rename to src/neo/Consensus/RecoveryMessage.CommitPayloadCompact.cs diff --git a/neo/Consensus/RecoveryMessage.PreparationPayloadCompact.cs b/src/neo/Consensus/RecoveryMessage.PreparationPayloadCompact.cs similarity index 100% rename from neo/Consensus/RecoveryMessage.PreparationPayloadCompact.cs rename to src/neo/Consensus/RecoveryMessage.PreparationPayloadCompact.cs diff --git a/neo/Consensus/RecoveryMessage.cs b/src/neo/Consensus/RecoveryMessage.cs similarity index 100% rename from neo/Consensus/RecoveryMessage.cs rename to src/neo/Consensus/RecoveryMessage.cs diff --git a/neo/Consensus/RecoveryRequest.cs b/src/neo/Consensus/RecoveryRequest.cs similarity index 100% rename from neo/Consensus/RecoveryRequest.cs rename to src/neo/Consensus/RecoveryRequest.cs diff --git a/src/neo/Cryptography/Base58.cs b/src/neo/Cryptography/Base58.cs new file mode 100644 index 0000000000..9ddbea3dc8 --- /dev/null +++ b/src/neo/Cryptography/Base58.cs @@ -0,0 +1,56 @@ +using System; +using System.Linq; +using System.Numerics; +using System.Text; + +namespace Neo.Cryptography +{ + public static class Base58 + { + public const string Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + + public static byte[] Decode(string input) + { + // Decode Base58 string to BigInteger + var bi = BigInteger.Zero; + for (int i = 0; i < input.Length; i++) + { + int digit = Alphabet.IndexOf(input[i]); + if (digit < 0) + throw new FormatException($"Invalid Base58 character '{input[i]}' at position {i}"); + bi = bi * Alphabet.Length + digit; + } + + // Encode BigInteger to byte[] + // Leading zero bytes get encoded as leading `1` characters + int leadingZeroCount = input.TakeWhile(c => c == Alphabet[0]).Count(); + var leadingZeros = new byte[leadingZeroCount]; + var bytesWithoutLeadingZeros = bi.ToByteArray() + .Reverse()// to big endian + .SkipWhile(b => b == 0);//strip sign byte + return leadingZeros.Concat(bytesWithoutLeadingZeros).ToArray(); + } + + public static string Encode(byte[] input) + { + // Decode byte[] to BigInteger + BigInteger value = new BigInteger(new byte[1].Concat(input).Reverse().ToArray()); + + // Encode BigInteger to Base58 string + var sb = new StringBuilder(); + + while (value > 0) + { + value = BigInteger.DivRem(value, Alphabet.Length, out var remainder); + sb.Insert(0, Alphabet[(int)remainder]); + } + + // Append `1` for each leading 0 byte + for (int i = 0; i < input.Length && input[i] == 0; i++) + { + sb.Insert(0, Alphabet[0]); + } + return sb.ToString(); + } + } +} diff --git a/neo/Cryptography/BloomFilter.cs b/src/neo/Cryptography/BloomFilter.cs similarity index 100% rename from neo/Cryptography/BloomFilter.cs rename to src/neo/Cryptography/BloomFilter.cs diff --git a/neo/Cryptography/Crypto.cs b/src/neo/Cryptography/Crypto.cs similarity index 100% rename from neo/Cryptography/Crypto.cs rename to src/neo/Cryptography/Crypto.cs diff --git a/neo/Cryptography/ECC/ECCurve.cs b/src/neo/Cryptography/ECC/ECCurve.cs similarity index 100% rename from neo/Cryptography/ECC/ECCurve.cs rename to src/neo/Cryptography/ECC/ECCurve.cs diff --git a/neo/Cryptography/ECC/ECDsa.cs b/src/neo/Cryptography/ECC/ECDsa.cs similarity index 100% rename from neo/Cryptography/ECC/ECDsa.cs rename to src/neo/Cryptography/ECC/ECDsa.cs diff --git a/neo/Cryptography/ECC/ECFieldElement.cs b/src/neo/Cryptography/ECC/ECFieldElement.cs similarity index 100% rename from neo/Cryptography/ECC/ECFieldElement.cs rename to src/neo/Cryptography/ECC/ECFieldElement.cs diff --git a/neo/Cryptography/ECC/ECPoint.cs b/src/neo/Cryptography/ECC/ECPoint.cs similarity index 100% rename from neo/Cryptography/ECC/ECPoint.cs rename to src/neo/Cryptography/ECC/ECPoint.cs diff --git a/neo/Cryptography/Helper.cs b/src/neo/Cryptography/Helper.cs similarity index 100% rename from neo/Cryptography/Helper.cs rename to src/neo/Cryptography/Helper.cs diff --git a/neo/Cryptography/MerkleTree.cs b/src/neo/Cryptography/MerkleTree.cs similarity index 100% rename from neo/Cryptography/MerkleTree.cs rename to src/neo/Cryptography/MerkleTree.cs diff --git a/neo/Cryptography/MerkleTreeNode.cs b/src/neo/Cryptography/MerkleTreeNode.cs similarity index 100% rename from neo/Cryptography/MerkleTreeNode.cs rename to src/neo/Cryptography/MerkleTreeNode.cs diff --git a/neo/Cryptography/Murmur3.cs b/src/neo/Cryptography/Murmur3.cs similarity index 100% rename from neo/Cryptography/Murmur3.cs rename to src/neo/Cryptography/Murmur3.cs diff --git a/neo/Cryptography/RIPEMD160Managed.cs b/src/neo/Cryptography/RIPEMD160Managed.cs similarity index 99% rename from neo/Cryptography/RIPEMD160Managed.cs rename to src/neo/Cryptography/RIPEMD160Managed.cs index 22ffafb835..89a4de23c8 100644 --- a/neo/Cryptography/RIPEMD160Managed.cs +++ b/src/neo/Cryptography/RIPEMD160Managed.cs @@ -1,4 +1,3 @@ -#if !NET47 using System; using System.Runtime.InteropServices; using System.Security; @@ -1051,4 +1050,3 @@ private static void DWORDToLittleEndian(byte[] block, uint[] x, int digits) } } } -#endif diff --git a/neo/Cryptography/SCrypt.cs b/src/neo/Cryptography/SCrypt.cs similarity index 97% rename from neo/Cryptography/SCrypt.cs rename to src/neo/Cryptography/SCrypt.cs index e40c2c83c5..4e6f3bc389 100644 --- a/neo/Cryptography/SCrypt.cs +++ b/src/neo/Cryptography/SCrypt.cs @@ -245,12 +245,6 @@ private unsafe static void SMix(byte* B, int r, int N, uint* V, uint* XY) } } -#if NET47 - public static byte[] DeriveKey(byte[] password, byte[] salt, int N, int r, int p, int derivedKeyLength) - { - return Replicon.Cryptography.SCrypt.SCrypt.DeriveKey(password, salt, (ulong)N, (uint)r, (uint)p, (uint)derivedKeyLength); - } -#else public unsafe static byte[] DeriveKey(byte[] password, byte[] salt, int N, int r, int p, int derivedKeyLength) { var Ba = new byte[128 * r * p + 63]; @@ -280,7 +274,6 @@ public unsafe static byte[] DeriveKey(byte[] password, byte[] salt, int N, int r return buf; } -#endif private static void PBKDF2_SHA256(HMACSHA256 mac, byte[] password, byte[] salt, int saltLength, long iterationCount, byte[] derivedKey, int derivedKeyLength) { diff --git a/neo/Helper.cs b/src/neo/Helper.cs similarity index 97% rename from neo/Helper.cs rename to src/neo/Helper.cs index fa3b384a35..8fa7005f5e 100644 --- a/neo/Helper.cs +++ b/src/neo/Helper.cs @@ -186,6 +186,14 @@ public static string ToHexString(this IEnumerable value) return sb.ToString(); } + public static string ToHexString(this ReadOnlySpan value) + { + StringBuilder sb = new StringBuilder(); + foreach (byte b in value) + sb.AppendFormat("{0:x2}", b); + return sb.ToString(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] unsafe internal static int ToInt32(this byte[] value, int startIndex) { diff --git a/neo/IO/Actors/Idle.cs b/src/neo/IO/Actors/Idle.cs similarity index 100% rename from neo/IO/Actors/Idle.cs rename to src/neo/IO/Actors/Idle.cs diff --git a/neo/IO/Actors/PriorityMailbox.cs b/src/neo/IO/Actors/PriorityMailbox.cs similarity index 100% rename from neo/IO/Actors/PriorityMailbox.cs rename to src/neo/IO/Actors/PriorityMailbox.cs diff --git a/neo/IO/Actors/PriorityMessageQueue.cs b/src/neo/IO/Actors/PriorityMessageQueue.cs similarity index 100% rename from neo/IO/Actors/PriorityMessageQueue.cs rename to src/neo/IO/Actors/PriorityMessageQueue.cs diff --git a/neo/IO/ByteArrayComparer.cs b/src/neo/IO/ByteArrayComparer.cs similarity index 100% rename from neo/IO/ByteArrayComparer.cs rename to src/neo/IO/ByteArrayComparer.cs diff --git a/neo/IO/Caching/Cache.cs b/src/neo/IO/Caching/Cache.cs similarity index 100% rename from neo/IO/Caching/Cache.cs rename to src/neo/IO/Caching/Cache.cs diff --git a/neo/IO/Caching/CloneCache.cs b/src/neo/IO/Caching/CloneCache.cs similarity index 100% rename from neo/IO/Caching/CloneCache.cs rename to src/neo/IO/Caching/CloneCache.cs diff --git a/neo/IO/Caching/CloneMetaCache.cs b/src/neo/IO/Caching/CloneMetaCache.cs similarity index 100% rename from neo/IO/Caching/CloneMetaCache.cs rename to src/neo/IO/Caching/CloneMetaCache.cs diff --git a/neo/IO/Caching/DataCache.cs b/src/neo/IO/Caching/DataCache.cs similarity index 100% rename from neo/IO/Caching/DataCache.cs rename to src/neo/IO/Caching/DataCache.cs diff --git a/neo/IO/Caching/FIFOCache.cs b/src/neo/IO/Caching/FIFOCache.cs similarity index 100% rename from neo/IO/Caching/FIFOCache.cs rename to src/neo/IO/Caching/FIFOCache.cs diff --git a/neo/IO/Caching/FIFOSet.cs b/src/neo/IO/Caching/FIFOSet.cs similarity index 100% rename from neo/IO/Caching/FIFOSet.cs rename to src/neo/IO/Caching/FIFOSet.cs diff --git a/neo/IO/Caching/MetaDataCache.cs b/src/neo/IO/Caching/MetaDataCache.cs similarity index 100% rename from neo/IO/Caching/MetaDataCache.cs rename to src/neo/IO/Caching/MetaDataCache.cs diff --git a/neo/IO/Caching/OrderedDictionary.cs b/src/neo/IO/Caching/OrderedDictionary.cs similarity index 100% rename from neo/IO/Caching/OrderedDictionary.cs rename to src/neo/IO/Caching/OrderedDictionary.cs diff --git a/src/neo/IO/Caching/ReflectionCache.cs b/src/neo/IO/Caching/ReflectionCache.cs new file mode 100644 index 0000000000..e0b92b2a92 --- /dev/null +++ b/src/neo/IO/Caching/ReflectionCache.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Neo.IO.Caching +{ + internal static class ReflectionCache where T : Enum + { + private static readonly Dictionary dictionary = new Dictionary(); + + public static int Count => dictionary.Count; + + static ReflectionCache() + { + Type enumType = typeof(T); + foreach (FieldInfo field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static)) + { + // Get attribute + ReflectionCacheAttribute attribute = field.GetCustomAttribute(); + if (attribute == null) continue; + + // Append to cache + dictionary.Add((T)field.GetValue(null), attribute.Type); + } + } + + public static object CreateInstance(T key, object def = null) + { + // Get Type from cache + if (dictionary.TryGetValue(key, out Type t)) + return Activator.CreateInstance(t); + + // return null + return def; + } + + public static ISerializable CreateSerializable(T key, byte[] data) + { + if (dictionary.TryGetValue(key, out Type t)) + return data.AsSerializable(t); + return null; + } + } +} diff --git a/neo/IO/Caching/ReflectionCacheAttribute.cs b/src/neo/IO/Caching/ReflectionCacheAttribute.cs similarity index 67% rename from neo/IO/Caching/ReflectionCacheAttribute.cs rename to src/neo/IO/Caching/ReflectionCacheAttribute.cs index b2ac3c3054..2bbbca8568 100644 --- a/neo/IO/Caching/ReflectionCacheAttribute.cs +++ b/src/neo/IO/Caching/ReflectionCacheAttribute.cs @@ -2,12 +2,13 @@ namespace Neo.IO.Caching { - public class ReflectionCacheAttribute : Attribute + [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] + internal class ReflectionCacheAttribute : Attribute { /// /// Type /// - public Type Type { get; private set; } + public Type Type { get; } /// /// Constructor diff --git a/neo/IO/Caching/RelayCache.cs b/src/neo/IO/Caching/RelayCache.cs similarity index 100% rename from neo/IO/Caching/RelayCache.cs rename to src/neo/IO/Caching/RelayCache.cs diff --git a/neo/IO/Caching/TrackState.cs b/src/neo/IO/Caching/TrackState.cs similarity index 100% rename from neo/IO/Caching/TrackState.cs rename to src/neo/IO/Caching/TrackState.cs diff --git a/neo/IO/Data/LevelDB/DB.cs b/src/neo/IO/Data/LevelDB/DB.cs similarity index 100% rename from neo/IO/Data/LevelDB/DB.cs rename to src/neo/IO/Data/LevelDB/DB.cs diff --git a/neo/IO/Data/LevelDB/Helper.cs b/src/neo/IO/Data/LevelDB/Helper.cs similarity index 100% rename from neo/IO/Data/LevelDB/Helper.cs rename to src/neo/IO/Data/LevelDB/Helper.cs diff --git a/neo/IO/Data/LevelDB/Iterator.cs b/src/neo/IO/Data/LevelDB/Iterator.cs similarity index 100% rename from neo/IO/Data/LevelDB/Iterator.cs rename to src/neo/IO/Data/LevelDB/Iterator.cs diff --git a/neo/IO/Data/LevelDB/LevelDBException.cs b/src/neo/IO/Data/LevelDB/LevelDBException.cs similarity index 100% rename from neo/IO/Data/LevelDB/LevelDBException.cs rename to src/neo/IO/Data/LevelDB/LevelDBException.cs diff --git a/neo/IO/Data/LevelDB/Native.cs b/src/neo/IO/Data/LevelDB/Native.cs similarity index 97% rename from neo/IO/Data/LevelDB/Native.cs rename to src/neo/IO/Data/LevelDB/Native.cs index 6a19ef4cfe..c83d3913f8 100644 --- a/neo/IO/Data/LevelDB/Native.cs +++ b/src/neo/IO/Data/LevelDB/Native.cs @@ -12,17 +12,6 @@ public enum CompressionType : byte public static class Native { -#if NET47 - static Native() - { - string platform = IntPtr.Size == 8 ? "x64" : "x86"; - LoadLibrary(Path.Combine(AppContext.BaseDirectory, platform, "libleveldb")); - } - - [DllImport("kernel32")] - private static extern IntPtr LoadLibrary(string dllToLoad); -#endif - #region Logger [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr leveldb_logger_create(IntPtr /* Action */ logger); diff --git a/neo/IO/Data/LevelDB/Options.cs b/src/neo/IO/Data/LevelDB/Options.cs similarity index 100% rename from neo/IO/Data/LevelDB/Options.cs rename to src/neo/IO/Data/LevelDB/Options.cs diff --git a/neo/IO/Data/LevelDB/ReadOptions.cs b/src/neo/IO/Data/LevelDB/ReadOptions.cs similarity index 100% rename from neo/IO/Data/LevelDB/ReadOptions.cs rename to src/neo/IO/Data/LevelDB/ReadOptions.cs diff --git a/neo/IO/Data/LevelDB/Slice.cs b/src/neo/IO/Data/LevelDB/Slice.cs similarity index 100% rename from neo/IO/Data/LevelDB/Slice.cs rename to src/neo/IO/Data/LevelDB/Slice.cs diff --git a/neo/IO/Data/LevelDB/SliceBuilder.cs b/src/neo/IO/Data/LevelDB/SliceBuilder.cs similarity index 100% rename from neo/IO/Data/LevelDB/SliceBuilder.cs rename to src/neo/IO/Data/LevelDB/SliceBuilder.cs diff --git a/neo/IO/Data/LevelDB/Snapshot.cs b/src/neo/IO/Data/LevelDB/Snapshot.cs similarity index 100% rename from neo/IO/Data/LevelDB/Snapshot.cs rename to src/neo/IO/Data/LevelDB/Snapshot.cs diff --git a/neo/IO/Data/LevelDB/WriteBatch.cs b/src/neo/IO/Data/LevelDB/WriteBatch.cs similarity index 100% rename from neo/IO/Data/LevelDB/WriteBatch.cs rename to src/neo/IO/Data/LevelDB/WriteBatch.cs diff --git a/neo/IO/Data/LevelDB/WriteOptions.cs b/src/neo/IO/Data/LevelDB/WriteOptions.cs similarity index 100% rename from neo/IO/Data/LevelDB/WriteOptions.cs rename to src/neo/IO/Data/LevelDB/WriteOptions.cs diff --git a/neo/IO/Helper.cs b/src/neo/IO/Helper.cs similarity index 90% rename from neo/IO/Helper.cs rename to src/neo/IO/Helper.cs index c47878579d..adba79fad6 100644 --- a/neo/IO/Helper.cs +++ b/src/neo/IO/Helper.cs @@ -21,6 +21,17 @@ public static class Helper } } + public static unsafe T AsSerializable(this ReadOnlySpan value) where T : ISerializable, new() + { + if (value.IsEmpty) throw new FormatException(); + fixed (byte* pointer = value) + { + using UnmanagedMemoryStream ms = new UnmanagedMemoryStream(pointer, value.Length); + using BinaryReader reader = new BinaryReader(ms, Encoding.UTF8); + return reader.ReadSerializable(); + } + } + public static ISerializable AsSerializable(this byte[] value, Type type) { if (!typeof(ISerializable).GetTypeInfo().IsAssignableFrom(type)) @@ -43,6 +54,17 @@ public static ISerializable AsSerializable(this byte[] value, Type type) } } + public static unsafe T[] AsSerializableArray(this ReadOnlySpan value, int max = 0x1000000) where T : ISerializable, new() + { + if (value.IsEmpty) throw new FormatException(); + fixed (byte* pointer = value) + { + using UnmanagedMemoryStream ms = new UnmanagedMemoryStream(pointer, value.Length); + using BinaryReader reader = new BinaryReader(ms, Encoding.UTF8); + return reader.ReadSerializableArray(max); + } + } + public static int GetVarSize(int value) { if (value < 0xFD) @@ -245,7 +267,7 @@ public static void WriteNullableArray(this BinaryWriter writer, T[] value) wh } } - public static void WriteVarBytes(this BinaryWriter writer, byte[] value) + public static void WriteVarBytes(this BinaryWriter writer, ReadOnlySpan value) { writer.WriteVarInt(value.Length); writer.Write(value); diff --git a/neo/IO/ICloneable.cs b/src/neo/IO/ICloneable.cs similarity index 100% rename from neo/IO/ICloneable.cs rename to src/neo/IO/ICloneable.cs diff --git a/neo/IO/ISerializable.cs b/src/neo/IO/ISerializable.cs similarity index 100% rename from neo/IO/ISerializable.cs rename to src/neo/IO/ISerializable.cs diff --git a/neo/IO/Json/JArray.cs b/src/neo/IO/Json/JArray.cs similarity index 100% rename from neo/IO/Json/JArray.cs rename to src/neo/IO/Json/JArray.cs diff --git a/neo/IO/Json/JBoolean.cs b/src/neo/IO/Json/JBoolean.cs similarity index 100% rename from neo/IO/Json/JBoolean.cs rename to src/neo/IO/Json/JBoolean.cs diff --git a/neo/IO/Json/JNumber.cs b/src/neo/IO/Json/JNumber.cs similarity index 100% rename from neo/IO/Json/JNumber.cs rename to src/neo/IO/Json/JNumber.cs diff --git a/neo/IO/Json/JObject.cs b/src/neo/IO/Json/JObject.cs similarity index 100% rename from neo/IO/Json/JObject.cs rename to src/neo/IO/Json/JObject.cs diff --git a/neo/IO/Json/JString.cs b/src/neo/IO/Json/JString.cs similarity index 100% rename from neo/IO/Json/JString.cs rename to src/neo/IO/Json/JString.cs diff --git a/neo/IO/Wrappers/SerializableWrapper.cs b/src/neo/IO/Wrappers/SerializableWrapper.cs similarity index 100% rename from neo/IO/Wrappers/SerializableWrapper.cs rename to src/neo/IO/Wrappers/SerializableWrapper.cs diff --git a/neo/IO/Wrappers/UInt32Wrapper.cs b/src/neo/IO/Wrappers/UInt32Wrapper.cs similarity index 100% rename from neo/IO/Wrappers/UInt32Wrapper.cs rename to src/neo/IO/Wrappers/UInt32Wrapper.cs diff --git a/neo/Ledger/Blockchain.ApplicationExecuted.cs b/src/neo/Ledger/Blockchain.ApplicationExecuted.cs similarity index 98% rename from neo/Ledger/Blockchain.ApplicationExecuted.cs rename to src/neo/Ledger/Blockchain.ApplicationExecuted.cs index 1bcc65563f..8134a1bd13 100644 --- a/neo/Ledger/Blockchain.ApplicationExecuted.cs +++ b/src/neo/Ledger/Blockchain.ApplicationExecuted.cs @@ -1,6 +1,7 @@ using Neo.Network.P2P.Payloads; using Neo.SmartContract; using Neo.VM; +using Neo.VM.Types; using System.Linq; namespace Neo.Ledger diff --git a/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs similarity index 100% rename from neo/Ledger/Blockchain.cs rename to src/neo/Ledger/Blockchain.cs diff --git a/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs similarity index 100% rename from neo/Ledger/ContractState.cs rename to src/neo/Ledger/ContractState.cs diff --git a/neo/Ledger/HashIndexState.cs b/src/neo/Ledger/HashIndexState.cs similarity index 100% rename from neo/Ledger/HashIndexState.cs rename to src/neo/Ledger/HashIndexState.cs diff --git a/neo/Ledger/HeaderHashList.cs b/src/neo/Ledger/HeaderHashList.cs similarity index 100% rename from neo/Ledger/HeaderHashList.cs rename to src/neo/Ledger/HeaderHashList.cs diff --git a/neo/Ledger/MemoryPool.cs b/src/neo/Ledger/MemoryPool.cs similarity index 99% rename from neo/Ledger/MemoryPool.cs rename to src/neo/Ledger/MemoryPool.cs index 15c647f163..78df9b97f6 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/src/neo/Ledger/MemoryPool.cs @@ -417,7 +417,10 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, foreach (PoolItem item in unverifiedSortedTxPool.Reverse().Take(count)) { if (item.Tx.Reverify(snapshot, SendersFeeMonitor.GetSenderFee(item.Tx.Sender))) + { reverifiedItems.Add(item); + SendersFeeMonitor.AddSenderFee(item.Tx); + } else // Transaction no longer valid -- it will be removed from unverifiedTxPool. invalidItems.Add(item); @@ -438,7 +441,6 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, { if (_unsortedTransactions.TryAdd(item.Tx.Hash, item)) { - SendersFeeMonitor.AddSenderFee(item.Tx); verifiedSortedTxPool.Add(item); if (item.LastBroadcastTimestamp < rebroadcastCutOffTime) @@ -447,6 +449,8 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, item.LastBroadcastTimestamp = DateTime.UtcNow; } } + else + SendersFeeMonitor.RemoveSenderFee(item.Tx); _unverifiedTransactions.Remove(item.Tx.Hash); unverifiedSortedTxPool.Remove(item); diff --git a/neo/Ledger/PoolItem.cs b/src/neo/Ledger/PoolItem.cs similarity index 100% rename from neo/Ledger/PoolItem.cs rename to src/neo/Ledger/PoolItem.cs diff --git a/neo/Ledger/RelayResultReason.cs b/src/neo/Ledger/RelayResultReason.cs similarity index 100% rename from neo/Ledger/RelayResultReason.cs rename to src/neo/Ledger/RelayResultReason.cs diff --git a/neo/Ledger/SendersFeeMonitor.cs b/src/neo/Ledger/SendersFeeMonitor.cs similarity index 100% rename from neo/Ledger/SendersFeeMonitor.cs rename to src/neo/Ledger/SendersFeeMonitor.cs diff --git a/neo/Ledger/StorageFlags.cs b/src/neo/Ledger/StorageFlags.cs similarity index 100% rename from neo/Ledger/StorageFlags.cs rename to src/neo/Ledger/StorageFlags.cs diff --git a/neo/Ledger/StorageItem.cs b/src/neo/Ledger/StorageItem.cs similarity index 100% rename from neo/Ledger/StorageItem.cs rename to src/neo/Ledger/StorageItem.cs diff --git a/neo/Ledger/StorageKey.cs b/src/neo/Ledger/StorageKey.cs similarity index 100% rename from neo/Ledger/StorageKey.cs rename to src/neo/Ledger/StorageKey.cs diff --git a/neo/Ledger/TransactionState.cs b/src/neo/Ledger/TransactionState.cs similarity index 100% rename from neo/Ledger/TransactionState.cs rename to src/neo/Ledger/TransactionState.cs diff --git a/neo/Ledger/TrimmedBlock.cs b/src/neo/Ledger/TrimmedBlock.cs similarity index 100% rename from neo/Ledger/TrimmedBlock.cs rename to src/neo/Ledger/TrimmedBlock.cs diff --git a/neo/NeoSystem.cs b/src/neo/NeoSystem.cs similarity index 100% rename from neo/NeoSystem.cs rename to src/neo/NeoSystem.cs diff --git a/neo/Network/P2P/Capabilities/FullNodeCapability.cs b/src/neo/Network/P2P/Capabilities/FullNodeCapability.cs similarity index 100% rename from neo/Network/P2P/Capabilities/FullNodeCapability.cs rename to src/neo/Network/P2P/Capabilities/FullNodeCapability.cs diff --git a/neo/Network/P2P/Capabilities/NodeCapability.cs b/src/neo/Network/P2P/Capabilities/NodeCapability.cs similarity index 100% rename from neo/Network/P2P/Capabilities/NodeCapability.cs rename to src/neo/Network/P2P/Capabilities/NodeCapability.cs diff --git a/neo/Network/P2P/Capabilities/NodeCapabilityType.cs b/src/neo/Network/P2P/Capabilities/NodeCapabilityType.cs similarity index 100% rename from neo/Network/P2P/Capabilities/NodeCapabilityType.cs rename to src/neo/Network/P2P/Capabilities/NodeCapabilityType.cs diff --git a/neo/Network/P2P/Capabilities/ServerCapability.cs b/src/neo/Network/P2P/Capabilities/ServerCapability.cs similarity index 100% rename from neo/Network/P2P/Capabilities/ServerCapability.cs rename to src/neo/Network/P2P/Capabilities/ServerCapability.cs diff --git a/neo/Network/P2P/ChannelsConfig.cs b/src/neo/Network/P2P/ChannelsConfig.cs similarity index 100% rename from neo/Network/P2P/ChannelsConfig.cs rename to src/neo/Network/P2P/ChannelsConfig.cs diff --git a/neo/Network/P2P/Connection.cs b/src/neo/Network/P2P/Connection.cs similarity index 100% rename from neo/Network/P2P/Connection.cs rename to src/neo/Network/P2P/Connection.cs diff --git a/neo/Network/P2P/Helper.cs b/src/neo/Network/P2P/Helper.cs similarity index 100% rename from neo/Network/P2P/Helper.cs rename to src/neo/Network/P2P/Helper.cs diff --git a/neo/Network/P2P/LocalNode.cs b/src/neo/Network/P2P/LocalNode.cs similarity index 100% rename from neo/Network/P2P/LocalNode.cs rename to src/neo/Network/P2P/LocalNode.cs diff --git a/neo/Network/P2P/Message.cs b/src/neo/Network/P2P/Message.cs similarity index 63% rename from neo/Network/P2P/Message.cs rename to src/neo/Network/P2P/Message.cs index 38bc2bf6c1..578259f789 100644 --- a/neo/Network/P2P/Message.cs +++ b/src/neo/Network/P2P/Message.cs @@ -1,7 +1,7 @@ using Akka.IO; using Neo.Cryptography; using Neo.IO; -using Neo.Network.P2P.Payloads; +using Neo.IO.Caching; using System; using System.IO; @@ -51,51 +51,7 @@ private void DecompressPayload() byte[] decompressed = Flags.HasFlag(MessageFlags.Compressed) ? _payload_compressed.DecompressLz4(PayloadMaxSize) : _payload_compressed; - switch (Command) - { - case MessageCommand.Version: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.Addr: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.Ping: - case MessageCommand.Pong: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.GetHeaders: - case MessageCommand.GetBlocks: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.Headers: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.Inv: - case MessageCommand.GetData: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.GetBlockData: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.Transaction: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.Block: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.Consensus: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.FilterLoad: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.FilterAdd: - Payload = decompressed.AsSerializable(); - break; - case MessageCommand.MerkleBlock: - Payload = decompressed.AsSerializable(); - break; - } + Payload = ReflectionCache.CreateSerializable(Command, decompressed); } void ISerializable.Deserialize(BinaryReader reader) diff --git a/src/neo/Network/P2P/MessageCommand.cs b/src/neo/Network/P2P/MessageCommand.cs new file mode 100644 index 0000000000..ccddacfba2 --- /dev/null +++ b/src/neo/Network/P2P/MessageCommand.cs @@ -0,0 +1,57 @@ +using Neo.IO.Caching; +using Neo.Network.P2P.Payloads; + +namespace Neo.Network.P2P +{ + public enum MessageCommand : byte + { + //handshaking + [ReflectionCache(typeof(VersionPayload))] + Version = 0x00, + Verack = 0x01, + + //connectivity + GetAddr = 0x10, + [ReflectionCache(typeof(AddrPayload))] + Addr = 0x11, + [ReflectionCache(typeof(PingPayload))] + Ping = 0x18, + [ReflectionCache(typeof(PingPayload))] + Pong = 0x19, + + //synchronization + [ReflectionCache(typeof(GetBlocksPayload))] + GetHeaders = 0x20, + [ReflectionCache(typeof(HeadersPayload))] + Headers = 0x21, + [ReflectionCache(typeof(GetBlocksPayload))] + GetBlocks = 0x24, + Mempool = 0x25, + [ReflectionCache(typeof(InvPayload))] + Inv = 0x27, + [ReflectionCache(typeof(InvPayload))] + GetData = 0x28, + [ReflectionCache(typeof(GetBlockDataPayload))] + GetBlockData = 0x29, + NotFound = 0x2a, + [ReflectionCache(typeof(Transaction))] + Transaction = 0x2b, + [ReflectionCache(typeof(Block))] + Block = 0x2c, + [ReflectionCache(typeof(ConsensusPayload))] + Consensus = 0x2d, + Reject = 0x2f, + + //SPV protocol + [ReflectionCache(typeof(FilterLoadPayload))] + FilterLoad = 0x30, + [ReflectionCache(typeof(FilterAddPayload))] + FilterAdd = 0x31, + FilterClear = 0x32, + [ReflectionCache(typeof(MerkleBlockPayload))] + MerkleBlock = 0x38, + + //others + Alert = 0x40, + } +} diff --git a/neo/Network/P2P/MessageFlags.cs b/src/neo/Network/P2P/MessageFlags.cs similarity index 100% rename from neo/Network/P2P/MessageFlags.cs rename to src/neo/Network/P2P/MessageFlags.cs diff --git a/neo/Network/P2P/Payloads/AddrPayload.cs b/src/neo/Network/P2P/Payloads/AddrPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/AddrPayload.cs rename to src/neo/Network/P2P/Payloads/AddrPayload.cs diff --git a/neo/Network/P2P/Payloads/Block.cs b/src/neo/Network/P2P/Payloads/Block.cs similarity index 100% rename from neo/Network/P2P/Payloads/Block.cs rename to src/neo/Network/P2P/Payloads/Block.cs diff --git a/neo/Network/P2P/Payloads/BlockBase.cs b/src/neo/Network/P2P/Payloads/BlockBase.cs similarity index 100% rename from neo/Network/P2P/Payloads/BlockBase.cs rename to src/neo/Network/P2P/Payloads/BlockBase.cs diff --git a/neo/Network/P2P/Payloads/ConsensusData.cs b/src/neo/Network/P2P/Payloads/ConsensusData.cs similarity index 100% rename from neo/Network/P2P/Payloads/ConsensusData.cs rename to src/neo/Network/P2P/Payloads/ConsensusData.cs diff --git a/neo/Network/P2P/Payloads/ConsensusPayload.cs b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/ConsensusPayload.cs rename to src/neo/Network/P2P/Payloads/ConsensusPayload.cs diff --git a/neo/Network/P2P/Payloads/Cosigner.cs b/src/neo/Network/P2P/Payloads/Cosigner.cs similarity index 100% rename from neo/Network/P2P/Payloads/Cosigner.cs rename to src/neo/Network/P2P/Payloads/Cosigner.cs diff --git a/neo/Network/P2P/Payloads/FilterAddPayload.cs b/src/neo/Network/P2P/Payloads/FilterAddPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/FilterAddPayload.cs rename to src/neo/Network/P2P/Payloads/FilterAddPayload.cs diff --git a/neo/Network/P2P/Payloads/FilterLoadPayload.cs b/src/neo/Network/P2P/Payloads/FilterLoadPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/FilterLoadPayload.cs rename to src/neo/Network/P2P/Payloads/FilterLoadPayload.cs diff --git a/neo/Network/P2P/Payloads/GetBlockDataPayload.cs b/src/neo/Network/P2P/Payloads/GetBlockDataPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/GetBlockDataPayload.cs rename to src/neo/Network/P2P/Payloads/GetBlockDataPayload.cs diff --git a/neo/Network/P2P/Payloads/GetBlocksPayload.cs b/src/neo/Network/P2P/Payloads/GetBlocksPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/GetBlocksPayload.cs rename to src/neo/Network/P2P/Payloads/GetBlocksPayload.cs diff --git a/neo/Network/P2P/Payloads/Header.cs b/src/neo/Network/P2P/Payloads/Header.cs similarity index 100% rename from neo/Network/P2P/Payloads/Header.cs rename to src/neo/Network/P2P/Payloads/Header.cs diff --git a/neo/Network/P2P/Payloads/HeadersPayload.cs b/src/neo/Network/P2P/Payloads/HeadersPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/HeadersPayload.cs rename to src/neo/Network/P2P/Payloads/HeadersPayload.cs diff --git a/neo/Network/P2P/Payloads/IInventory.cs b/src/neo/Network/P2P/Payloads/IInventory.cs similarity index 100% rename from neo/Network/P2P/Payloads/IInventory.cs rename to src/neo/Network/P2P/Payloads/IInventory.cs diff --git a/neo/Network/P2P/Payloads/IVerifiable.cs b/src/neo/Network/P2P/Payloads/IVerifiable.cs similarity index 100% rename from neo/Network/P2P/Payloads/IVerifiable.cs rename to src/neo/Network/P2P/Payloads/IVerifiable.cs diff --git a/neo/Network/P2P/Payloads/InvPayload.cs b/src/neo/Network/P2P/Payloads/InvPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/InvPayload.cs rename to src/neo/Network/P2P/Payloads/InvPayload.cs diff --git a/neo/Network/P2P/Payloads/InventoryType.cs b/src/neo/Network/P2P/Payloads/InventoryType.cs similarity index 100% rename from neo/Network/P2P/Payloads/InventoryType.cs rename to src/neo/Network/P2P/Payloads/InventoryType.cs diff --git a/neo/Network/P2P/Payloads/MerkleBlockPayload.cs b/src/neo/Network/P2P/Payloads/MerkleBlockPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/MerkleBlockPayload.cs rename to src/neo/Network/P2P/Payloads/MerkleBlockPayload.cs diff --git a/neo/Network/P2P/Payloads/NetworkAddressWithTime.cs b/src/neo/Network/P2P/Payloads/NetworkAddressWithTime.cs similarity index 100% rename from neo/Network/P2P/Payloads/NetworkAddressWithTime.cs rename to src/neo/Network/P2P/Payloads/NetworkAddressWithTime.cs diff --git a/neo/Network/P2P/Payloads/PingPayload.cs b/src/neo/Network/P2P/Payloads/PingPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/PingPayload.cs rename to src/neo/Network/P2P/Payloads/PingPayload.cs diff --git a/neo/Network/P2P/Payloads/Transaction.cs b/src/neo/Network/P2P/Payloads/Transaction.cs similarity index 100% rename from neo/Network/P2P/Payloads/Transaction.cs rename to src/neo/Network/P2P/Payloads/Transaction.cs diff --git a/neo/Network/P2P/Payloads/TransactionAttribute.cs b/src/neo/Network/P2P/Payloads/TransactionAttribute.cs similarity index 100% rename from neo/Network/P2P/Payloads/TransactionAttribute.cs rename to src/neo/Network/P2P/Payloads/TransactionAttribute.cs diff --git a/neo/Network/P2P/Payloads/TransactionAttributeUsage.cs b/src/neo/Network/P2P/Payloads/TransactionAttributeUsage.cs similarity index 100% rename from neo/Network/P2P/Payloads/TransactionAttributeUsage.cs rename to src/neo/Network/P2P/Payloads/TransactionAttributeUsage.cs diff --git a/neo/Network/P2P/Payloads/VersionPayload.cs b/src/neo/Network/P2P/Payloads/VersionPayload.cs similarity index 100% rename from neo/Network/P2P/Payloads/VersionPayload.cs rename to src/neo/Network/P2P/Payloads/VersionPayload.cs diff --git a/neo/Network/P2P/Payloads/Witness.cs b/src/neo/Network/P2P/Payloads/Witness.cs similarity index 100% rename from neo/Network/P2P/Payloads/Witness.cs rename to src/neo/Network/P2P/Payloads/Witness.cs diff --git a/neo/Network/P2P/Payloads/WitnessScope.cs b/src/neo/Network/P2P/Payloads/WitnessScope.cs similarity index 100% rename from neo/Network/P2P/Payloads/WitnessScope.cs rename to src/neo/Network/P2P/Payloads/WitnessScope.cs diff --git a/neo/Network/P2P/Peer.cs b/src/neo/Network/P2P/Peer.cs similarity index 100% rename from neo/Network/P2P/Peer.cs rename to src/neo/Network/P2P/Peer.cs diff --git a/neo/Network/P2P/ProtocolHandler.cs b/src/neo/Network/P2P/ProtocolHandler.cs similarity index 100% rename from neo/Network/P2P/ProtocolHandler.cs rename to src/neo/Network/P2P/ProtocolHandler.cs diff --git a/neo/Network/P2P/RemoteNode.cs b/src/neo/Network/P2P/RemoteNode.cs similarity index 100% rename from neo/Network/P2P/RemoteNode.cs rename to src/neo/Network/P2P/RemoteNode.cs diff --git a/neo/Network/P2P/TaskManager.cs b/src/neo/Network/P2P/TaskManager.cs similarity index 100% rename from neo/Network/P2P/TaskManager.cs rename to src/neo/Network/P2P/TaskManager.cs diff --git a/neo/Network/P2P/TaskSession.cs b/src/neo/Network/P2P/TaskSession.cs similarity index 100% rename from neo/Network/P2P/TaskSession.cs rename to src/neo/Network/P2P/TaskSession.cs diff --git a/neo/Network/RPC/ContractClient.cs b/src/neo/Network/RPC/ContractClient.cs similarity index 87% rename from neo/Network/RPC/ContractClient.cs rename to src/neo/Network/RPC/ContractClient.cs index a329e07674..45fb31d267 100644 --- a/neo/Network/RPC/ContractClient.cs +++ b/src/neo/Network/RPC/ContractClient.cs @@ -44,7 +44,7 @@ public RpcInvokeResult TestInvoke(UInt160 scriptHash, string operation, params o /// sender KeyPair /// transaction NetworkFee, set to be 0 if you don't need higher priority /// - public Transaction DeployContract(byte[] contractScript, ContractManifest manifest, KeyPair key, long networkFee = 0) + public Transaction CreateDeployContractTx(byte[] contractScript, ContractManifest manifest, KeyPair key, long networkFee = 0) { byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) @@ -53,7 +53,8 @@ public Transaction DeployContract(byte[] contractScript, ContractManifest manife script = sb.ToArray(); } - Transaction tx = new TransactionManager(rpcClient, Contract.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash()) + UInt160 sender = Contract.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash(); + Transaction tx = new TransactionManager(rpcClient, sender) .MakeTransaction(script, null, null, networkFee) .AddSignature(key) .Sign() diff --git a/src/neo/Network/RPC/Helper.cs b/src/neo/Network/RPC/Helper.cs new file mode 100644 index 0000000000..5c5c82e329 --- /dev/null +++ b/src/neo/Network/RPC/Helper.cs @@ -0,0 +1,38 @@ +using System; +using System.Numerics; + +namespace Neo.Network.RPC +{ + internal static class Helper + { + /// + /// Convert decimal amount to BigInteger: amount * 10 ^ decimals + /// + /// float value + /// token decimals + /// + public static BigInteger ToBigInteger(this decimal amount, uint decimals) + { + BigInteger factor = BigInteger.Pow(10, (int)decimals); + var (numerator, denominator) = Fraction(amount); + if (factor < denominator) + { + throw new OverflowException("The decimal places is too long."); + } + + BigInteger res = factor * numerator / denominator; + return res; + } + + private static (BigInteger numerator, BigInteger denominator) Fraction(decimal d) + { + int[] bits = decimal.GetBits(d); + BigInteger numerator = (1 - ((bits[3] >> 30) & 2)) * + unchecked(((BigInteger)(uint)bits[2] << 64) | + ((BigInteger)(uint)bits[1] << 32) | + (uint)bits[0]); + BigInteger denominator = BigInteger.Pow(10, (bits[3] >> 16) & 0xff); + return (numerator, denominator); + } + } +} diff --git a/neo/Network/RPC/Models/RpcBlock.cs b/src/neo/Network/RPC/Models/RpcBlock.cs similarity index 73% rename from neo/Network/RPC/Models/RpcBlock.cs rename to src/neo/Network/RPC/Models/RpcBlock.cs index f71af51168..1ff485f96e 100644 --- a/neo/Network/RPC/Models/RpcBlock.cs +++ b/src/neo/Network/RPC/Models/RpcBlock.cs @@ -7,16 +7,16 @@ public class RpcBlock { public Block Block { get; set; } - public int? Confirmations { get; set; } + public int Confirmations { get; set; } public UInt256 NextBlockHash { get; set; } public JObject ToJson() { JObject json = Block.ToJson(); - if (Confirmations != null) + json["confirmations"] = Confirmations; + if (NextBlockHash != null) { - json["confirmations"] = Confirmations; json["nextblockhash"] = NextBlockHash.ToString(); } return json; @@ -26,9 +26,9 @@ public static RpcBlock FromJson(JObject json) { RpcBlock block = new RpcBlock(); block.Block = Block.FromJson(json); - if (json["confirmations"] != null) + block.Confirmations = (int)json["confirmations"].AsNumber(); + if (json["nextblockhash"] != null) { - block.Confirmations = (int)json["confirmations"].AsNumber(); block.NextBlockHash = UInt256.Parse(json["nextblockhash"].AsString()); } return block; diff --git a/neo/Network/RPC/Models/RpcBlockHeader.cs b/src/neo/Network/RPC/Models/RpcBlockHeader.cs similarity index 74% rename from neo/Network/RPC/Models/RpcBlockHeader.cs rename to src/neo/Network/RPC/Models/RpcBlockHeader.cs index 2b9293ecaf..5346dffd91 100644 --- a/neo/Network/RPC/Models/RpcBlockHeader.cs +++ b/src/neo/Network/RPC/Models/RpcBlockHeader.cs @@ -7,16 +7,16 @@ public class RpcBlockHeader { public Header Header { get; set; } - public int? Confirmations { get; set; } + public int Confirmations { get; set; } public UInt256 NextBlockHash { get; set; } public JObject ToJson() { JObject json = Header.ToJson(); - if (Confirmations != null) + json["confirmations"] = Confirmations; + if (NextBlockHash != null) { - json["confirmations"] = Confirmations; json["nextblockhash"] = NextBlockHash.ToString(); } return json; @@ -26,9 +26,9 @@ public static RpcBlockHeader FromJson(JObject json) { RpcBlockHeader block = new RpcBlockHeader(); block.Header = Header.FromJson(json); - if (json["confirmations"] != null) + block.Confirmations = (int)json["confirmations"].AsNumber(); + if (json["nextblockhash"] != null) { - block.Confirmations = (int)json["confirmations"].AsNumber(); block.NextBlockHash = UInt256.Parse(json["nextblockhash"].AsString()); } return block; diff --git a/neo/Network/RPC/Models/RpcInvokeResult.cs b/src/neo/Network/RPC/Models/RpcInvokeResult.cs similarity index 93% rename from neo/Network/RPC/Models/RpcInvokeResult.cs rename to src/neo/Network/RPC/Models/RpcInvokeResult.cs index c56307950a..a9c5f04c48 100644 --- a/neo/Network/RPC/Models/RpcInvokeResult.cs +++ b/src/neo/Network/RPC/Models/RpcInvokeResult.cs @@ -14,8 +14,6 @@ public class RpcInvokeResult public ContractParameter[] Stack { get; set; } - public string Tx { get; set; } - public JObject ToJson() { JObject json = new JObject(); @@ -23,7 +21,6 @@ public JObject ToJson() json["state"] = State; json["gas_consumed"] = GasConsumed; json["stack"] = new JArray(Stack.Select(p => p.ToJson())); - json["tx"] = Tx; return json; } @@ -33,7 +30,6 @@ public static RpcInvokeResult FromJson(JObject json) invokeScriptResult.Script = json["script"].AsString(); invokeScriptResult.State = json["state"].AsString(); invokeScriptResult.GasConsumed = json["gas_consumed"].AsString(); - invokeScriptResult.Tx = json["tx"].AsString(); invokeScriptResult.Stack = ((JArray)json["stack"]).Select(p => ContractParameter.FromJson(p)).ToArray(); return invokeScriptResult; } diff --git a/neo/Network/RPC/Models/RpcNep5Balances.cs b/src/neo/Network/RPC/Models/RpcNep5Balances.cs similarity index 100% rename from neo/Network/RPC/Models/RpcNep5Balances.cs rename to src/neo/Network/RPC/Models/RpcNep5Balances.cs diff --git a/src/neo/Network/RPC/Models/RpcNep5TokenInfo.cs b/src/neo/Network/RPC/Models/RpcNep5TokenInfo.cs new file mode 100644 index 0000000000..0f251a5a37 --- /dev/null +++ b/src/neo/Network/RPC/Models/RpcNep5TokenInfo.cs @@ -0,0 +1,15 @@ +using System.Numerics; + +namespace Neo.Network.RPC.Models +{ + public class RpcNep5TokenInfo + { + public string Name { get; set; } + + public string Symbol { get; set; } + + public uint Decimals { get; set; } + + public BigInteger TotalSupply { get; set; } + } +} diff --git a/neo/Network/RPC/Models/RpcPeers.cs b/src/neo/Network/RPC/Models/RpcPeers.cs similarity index 100% rename from neo/Network/RPC/Models/RpcPeers.cs rename to src/neo/Network/RPC/Models/RpcPeers.cs diff --git a/neo/Network/RPC/Models/RpcPlugin.cs b/src/neo/Network/RPC/Models/RpcPlugin.cs similarity index 100% rename from neo/Network/RPC/Models/RpcPlugin.cs rename to src/neo/Network/RPC/Models/RpcPlugin.cs diff --git a/neo/Network/RPC/Models/RpcRawMemPool.cs b/src/neo/Network/RPC/Models/RpcRawMemPool.cs similarity index 100% rename from neo/Network/RPC/Models/RpcRawMemPool.cs rename to src/neo/Network/RPC/Models/RpcRawMemPool.cs diff --git a/neo/Network/RPC/Models/RpcRequest.cs b/src/neo/Network/RPC/Models/RpcRequest.cs similarity index 100% rename from neo/Network/RPC/Models/RpcRequest.cs rename to src/neo/Network/RPC/Models/RpcRequest.cs diff --git a/neo/Network/RPC/Models/RpcResponse.cs b/src/neo/Network/RPC/Models/RpcResponse.cs similarity index 100% rename from neo/Network/RPC/Models/RpcResponse.cs rename to src/neo/Network/RPC/Models/RpcResponse.cs diff --git a/neo/Network/RPC/Models/RpcTransaction.cs b/src/neo/Network/RPC/Models/RpcTransaction.cs similarity index 86% rename from neo/Network/RPC/Models/RpcTransaction.cs rename to src/neo/Network/RPC/Models/RpcTransaction.cs index f96179c358..48b1e19bd4 100644 --- a/neo/Network/RPC/Models/RpcTransaction.cs +++ b/src/neo/Network/RPC/Models/RpcTransaction.cs @@ -24,7 +24,10 @@ public JObject ToJson() json["blockhash"] = BlockHash.ToString(); json["confirmations"] = Confirmations; json["blocktime"] = BlockTime; - json["vmState"] = VMState; + if (VMState != null) + { + json["vmState"] = VMState; + } } return json; } @@ -38,7 +41,7 @@ public static RpcTransaction FromJson(JObject json) transaction.BlockHash = UInt256.Parse(json["blockhash"].AsString()); transaction.Confirmations = (int)json["confirmations"].AsNumber(); transaction.BlockTime = (uint)json["blocktime"].AsNumber(); - transaction.VMState = json["vmState"].TryGetEnum(); + transaction.VMState = json["vmState"]?.TryGetEnum(); } return transaction; } diff --git a/neo/Network/RPC/Models/RpcValidateAddressResult.cs b/src/neo/Network/RPC/Models/RpcValidateAddressResult.cs similarity index 100% rename from neo/Network/RPC/Models/RpcValidateAddressResult.cs rename to src/neo/Network/RPC/Models/RpcValidateAddressResult.cs diff --git a/neo/Network/RPC/Models/RpcValidator.cs b/src/neo/Network/RPC/Models/RpcValidator.cs similarity index 100% rename from neo/Network/RPC/Models/RpcValidator.cs rename to src/neo/Network/RPC/Models/RpcValidator.cs diff --git a/neo/Network/RPC/Models/RpcVersion.cs b/src/neo/Network/RPC/Models/RpcVersion.cs similarity index 100% rename from neo/Network/RPC/Models/RpcVersion.cs rename to src/neo/Network/RPC/Models/RpcVersion.cs diff --git a/neo/Network/RPC/Nep5API.cs b/src/neo/Network/RPC/Nep5API.cs similarity index 72% rename from neo/Network/RPC/Nep5API.cs rename to src/neo/Network/RPC/Nep5API.cs index abfad6c9ed..26ae041ae0 100644 --- a/neo/Network/RPC/Nep5API.cs +++ b/src/neo/Network/RPC/Nep5API.cs @@ -1,4 +1,5 @@ using Neo.Network.P2P.Payloads; +using Neo.Network.RPC.Models; using Neo.SmartContract; using Neo.VM; using Neo.Wallets; @@ -71,15 +72,39 @@ public BigInteger TotalSupply(UInt160 scriptHash) } /// - /// Get name of NEP5 token + /// Get token information in one rpc call + /// + /// contract script hash + /// + public RpcNep5TokenInfo GetTokenInfo(UInt160 scriptHash) + { + byte[] script = scriptHash.MakeScript("name") + .Concat(scriptHash.MakeScript("symbol")) + .Concat(scriptHash.MakeScript("decimals")) + .Concat(scriptHash.MakeScript("totalSupply")) + .ToArray(); + + var result = rpcClient.InvokeScript(script).Stack; + + return new RpcNep5TokenInfo + { + Name = result[0].ToStackItem().GetString(), + Symbol = result[1].ToStackItem().GetString(), + Decimals = (uint)result[2].ToStackItem().GetBigInteger(), + TotalSupply = result[3].ToStackItem().GetBigInteger() + }; + } + + /// + /// Create NEP5 token transfer transaction /// /// contract script hash /// from KeyPair /// to account script hash /// transfer amount - /// netwotk fee, set to be 0 if you don't need higher priority + /// netwotk fee, set to be 0 will auto calculate the least fee /// - public Transaction Transfer(UInt160 scriptHash, KeyPair fromKey, UInt160 to, BigInteger amount, long networkFee = 0) + public Transaction CreateTransferTx(UInt160 scriptHash, KeyPair fromKey, UInt160 to, BigInteger amount, long networkFee = 0) { var sender = Contract.CreateSignatureRedeemScript(fromKey.PublicKey).ToScriptHash(); Cosigner[] cosigners = new[] { new Cosigner { Scopes = WitnessScope.CalledByEntry, Account = sender } }; diff --git a/neo/Network/RPC/PolicyAPI.cs b/src/neo/Network/RPC/PolicyAPI.cs similarity index 95% rename from neo/Network/RPC/PolicyAPI.cs rename to src/neo/Network/RPC/PolicyAPI.cs index 969c1c22f1..1b401cd7e5 100644 --- a/neo/Network/RPC/PolicyAPI.cs +++ b/src/neo/Network/RPC/PolicyAPI.cs @@ -51,7 +51,7 @@ public long GetFeePerByte() public UInt160[] GetBlockedAccounts() { var result = (VM.Types.Array)TestInvoke(scriptHash, "getBlockedAccounts").Stack.Single().ToStackItem(); - return result.Select(p => new UInt160(p.GetByteArray())).ToArray(); + return result.Select(p => new UInt160(p.GetSpan().ToArray())).ToArray(); } } } diff --git a/neo/Network/RPC/RpcClient.cs b/src/neo/Network/RPC/RpcClient.cs similarity index 92% rename from neo/Network/RPC/RpcClient.cs rename to src/neo/Network/RPC/RpcClient.cs index cd0578953e..0721efcb33 100644 --- a/neo/Network/RPC/RpcClient.cs +++ b/src/neo/Network/RPC/RpcClient.cs @@ -1,7 +1,10 @@ +using Neo.IO; using Neo.IO.Json; using Neo.Ledger; +using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; using System; +using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; @@ -257,9 +260,14 @@ public RpcInvokeResult InvokeFunction(string address, string function, RpcStack[ /// Returns the result after passing a script through the VM. /// This RPC call does not affect the blockchain in any way. /// - public RpcInvokeResult InvokeScript(byte[] script) + public RpcInvokeResult InvokeScript(byte[] script, params UInt160[] scriptHashesForVerifying) { - return RpcInvokeResult.FromJson(RpcSend("invokescript", script.ToHexString())); + List parameters = new List + { + script.ToHexString() + }; + parameters.AddRange(scriptHashesForVerifying.Select(p => (JObject)p.ToString())); + return RpcInvokeResult.FromJson(RpcSend("invokescript", parameters.ToArray())); } /// @@ -271,7 +279,7 @@ public RpcPlugin[] ListPlugins() } /// - /// Broadcasts a transaction over the NEO network. + /// Broadcasts a serialized transaction over the NEO network. /// public bool SendRawTransaction(byte[] rawTransaction) { @@ -279,7 +287,15 @@ public bool SendRawTransaction(byte[] rawTransaction) } /// - /// Broadcasts a raw block over the NEO network. + /// Broadcasts a transaction over the NEO network. + /// + public bool SendRawTransaction(Transaction transaction) + { + return SendRawTransaction(transaction.ToArray()); + } + + /// + /// Broadcasts a serialized block over the NEO network. /// public bool SubmitBlock(byte[] block) { diff --git a/neo/Network/RPC/RpcException.cs b/src/neo/Network/RPC/RpcException.cs similarity index 100% rename from neo/Network/RPC/RpcException.cs rename to src/neo/Network/RPC/RpcException.cs diff --git a/neo/Network/RPC/RpcServer.cs b/src/neo/Network/RPC/RpcServer.cs similarity index 100% rename from neo/Network/RPC/RpcServer.cs rename to src/neo/Network/RPC/RpcServer.cs diff --git a/neo/Network/RPC/TransactionManager.cs b/src/neo/Network/RPC/TransactionManager.cs similarity index 93% rename from neo/Network/RPC/TransactionManager.cs rename to src/neo/Network/RPC/TransactionManager.cs index ba714a52ef..27741a58e3 100644 --- a/neo/Network/RPC/TransactionManager.cs +++ b/src/neo/Network/RPC/TransactionManager.cs @@ -1,5 +1,6 @@ using Neo.Cryptography.ECC; using Neo.IO; +using Neo.IO.Json; using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; using Neo.SmartContract; @@ -7,6 +8,7 @@ using Neo.VM; using Neo.Wallets; using System; +using System.Linq; namespace Neo.Network.RPC { @@ -16,6 +18,8 @@ namespace Neo.Network.RPC public class TransactionManager { private readonly RpcClient rpcClient; + private readonly PolicyAPI policyAPI; + private readonly Nep5API nep5API; private readonly UInt160 sender; /// @@ -36,6 +40,8 @@ public class TransactionManager public TransactionManager(RpcClient rpc, UInt160 sender) { rpcClient = rpc; + policyAPI = new PolicyAPI(rpc); + nep5API = new Nep5API(rpc); this.sender = sender; } @@ -63,7 +69,9 @@ public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[] Witnesses = new Witness[0] }; - RpcInvokeResult result = rpcClient.InvokeScript(script); + // Add witness hashes parameter to pass CheckWitness + UInt160[] hashes = Tx.GetScriptHashesForVerifying(null).ToArray(); + RpcInvokeResult result = rpcClient.InvokeScript(script, hashes); Tx.SystemFee = Math.Max(long.Parse(result.GasConsumed) - ApplicationEngine.GasFree, 0); if (Tx.SystemFee > 0) { @@ -80,7 +88,7 @@ public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[] // set networkfee to estimate value when networkFee is 0 Tx.NetworkFee = networkFee == 0 ? EstimateNetworkFee() : networkFee; - var gasBalance = new Nep5API(rpcClient).BalanceOf(NativeContract.GAS.Hash, sender); + var gasBalance = nep5API.BalanceOf(NativeContract.GAS.Hash, sender); if (gasBalance >= Tx.SystemFee + Tx.NetworkFee) return this; throw new InvalidOperationException($"Insufficient GAS in address: {sender.ToAddress()}"); } @@ -101,7 +109,7 @@ private long EstimateNetworkFee() networkFee += ApplicationEngine.OpCodePrices[OpCode.PUSHBYTES64] + ApplicationEngine.OpCodePrices[OpCode.PUSHBYTES33] + InteropService.GetPrice(InteropService.Neo_Crypto_ECDsaVerify, null); } - networkFee += size * new PolicyAPI(rpcClient).GetFeePerByte(); + networkFee += size * policyAPI.GetFeePerByte(); return networkFee; } @@ -129,7 +137,7 @@ private long CalculateNetworkFee() networkFee += Wallet.CalculateNetWorkFee(witness_script, ref size); } - networkFee += size * new PolicyAPI(rpcClient).GetFeePerByte(); + networkFee += size * policyAPI.GetFeePerByte(); return networkFee; } diff --git a/src/neo/Network/RPC/WalletAPI.cs b/src/neo/Network/RPC/WalletAPI.cs new file mode 100644 index 0000000000..e1ab3b777f --- /dev/null +++ b/src/neo/Network/RPC/WalletAPI.cs @@ -0,0 +1,192 @@ +using Neo.Ledger; +using Neo.Network.P2P.Payloads; +using Neo.Network.RPC.Models; +using Neo.SmartContract; +using Neo.SmartContract.Native; +using Neo.VM; +using Neo.Wallets; +using System; +using System.Linq; +using System.Numerics; +using System.Threading.Tasks; + +namespace Neo.Network.RPC +{ + /// + /// Wallet Common APIs + /// + public class WalletAPI + { + private readonly RpcClient rpcClient; + private readonly Nep5API nep5API; + + /// + /// WalletAPI Constructor + /// + /// the RPC client to call NEO RPC methods + public WalletAPI(RpcClient rpc) + { + rpcClient = rpc; + nep5API = new Nep5API(rpc); + } + + /// + /// Get unclaimed gas with address, scripthash or public key string + /// + /// address, scripthash or public key string + /// Example: address ("AV556nYUwyJKNv8Xy7hVMLQnkmKPukw6x5"), scripthash ("0x6a38cd693b615aea24dd00de12a9f5836844da91"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575") + /// + public decimal GetUnclaimedGas(string account) + { + UInt160 accountHash = Utility.GetScriptHash(account); + return GetUnclaimedGas(accountHash); + } + + /// + /// Get unclaimed gas + /// + /// account scripthash + /// + public decimal GetUnclaimedGas(UInt160 account) + { + UInt160 scriptHash = NativeContract.NEO.Hash; + BigInteger balance = nep5API.TestInvoke(scriptHash, "unclaimedGas", account, rpcClient.GetBlockCount() - 1) + .Stack.Single().ToStackItem().GetBigInteger(); + return ((decimal)balance) / (long)NativeContract.GAS.Factor; + } + + /// + /// Get Neo Balance + /// + /// address, scripthash or public key string + /// Example: address ("AV556nYUwyJKNv8Xy7hVMLQnkmKPukw6x5"), scripthash ("0x6a38cd693b615aea24dd00de12a9f5836844da91"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575") + /// + public uint GetNeoBalance(string account) + { + BigInteger balance = GetTokenBalance(NativeContract.NEO.Hash.ToString(), account); + return (uint)balance; + } + + /// + /// Get Gas Balance + /// + /// address, scripthash or public key string + /// Example: address ("AV556nYUwyJKNv8Xy7hVMLQnkmKPukw6x5"), scripthash ("0x6a38cd693b615aea24dd00de12a9f5836844da91"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575") + /// + public decimal GetGasBalance(string account) + { + BigInteger balance = GetTokenBalance(NativeContract.GAS.Hash.ToString(), account); + return ((decimal)balance) / (long)NativeContract.GAS.Factor; + } + + /// + /// Get token balance with string parameters + /// + /// token script hash, Example: "0x43cf98eddbe047e198a3e5d57006311442a0ca15"(NEO) + /// address, scripthash or public key string + /// Example: address ("AV556nYUwyJKNv8Xy7hVMLQnkmKPukw6x5"), scripthash ("0x6a38cd693b615aea24dd00de12a9f5836844da91"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575") + /// + public BigInteger GetTokenBalance(string tokenHash, string account) + { + UInt160 scriptHash = Utility.GetScriptHash(tokenHash); + UInt160 accountHash = Utility.GetScriptHash(account); + return nep5API.BalanceOf(scriptHash, accountHash); + } + + /// + /// The GAS is claimed when doing NEO transfer + /// This function will transfer NEO balance from account to itself + /// + /// wif or private key + /// Example: WIF ("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"), PrivateKey ("450d6c2a04b5b470339a745427bae6828400cf048400837d73c415063835e005") + /// The transaction sended + public Transaction ClaimGas(string key) + { + KeyPair keyPair = Utility.GetKeyPair(key); + return ClaimGas(keyPair); + } + + /// + /// The GAS is claimed when doing NEO transfer + /// This function will transfer NEO balance from account to itself + /// + /// keyPair + /// The transaction sended + public Transaction ClaimGas(KeyPair keyPair) + { + UInt160 toHash = Contract.CreateSignatureRedeemScript(keyPair.PublicKey).ToScriptHash(); + BigInteger balance = nep5API.BalanceOf(NativeContract.NEO.Hash, toHash); + Transaction transaction = nep5API.CreateTransferTx(NativeContract.NEO.Hash, keyPair, toHash, balance); + rpcClient.SendRawTransaction(transaction); + return transaction; + } + + /// + /// Transfer NEP5 token balance, with common data types + /// + /// nep5 token script hash, Example: scripthash ("0x6a38cd693b615aea24dd00de12a9f5836844da91") + /// wif or private key + /// Example: WIF ("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"), PrivateKey ("450d6c2a04b5b470339a745427bae6828400cf048400837d73c415063835e005") + /// address or account script hash + /// token amount + /// netwotk fee, set to be 0 will auto calculate the least fee + /// + public Transaction Transfer(string tokenHash, string fromKey, string toAddress, decimal amount, decimal networkFee = 0) + { + UInt160 scriptHash = Utility.GetScriptHash(tokenHash); + var decimals = nep5API.Decimals(scriptHash); + + KeyPair from = Utility.GetKeyPair(fromKey); + UInt160 to = Utility.GetScriptHash(toAddress); + BigInteger amountInteger = amount.ToBigInteger(decimals); + BigInteger networkFeeInteger = networkFee.ToBigInteger(NativeContract.GAS.Decimals); + return Transfer(scriptHash, from, to, amountInteger, (long)networkFeeInteger); + } + + /// + /// Transfer NEP5 token balance + /// + /// contract script hash + /// from KeyPair + /// to account script hash + /// transfer amount + /// netwotk fee, set to be 0 will auto calculate the least fee + /// + public Transaction Transfer(UInt160 scriptHash, KeyPair from, UInt160 to, BigInteger amountInteger, BigInteger networkFeeInteger = default) + { + Transaction transaction = nep5API.CreateTransferTx(scriptHash, from, to, amountInteger, (long)networkFeeInteger); + rpcClient.SendRawTransaction(transaction); + return transaction; + } + + /// + /// Wait until the transaction is observable block chain + /// + /// the transaction to observe + /// TimeoutException throws after "timeout" seconds + /// the Transaction state, including vmState and blockhash + public async Task WaitTransaction(Transaction transaction, int timeout = 60) + { + DateTime deadline = DateTime.UtcNow.AddSeconds(timeout); + RpcTransaction rpcTx = null; + while (rpcTx == null || rpcTx.Confirmations == null) + { + if (deadline < DateTime.UtcNow) + { + throw new TimeoutException(); + } + + try + { + rpcTx = rpcClient.GetRawTransaction(transaction.Hash.ToString()); + if (rpcTx == null || rpcTx.Confirmations == null) + { + await Task.Delay((int)Blockchain.MillisecondsPerBlock / 2); + } + } + catch (Exception) { } + } + return rpcTx; + } + } +} diff --git a/neo/Network/UPnP.cs b/src/neo/Network/UPnP.cs similarity index 100% rename from neo/Network/UPnP.cs rename to src/neo/Network/UPnP.cs diff --git a/neo/Persistence/CloneSnapshot.cs b/src/neo/Persistence/CloneSnapshot.cs similarity index 100% rename from neo/Persistence/CloneSnapshot.cs rename to src/neo/Persistence/CloneSnapshot.cs diff --git a/neo/Persistence/Helper.cs b/src/neo/Persistence/Helper.cs similarity index 100% rename from neo/Persistence/Helper.cs rename to src/neo/Persistence/Helper.cs diff --git a/neo/Persistence/IPersistence.cs b/src/neo/Persistence/IPersistence.cs similarity index 100% rename from neo/Persistence/IPersistence.cs rename to src/neo/Persistence/IPersistence.cs diff --git a/neo/Persistence/LevelDB/DbCache.cs b/src/neo/Persistence/LevelDB/DbCache.cs similarity index 100% rename from neo/Persistence/LevelDB/DbCache.cs rename to src/neo/Persistence/LevelDB/DbCache.cs diff --git a/neo/Persistence/LevelDB/DbMetaDataCache.cs b/src/neo/Persistence/LevelDB/DbMetaDataCache.cs similarity index 100% rename from neo/Persistence/LevelDB/DbMetaDataCache.cs rename to src/neo/Persistence/LevelDB/DbMetaDataCache.cs diff --git a/neo/Persistence/LevelDB/DbSnapshot.cs b/src/neo/Persistence/LevelDB/DbSnapshot.cs similarity index 100% rename from neo/Persistence/LevelDB/DbSnapshot.cs rename to src/neo/Persistence/LevelDB/DbSnapshot.cs diff --git a/neo/Persistence/LevelDB/LevelDBStore.cs b/src/neo/Persistence/LevelDB/LevelDBStore.cs similarity index 100% rename from neo/Persistence/LevelDB/LevelDBStore.cs rename to src/neo/Persistence/LevelDB/LevelDBStore.cs diff --git a/neo/Persistence/LevelDB/Prefixes.cs b/src/neo/Persistence/LevelDB/Prefixes.cs similarity index 100% rename from neo/Persistence/LevelDB/Prefixes.cs rename to src/neo/Persistence/LevelDB/Prefixes.cs diff --git a/neo/Persistence/Snapshot.cs b/src/neo/Persistence/Snapshot.cs similarity index 100% rename from neo/Persistence/Snapshot.cs rename to src/neo/Persistence/Snapshot.cs diff --git a/neo/Persistence/Store.cs b/src/neo/Persistence/Store.cs similarity index 100% rename from neo/Persistence/Store.cs rename to src/neo/Persistence/Store.cs diff --git a/neo/Plugins/ILogPlugin.cs b/src/neo/Plugins/ILogPlugin.cs similarity index 100% rename from neo/Plugins/ILogPlugin.cs rename to src/neo/Plugins/ILogPlugin.cs diff --git a/neo/Plugins/IMemoryPoolTxObserverPlugin.cs b/src/neo/Plugins/IMemoryPoolTxObserverPlugin.cs similarity index 100% rename from neo/Plugins/IMemoryPoolTxObserverPlugin.cs rename to src/neo/Plugins/IMemoryPoolTxObserverPlugin.cs diff --git a/neo/Plugins/IP2PPlugin.cs b/src/neo/Plugins/IP2PPlugin.cs similarity index 100% rename from neo/Plugins/IP2PPlugin.cs rename to src/neo/Plugins/IP2PPlugin.cs diff --git a/neo/Plugins/IPersistencePlugin.cs b/src/neo/Plugins/IPersistencePlugin.cs similarity index 100% rename from neo/Plugins/IPersistencePlugin.cs rename to src/neo/Plugins/IPersistencePlugin.cs diff --git a/neo/Plugins/IRpcPlugin.cs b/src/neo/Plugins/IRpcPlugin.cs similarity index 100% rename from neo/Plugins/IRpcPlugin.cs rename to src/neo/Plugins/IRpcPlugin.cs diff --git a/neo/Plugins/LogLevel.cs b/src/neo/Plugins/LogLevel.cs similarity index 100% rename from neo/Plugins/LogLevel.cs rename to src/neo/Plugins/LogLevel.cs diff --git a/neo/Plugins/MemoryPoolTxRemovalReason.cs b/src/neo/Plugins/MemoryPoolTxRemovalReason.cs similarity index 100% rename from neo/Plugins/MemoryPoolTxRemovalReason.cs rename to src/neo/Plugins/MemoryPoolTxRemovalReason.cs diff --git a/neo/Plugins/Plugin.cs b/src/neo/Plugins/Plugin.cs similarity index 100% rename from neo/Plugins/Plugin.cs rename to src/neo/Plugins/Plugin.cs diff --git a/neo/Properties/AssemblyInfo.cs b/src/neo/Properties/AssemblyInfo.cs similarity index 100% rename from neo/Properties/AssemblyInfo.cs rename to src/neo/Properties/AssemblyInfo.cs diff --git a/neo/ProtocolSettings.cs b/src/neo/ProtocolSettings.cs similarity index 100% rename from neo/ProtocolSettings.cs rename to src/neo/ProtocolSettings.cs diff --git a/neo/SmartContract/ApplicationEngine.OpCodePrices.cs b/src/neo/SmartContract/ApplicationEngine.OpCodePrices.cs similarity index 100% rename from neo/SmartContract/ApplicationEngine.OpCodePrices.cs rename to src/neo/SmartContract/ApplicationEngine.OpCodePrices.cs diff --git a/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs similarity index 99% rename from neo/SmartContract/ApplicationEngine.cs rename to src/neo/SmartContract/ApplicationEngine.cs index 2eeeef52e0..41c17aebeb 100644 --- a/neo/SmartContract/ApplicationEngine.cs +++ b/src/neo/SmartContract/ApplicationEngine.cs @@ -2,6 +2,7 @@ using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.VM; +using Neo.VM.Types; using System; using System.Collections.Generic; diff --git a/neo/SmartContract/ContainerPlaceholder.cs b/src/neo/SmartContract/ContainerPlaceholder.cs similarity index 60% rename from neo/SmartContract/ContainerPlaceholder.cs rename to src/neo/SmartContract/ContainerPlaceholder.cs index a379ddd9d3..29fa0f6e6e 100644 --- a/neo/SmartContract/ContainerPlaceholder.cs +++ b/src/neo/SmartContract/ContainerPlaceholder.cs @@ -1,4 +1,4 @@ -using Neo.VM; +using Neo.VM.Types; using System; namespace Neo.SmartContract @@ -10,8 +10,8 @@ internal class ContainerPlaceholder : StackItem public override bool Equals(StackItem other) => throw new NotSupportedException(); - public override bool GetBoolean() => throw new NotImplementedException(); + public override int GetHashCode() => throw new NotSupportedException(); - public override byte[] GetByteArray() => throw new NotSupportedException(); + public override bool ToBoolean() => throw new NotSupportedException(); } } diff --git a/neo/SmartContract/Contract.cs b/src/neo/SmartContract/Contract.cs similarity index 100% rename from neo/SmartContract/Contract.cs rename to src/neo/SmartContract/Contract.cs diff --git a/neo/SmartContract/ContractParameter.cs b/src/neo/SmartContract/ContractParameter.cs similarity index 100% rename from neo/SmartContract/ContractParameter.cs rename to src/neo/SmartContract/ContractParameter.cs diff --git a/neo/SmartContract/ContractParameterType.cs b/src/neo/SmartContract/ContractParameterType.cs similarity index 100% rename from neo/SmartContract/ContractParameterType.cs rename to src/neo/SmartContract/ContractParameterType.cs diff --git a/neo/SmartContract/ContractParametersContext.cs b/src/neo/SmartContract/ContractParametersContext.cs similarity index 100% rename from neo/SmartContract/ContractParametersContext.cs rename to src/neo/SmartContract/ContractParametersContext.cs diff --git a/neo/SmartContract/Enumerators/ConcatenatedEnumerator.cs b/src/neo/SmartContract/Enumerators/ConcatenatedEnumerator.cs similarity index 97% rename from neo/SmartContract/Enumerators/ConcatenatedEnumerator.cs rename to src/neo/SmartContract/Enumerators/ConcatenatedEnumerator.cs index 2b75b1d46b..05cde03e54 100644 --- a/neo/SmartContract/Enumerators/ConcatenatedEnumerator.cs +++ b/src/neo/SmartContract/Enumerators/ConcatenatedEnumerator.cs @@ -1,4 +1,4 @@ -using Neo.VM; +using Neo.VM.Types; namespace Neo.SmartContract.Enumerators { diff --git a/neo/SmartContract/Enumerators/IEnumerator.cs b/src/neo/SmartContract/Enumerators/IEnumerator.cs similarity index 89% rename from neo/SmartContract/Enumerators/IEnumerator.cs rename to src/neo/SmartContract/Enumerators/IEnumerator.cs index 4d1f11fe65..948bad9371 100644 --- a/neo/SmartContract/Enumerators/IEnumerator.cs +++ b/src/neo/SmartContract/Enumerators/IEnumerator.cs @@ -1,4 +1,4 @@ -using Neo.VM; +using Neo.VM.Types; using System; namespace Neo.SmartContract.Enumerators diff --git a/neo/SmartContract/Enumerators/IteratorKeysWrapper.cs b/src/neo/SmartContract/Enumerators/IteratorKeysWrapper.cs similarity index 96% rename from neo/SmartContract/Enumerators/IteratorKeysWrapper.cs rename to src/neo/SmartContract/Enumerators/IteratorKeysWrapper.cs index d134eb884c..a7a7f040a4 100644 --- a/neo/SmartContract/Enumerators/IteratorKeysWrapper.cs +++ b/src/neo/SmartContract/Enumerators/IteratorKeysWrapper.cs @@ -1,5 +1,5 @@ using Neo.SmartContract.Iterators; -using Neo.VM; +using Neo.VM.Types; namespace Neo.SmartContract.Enumerators { diff --git a/neo/SmartContract/Enumerators/IteratorValuesWrapper.cs b/src/neo/SmartContract/Enumerators/IteratorValuesWrapper.cs similarity index 96% rename from neo/SmartContract/Enumerators/IteratorValuesWrapper.cs rename to src/neo/SmartContract/Enumerators/IteratorValuesWrapper.cs index 15e06f2223..5e285938cf 100644 --- a/neo/SmartContract/Enumerators/IteratorValuesWrapper.cs +++ b/src/neo/SmartContract/Enumerators/IteratorValuesWrapper.cs @@ -1,5 +1,5 @@ using Neo.SmartContract.Iterators; -using Neo.VM; +using Neo.VM.Types; namespace Neo.SmartContract.Enumerators { diff --git a/neo/SmartContract/ExecutionContextState.cs b/src/neo/SmartContract/ExecutionContextState.cs similarity index 100% rename from neo/SmartContract/ExecutionContextState.cs rename to src/neo/SmartContract/ExecutionContextState.cs diff --git a/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs similarity index 96% rename from neo/SmartContract/Helper.cs rename to src/neo/SmartContract/Helper.cs index 4f7e320c37..f8c819dbeb 100644 --- a/neo/SmartContract/Helper.cs +++ b/src/neo/SmartContract/Helper.cs @@ -100,7 +100,7 @@ private static StackItem DeserializeStackItem(BinaryReader reader, uint maxArray { StackItem key = stack_temp.Pop(); StackItem value = stack_temp.Pop(); - map.Add(key, value); + map.Add((PrimitiveType)key, value); } item = map; break; @@ -199,17 +199,17 @@ private static void SerializeStackItem(StackItem item, BinaryWriter writer) item = unserialized.Pop(); switch (item) { - case ByteArray _: + case ByteArray bytes: writer.Write((byte)StackItemType.ByteArray); - writer.WriteVarBytes(item.GetByteArray()); + writer.WriteVarBytes(bytes.ToByteArray()); break; case VMBoolean _: writer.Write((byte)StackItemType.Boolean); - writer.Write(item.GetBoolean()); + writer.Write(item.ToBoolean()); break; - case Integer _: + case Integer integer: writer.Write((byte)StackItemType.Integer); - writer.WriteVarBytes(item.GetByteArray()); + writer.WriteVarBytes(integer.ToByteArray()); break; case InteropInterface _: throw new NotSupportedException(); @@ -285,7 +285,7 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, Snapshot snaps engine.LoadScript(verification); engine.LoadScript(verifiable.Witnesses[i].InvocationScript); if (engine.Execute().HasFlag(VMState.FAULT)) return false; - if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return false; + if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().ToBoolean()) return false; } } return true; diff --git a/neo/SmartContract/IInteroperable.cs b/src/neo/SmartContract/IInteroperable.cs similarity index 85% rename from neo/SmartContract/IInteroperable.cs rename to src/neo/SmartContract/IInteroperable.cs index 972147877c..047ce05168 100644 --- a/neo/SmartContract/IInteroperable.cs +++ b/src/neo/SmartContract/IInteroperable.cs @@ -1,4 +1,4 @@ -using Neo.VM; +using Neo.VM.Types; namespace Neo.SmartContract { diff --git a/neo/SmartContract/InteropDescriptor.cs b/src/neo/SmartContract/InteropDescriptor.cs similarity index 98% rename from neo/SmartContract/InteropDescriptor.cs rename to src/neo/SmartContract/InteropDescriptor.cs index 6db599ea64..f446d4fbfc 100644 --- a/neo/SmartContract/InteropDescriptor.cs +++ b/src/neo/SmartContract/InteropDescriptor.cs @@ -1,4 +1,5 @@ using Neo.VM; +using Neo.VM.Types; using System; namespace Neo.SmartContract diff --git a/neo/SmartContract/InteropService.NEO.cs b/src/neo/SmartContract/InteropService.NEO.cs similarity index 96% rename from neo/SmartContract/InteropService.NEO.cs rename to src/neo/SmartContract/InteropService.NEO.cs index 90a49a4df2..10798c053d 100644 --- a/neo/SmartContract/InteropService.NEO.cs +++ b/src/neo/SmartContract/InteropService.NEO.cs @@ -81,10 +81,10 @@ private static bool Crypto_ECDsaVerify(ApplicationEngine engine) { InteropInterface _interface => _interface.GetInterface().GetHashData(), Null _ => engine.ScriptContainer.GetHashData(), - _ => item0.GetByteArray() + _ => item0.GetSpan().ToArray() }; - byte[] pubkey = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); - byte[] signature = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] pubkey = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); + byte[] signature = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); try { engine.CurrentContext.EvaluationStack.Push(Crypto.Default.VerifySignature(message, signature, pubkey)); @@ -103,14 +103,14 @@ private static bool Crypto_ECDsaCheckMultiSig(ApplicationEngine engine) { InteropInterface _interface => _interface.GetInterface().GetHashData(), Null _ => engine.ScriptContainer.GetHashData(), - _ => item0.GetByteArray() + _ => item0.GetSpan().ToArray() }; int n; byte[][] pubkeys; StackItem item = engine.CurrentContext.EvaluationStack.Pop(); if (item is VMArray array1) { - pubkeys = array1.Select(p => p.GetByteArray()).ToArray(); + pubkeys = array1.Select(p => p.GetSpan().ToArray()).ToArray(); n = pubkeys.Length; if (n == 0) return false; } @@ -120,14 +120,14 @@ private static bool Crypto_ECDsaCheckMultiSig(ApplicationEngine engine) if (n < 1 || n > engine.CurrentContext.EvaluationStack.Count) return false; pubkeys = new byte[n][]; for (int i = 0; i < n; i++) - pubkeys[i] = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + pubkeys[i] = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); } int m; byte[][] signatures; item = engine.CurrentContext.EvaluationStack.Pop(); if (item is VMArray array2) { - signatures = array2.Select(p => p.GetByteArray()).ToArray(); + signatures = array2.Select(p => p.GetSpan().ToArray()).ToArray(); m = signatures.Length; if (m == 0 || m > n) return false; } @@ -137,7 +137,7 @@ private static bool Crypto_ECDsaCheckMultiSig(ApplicationEngine engine) if (m < 1 || m > n || m > engine.CurrentContext.EvaluationStack.Count) return false; signatures = new byte[m][]; for (int i = 0; i < m; i++) - signatures[i] = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + signatures[i] = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); } bool fSuccess = true; try @@ -161,7 +161,7 @@ private static bool Crypto_ECDsaCheckMultiSig(ApplicationEngine engine) private static bool Account_IsStandard(ApplicationEngine engine) { - UInt160 hash = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray()); + UInt160 hash = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray()); ContractState contract = engine.Snapshot.Contracts.TryGet(hash); bool isStandard = contract is null || contract.Script.IsStandardContract(); engine.CurrentContext.EvaluationStack.Push(isStandard); @@ -170,7 +170,7 @@ private static bool Account_IsStandard(ApplicationEngine engine) private static bool Contract_Create(ApplicationEngine engine) { - byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); if (script.Length > 1024 * 1024) return false; var manifest = engine.CurrentContext.EvaluationStack.Pop().GetString(); @@ -194,7 +194,7 @@ private static bool Contract_Create(ApplicationEngine engine) private static bool Contract_Update(ApplicationEngine engine) { - byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); if (script.Length > 1024 * 1024) return false; var manifest = engine.CurrentContext.EvaluationStack.Pop().GetString(); if (manifest.Length > ContractManifest.MaxLength) return false; @@ -236,6 +236,7 @@ private static bool Contract_Update(ApplicationEngine engine) contract = engine.Snapshot.Contracts.GetAndChange(contract.ScriptHash); contract.Manifest = ContractManifest.Parse(manifest); if (!contract.Manifest.IsValid(contract.ScriptHash)) return false; + if (!contract.HasStorage && engine.Snapshot.Storages.Find(engine.CurrentScriptHash.ToArray()).Any()) return false; } return true; @@ -247,7 +248,7 @@ private static bool Storage_Find(ApplicationEngine engine) { StorageContext context = _interface.GetInterface(); if (!CheckStorageContext(engine, context)) return false; - byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); byte[] prefix_key = StorageKey.CreateSearchPrefix(context.ScriptHash, prefix); StorageIterator iterator = engine.AddDisposable(new StorageIterator(engine.Snapshot.Storages.Find(prefix_key).Where(p => p.Key.Key.Take(prefix.Length).SequenceEqual(prefix)).GetEnumerator())); engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(iterator)); diff --git a/neo/SmartContract/InteropService.cs b/src/neo/SmartContract/InteropService.cs similarity index 97% rename from neo/SmartContract/InteropService.cs rename to src/neo/SmartContract/InteropService.cs index be80366811..012876c96e 100644 --- a/neo/SmartContract/InteropService.cs +++ b/src/neo/SmartContract/InteropService.cs @@ -229,7 +229,7 @@ private static bool CheckWitness(ApplicationEngine engine, ECPoint pubkey) private static bool Runtime_CheckWitness(ApplicationEngine engine) { - byte[] hashOrPubkey = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] hashOrPubkey = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); bool result; if (hashOrPubkey.Length == 20) result = CheckWitness(engine, new UInt160(hashOrPubkey)); @@ -251,7 +251,7 @@ private static bool Runtime_Notify(ApplicationEngine engine) private static bool Runtime_Log(ApplicationEngine engine) { - byte[] state = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] state = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); if (state.Length > MaxNotificationSize) return false; string message = Encoding.UTF8.GetString(state); engine.SendLog(engine.CurrentScriptHash, message); @@ -288,7 +288,7 @@ private static bool Runtime_GetNotifications(ApplicationEngine engine) IEnumerable notifications = engine.Notifications; if (!item.IsNull) // must filter by scriptHash { - var hash = new UInt160(item.GetByteArray()); + var hash = new UInt160(item.GetSpan().ToArray()); notifications = notifications.Where(p => p.ScriptHash == hash); } @@ -313,7 +313,7 @@ private static bool Runtime_Deserialize(ApplicationEngine engine) StackItem item; try { - item = engine.CurrentContext.EvaluationStack.Pop().GetByteArray().DeserializeStackItem(engine.MaxArraySize, engine.MaxItemSize); + item = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray().DeserializeStackItem(engine.MaxArraySize, engine.MaxItemSize); } catch (FormatException) { @@ -335,7 +335,7 @@ private static bool Blockchain_GetHeight(ApplicationEngine engine) private static bool Blockchain_GetBlock(ApplicationEngine engine) { - byte[] data = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] data = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); UInt256 hash; if (data.Length <= 5) hash = Blockchain.Singleton.GetBlockHash((uint)new BigInteger(data)); @@ -354,7 +354,7 @@ private static bool Blockchain_GetBlock(ApplicationEngine engine) private static bool Blockchain_GetTransaction(ApplicationEngine engine) { - byte[] hash = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] hash = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); Transaction tx = engine.Snapshot.GetTransaction(new UInt256(hash)); if (tx == null) engine.CurrentContext.EvaluationStack.Push(StackItem.Null); @@ -365,7 +365,7 @@ private static bool Blockchain_GetTransaction(ApplicationEngine engine) private static bool Blockchain_GetTransactionHeight(ApplicationEngine engine) { - byte[] hash = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] hash = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); var tx = engine.Snapshot.Transactions.TryGet(new UInt256(hash)); engine.CurrentContext.EvaluationStack.Push(tx != null ? new BigInteger(tx.BlockIndex) : BigInteger.MinusOne); return true; @@ -373,7 +373,7 @@ private static bool Blockchain_GetTransactionHeight(ApplicationEngine engine) private static bool Blockchain_GetTransactionFromBlock(ApplicationEngine engine) { - byte[] data = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] data = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); UInt256 hash; if (data.Length <= 5) hash = Blockchain.Singleton.GetBlockHash((uint)new BigInteger(data)); @@ -403,7 +403,7 @@ private static bool Blockchain_GetTransactionFromBlock(ApplicationEngine engine) private static bool Blockchain_GetContract(ApplicationEngine engine) { - UInt160 hash = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray()); + UInt160 hash = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray()); ContractState contract = engine.Snapshot.Contracts.TryGet(hash); if (contract == null) engine.CurrentContext.EvaluationStack.Push(StackItem.Null); @@ -438,7 +438,7 @@ private static bool Storage_Get(ApplicationEngine engine) { StorageContext context = _interface.GetInterface(); if (!CheckStorageContext(engine, context)) return false; - byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); StorageItem item = engine.Snapshot.Storages.TryGet(new StorageKey { ScriptHash = context.ScriptHash, @@ -471,7 +471,7 @@ private static bool Contract_Call(ApplicationEngine engine) { StackItem contractHash = engine.CurrentContext.EvaluationStack.Pop(); - ContractState contract = engine.Snapshot.Contracts.TryGet(new UInt160(contractHash.GetByteArray())); + ContractState contract = engine.Snapshot.Contracts.TryGet(new UInt160(contractHash.GetSpan().ToArray())); if (contract is null) return false; StackItem method = engine.CurrentContext.EvaluationStack.Pop(); @@ -542,8 +542,8 @@ private static bool Storage_Put(ApplicationEngine engine) if (!(engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface)) return false; StorageContext context = _interface.GetInterface(); - byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); - byte[] value = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); + byte[] value = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); return PutEx(engine, context, key, value, StorageFlags.None); } @@ -552,8 +552,8 @@ private static bool Storage_PutEx(ApplicationEngine engine) if (!(engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface)) return false; StorageContext context = _interface.GetInterface(); - byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); - byte[] value = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); + byte[] value = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); StorageFlags flags = (StorageFlags)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger(); return PutEx(engine, context, key, value, flags); } @@ -568,7 +568,7 @@ private static bool Storage_Delete(ApplicationEngine engine) StorageKey key = new StorageKey { ScriptHash = context.ScriptHash, - Key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray() + Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray() }; if (engine.Snapshot.Storages.TryGet(key)?.IsConstant == true) return false; engine.Snapshot.Storages.Delete(key); diff --git a/neo/SmartContract/Iterators/ArrayWrapper.cs b/src/neo/SmartContract/Iterators/ArrayWrapper.cs similarity index 94% rename from neo/SmartContract/Iterators/ArrayWrapper.cs rename to src/neo/SmartContract/Iterators/ArrayWrapper.cs index 883327bee0..84c248c679 100644 --- a/neo/SmartContract/Iterators/ArrayWrapper.cs +++ b/src/neo/SmartContract/Iterators/ArrayWrapper.cs @@ -1,4 +1,4 @@ -using Neo.VM; +using Neo.VM.Types; using System; using System.Collections.Generic; @@ -18,7 +18,7 @@ public void Dispose() { } - public StackItem Key() + public PrimitiveType Key() { if (index < 0) throw new InvalidOperationException(); diff --git a/neo/SmartContract/Iterators/ConcatenatedIterator.cs b/src/neo/SmartContract/Iterators/ConcatenatedIterator.cs similarity index 90% rename from neo/SmartContract/Iterators/ConcatenatedIterator.cs rename to src/neo/SmartContract/Iterators/ConcatenatedIterator.cs index 12f2a8cc8e..d8c556f140 100644 --- a/neo/SmartContract/Iterators/ConcatenatedIterator.cs +++ b/src/neo/SmartContract/Iterators/ConcatenatedIterator.cs @@ -1,4 +1,4 @@ -using Neo.VM; +using Neo.VM.Types; namespace Neo.SmartContract.Iterators { @@ -13,7 +13,7 @@ public ConcatenatedIterator(IIterator first, IIterator second) this.second = second; } - public StackItem Key() => current.Key(); + public PrimitiveType Key() => current.Key(); public StackItem Value() => current.Value(); public bool Next() diff --git a/neo/SmartContract/Iterators/IIterator.cs b/src/neo/SmartContract/Iterators/IIterator.cs similarity index 73% rename from neo/SmartContract/Iterators/IIterator.cs rename to src/neo/SmartContract/Iterators/IIterator.cs index 3438286615..66b3ef3bc6 100644 --- a/neo/SmartContract/Iterators/IIterator.cs +++ b/src/neo/SmartContract/Iterators/IIterator.cs @@ -1,10 +1,10 @@ using Neo.SmartContract.Enumerators; -using Neo.VM; +using Neo.VM.Types; namespace Neo.SmartContract.Iterators { internal interface IIterator : IEnumerator { - StackItem Key(); + PrimitiveType Key(); } } diff --git a/neo/SmartContract/Iterators/MapWrapper.cs b/src/neo/SmartContract/Iterators/MapWrapper.cs similarity index 70% rename from neo/SmartContract/Iterators/MapWrapper.cs rename to src/neo/SmartContract/Iterators/MapWrapper.cs index 343b946982..783993a43c 100644 --- a/neo/SmartContract/Iterators/MapWrapper.cs +++ b/src/neo/SmartContract/Iterators/MapWrapper.cs @@ -1,13 +1,13 @@ -using Neo.VM; +using Neo.VM.Types; using System.Collections.Generic; namespace Neo.SmartContract.Iterators { internal class MapWrapper : IIterator { - private readonly IEnumerator> enumerator; + private readonly IEnumerator> enumerator; - public MapWrapper(IEnumerable> map) + public MapWrapper(IEnumerable> map) { this.enumerator = map.GetEnumerator(); } @@ -17,7 +17,7 @@ public void Dispose() enumerator.Dispose(); } - public StackItem Key() + public PrimitiveType Key() { return enumerator.Current.Key; } diff --git a/neo/SmartContract/Iterators/StorageIterator.cs b/src/neo/SmartContract/Iterators/StorageIterator.cs similarity index 93% rename from neo/SmartContract/Iterators/StorageIterator.cs rename to src/neo/SmartContract/Iterators/StorageIterator.cs index 45c9d21ebd..f35d70d890 100644 --- a/neo/SmartContract/Iterators/StorageIterator.cs +++ b/src/neo/SmartContract/Iterators/StorageIterator.cs @@ -1,5 +1,5 @@ using Neo.Ledger; -using Neo.VM; +using Neo.VM.Types; using System.Collections.Generic; namespace Neo.SmartContract.Iterators @@ -18,7 +18,7 @@ public void Dispose() enumerator.Dispose(); } - public StackItem Key() + public PrimitiveType Key() { return enumerator.Current.Key.Key; } diff --git a/neo/SmartContract/JsonSerializer.cs b/src/neo/SmartContract/JsonSerializer.cs similarity index 98% rename from neo/SmartContract/JsonSerializer.cs rename to src/neo/SmartContract/JsonSerializer.cs index 96c525e0b1..14edaa5caa 100644 --- a/neo/SmartContract/JsonSerializer.cs +++ b/src/neo/SmartContract/JsonSerializer.cs @@ -26,7 +26,7 @@ public static JObject Serialize(StackItem item) } case ByteArray buffer: { - return Convert.ToBase64String(buffer.GetByteArray()); + return Convert.ToBase64String(buffer.GetSpan()); } case Integer num: { @@ -37,7 +37,7 @@ public static JObject Serialize(StackItem item) } case VMBoolean boolean: { - return boolean.GetBoolean(); + return boolean.ToBoolean(); } case Map map: { diff --git a/neo/SmartContract/LogEventArgs.cs b/src/neo/SmartContract/LogEventArgs.cs similarity index 100% rename from neo/SmartContract/LogEventArgs.cs rename to src/neo/SmartContract/LogEventArgs.cs diff --git a/neo/SmartContract/Manifest/ContractAbi.cs b/src/neo/SmartContract/Manifest/ContractAbi.cs similarity index 100% rename from neo/SmartContract/Manifest/ContractAbi.cs rename to src/neo/SmartContract/Manifest/ContractAbi.cs diff --git a/neo/SmartContract/Manifest/ContractEventDescriptor.cs b/src/neo/SmartContract/Manifest/ContractEventDescriptor.cs similarity index 100% rename from neo/SmartContract/Manifest/ContractEventDescriptor.cs rename to src/neo/SmartContract/Manifest/ContractEventDescriptor.cs diff --git a/neo/SmartContract/Manifest/ContractFeatures.cs b/src/neo/SmartContract/Manifest/ContractFeatures.cs similarity index 100% rename from neo/SmartContract/Manifest/ContractFeatures.cs rename to src/neo/SmartContract/Manifest/ContractFeatures.cs diff --git a/neo/SmartContract/Manifest/ContractGroup.cs b/src/neo/SmartContract/Manifest/ContractGroup.cs similarity index 100% rename from neo/SmartContract/Manifest/ContractGroup.cs rename to src/neo/SmartContract/Manifest/ContractGroup.cs diff --git a/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs similarity index 100% rename from neo/SmartContract/Manifest/ContractManifest.cs rename to src/neo/SmartContract/Manifest/ContractManifest.cs diff --git a/neo/SmartContract/Manifest/ContractMethodDescriptor.cs b/src/neo/SmartContract/Manifest/ContractMethodDescriptor.cs similarity index 100% rename from neo/SmartContract/Manifest/ContractMethodDescriptor.cs rename to src/neo/SmartContract/Manifest/ContractMethodDescriptor.cs diff --git a/neo/SmartContract/Manifest/ContractParameterDefinition.cs b/src/neo/SmartContract/Manifest/ContractParameterDefinition.cs similarity index 100% rename from neo/SmartContract/Manifest/ContractParameterDefinition.cs rename to src/neo/SmartContract/Manifest/ContractParameterDefinition.cs diff --git a/neo/SmartContract/Manifest/ContractPermission.cs b/src/neo/SmartContract/Manifest/ContractPermission.cs similarity index 100% rename from neo/SmartContract/Manifest/ContractPermission.cs rename to src/neo/SmartContract/Manifest/ContractPermission.cs diff --git a/neo/SmartContract/Manifest/ContractPermissionDescriptor.cs b/src/neo/SmartContract/Manifest/ContractPermissionDescriptor.cs similarity index 100% rename from neo/SmartContract/Manifest/ContractPermissionDescriptor.cs rename to src/neo/SmartContract/Manifest/ContractPermissionDescriptor.cs diff --git a/neo/SmartContract/Manifest/WildCardContainer.cs b/src/neo/SmartContract/Manifest/WildCardContainer.cs similarity index 100% rename from neo/SmartContract/Manifest/WildCardContainer.cs rename to src/neo/SmartContract/Manifest/WildCardContainer.cs diff --git a/neo/SmartContract/Native/ContractMethodAttribute.cs b/src/neo/SmartContract/Native/ContractMethodAttribute.cs similarity index 100% rename from neo/SmartContract/Native/ContractMethodAttribute.cs rename to src/neo/SmartContract/Native/ContractMethodAttribute.cs diff --git a/neo/SmartContract/Native/ContractMethodMetadata.cs b/src/neo/SmartContract/Native/ContractMethodMetadata.cs similarity index 92% rename from neo/SmartContract/Native/ContractMethodMetadata.cs rename to src/neo/SmartContract/Native/ContractMethodMetadata.cs index 9267bb7db9..87dfba4a40 100644 --- a/neo/SmartContract/Native/ContractMethodMetadata.cs +++ b/src/neo/SmartContract/Native/ContractMethodMetadata.cs @@ -1,4 +1,4 @@ -using Neo.VM; +using Neo.VM.Types; using System; using VMArray = Neo.VM.Types.Array; diff --git a/neo/SmartContract/Native/NativeContract.cs b/src/neo/SmartContract/Native/NativeContract.cs similarity index 99% rename from neo/SmartContract/Native/NativeContract.cs rename to src/neo/SmartContract/Native/NativeContract.cs index 546743fc49..b9d3c9ecba 100644 --- a/neo/SmartContract/Native/NativeContract.cs +++ b/src/neo/SmartContract/Native/NativeContract.cs @@ -5,6 +5,7 @@ using Neo.SmartContract.Manifest; using Neo.SmartContract.Native.Tokens; using Neo.VM; +using Neo.VM.Types; using System; using System.Collections.Generic; using System.Linq; diff --git a/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs similarity index 97% rename from neo/SmartContract/Native/PolicyContract.cs rename to src/neo/SmartContract/Native/PolicyContract.cs index 3ffe8199e5..797104924e 100644 --- a/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -7,6 +7,7 @@ using Neo.Persistence; using Neo.SmartContract.Manifest; using Neo.VM; +using Neo.VM.Types; using System; using System.Collections.Generic; using System.Linq; @@ -144,7 +145,7 @@ private StackItem SetFeePerByte(ApplicationEngine engine, VMArray args) private StackItem BlockAccount(ApplicationEngine engine, VMArray args) { if (!CheckValidators(engine)) return false; - UInt160 account = new UInt160(args[0].GetByteArray()); + UInt160 account = new UInt160(args[0].GetSpan().ToArray()); StorageKey key = CreateStorageKey(Prefix_BlockedAccounts); StorageItem storage = engine.Snapshot.Storages[key]; HashSet accounts = new HashSet(storage.Value.AsSerializableArray()); @@ -158,7 +159,7 @@ private StackItem BlockAccount(ApplicationEngine engine, VMArray args) private StackItem UnblockAccount(ApplicationEngine engine, VMArray args) { if (!CheckValidators(engine)) return false; - UInt160 account = new UInt160(args[0].GetByteArray()); + UInt160 account = new UInt160(args[0].GetSpan().ToArray()); StorageKey key = CreateStorageKey(Prefix_BlockedAccounts); StorageItem storage = engine.Snapshot.Storages[key]; HashSet accounts = new HashSet(storage.Value.AsSerializableArray()); diff --git a/neo/SmartContract/Native/Tokens/GasToken.cs b/src/neo/SmartContract/Native/Tokens/GasToken.cs similarity index 99% rename from neo/SmartContract/Native/Tokens/GasToken.cs rename to src/neo/SmartContract/Native/Tokens/GasToken.cs index 7ef522dab7..4266494a4f 100644 --- a/neo/SmartContract/Native/Tokens/GasToken.cs +++ b/src/neo/SmartContract/Native/Tokens/GasToken.cs @@ -5,6 +5,7 @@ using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.VM; +using Neo.VM.Types; using System; using System.Linq; using System.Numerics; diff --git a/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs similarity index 97% rename from neo/SmartContract/Native/Tokens/NeoToken.cs rename to src/neo/SmartContract/Native/Tokens/NeoToken.cs index 7b28bd0923..ba059aff4d 100644 --- a/neo/SmartContract/Native/Tokens/NeoToken.cs +++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs @@ -119,7 +119,7 @@ protected override bool OnPersist(ApplicationEngine engine) [ContractMethod(0_03000000, ContractParameterType.Integer, ParameterTypes = new[] { ContractParameterType.Hash160, ContractParameterType.Integer }, ParameterNames = new[] { "account", "end" }, SafeMethod = true)] private StackItem UnclaimedGas(ApplicationEngine engine, VMArray args) { - UInt160 account = new UInt160(args[0].GetByteArray()); + UInt160 account = new UInt160(args[0].GetSpan().ToArray()); uint end = (uint)args[1].GetBigInteger(); return UnclaimedGas(engine.Snapshot, account, end); } @@ -135,7 +135,7 @@ public BigInteger UnclaimedGas(Snapshot snapshot, UInt160 account, uint end) [ContractMethod(0_05000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.PublicKey }, ParameterNames = new[] { "pubkey" })] private StackItem RegisterValidator(ApplicationEngine engine, VMArray args) { - ECPoint pubkey = args[0].GetByteArray().AsSerializable(); + ECPoint pubkey = args[0].GetSpan().AsSerializable(); return RegisterValidator(engine.Snapshot, pubkey); } @@ -153,8 +153,8 @@ private bool RegisterValidator(Snapshot snapshot, ECPoint pubkey) [ContractMethod(5_00000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.Hash160, ContractParameterType.Array }, ParameterNames = new[] { "account", "pubkeys" })] private StackItem Vote(ApplicationEngine engine, VMArray args) { - UInt160 account = new UInt160(args[0].GetByteArray()); - ECPoint[] pubkeys = ((VMArray)args[1]).Select(p => p.GetByteArray().AsSerializable()).ToArray(); + UInt160 account = new UInt160(args[0].GetSpan().ToArray()); + ECPoint[] pubkeys = ((VMArray)args[1]).Select(p => p.GetSpan().AsSerializable()).ToArray(); if (!InteropService.CheckWitness(engine, account)) return false; StorageKey key_account = CreateAccountKey(account); if (engine.Snapshot.Storages.TryGet(key_account) is null) return false; @@ -266,7 +266,7 @@ protected override void FromStruct(Struct @struct) { base.FromStruct(@struct); BalanceHeight = (uint)@struct[1].GetBigInteger(); - Votes = @struct[2].GetByteArray().AsSerializableArray(Blockchain.MaxValidators); + Votes = @struct[2].GetSpan().AsSerializableArray(Blockchain.MaxValidators); } protected override Struct ToStruct() diff --git a/neo/SmartContract/Native/Tokens/Nep5AccountState.cs b/src/neo/SmartContract/Native/Tokens/Nep5AccountState.cs similarity index 100% rename from neo/SmartContract/Native/Tokens/Nep5AccountState.cs rename to src/neo/SmartContract/Native/Tokens/Nep5AccountState.cs diff --git a/neo/SmartContract/Native/Tokens/Nep5Token.cs b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs similarity index 98% rename from neo/SmartContract/Native/Tokens/Nep5Token.cs rename to src/neo/SmartContract/Native/Tokens/Nep5Token.cs index a95885a665..6d35d00410 100644 --- a/neo/SmartContract/Native/Tokens/Nep5Token.cs +++ b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs @@ -4,6 +4,7 @@ using Neo.Persistence; using Neo.SmartContract.Manifest; using Neo.VM; +using Neo.VM.Types; using System; using System.Collections.Generic; using System.Numerics; @@ -147,7 +148,7 @@ public virtual BigInteger TotalSupply(Snapshot snapshot) [ContractMethod(0_01000000, ContractParameterType.Integer, ParameterTypes = new[] { ContractParameterType.Hash160 }, ParameterNames = new[] { "account" }, SafeMethod = true)] protected StackItem BalanceOf(ApplicationEngine engine, VMArray args) { - return BalanceOf(engine.Snapshot, new UInt160(args[0].GetByteArray())); + return BalanceOf(engine.Snapshot, new UInt160(args[0].GetSpan().ToArray())); } public virtual BigInteger BalanceOf(Snapshot snapshot, UInt160 account) @@ -161,8 +162,8 @@ public virtual BigInteger BalanceOf(Snapshot snapshot, UInt160 account) [ContractMethod(0_08000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.Hash160, ContractParameterType.Hash160, ContractParameterType.Integer }, ParameterNames = new[] { "from", "to", "amount" })] protected StackItem Transfer(ApplicationEngine engine, VMArray args) { - UInt160 from = new UInt160(args[0].GetByteArray()); - UInt160 to = new UInt160(args[1].GetByteArray()); + UInt160 from = new UInt160(args[0].GetSpan().ToArray()); + UInt160 to = new UInt160(args[1].GetSpan().ToArray()); BigInteger amount = args[2].GetBigInteger(); return Transfer(engine, from, to, amount); } diff --git a/neo/SmartContract/NefFile.cs b/src/neo/SmartContract/NefFile.cs similarity index 100% rename from neo/SmartContract/NefFile.cs rename to src/neo/SmartContract/NefFile.cs diff --git a/neo/SmartContract/NotifyEventArgs.cs b/src/neo/SmartContract/NotifyEventArgs.cs similarity index 96% rename from neo/SmartContract/NotifyEventArgs.cs rename to src/neo/SmartContract/NotifyEventArgs.cs index 8fab961408..e1d3fd8c1e 100644 --- a/neo/SmartContract/NotifyEventArgs.cs +++ b/src/neo/SmartContract/NotifyEventArgs.cs @@ -1,5 +1,5 @@ using Neo.Network.P2P.Payloads; -using Neo.VM; +using Neo.VM.Types; using System; namespace Neo.SmartContract diff --git a/neo/SmartContract/StackItemType.cs b/src/neo/SmartContract/StackItemType.cs similarity index 100% rename from neo/SmartContract/StackItemType.cs rename to src/neo/SmartContract/StackItemType.cs diff --git a/neo/SmartContract/StorageContext.cs b/src/neo/SmartContract/StorageContext.cs similarity index 100% rename from neo/SmartContract/StorageContext.cs rename to src/neo/SmartContract/StorageContext.cs diff --git a/neo/SmartContract/TriggerType.cs b/src/neo/SmartContract/TriggerType.cs similarity index 100% rename from neo/SmartContract/TriggerType.cs rename to src/neo/SmartContract/TriggerType.cs diff --git a/neo/TimeProvider.cs b/src/neo/TimeProvider.cs similarity index 100% rename from neo/TimeProvider.cs rename to src/neo/TimeProvider.cs diff --git a/neo/UInt160.cs b/src/neo/UInt160.cs similarity index 100% rename from neo/UInt160.cs rename to src/neo/UInt160.cs diff --git a/neo/UInt256.cs b/src/neo/UInt256.cs similarity index 100% rename from neo/UInt256.cs rename to src/neo/UInt256.cs diff --git a/neo/UIntBase.cs b/src/neo/UIntBase.cs similarity index 100% rename from neo/UIntBase.cs rename to src/neo/UIntBase.cs diff --git a/src/neo/Utility.cs b/src/neo/Utility.cs new file mode 100644 index 0000000000..56e048a512 --- /dev/null +++ b/src/neo/Utility.cs @@ -0,0 +1,61 @@ +using Neo.Cryptography.ECC; +using Neo.SmartContract; +using Neo.Wallets; +using System; + +namespace Neo +{ + public static class Utility + { + /// + /// Parse WIF or private key hex string to KeyPair + /// + /// WIF or private key hex string + /// Example: WIF ("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"), PrivateKey ("450d6c2a04b5b470339a745427bae6828400cf048400837d73c415063835e005") + /// + public static KeyPair GetKeyPair(string key) + { + if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException(nameof(key)); } + if (key.StartsWith("0x")) { key = key.Substring(2); } + + if (key.Length == 52) + { + return new KeyPair(Wallet.GetPrivateKeyFromWIF(key)); + } + else if (key.Length == 64) + { + return new KeyPair(key.HexToBytes()); + } + + throw new FormatException(); + } + + /// + /// Parse address, scripthash or public key string to UInt160 + /// + /// account address, scripthash or public key string + /// Example: address ("AV556nYUwyJKNv8Xy7hVMLQnkmKPukw6x5"), scripthash ("0x6a38cd693b615aea24dd00de12a9f5836844da91"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575") + /// + public static UInt160 GetScriptHash(string account) + { + if (string.IsNullOrEmpty(account)) { throw new ArgumentNullException(nameof(account)); } + if (account.StartsWith("0x")) { account = account.Substring(2); } + + if (account.Length == 34) + { + return Wallets.Helper.ToScriptHash(account); + } + else if (account.Length == 40) + { + return UInt160.Parse(account); + } + else if (account.Length == 66) + { + var pubKey = ECPoint.Parse(account, ECCurve.Secp256r1); + return Contract.CreateSignatureRedeemScript(pubKey).ToScriptHash(); + } + + throw new FormatException(); + } + } +} diff --git a/neo/VM/Helper.cs b/src/neo/VM/Helper.cs similarity index 92% rename from neo/VM/Helper.cs rename to src/neo/VM/Helper.cs index 5d2a2aa485..37a4d964c2 100644 --- a/neo/VM/Helper.cs +++ b/src/neo/VM/Helper.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; +using System.Text; using VMArray = Neo.VM.Types.Array; using VMBoolean = Neo.VM.Types.Boolean; @@ -165,6 +166,32 @@ public static ScriptBuilder EmitSysCall(this ScriptBuilder sb, uint method, para return sb.EmitSysCall(method); } + public static BigInteger GetBigInteger(this StackItem item) + { + if (!(item is PrimitiveType primitive)) + throw new ArgumentException(); + return primitive.ToBigInteger(); + } + + public static int GetByteLength(this StackItem item) + { + if (!(item is PrimitiveType primitive)) + throw new ArgumentException(); + return primitive.GetByteLength(); + } + + public static ReadOnlySpan GetSpan(this StackItem item) + { + if (!(item is PrimitiveType primitive)) + throw new ArgumentException(); + return primitive.ToByteArray(); + } + + public static string GetString(this StackItem item) + { + return Encoding.UTF8.GetString(item.GetSpan()); + } + /// /// Generate scripts to call a specific method from a specific contract. /// @@ -222,14 +249,14 @@ private static ContractParameter ToParameter(StackItem item, List ReferenceEquals(p.Item2, parameter))?.Item1; if (stackItem is null) { - stackItem = new Map(((IList>)parameter.Value).ToDictionary(p => ToStackItem(p.Key, context), p => ToStackItem(p.Value, context))); + stackItem = new Map(((IList>)parameter.Value).ToDictionary(p => (PrimitiveType)ToStackItem(p.Key, context), p => ToStackItem(p.Value, context))); context.Add(new Tuple(stackItem, parameter)); } break; diff --git a/neo/Wallets/AssetDescriptor.cs b/src/neo/Wallets/AssetDescriptor.cs similarity index 100% rename from neo/Wallets/AssetDescriptor.cs rename to src/neo/Wallets/AssetDescriptor.cs diff --git a/neo/Wallets/Helper.cs b/src/neo/Wallets/Helper.cs similarity index 100% rename from neo/Wallets/Helper.cs rename to src/neo/Wallets/Helper.cs diff --git a/neo/Wallets/KeyPair.cs b/src/neo/Wallets/KeyPair.cs similarity index 100% rename from neo/Wallets/KeyPair.cs rename to src/neo/Wallets/KeyPair.cs diff --git a/neo/Wallets/NEP6/NEP6Account.cs b/src/neo/Wallets/NEP6/NEP6Account.cs similarity index 100% rename from neo/Wallets/NEP6/NEP6Account.cs rename to src/neo/Wallets/NEP6/NEP6Account.cs diff --git a/neo/Wallets/NEP6/NEP6Contract.cs b/src/neo/Wallets/NEP6/NEP6Contract.cs similarity index 100% rename from neo/Wallets/NEP6/NEP6Contract.cs rename to src/neo/Wallets/NEP6/NEP6Contract.cs diff --git a/neo/Wallets/NEP6/NEP6Wallet.cs b/src/neo/Wallets/NEP6/NEP6Wallet.cs similarity index 100% rename from neo/Wallets/NEP6/NEP6Wallet.cs rename to src/neo/Wallets/NEP6/NEP6Wallet.cs diff --git a/neo/Wallets/NEP6/ScryptParameters.cs b/src/neo/Wallets/NEP6/ScryptParameters.cs similarity index 100% rename from neo/Wallets/NEP6/ScryptParameters.cs rename to src/neo/Wallets/NEP6/ScryptParameters.cs diff --git a/neo/Wallets/NEP6/WalletLocker.cs b/src/neo/Wallets/NEP6/WalletLocker.cs similarity index 100% rename from neo/Wallets/NEP6/WalletLocker.cs rename to src/neo/Wallets/NEP6/WalletLocker.cs diff --git a/neo/Wallets/SQLite/Account.cs b/src/neo/Wallets/SQLite/Account.cs similarity index 100% rename from neo/Wallets/SQLite/Account.cs rename to src/neo/Wallets/SQLite/Account.cs diff --git a/neo/Wallets/SQLite/Address.cs b/src/neo/Wallets/SQLite/Address.cs similarity index 100% rename from neo/Wallets/SQLite/Address.cs rename to src/neo/Wallets/SQLite/Address.cs diff --git a/neo/Wallets/SQLite/Contract.cs b/src/neo/Wallets/SQLite/Contract.cs similarity index 100% rename from neo/Wallets/SQLite/Contract.cs rename to src/neo/Wallets/SQLite/Contract.cs diff --git a/neo/Wallets/SQLite/Key.cs b/src/neo/Wallets/SQLite/Key.cs similarity index 100% rename from neo/Wallets/SQLite/Key.cs rename to src/neo/Wallets/SQLite/Key.cs diff --git a/neo/Wallets/SQLite/UserWallet.cs b/src/neo/Wallets/SQLite/UserWallet.cs similarity index 100% rename from neo/Wallets/SQLite/UserWallet.cs rename to src/neo/Wallets/SQLite/UserWallet.cs diff --git a/neo/Wallets/SQLite/UserWalletAccount.cs b/src/neo/Wallets/SQLite/UserWalletAccount.cs similarity index 100% rename from neo/Wallets/SQLite/UserWalletAccount.cs rename to src/neo/Wallets/SQLite/UserWalletAccount.cs diff --git a/neo/Wallets/SQLite/VerificationContract.cs b/src/neo/Wallets/SQLite/VerificationContract.cs similarity index 100% rename from neo/Wallets/SQLite/VerificationContract.cs rename to src/neo/Wallets/SQLite/VerificationContract.cs diff --git a/neo/Wallets/SQLite/WalletDataContext.cs b/src/neo/Wallets/SQLite/WalletDataContext.cs similarity index 100% rename from neo/Wallets/SQLite/WalletDataContext.cs rename to src/neo/Wallets/SQLite/WalletDataContext.cs diff --git a/neo/Wallets/TransferOutput.cs b/src/neo/Wallets/TransferOutput.cs similarity index 100% rename from neo/Wallets/TransferOutput.cs rename to src/neo/Wallets/TransferOutput.cs diff --git a/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs similarity index 100% rename from neo/Wallets/Wallet.cs rename to src/neo/Wallets/Wallet.cs diff --git a/neo/Wallets/WalletAccount.cs b/src/neo/Wallets/WalletAccount.cs similarity index 100% rename from neo/Wallets/WalletAccount.cs rename to src/neo/Wallets/WalletAccount.cs diff --git a/neo/neo.csproj b/src/neo/neo.csproj similarity index 71% rename from neo/neo.csproj rename to src/neo/neo.csproj index 98824eb526..5897121579 100644 --- a/neo/neo.csproj +++ b/src/neo/neo.csproj @@ -3,9 +3,10 @@ 2015-2019 The Neo Project Neo - 3.0.0-preview1 + 3.0.0 + preview1 The Neo Project - netstandard2.0;net47 + netstandard2.1 true Neo Neo @@ -17,25 +18,19 @@ Neo The Neo Project Neo - preview - + - - - - - - - - - + + + + diff --git a/neo.UnitTests/Consensus/UT_Consensus.cs b/tests/neo.UnitTests/Consensus/UT_Consensus.cs similarity index 99% rename from neo.UnitTests/Consensus/UT_Consensus.cs rename to tests/neo.UnitTests/Consensus/UT_Consensus.cs index c8d8fbf6c4..c10e6c94e3 100644 --- a/neo.UnitTests/Consensus/UT_Consensus.cs +++ b/tests/neo.UnitTests/Consensus/UT_Consensus.cs @@ -20,7 +20,6 @@ namespace Neo.UnitTests.Consensus { - [TestClass] public class ConsensusTests : TestKit { diff --git a/neo.UnitTests/Consensus/UT_ConsensusContext.cs b/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs similarity index 84% rename from neo.UnitTests/Consensus/UT_ConsensusContext.cs rename to tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs index 9a0dd39ba7..821b6f8da5 100644 --- a/neo.UnitTests/Consensus/UT_ConsensusContext.cs +++ b/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs @@ -4,7 +4,6 @@ using Neo.Consensus; using Neo.IO; using Neo.Network.P2P.Payloads; -using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.Wallets; using System; @@ -119,6 +118,8 @@ private Block SignBlock(ConsensusContext context) { context.Block.MerkleRoot = null; + // Fake commits + for (int x = 0; x < _validatorKeys.Length; x++) { _context.MyIndex = x; @@ -127,19 +128,7 @@ private Block SignBlock(ConsensusContext context) _context.CommitPayloads[_context.MyIndex] = com; } - // Manual block sign - - Contract contract = Contract.CreateMultiSigContract(context.M, context.Validators); - ContractParametersContext sc = new ContractParametersContext(context.Block); - for (int i = 0, j = 0; i < context.Validators.Length && j < context.M; i++) - { - if (context.CommitPayloads[i]?.ConsensusMessage.ViewNumber != context.ViewNumber) continue; - sc.AddSignature(contract, context.Validators[i], context.CommitPayloads[i].GetDeserializedMessage().Signature); - j++; - } - context.Block.Witness = sc.GetWitnesses()[0]; - context.Block.Transactions = context.TransactionHashes.Select(p => context.Transactions[p]).ToArray(); - return context.Block; + return context.CreateBlock(); } private void EnsureContext(ConsensusContext context, params Transaction[] expected) diff --git a/neo.UnitTests/Consensus/UT_ConsensusServiceMailbox.cs b/tests/neo.UnitTests/Consensus/UT_ConsensusServiceMailbox.cs similarity index 100% rename from neo.UnitTests/Consensus/UT_ConsensusServiceMailbox.cs rename to tests/neo.UnitTests/Consensus/UT_ConsensusServiceMailbox.cs diff --git a/neo.UnitTests/Cryptography/ECC/UT_ECDsa.cs b/tests/neo.UnitTests/Cryptography/ECC/UT_ECDsa.cs similarity index 100% rename from neo.UnitTests/Cryptography/ECC/UT_ECDsa.cs rename to tests/neo.UnitTests/Cryptography/ECC/UT_ECDsa.cs diff --git a/neo.UnitTests/Cryptography/ECC/UT_ECFieldElement.cs b/tests/neo.UnitTests/Cryptography/ECC/UT_ECFieldElement.cs similarity index 100% rename from neo.UnitTests/Cryptography/ECC/UT_ECFieldElement.cs rename to tests/neo.UnitTests/Cryptography/ECC/UT_ECFieldElement.cs diff --git a/neo.UnitTests/Cryptography/ECC/UT_ECPoint.cs b/tests/neo.UnitTests/Cryptography/ECC/UT_ECPoint.cs similarity index 100% rename from neo.UnitTests/Cryptography/ECC/UT_ECPoint.cs rename to tests/neo.UnitTests/Cryptography/ECC/UT_ECPoint.cs diff --git a/tests/neo.UnitTests/Cryptography/UT_Base58.cs b/tests/neo.UnitTests/Cryptography/UT_Base58.cs new file mode 100644 index 0000000000..fbf29ba888 --- /dev/null +++ b/tests/neo.UnitTests/Cryptography/UT_Base58.cs @@ -0,0 +1,50 @@ +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Cryptography; +using System; +using System.Collections.Generic; + +namespace Neo.UnitTests.Cryptography +{ + [TestClass] + public class UT_Base58 + { + [TestMethod] + public void TestEncodeDecode() + { + var bitcoinTest = new Dictionary() + { + // Tests from https://github.com/bitcoin/bitcoin/blob/46fc4d1a24c88e797d6080336e3828e45e39c3fd/src/test/data/base58_encode_decode.json + + {"", ""}, + {"61", "2g"}, + {"626262", "a3gV"}, + {"636363", "aPEr"}, + {"73696d706c792061206c6f6e6720737472696e67", "2cFupjhnEsSn59qHXstmK2ffpLv2"}, + {"00eb15231dfceb60925886b67d065299925915aeb172c06647", "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"}, + {"516b6fcd0f", "ABnLTmg"}, + {"bf4f89001e670274dd", "3SEo3LWLoPntC"}, + {"572e4794", "3EFU7m"}, + {"ecac89cad93923c02321", "EJDM8drfXA6uyA"}, + {"10c8511e", "Rt5zm"}, + {"00000000000000000000", "1111111111"}, + {"000111d38e5fc9071ffcd20b4a763cc9ae4f252bb4e48fd66a835e252ada93ff480d6dd43dc62a641155a5", "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"}, + {"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "1cWB5HCBdLjAuqGGReWE3R3CguuwSjw6RHn39s2yuDRTS5NsBgNiFpWgAnEx6VQi8csexkgYw3mdYrMHr8x9i7aEwP8kZ7vccXWqKDvGv3u1GxFKPuAkn8JCPPGDMf3vMMnbzm6Nh9zh1gcNsMvH3ZNLmP5fSG6DGbbi2tuwMWPthr4boWwCxf7ewSgNQeacyozhKDDQQ1qL5fQFUW52QKUZDZ5fw3KXNQJMcNTcaB723LchjeKun7MuGW5qyCBZYzA1KjofN1gYBV3NqyhQJ3Ns746GNuf9N2pQPmHz4xpnSrrfCvy6TVVz5d4PdrjeshsWQwpZsZGzvbdAdN8MKV5QsBDY"}, + + // Extra tests + + {"00", "1"}, + {"00010203040506070809", "1kA3B2yGe2z4"}, + }; + + foreach (var entry in bitcoinTest) + { + Base58.Encode(entry.Key.HexToBytes()).Should().Be(entry.Value); + Base58.Decode(entry.Value).Should().BeEquivalentTo(entry.Key.HexToBytes()); + + Action action = () => Base58.Decode(entry.Value + "l"); + action.Should().Throw(); + } + } + } +} diff --git a/neo.UnitTests/Cryptography/UT_BloomFilter.cs b/tests/neo.UnitTests/Cryptography/UT_BloomFilter.cs similarity index 100% rename from neo.UnitTests/Cryptography/UT_BloomFilter.cs rename to tests/neo.UnitTests/Cryptography/UT_BloomFilter.cs diff --git a/neo.UnitTests/Cryptography/UT_Crypto.cs b/tests/neo.UnitTests/Cryptography/UT_Crypto.cs similarity index 100% rename from neo.UnitTests/Cryptography/UT_Crypto.cs rename to tests/neo.UnitTests/Cryptography/UT_Crypto.cs diff --git a/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs b/tests/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs similarity index 100% rename from neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs rename to tests/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs diff --git a/neo.UnitTests/Cryptography/UT_MerkleTree.cs b/tests/neo.UnitTests/Cryptography/UT_MerkleTree.cs similarity index 100% rename from neo.UnitTests/Cryptography/UT_MerkleTree.cs rename to tests/neo.UnitTests/Cryptography/UT_MerkleTree.cs diff --git a/neo.UnitTests/Cryptography/UT_MerkleTreeNode.cs b/tests/neo.UnitTests/Cryptography/UT_MerkleTreeNode.cs similarity index 100% rename from neo.UnitTests/Cryptography/UT_MerkleTreeNode.cs rename to tests/neo.UnitTests/Cryptography/UT_MerkleTreeNode.cs diff --git a/neo.UnitTests/Cryptography/UT_Murmur3.cs b/tests/neo.UnitTests/Cryptography/UT_Murmur3.cs similarity index 100% rename from neo.UnitTests/Cryptography/UT_Murmur3.cs rename to tests/neo.UnitTests/Cryptography/UT_Murmur3.cs diff --git a/neo.UnitTests/Cryptography/UT_SCrypt.cs b/tests/neo.UnitTests/Cryptography/UT_SCrypt.cs similarity index 100% rename from neo.UnitTests/Cryptography/UT_SCrypt.cs rename to tests/neo.UnitTests/Cryptography/UT_SCrypt.cs diff --git a/neo.UnitTests/Extensions/NativeContractExtensions.cs b/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs similarity index 98% rename from neo.UnitTests/Extensions/NativeContractExtensions.cs rename to tests/neo.UnitTests/Extensions/NativeContractExtensions.cs index 4d3f7bcb95..9847bddd48 100644 --- a/neo.UnitTests/Extensions/NativeContractExtensions.cs +++ b/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs @@ -2,6 +2,7 @@ using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; +using Neo.VM.Types; using System; namespace Neo.UnitTests.Extensions diff --git a/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs b/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs similarity index 94% rename from neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs rename to tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs index a531591d34..f06a7eb201 100644 --- a/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs +++ b/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs @@ -7,7 +7,6 @@ using System.IO; using System.Linq; using System.Numerics; -using System.Text; namespace Neo.UnitTests.Extensions { @@ -65,7 +64,7 @@ public static bool Transfer(this NativeContract contract, Persistence.Snapshot s var result = engine.ResultStack.Pop(); result.Should().BeOfType(typeof(VM.Types.Boolean)); - return (result as VM.Types.Boolean).GetBoolean(); + return result.ToBoolean(); } public static string[] SupportedStandards(this NativeContract contract) @@ -86,7 +85,7 @@ public static string[] SupportedStandards(this NativeContract contract) result.Should().BeOfType(typeof(VM.Types.Array)); return (result as VM.Types.Array).ToArray() - .Select(u => Encoding.ASCII.GetString(u.GetByteArray())) + .Select(u => u.GetString()) .ToArray(); } @@ -168,7 +167,7 @@ public static string Symbol(this NativeContract contract) var result = engine.ResultStack.Pop(); result.Should().BeOfType(typeof(VM.Types.ByteArray)); - return Encoding.UTF8.GetString((result as VM.Types.ByteArray).GetByteArray()); + return result.GetString(); } public static string Name(this NativeContract contract) @@ -188,7 +187,7 @@ public static string Name(this NativeContract contract) var result = engine.ResultStack.Pop(); result.Should().BeOfType(typeof(VM.Types.ByteArray)); - return Encoding.UTF8.GetString((result as VM.Types.ByteArray).GetByteArray()); + return result.GetString(); } } } diff --git a/neo.UnitTests/IO/Caching/UT_Cache.cs b/tests/neo.UnitTests/IO/Caching/UT_Cache.cs similarity index 100% rename from neo.UnitTests/IO/Caching/UT_Cache.cs rename to tests/neo.UnitTests/IO/Caching/UT_Cache.cs diff --git a/neo.UnitTests/IO/Caching/UT_CloneCache.cs b/tests/neo.UnitTests/IO/Caching/UT_CloneCache.cs similarity index 100% rename from neo.UnitTests/IO/Caching/UT_CloneCache.cs rename to tests/neo.UnitTests/IO/Caching/UT_CloneCache.cs diff --git a/neo.UnitTests/IO/Caching/UT_CloneMetaCache.cs b/tests/neo.UnitTests/IO/Caching/UT_CloneMetaCache.cs similarity index 100% rename from neo.UnitTests/IO/Caching/UT_CloneMetaCache.cs rename to tests/neo.UnitTests/IO/Caching/UT_CloneMetaCache.cs diff --git a/neo.UnitTests/IO/Caching/UT_DataCache.cs b/tests/neo.UnitTests/IO/Caching/UT_DataCache.cs similarity index 100% rename from neo.UnitTests/IO/Caching/UT_DataCache.cs rename to tests/neo.UnitTests/IO/Caching/UT_DataCache.cs diff --git a/neo.UnitTests/IO/Caching/UT_FIFOSet.cs b/tests/neo.UnitTests/IO/Caching/UT_FIFOSet.cs similarity index 100% rename from neo.UnitTests/IO/Caching/UT_FIFOSet.cs rename to tests/neo.UnitTests/IO/Caching/UT_FIFOSet.cs diff --git a/neo.UnitTests/IO/Caching/UT_MetaDataCache.cs b/tests/neo.UnitTests/IO/Caching/UT_MetaDataCache.cs similarity index 100% rename from neo.UnitTests/IO/Caching/UT_MetaDataCache.cs rename to tests/neo.UnitTests/IO/Caching/UT_MetaDataCache.cs diff --git a/neo.UnitTests/IO/Caching/UT_OrderedDictionary.cs b/tests/neo.UnitTests/IO/Caching/UT_OrderedDictionary.cs similarity index 100% rename from neo.UnitTests/IO/Caching/UT_OrderedDictionary.cs rename to tests/neo.UnitTests/IO/Caching/UT_OrderedDictionary.cs diff --git a/tests/neo.UnitTests/IO/Caching/UT_ReflectionCache.cs b/tests/neo.UnitTests/IO/Caching/UT_ReflectionCache.cs new file mode 100644 index 0000000000..547c18787d --- /dev/null +++ b/tests/neo.UnitTests/IO/Caching/UT_ReflectionCache.cs @@ -0,0 +1,77 @@ +using System.IO; +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.IO; +using Neo.IO.Caching; + +namespace Neo.UnitTests.IO.Caching +{ + public class TestItem : ISerializable + { + public int Size => 0; + public void Deserialize(BinaryReader reader) { } + public void Serialize(BinaryWriter writer) { } + } + + public class TestItem1 : TestItem { } + + public class TestItem2 : TestItem { } + + public enum MyTestEnum : byte + { + [ReflectionCache(typeof(TestItem1))] + Item1 = 0x00, + + [ReflectionCache(typeof(TestItem2))] + Item2 = 0x01, + } + + public enum MyEmptyEnum : byte { } + + [TestClass] + public class UT_ReflectionCache + { + [TestMethod] + public void TestCreateFromEmptyEnum() + { + ReflectionCache.Count.Should().Be(0); + } + + [TestMethod] + public void TestCreateInstance() + { + object item1 = ReflectionCache.CreateInstance(MyTestEnum.Item1, null); + (item1 is TestItem1).Should().BeTrue(); + + object item2 = ReflectionCache.CreateInstance(MyTestEnum.Item2, null); + (item2 is TestItem2).Should().BeTrue(); + + object item3 = ReflectionCache.CreateInstance((MyTestEnum)0x02, null); + item3.Should().BeNull(); + } + + [TestMethod] + public void TestCreateSerializable() + { + object item1 = ReflectionCache.CreateSerializable(MyTestEnum.Item1, new byte[0]); + (item1 is TestItem1).Should().BeTrue(); + + object item2 = ReflectionCache.CreateSerializable(MyTestEnum.Item2, new byte[0]); + (item2 is TestItem2).Should().BeTrue(); + + object item3 = ReflectionCache.CreateSerializable((MyTestEnum)0x02, new byte[0]); + item3.Should().BeNull(); + } + + [TestMethod] + public void TestCreateInstance2() + { + TestItem defaultItem = new TestItem1(); + object item2 = ReflectionCache.CreateInstance(MyTestEnum.Item2, defaultItem); + (item2 is TestItem2).Should().BeTrue(); + + object item1 = ReflectionCache.CreateInstance((MyTestEnum)0x02, new TestItem1()); + (item1 is TestItem1).Should().BeTrue(); + } + } +} diff --git a/neo.UnitTests/IO/Caching/UT_RelayCache.cs b/tests/neo.UnitTests/IO/Caching/UT_RelayCache.cs similarity index 100% rename from neo.UnitTests/IO/Caching/UT_RelayCache.cs rename to tests/neo.UnitTests/IO/Caching/UT_RelayCache.cs diff --git a/neo.UnitTests/IO/Data/LevelDb/UT_Slice.cs b/tests/neo.UnitTests/IO/Data/LevelDb/UT_Slice.cs similarity index 100% rename from neo.UnitTests/IO/Data/LevelDb/UT_Slice.cs rename to tests/neo.UnitTests/IO/Data/LevelDb/UT_Slice.cs diff --git a/neo.UnitTests/IO/Json/UT_JArray.cs b/tests/neo.UnitTests/IO/Json/UT_JArray.cs similarity index 100% rename from neo.UnitTests/IO/Json/UT_JArray.cs rename to tests/neo.UnitTests/IO/Json/UT_JArray.cs diff --git a/neo.UnitTests/IO/Json/UT_JBoolean.cs b/tests/neo.UnitTests/IO/Json/UT_JBoolean.cs similarity index 100% rename from neo.UnitTests/IO/Json/UT_JBoolean.cs rename to tests/neo.UnitTests/IO/Json/UT_JBoolean.cs diff --git a/neo.UnitTests/IO/Json/UT_JNumber.cs b/tests/neo.UnitTests/IO/Json/UT_JNumber.cs similarity index 100% rename from neo.UnitTests/IO/Json/UT_JNumber.cs rename to tests/neo.UnitTests/IO/Json/UT_JNumber.cs diff --git a/neo.UnitTests/IO/Json/UT_JObject.cs b/tests/neo.UnitTests/IO/Json/UT_JObject.cs similarity index 100% rename from neo.UnitTests/IO/Json/UT_JObject.cs rename to tests/neo.UnitTests/IO/Json/UT_JObject.cs diff --git a/neo.UnitTests/IO/Json/UT_JString.cs b/tests/neo.UnitTests/IO/Json/UT_JString.cs similarity index 100% rename from neo.UnitTests/IO/Json/UT_JString.cs rename to tests/neo.UnitTests/IO/Json/UT_JString.cs diff --git a/neo.UnitTests/IO/UT_ByteArrayComparer.cs b/tests/neo.UnitTests/IO/UT_ByteArrayComparer.cs similarity index 100% rename from neo.UnitTests/IO/UT_ByteArrayComparer.cs rename to tests/neo.UnitTests/IO/UT_ByteArrayComparer.cs diff --git a/neo.UnitTests/IO/UT_IOHelper.cs b/tests/neo.UnitTests/IO/UT_IOHelper.cs similarity index 100% rename from neo.UnitTests/IO/UT_IOHelper.cs rename to tests/neo.UnitTests/IO/UT_IOHelper.cs diff --git a/neo.UnitTests/IO/Wrappers/UT_SerializableWrapper.cs b/tests/neo.UnitTests/IO/Wrappers/UT_SerializableWrapper.cs similarity index 100% rename from neo.UnitTests/IO/Wrappers/UT_SerializableWrapper.cs rename to tests/neo.UnitTests/IO/Wrappers/UT_SerializableWrapper.cs diff --git a/neo.UnitTests/IO/Wrappers/UT_UInt32Wrapper.cs b/tests/neo.UnitTests/IO/Wrappers/UT_UInt32Wrapper.cs similarity index 100% rename from neo.UnitTests/IO/Wrappers/UT_UInt32Wrapper.cs rename to tests/neo.UnitTests/IO/Wrappers/UT_UInt32Wrapper.cs diff --git a/neo.UnitTests/Ledger/UT_Blockchain.cs b/tests/neo.UnitTests/Ledger/UT_Blockchain.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_Blockchain.cs rename to tests/neo.UnitTests/Ledger/UT_Blockchain.cs diff --git a/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_ContractState.cs rename to tests/neo.UnitTests/Ledger/UT_ContractState.cs diff --git a/neo.UnitTests/Ledger/UT_HashIndexState.cs b/tests/neo.UnitTests/Ledger/UT_HashIndexState.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_HashIndexState.cs rename to tests/neo.UnitTests/Ledger/UT_HashIndexState.cs diff --git a/neo.UnitTests/Ledger/UT_HeaderHashList.cs b/tests/neo.UnitTests/Ledger/UT_HeaderHashList.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_HeaderHashList.cs rename to tests/neo.UnitTests/Ledger/UT_HeaderHashList.cs diff --git a/neo.UnitTests/Ledger/UT_MemoryPool.cs b/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs similarity index 86% rename from neo.UnitTests/Ledger/UT_MemoryPool.cs rename to tests/neo.UnitTests/Ledger/UT_MemoryPool.cs index 6f9022bef1..631ae06dbc 100644 --- a/neo.UnitTests/Ledger/UT_MemoryPool.cs +++ b/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs @@ -8,6 +8,7 @@ using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.Plugins; +using Neo.SmartContract; using Neo.SmartContract.Native; using System; using System.Collections; @@ -92,6 +93,31 @@ private Transaction CreateTransactionWithFee(long fee) return mock.Object; } + private Transaction CreateTransactionWithFeeAndBalanceVerify(long fee) + { + Random random = new Random(); + var randomBytes = new byte[16]; + random.NextBytes(randomBytes); + Mock mock = new Mock(); + UInt160 sender = UInt160.Zero; + mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny())).Returns(((Snapshot snapshot, BigInteger amount) => NativeContract.GAS.BalanceOf(snapshot, sender) >= amount + fee)); + mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(true); + mock.Object.Script = randomBytes; + mock.Object.Sender = sender; + mock.Object.NetworkFee = fee; + mock.Object.Attributes = new TransactionAttribute[0]; + mock.Object.Cosigners = new Cosigner[0]; + mock.Object.Witnesses = new[] + { + new Witness + { + InvocationScript = new byte[0], + VerificationScript = new byte[0] + } + }; + return mock.Object; + } + private Transaction CreateTransaction(long fee = -1) { if (fee != -1) @@ -115,6 +141,17 @@ private void AddTransaction(Transaction txToAdd) _unit.TryAdd(txToAdd.Hash, txToAdd); } + private void AddTransactionsWithBalanceVerify(int count, long fee) + { + for (int i = 0; i < count; i++) + { + var txToAdd = CreateTransactionWithFeeAndBalanceVerify(fee); + _unit.TryAdd(txToAdd.Hash, txToAdd); + } + + Console.WriteLine($"created {count} tx"); + } + [TestMethod] public void CapacityTest() { @@ -171,6 +208,38 @@ public void BlockPersistMovesTxToUnverifiedAndReverification() _unit.UnverifiedSortedTxCount.Should().Be(0); } + [TestMethod] + public void BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered() + { + long txFee = 1; + AddTransactionsWithBalanceVerify(70, txFee); + + _unit.SortedTxCount.Should().Be(70); + + var block = new Block + { + Transactions = _unit.GetSortedVerifiedTransactions().Take(10).ToArray() + }; + + // Simulate the transfer process in tx by burning the balance + UInt160 sender = block.Transactions[0].Sender; + Snapshot snapshot = Blockchain.Singleton.GetSnapshot(); + BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, sender); + + ApplicationEngine applicationEngine = new ApplicationEngine(TriggerType.All, block, snapshot, (long)balance); + NativeContract.GAS.Burn(applicationEngine, sender, balance); + NativeContract.GAS.Mint(applicationEngine, sender, txFee * 30); // Set the balance to meet 30 txs only + + // Persist block and reverify all the txs in mempool, but half of the txs will be discarded + _unit.UpdatePoolForBlockPersisted(block, snapshot); + _unit.SortedTxCount.Should().Be(30); + _unit.UnverifiedSortedTxCount.Should().Be(0); + + // Revert the balance + NativeContract.GAS.Burn(applicationEngine, sender, txFee * 30); + NativeContract.GAS.Mint(applicationEngine, sender, balance); + } + private void VerifyTransactionsSortedDescending(IEnumerable transactions) { Transaction lastTransaction = null; diff --git a/neo.UnitTests/Ledger/UT_PoolItem.cs b/tests/neo.UnitTests/Ledger/UT_PoolItem.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_PoolItem.cs rename to tests/neo.UnitTests/Ledger/UT_PoolItem.cs diff --git a/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs b/tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs rename to tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs diff --git a/neo.UnitTests/Ledger/UT_StorageItem.cs b/tests/neo.UnitTests/Ledger/UT_StorageItem.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_StorageItem.cs rename to tests/neo.UnitTests/Ledger/UT_StorageItem.cs diff --git a/neo.UnitTests/Ledger/UT_StorageKey.cs b/tests/neo.UnitTests/Ledger/UT_StorageKey.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_StorageKey.cs rename to tests/neo.UnitTests/Ledger/UT_StorageKey.cs diff --git a/neo.UnitTests/Ledger/UT_TransactionState.cs b/tests/neo.UnitTests/Ledger/UT_TransactionState.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_TransactionState.cs rename to tests/neo.UnitTests/Ledger/UT_TransactionState.cs diff --git a/neo.UnitTests/Ledger/UT_TrimmedBlock.cs b/tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs similarity index 100% rename from neo.UnitTests/Ledger/UT_TrimmedBlock.cs rename to tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Block.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Block.cs similarity index 100% rename from neo.UnitTests/Network/P2P/Payloads/UT_Block.cs rename to tests/neo.UnitTests/Network/P2P/Payloads/UT_Block.cs diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Cosigner.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Cosigner.cs similarity index 100% rename from neo.UnitTests/Network/P2P/Payloads/UT_Cosigner.cs rename to tests/neo.UnitTests/Network/P2P/Payloads/UT_Cosigner.cs diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Header.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Header.cs similarity index 100% rename from neo.UnitTests/Network/P2P/Payloads/UT_Header.cs rename to tests/neo.UnitTests/Network/P2P/Payloads/UT_Header.cs diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs similarity index 98% rename from neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs rename to tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index c8c874cee6..cf5f4504fe 100644 --- a/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -159,7 +159,7 @@ public void FeeIsMultiSigContract() engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(1, engine.ResultStack.Count); - Assert.IsTrue(engine.ResultStack.Pop().GetBoolean()); + Assert.IsTrue(engine.ResultStack.Pop().ToBoolean()); verificationGas += engine.GasConsumed; } } @@ -246,7 +246,7 @@ public void FeeIsSignatureContractDetailed() engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(1, engine.ResultStack.Count); - Assert.IsTrue(engine.ResultStack.Pop().GetBoolean()); + Assert.IsTrue(engine.ResultStack.Pop().ToBoolean()); verificationGas += engine.GasConsumed; } } @@ -364,7 +364,7 @@ public void FeeIsSignatureContract_TestScope_Global() engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(1, engine.ResultStack.Count); - Assert.IsTrue(engine.ResultStack.Pop().GetBoolean()); + Assert.IsTrue(engine.ResultStack.Pop().ToBoolean()); verificationGas += engine.GasConsumed; } } @@ -456,7 +456,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(1, engine.ResultStack.Count); - Assert.IsTrue(engine.ResultStack.Pop().GetBoolean()); + Assert.IsTrue(engine.ResultStack.Pop().ToBoolean()); verificationGas += engine.GasConsumed; } } @@ -551,7 +551,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(1, engine.ResultStack.Count); - Assert.IsTrue(engine.ResultStack.Pop().GetBoolean()); + Assert.IsTrue(engine.ResultStack.Pop().ToBoolean()); verificationGas += engine.GasConsumed; } } @@ -706,7 +706,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(1, engine.ResultStack.Count); - Assert.IsTrue(engine.ResultStack.Pop().GetBoolean()); + Assert.IsTrue(engine.ResultStack.Pop().ToBoolean()); verificationGas += engine.GasConsumed; } } @@ -1054,7 +1054,7 @@ public void FeeIsSignatureContract_TestScope_Global_Default() engine.LoadScript(witness.InvocationScript); Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(1, engine.ResultStack.Count); - Assert.IsTrue(engine.ResultStack.Pop().GetBoolean()); + Assert.IsTrue(engine.ResultStack.Pop().ToBoolean()); verificationGas += engine.GasConsumed; } } diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs similarity index 100% rename from neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs rename to tests/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs diff --git a/neo.UnitTests/Network/P2P/UT_Message.cs b/tests/neo.UnitTests/Network/P2P/UT_Message.cs similarity index 100% rename from neo.UnitTests/Network/P2P/UT_Message.cs rename to tests/neo.UnitTests/Network/P2P/UT_Message.cs diff --git a/neo.UnitTests/Network/P2P/UT_ProtocolHandler.cs b/tests/neo.UnitTests/Network/P2P/UT_ProtocolHandler.cs similarity index 100% rename from neo.UnitTests/Network/P2P/UT_ProtocolHandler.cs rename to tests/neo.UnitTests/Network/P2P/UT_ProtocolHandler.cs diff --git a/neo.UnitTests/Network/P2P/UT_ProtocolHandlerMailbox.cs b/tests/neo.UnitTests/Network/P2P/UT_ProtocolHandlerMailbox.cs similarity index 100% rename from neo.UnitTests/Network/P2P/UT_ProtocolHandlerMailbox.cs rename to tests/neo.UnitTests/Network/P2P/UT_ProtocolHandlerMailbox.cs diff --git a/neo.UnitTests/Network/P2P/UT_RemoteNode.cs b/tests/neo.UnitTests/Network/P2P/UT_RemoteNode.cs similarity index 100% rename from neo.UnitTests/Network/P2P/UT_RemoteNode.cs rename to tests/neo.UnitTests/Network/P2P/UT_RemoteNode.cs diff --git a/neo.UnitTests/Network/P2P/UT_RemoteNodeMailbox.cs b/tests/neo.UnitTests/Network/P2P/UT_RemoteNodeMailbox.cs similarity index 100% rename from neo.UnitTests/Network/P2P/UT_RemoteNodeMailbox.cs rename to tests/neo.UnitTests/Network/P2P/UT_RemoteNodeMailbox.cs diff --git a/neo.UnitTests/Network/P2P/UT_TaskManagerMailbox.cs b/tests/neo.UnitTests/Network/P2P/UT_TaskManagerMailbox.cs similarity index 100% rename from neo.UnitTests/Network/P2P/UT_TaskManagerMailbox.cs rename to tests/neo.UnitTests/Network/P2P/UT_TaskManagerMailbox.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcBlock.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcBlock.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcBlock.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcBlock.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcBlockHeader.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcBlockHeader.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcBlockHeader.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcBlockHeader.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcNep5Balance.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcNep5Balance.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcNep5Balance.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcNep5Balance.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcNep5Balances.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcNep5Balances.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcNep5Balances.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcNep5Balances.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcPeer.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcPeer.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcPeer.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcPeer.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcPeers.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcPeers.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcPeers.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcPeers.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcRawMemPool.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcRawMemPool.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcRawMemPool.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcRawMemPool.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcRequest.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcRequest.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcRequest.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcRequest.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcResponse.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcResponse.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcResponse.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcResponse.cs diff --git a/neo.UnitTests/Network/RPC/Models/UT_RpcVersion.cs b/tests/neo.UnitTests/Network/RPC/Models/UT_RpcVersion.cs similarity index 100% rename from neo.UnitTests/Network/RPC/Models/UT_RpcVersion.cs rename to tests/neo.UnitTests/Network/RPC/Models/UT_RpcVersion.cs diff --git a/neo.UnitTests/Network/RPC/UT_ContractClient.cs b/tests/neo.UnitTests/Network/RPC/UT_ContractClient.cs similarity index 82% rename from neo.UnitTests/Network/RPC/UT_ContractClient.cs rename to tests/neo.UnitTests/Network/RPC/UT_ContractClient.cs index fde8a7747d..13a02b5b9d 100644 --- a/neo.UnitTests/Network/RPC/UT_ContractClient.cs +++ b/tests/neo.UnitTests/Network/RPC/UT_ContractClient.cs @@ -24,15 +24,6 @@ public void TestSetup() rpcClientMock = UT_TransactionManager.MockRpcClient(sender, new byte[0]); } - [TestMethod] - public void TestMakeScript() - { - byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero); - - Assert.AreEqual("14000000000000000000000000000000000000000051c10962616c616e63654f66142582d1b275e86c8f0e93a9b2facd5fdb760976a168627d5b52", - testScript.ToHexString()); - } - [TestMethod] public void TestInvoke() { @@ -60,7 +51,7 @@ public void TestDeployContract() UT_TransactionManager.MockInvokeScript(rpcClientMock, script, new ContractParameter()); ContractClient contractClient = new ContractClient(rpcClientMock.Object); - var result = contractClient.DeployContract(new byte[1], manifest, keyPair1); + var result = contractClient.CreateDeployContractTx(new byte[1], manifest, keyPair1); Assert.IsNotNull(result); } diff --git a/tests/neo.UnitTests/Network/RPC/UT_Helper.cs b/tests/neo.UnitTests/Network/RPC/UT_Helper.cs new file mode 100644 index 0000000000..cb791fa6ce --- /dev/null +++ b/tests/neo.UnitTests/Network/RPC/UT_Helper.cs @@ -0,0 +1,29 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Network.RPC; +using System; +using System.Numerics; + +namespace Neo.UnitTests.Network.RPC +{ + [TestClass] + public class UT_Helper + { + [TestMethod] + public void TestToBigInteger() + { + decimal amount = 1.23456789m; + uint decimals = 9; + var result = amount.ToBigInteger(decimals); + Assert.AreEqual(1234567890, result); + + amount = 1.23456789m; + decimals = 18; + result = amount.ToBigInteger(decimals); + Assert.AreEqual(BigInteger.Parse("1234567890000000000"), result); + + amount = 1.23456789m; + decimals = 4; + Assert.ThrowsException(() => result = amount.ToBigInteger(decimals)); + } + } +} diff --git a/neo.UnitTests/Network/RPC/UT_Nep5API.cs b/tests/neo.UnitTests/Network/RPC/UT_Nep5API.cs similarity index 71% rename from neo.UnitTests/Network/RPC/UT_Nep5API.cs rename to tests/neo.UnitTests/Network/RPC/UT_Nep5API.cs index 72e0c29487..48fd711638 100644 --- a/neo.UnitTests/Network/RPC/UT_Nep5API.cs +++ b/tests/neo.UnitTests/Network/RPC/UT_Nep5API.cs @@ -5,6 +5,7 @@ using Neo.SmartContract.Native; using Neo.VM; using Neo.Wallets; +using System.Linq; using System.Numerics; namespace Neo.UnitTests.Network.RPC @@ -76,13 +77,35 @@ public void TestGetTotalSupply() Assert.AreEqual(1_00000000, (int)result); } + [TestMethod] + public void TestGetTokenInfo() + { + UInt160 scriptHash = NativeContract.GAS.Hash; + byte[] testScript = scriptHash.MakeScript("name") + .Concat(scriptHash.MakeScript("symbol")) + .Concat(scriptHash.MakeScript("decimals")) + .Concat(scriptHash.MakeScript("totalSupply")) + .ToArray(); ; + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, + new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Name }, + new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Symbol }, + new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.GAS.Decimals) }, + new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); + + var result = nep5API.GetTokenInfo(NativeContract.GAS.Hash); + Assert.AreEqual(NativeContract.GAS.Name, result.Name); + Assert.AreEqual(NativeContract.GAS.Symbol, result.Symbol); + Assert.AreEqual(8, (int)result.Decimals); + Assert.AreEqual(1_00000000, (int)result.TotalSupply); + } + [TestMethod] public void TestTransfer() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, new BigInteger(1_00000000)); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter()); - var result = nep5API.Transfer(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000)); + var result = nep5API.CreateTransferTx(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000)); Assert.IsNotNull(result); } } diff --git a/neo.UnitTests/Network/RPC/UT_PolicyAPI.cs b/tests/neo.UnitTests/Network/RPC/UT_PolicyAPI.cs similarity index 100% rename from neo.UnitTests/Network/RPC/UT_PolicyAPI.cs rename to tests/neo.UnitTests/Network/RPC/UT_PolicyAPI.cs diff --git a/neo.UnitTests/Network/RPC/UT_RpcClient.cs b/tests/neo.UnitTests/Network/RPC/UT_RpcClient.cs similarity index 93% rename from neo.UnitTests/Network/RPC/UT_RpcClient.cs rename to tests/neo.UnitTests/Network/RPC/UT_RpcClient.cs index eb256cc6d1..a8b212fe37 100644 --- a/neo.UnitTests/Network/RPC/UT_RpcClient.cs +++ b/tests/neo.UnitTests/Network/RPC/UT_RpcClient.cs @@ -109,13 +109,9 @@ public void TestGetBlockHex() { JObject response = CreateResponse(1); response["result"] = "000000002deadfa82cbc4682f5800"; - MockResponse(response.ToString()); - var result = rpc.GetBlockHex("773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e"); - Assert.AreEqual("000000002deadfa82cbc4682f5800", result); - MockResponse(response.ToString()); - result = rpc.GetBlockHex("100"); + var result = rpc.GetBlockHex("773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e"); Assert.AreEqual("000000002deadfa82cbc4682f5800", result); } @@ -134,20 +130,15 @@ public void TestGetBlock() }; JObject json = block.ToJson(); + json["confirmations"] = 20; JObject response = CreateResponse(1); response["result"] = json; - MockResponse(response.ToString()); - var result = rpc.GetBlock("773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e"); - Assert.AreEqual(block.Hash.ToString(), result.Block.Hash.ToString()); - Assert.IsNull(result.Confirmations); - Assert.AreEqual(block.Transactions.Length, result.Block.Transactions.Length); - Assert.AreEqual(block.Transactions[0].Hash.ToString(), result.Block.Transactions[0].Hash.ToString()); - MockResponse(response.ToString()); - result = rpc.GetBlock("100"); + var result = rpc.GetBlock("773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e"); Assert.AreEqual(block.Hash.ToString(), result.Block.Hash.ToString()); - Assert.IsNull(result.Confirmations); + Assert.IsNull(result.NextBlockHash); + Assert.AreEqual(20, result.Confirmations); Assert.AreEqual(block.Transactions.Length, result.Block.Transactions.Length); Assert.AreEqual(block.Transactions[0].Hash.ToString(), result.Block.Transactions[0].Hash.ToString()); @@ -158,6 +149,7 @@ public void TestGetBlock() result = rpc.GetBlock("773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e"); Assert.AreEqual(block.Hash.ToString(), result.Block.Hash.ToString()); Assert.AreEqual(20, result.Confirmations); + Assert.AreEqual("0x773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e", result.NextBlockHash.ToString()); Assert.AreEqual(block.Transactions.Length, result.Block.Transactions.Length); Assert.AreEqual(block.Transactions[0].Hash.ToString(), result.Block.Transactions[0].Hash.ToString()); } @@ -189,13 +181,9 @@ public void TestGetBlockHeaderHex() { JObject response = CreateResponse(1); response["result"] = "0x4c1e879872344349067c3b1a30781eeb4f9040d3795db7922f513f6f9660b9b2"; - MockResponse(response.ToString()); - var result = rpc.GetBlockHeaderHex("100"); - Assert.AreEqual("0x4c1e879872344349067c3b1a30781eeb4f9040d3795db7922f513f6f9660b9b2", result); - MockResponse(response.ToString()); - result = rpc.GetBlockHeaderHex("773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e"); + var result = rpc.GetBlockHeaderHex("100"); Assert.AreEqual("0x4c1e879872344349067c3b1a30781eeb4f9040d3795db7922f513f6f9660b9b2", result); } @@ -206,18 +194,15 @@ public void TestGetBlockHeader() TestUtils.SetupHeaderWithValues(header, UInt256.Zero, out UInt256 _, out UInt160 _, out ulong _, out uint _, out Witness _); JObject json = header.ToJson(); + json["confirmations"] = 20; JObject response = CreateResponse(1); response["result"] = json; MockResponse(response.ToString()); var result = rpc.GetBlockHeader("100"); Assert.AreEqual(header.Hash.ToString(), result.Header.Hash.ToString()); - Assert.IsNull(result.Confirmations); - - MockResponse(response.ToString()); - result = rpc.GetBlockHeader("773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e"); - Assert.AreEqual(header.Hash.ToString(), result.Header.Hash.ToString()); - Assert.IsNull(result.Confirmations); + Assert.IsNull(result.NextBlockHash); + Assert.AreEqual(20, result.Confirmations); json["confirmations"] = 20; json["nextblockhash"] = "4c1e879872344349067c3b1a30781eeb4f9040d3795db7922f513f6f9660b9b2"; @@ -373,9 +358,18 @@ public void TestGetRawTransaction() Assert.AreEqual(transaction.Hash, result.Transaction.Hash); Assert.AreEqual(json.ToString(), result.ToJson().ToString()); + // make the code compatible with the old version json["blockhash"] = UInt256.Zero.ToString(); json["confirmations"] = 100; json["blocktime"] = 10; + MockResponse(response.ToString()); + + result = rpc.GetRawTransaction("0x9786cce0dddb524c40ddbdd5e31a41ed1f6b5c8a683c122f627ca4a007a7cf4e"); + Assert.AreEqual(transaction.Hash, result.Transaction.Hash); + Assert.AreEqual(100, result.Confirmations); + Assert.AreEqual(null, result.VMState); + Assert.AreEqual(json.ToString(), result.ToJson().ToString()); + json["vmState"] = VMState.HALT; MockResponse(response.ToString()); @@ -472,8 +466,7 @@ public void TestInvokeFunction() ""type"": ""ByteArray"", ""value"": ""262bec084432"" } - ], - ""tx"":""d101361426ae7c6c9861ec418468c1f0fdc4a7f2963eb89151c10962616c616e63654f6667be39e7b562f60cbfe2aebca375a2e5ee28737caf000000000000000000000000"" + ] }"); JObject response = CreateResponse(1); response["result"] = json; @@ -496,8 +489,7 @@ public void TestInvokeScript() ""type"": ""ByteArray"", ""value"": ""262bec084432"" } - ], - ""tx"":""d101361426ae7c6c9861ec418468c1f0fdc4a7f2963eb89151c10962616c616e63654f6667be39e7b562f60cbfe2aebca375a2e5ee28737caf000000000000000000000000"" + ] }"); JObject response = CreateResponse(1); response["result"] = json; diff --git a/neo.UnitTests/Network/RPC/UT_RpcServer.cs b/tests/neo.UnitTests/Network/RPC/UT_RpcServer.cs similarity index 100% rename from neo.UnitTests/Network/RPC/UT_RpcServer.cs rename to tests/neo.UnitTests/Network/RPC/UT_RpcServer.cs diff --git a/neo.UnitTests/Network/RPC/UT_TransactionManager.cs b/tests/neo.UnitTests/Network/RPC/UT_TransactionManager.cs similarity index 98% rename from neo.UnitTests/Network/RPC/UT_TransactionManager.cs rename to tests/neo.UnitTests/Network/RPC/UT_TransactionManager.cs index ee55f81bb9..e1cce967cd 100644 --- a/neo.UnitTests/Network/RPC/UT_TransactionManager.cs +++ b/tests/neo.UnitTests/Network/RPC/UT_TransactionManager.cs @@ -68,11 +68,10 @@ public static void MockInvokeScript(Mock mockClient, byte[] script, p Stack = parameters, GasConsumed = "100", Script = script.ToHexString(), - State = "", - Tx = "" + State = "" }; - mockClient.Setup(p => p.RpcSend("invokescript", It.Is(j => j.AsString() == script.ToHexString()))) + mockClient.Setup(p => p.RpcSend("invokescript", It.Is(j => j[0].AsString() == script.ToHexString()))) .Returns(result.ToJson()) .Verifiable(); } diff --git a/tests/neo.UnitTests/Network/RPC/UT_WalletAPI.cs b/tests/neo.UnitTests/Network/RPC/UT_WalletAPI.cs new file mode 100644 index 0000000000..bba6a787e1 --- /dev/null +++ b/tests/neo.UnitTests/Network/RPC/UT_WalletAPI.cs @@ -0,0 +1,116 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Neo.IO.Json; +using Neo.Network.P2P.Payloads; +using Neo.Network.RPC; +using Neo.Network.RPC.Models; +using Neo.SmartContract; +using Neo.SmartContract.Native; +using Neo.VM; +using Neo.Wallets; +using System.Numerics; + +namespace Neo.UnitTests.Network.RPC +{ + [TestClass] + public class UT_WalletAPI + { + Mock rpcClientMock; + KeyPair keyPair1; + string address1; + UInt160 sender; + WalletAPI walletAPI; + + [TestInitialize] + public void TestSetup() + { + keyPair1 = new KeyPair(Wallet.GetPrivateKeyFromWIF("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p")); + sender = Contract.CreateSignatureRedeemScript(keyPair1.PublicKey).ToScriptHash(); + address1 = Neo.Wallets.Helper.ToAddress(sender); + rpcClientMock = UT_TransactionManager.MockRpcClient(sender, new byte[0]); + walletAPI = new WalletAPI(rpcClientMock.Object); + } + + [TestMethod] + public void TestGetUnclaimedGas() + { + byte[] testScript = NativeContract.NEO.Hash.MakeScript("unclaimedGas", sender, 99); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); + + var balance = walletAPI.GetUnclaimedGas(address1); + Assert.AreEqual(1.1m, balance); + } + + [TestMethod] + public void TestGetNeoBalance() + { + byte[] testScript = NativeContract.NEO.Hash.MakeScript("balanceOf", sender); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); + + var balance = walletAPI.GetNeoBalance(address1); + Assert.AreEqual(1_00000000u, balance); + } + + [TestMethod] + public void TestGetGasBalance() + { + byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", sender); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); + + var balance = walletAPI.GetGasBalance(address1); + Assert.AreEqual(1.1m, balance); + } + + [TestMethod] + public void TestGetTokenBalance() + { + byte[] testScript = UInt160.Zero.MakeScript("balanceOf", sender); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); + + var balance = walletAPI.GetTokenBalance(UInt160.Zero.ToString(), address1); + Assert.AreEqual(1_10000000, balance); + } + + [TestMethod] + public void TestClaimGas() + { + byte[] balanceScript = NativeContract.NEO.Hash.MakeScript("balanceOf", sender); + UT_TransactionManager.MockInvokeScript(rpcClientMock, balanceScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); + + byte[] testScript = NativeContract.NEO.Hash.MakeScript("transfer", sender, sender, new BigInteger(1_00000000)); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); + + rpcClientMock.Setup(p => p.RpcSend("sendrawtransaction", It.IsAny())).Returns(true); + + var tranaction = walletAPI.ClaimGas(keyPair1.Export()); + Assert.AreEqual(testScript.ToHexString(), tranaction.Script.ToHexString()); + } + + [TestMethod] + public void TestTransfer() + { + byte[] decimalsScript = NativeContract.GAS.Hash.MakeScript("decimals"); + UT_TransactionManager.MockInvokeScript(rpcClientMock, decimalsScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(8) }); + + byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, NativeContract.GAS.Factor * 100); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); + + rpcClientMock.Setup(p => p.RpcSend("sendrawtransaction", It.IsAny())).Returns(true); + + var tranaction = walletAPI.Transfer(NativeContract.GAS.Hash.ToString(), keyPair1.Export(), UInt160.Zero.ToAddress(), 100, 1.1m); + Assert.AreEqual(testScript.ToHexString(), tranaction.Script.ToHexString()); + } + + [TestMethod] + public void TestWaitTransaction() + { + Transaction transaction = TestUtils.GetTransaction(); + rpcClientMock.Setup(p => p.RpcSend("getrawtransaction", It.Is(j => j[0].AsString() == transaction.Hash.ToString()))) + .Returns(new RpcTransaction { Transaction = transaction, VMState = VMState.HALT, BlockHash = UInt256.Zero, BlockTime = 100, Confirmations = 1 }.ToJson()); + + var tx = walletAPI.WaitTransaction(transaction).Result; + Assert.AreEqual(VMState.HALT, tx.VMState); + Assert.AreEqual(UInt256.Zero, tx.BlockHash); + } + } +} diff --git a/neo.UnitTests/Plugins/TestLogPlugin.cs b/tests/neo.UnitTests/Plugins/TestLogPlugin.cs similarity index 100% rename from neo.UnitTests/Plugins/TestLogPlugin.cs rename to tests/neo.UnitTests/Plugins/TestLogPlugin.cs diff --git a/neo.UnitTests/Plugins/UT_Plugin.cs b/tests/neo.UnitTests/Plugins/UT_Plugin.cs similarity index 100% rename from neo.UnitTests/Plugins/UT_Plugin.cs rename to tests/neo.UnitTests/Plugins/UT_Plugin.cs diff --git a/neo.UnitTests/README.md b/tests/neo.UnitTests/README.md similarity index 100% rename from neo.UnitTests/README.md rename to tests/neo.UnitTests/README.md diff --git a/neo.UnitTests/SmartContract/Enumerators/UT_ConcatenatedEnumerator.cs b/tests/neo.UnitTests/SmartContract/Enumerators/UT_ConcatenatedEnumerator.cs similarity index 100% rename from neo.UnitTests/SmartContract/Enumerators/UT_ConcatenatedEnumerator.cs rename to tests/neo.UnitTests/SmartContract/Enumerators/UT_ConcatenatedEnumerator.cs diff --git a/neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs b/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs similarity index 98% rename from neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs rename to tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs index 2a345893e0..12b82be599 100644 --- a/neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs +++ b/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs @@ -2,7 +2,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.SmartContract.Enumerators; using Neo.SmartContract.Iterators; -using Neo.VM; +using Neo.VM.Types; using System; using System.Collections.Generic; diff --git a/neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs b/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs similarity index 98% rename from neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs rename to tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs index f236faab1a..2e8bf5709b 100644 --- a/neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs +++ b/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs @@ -2,7 +2,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.SmartContract.Enumerators; using Neo.SmartContract.Iterators; -using Neo.VM; +using Neo.VM.Types; using System; using System.Collections.Generic; diff --git a/neo.UnitTests/SmartContract/Iterators/UT_ArrayWrapper.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_ArrayWrapper.cs similarity index 100% rename from neo.UnitTests/SmartContract/Iterators/UT_ArrayWrapper.cs rename to tests/neo.UnitTests/SmartContract/Iterators/UT_ArrayWrapper.cs diff --git a/neo.UnitTests/SmartContract/Iterators/UT_ConcatenatedIterator.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_ConcatenatedIterator.cs similarity index 100% rename from neo.UnitTests/SmartContract/Iterators/UT_ConcatenatedIterator.cs rename to tests/neo.UnitTests/SmartContract/Iterators/UT_ConcatenatedIterator.cs diff --git a/neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs similarity index 77% rename from neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs rename to tests/neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs index b111b0aa54..7ce7c7e845 100644 --- a/neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs +++ b/tests/neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs @@ -1,7 +1,6 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.SmartContract.Iterators; -using Neo.VM; using Neo.VM.Types; using System; using System.Collections.Generic; @@ -14,7 +13,7 @@ public class UT_MapWrapper [TestMethod] public void TestGeneratorAndDispose() { - MapWrapper mapWrapper = new MapWrapper(new List>()); + MapWrapper mapWrapper = new MapWrapper(new List>()); Assert.IsNotNull(mapWrapper); Action action = () => mapWrapper.Dispose(); action.Should().NotThrow(); @@ -23,10 +22,10 @@ public void TestGeneratorAndDispose() [TestMethod] public void TestKeyAndValue() { - List> list = new List>(); - StackItem stackItem1 = new Integer(0); + List> list = new List>(); + Integer stackItem1 = new Integer(0); StackItem stackItem2 = new Integer(1); - list.Add(new KeyValuePair(stackItem1, stackItem2)); + list.Add(new KeyValuePair(stackItem1, stackItem2)); MapWrapper mapWrapper = new MapWrapper(list); mapWrapper.Next(); Assert.AreEqual(stackItem1, mapWrapper.Key()); @@ -36,7 +35,7 @@ public void TestKeyAndValue() [TestMethod] public void TestNext() { - MapWrapper mapWrapper = new MapWrapper(new List>()); + MapWrapper mapWrapper = new MapWrapper(new List>()); Assert.AreEqual(false, mapWrapper.Next()); } } diff --git a/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs similarity index 100% rename from neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs rename to tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs diff --git a/neo.UnitTests/SmartContract/Manifest/UT_ContractEventDescriptor.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractEventDescriptor.cs similarity index 100% rename from neo.UnitTests/SmartContract/Manifest/UT_ContractEventDescriptor.cs rename to tests/neo.UnitTests/SmartContract/Manifest/UT_ContractEventDescriptor.cs diff --git a/neo.UnitTests/SmartContract/Manifest/UT_ContractGroup.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractGroup.cs similarity index 100% rename from neo.UnitTests/SmartContract/Manifest/UT_ContractGroup.cs rename to tests/neo.UnitTests/SmartContract/Manifest/UT_ContractGroup.cs diff --git a/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs similarity index 100% rename from neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs rename to tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs diff --git a/neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs similarity index 100% rename from neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs rename to tests/neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs diff --git a/neo.UnitTests/SmartContract/Manifest/UT_ContractPermissionDescriptor.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractPermissionDescriptor.cs similarity index 100% rename from neo.UnitTests/SmartContract/Manifest/UT_ContractPermissionDescriptor.cs rename to tests/neo.UnitTests/SmartContract/Manifest/UT_ContractPermissionDescriptor.cs diff --git a/neo.UnitTests/SmartContract/Manifest/UT_WildCardContainer.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_WildCardContainer.cs similarity index 100% rename from neo.UnitTests/SmartContract/Manifest/UT_WildCardContainer.cs rename to tests/neo.UnitTests/SmartContract/Manifest/UT_WildCardContainer.cs diff --git a/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs similarity index 100% rename from neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs rename to tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs diff --git a/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs similarity index 87% rename from neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs rename to tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs index 6df9f7074e..19f7ad2f6a 100644 --- a/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs +++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs @@ -282,13 +282,13 @@ public void TestGetNextBlockValidators1() var result = engine.ResultStack.Peek(); result.GetType().Should().Be(typeof(VM.Types.Array)); ((VM.Types.Array)result).Count.Should().Be(7); - ((VM.Types.ByteArray)((VM.Types.Array)result)[0]).GetByteArray().ToHexString().Should().Be("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[1]).GetByteArray().ToHexString().Should().Be("02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[2]).GetByteArray().ToHexString().Should().Be("03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[3]).GetByteArray().ToHexString().Should().Be("02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[4]).GetByteArray().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[5]).GetByteArray().ToHexString().Should().Be("02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[6]).GetByteArray().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"); + ((VM.Types.Array)result)[0].GetSpan().ToHexString().Should().Be("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"); + ((VM.Types.Array)result)[1].GetSpan().ToHexString().Should().Be("02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093"); + ((VM.Types.Array)result)[2].GetSpan().ToHexString().Should().Be("03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a"); + ((VM.Types.Array)result)[3].GetSpan().ToHexString().Should().Be("02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554"); + ((VM.Types.Array)result)[4].GetSpan().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d"); + ((VM.Types.Array)result)[5].GetSpan().ToHexString().Should().Be("02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e"); + ((VM.Types.Array)result)[6].GetSpan().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"); } } @@ -323,19 +323,19 @@ public void TestGetRegisteredValidators1() var result = engine.ResultStack.Peek(); result.GetType().Should().Be(typeof(VM.Types.Array)); ((VM.Types.Array)result).Count.Should().Be(7); - ((VM.Types.ByteArray)((VM.Types.Struct)((VM.Types.Array)result)[0])[0]).GetByteArray().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"); + ((VM.Types.Struct)((VM.Types.Array)result)[0])[0].GetSpan().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"); ((VM.Types.Struct)((VM.Types.Array)result)[0])[1].GetBigInteger().Should().Be(new BigInteger(0)); - ((VM.Types.ByteArray)((VM.Types.Struct)((VM.Types.Array)result)[1])[0]).GetByteArray().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d"); + ((VM.Types.Struct)((VM.Types.Array)result)[1])[0].GetSpan().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d"); ((VM.Types.Struct)((VM.Types.Array)result)[1])[1].GetBigInteger().Should().Be(new BigInteger(0)); - ((VM.Types.ByteArray)((VM.Types.Struct)((VM.Types.Array)result)[2])[0]).GetByteArray().ToHexString().Should().Be("02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e"); + ((VM.Types.Struct)((VM.Types.Array)result)[2])[0].GetSpan().ToHexString().Should().Be("02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e"); ((VM.Types.Struct)((VM.Types.Array)result)[2])[1].GetBigInteger().Should().Be(new BigInteger(0)); - ((VM.Types.ByteArray)((VM.Types.Struct)((VM.Types.Array)result)[3])[0]).GetByteArray().ToHexString().Should().Be("02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554"); + ((VM.Types.Struct)((VM.Types.Array)result)[3])[0].GetSpan().ToHexString().Should().Be("02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554"); ((VM.Types.Struct)((VM.Types.Array)result)[3])[1].GetBigInteger().Should().Be(new BigInteger(0)); - ((VM.Types.ByteArray)((VM.Types.Struct)((VM.Types.Array)result)[4])[0]).GetByteArray().ToHexString().Should().Be("02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093"); + ((VM.Types.Struct)((VM.Types.Array)result)[4])[0].GetSpan().ToHexString().Should().Be("02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093"); ((VM.Types.Struct)((VM.Types.Array)result)[4])[1].GetBigInteger().Should().Be(new BigInteger(0)); - ((VM.Types.ByteArray)((VM.Types.Struct)((VM.Types.Array)result)[5])[0]).GetByteArray().ToHexString().Should().Be("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"); + ((VM.Types.Struct)((VM.Types.Array)result)[5])[0].GetSpan().ToHexString().Should().Be("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"); ((VM.Types.Struct)((VM.Types.Array)result)[5])[1].GetBigInteger().Should().Be(new BigInteger(0)); - ((VM.Types.ByteArray)((VM.Types.Struct)((VM.Types.Array)result)[6])[0]).GetByteArray().ToHexString().Should().Be("03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a"); + ((VM.Types.Struct)((VM.Types.Array)result)[6])[0].GetSpan().ToHexString().Should().Be("03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a"); ((VM.Types.Struct)((VM.Types.Array)result)[6])[1].GetBigInteger().Should().Be(new BigInteger(0)); } } @@ -377,13 +377,13 @@ public void TestGetValidators1() var result = engine.ResultStack.Peek(); result.GetType().Should().Be(typeof(VM.Types.Array)); ((VM.Types.Array)result).Count.Should().Be(7); - ((VM.Types.ByteArray)((VM.Types.Array)result)[0]).GetByteArray().ToHexString().Should().Be("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[1]).GetByteArray().ToHexString().Should().Be("02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[2]).GetByteArray().ToHexString().Should().Be("03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[3]).GetByteArray().ToHexString().Should().Be("02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[4]).GetByteArray().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[5]).GetByteArray().ToHexString().Should().Be("02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e"); - ((VM.Types.ByteArray)((VM.Types.Array)result)[6]).GetByteArray().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"); + ((VM.Types.Array)result)[0].GetSpan().ToHexString().Should().Be("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"); + ((VM.Types.Array)result)[1].GetSpan().ToHexString().Should().Be("02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093"); + ((VM.Types.Array)result)[2].GetSpan().ToHexString().Should().Be("03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a"); + ((VM.Types.Array)result)[3].GetSpan().ToHexString().Should().Be("02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554"); + ((VM.Types.Array)result)[4].GetSpan().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d"); + ((VM.Types.Array)result)[5].GetSpan().ToHexString().Should().Be("02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e"); + ((VM.Types.Array)result)[6].GetSpan().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"); } } @@ -575,7 +575,7 @@ public void TestValidatorState_ToByteArray() engine.Execute(); var result = engine.ResultStack.Peek(); result.GetType().Should().Be(typeof(VM.Types.Boolean)); - return (true, (result as VM.Types.Boolean).GetBoolean()); + return (true, result.ToBoolean()); } internal static (bool State, bool Result) Check_Vote(Snapshot snapshot, byte[] account, byte[][] pubkeys, bool signAccount) @@ -605,7 +605,7 @@ internal static (bool State, bool Result) Check_Vote(Snapshot snapshot, byte[] a var result = engine.ResultStack.Pop(); result.Should().BeOfType(typeof(VM.Types.Boolean)); - return (true, (result as VM.Types.Boolean).GetBoolean()); + return (true, result.ToBoolean()); } internal static (bool State, bool Result) Check_RegisterValidator(Snapshot snapshot, byte[] pubkey) @@ -629,7 +629,7 @@ internal static (bool State, bool Result) Check_RegisterValidator(Snapshot snaps var result = engine.ResultStack.Pop(); result.Should().BeOfType(typeof(VM.Types.Boolean)); - return (true, (result as VM.Types.Boolean).GetBoolean()); + return (true, result.ToBoolean()); } internal static ECPoint[] Check_GetValidators(Snapshot snapshot) @@ -649,7 +649,7 @@ internal static ECPoint[] Check_GetValidators(Snapshot snapshot) var result = engine.ResultStack.Pop(); result.Should().BeOfType(typeof(VM.Types.Array)); - return (result as VM.Types.Array).Select(u => u.GetByteArray().AsSerializable()).ToArray(); + return (result as VM.Types.Array).Select(u => u.GetSpan().AsSerializable()).ToArray(); } internal static (BigInteger Value, bool State) Check_UnclaimedGas(Snapshot snapshot, byte[] address) @@ -695,7 +695,7 @@ internal static void CheckBalance(byte[] account, DataCache(Blockchain.MaxValidators)).Should().BeEquivalentTo(votes); // Votes + (st[2].GetSpan().AsSerializableArray(Blockchain.MaxValidators)).Should().BeEquivalentTo(votes); // Votes trackable.Key.Key.Should().BeEquivalentTo(new byte[] { 20 }.Concat(account)); trackable.Item.IsConstant.Should().Be(false); diff --git a/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs similarity index 99% rename from neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs rename to tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs index 0cec84a5a8..a34c7a109f 100644 --- a/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs +++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs @@ -6,6 +6,7 @@ using Neo.SmartContract; using Neo.SmartContract.Native.Tokens; using Neo.VM; +using Neo.VM.Types; using System; using System.Numerics; diff --git a/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs similarity index 100% rename from neo.UnitTests/SmartContract/Native/UT_NativeContract.cs rename to tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs diff --git a/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs similarity index 93% rename from neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs rename to tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index e0f87182a6..b75141459f 100644 --- a/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -7,6 +7,7 @@ using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.UnitTests.Extensions; +using Neo.VM; using System.Linq; namespace Neo.UnitTests.SmartContract.Native @@ -70,7 +71,7 @@ public void Check_SetMaxBlockSize() var ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(null), "setMaxBlockSize", new ContractParameter(ContractParameterType.Integer) { Value = 1024 }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeFalse(); + ret.ToBoolean().Should().BeFalse(); ret = NativeContract.Policy.Call(snapshot, "getMaxBlockSize"); ret.Should().BeOfType(); @@ -81,7 +82,7 @@ public void Check_SetMaxBlockSize() ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), "setMaxBlockSize", new ContractParameter(ContractParameterType.Integer) { Value = Neo.Network.P2P.Message.PayloadMaxSize }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeFalse(); + ret.ToBoolean().Should().BeFalse(); ret = NativeContract.Policy.Call(snapshot, "getMaxBlockSize"); ret.Should().BeOfType(); @@ -92,7 +93,7 @@ public void Check_SetMaxBlockSize() ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), "setMaxBlockSize", new ContractParameter(ContractParameterType.Integer) { Value = 1024 }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeTrue(); + ret.ToBoolean().Should().BeTrue(); ret = NativeContract.Policy.Call(snapshot, "getMaxBlockSize"); ret.Should().BeOfType(); @@ -116,7 +117,7 @@ public void Check_SetMaxTransactionsPerBlock() var ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(), "setMaxTransactionsPerBlock", new ContractParameter(ContractParameterType.Integer) { Value = 1 }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeFalse(); + ret.ToBoolean().Should().BeFalse(); ret = NativeContract.Policy.Call(snapshot, "getMaxTransactionsPerBlock"); ret.Should().BeOfType(); @@ -127,7 +128,7 @@ public void Check_SetMaxTransactionsPerBlock() ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), "setMaxTransactionsPerBlock", new ContractParameter(ContractParameterType.Integer) { Value = 1 }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeTrue(); + ret.ToBoolean().Should().BeTrue(); ret = NativeContract.Policy.Call(snapshot, "getMaxTransactionsPerBlock"); ret.Should().BeOfType(); @@ -151,7 +152,7 @@ public void Check_SetFeePerByte() var ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(), "setFeePerByte", new ContractParameter(ContractParameterType.Integer) { Value = 1 }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeFalse(); + ret.ToBoolean().Should().BeFalse(); ret = NativeContract.Policy.Call(snapshot, "getFeePerByte"); ret.Should().BeOfType(); @@ -162,7 +163,7 @@ public void Check_SetFeePerByte() ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), "setFeePerByte", new ContractParameter(ContractParameterType.Integer) { Value = 1 }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeTrue(); + ret.ToBoolean().Should().BeTrue(); ret = NativeContract.Policy.Call(snapshot, "getFeePerByte"); ret.Should().BeOfType(); @@ -186,7 +187,7 @@ public void Check_Block_UnblockAccount() var ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(), "blockAccount", new ContractParameter(ContractParameterType.Hash160) { Value = UInt160.Zero }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeFalse(); + ret.ToBoolean().Should().BeFalse(); ret = NativeContract.Policy.Call(snapshot, "getBlockedAccounts"); ret.Should().BeOfType(); @@ -197,31 +198,31 @@ public void Check_Block_UnblockAccount() ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), "blockAccount", new ContractParameter(ContractParameterType.Hash160) { Value = UInt160.Zero }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeTrue(); + ret.ToBoolean().Should().BeTrue(); ret = NativeContract.Policy.Call(snapshot, "getBlockedAccounts"); ret.Should().BeOfType(); ((VM.Types.Array)ret).Count.Should().Be(1); - ((VM.Types.Array)ret)[0].GetByteArray().Should().BeEquivalentTo(UInt160.Zero.ToArray()); + ((VM.Types.Array)ret)[0].GetSpan().ToArray().Should().BeEquivalentTo(UInt160.Zero.ToArray()); // Unblock without signature ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(), "unblockAccount", new ContractParameter(ContractParameterType.Hash160) { Value = UInt160.Zero }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeFalse(); + ret.ToBoolean().Should().BeFalse(); ret = NativeContract.Policy.Call(snapshot, "getBlockedAccounts"); ret.Should().BeOfType(); ((VM.Types.Array)ret).Count.Should().Be(1); - ((VM.Types.Array)ret)[0].GetByteArray().Should().BeEquivalentTo(UInt160.Zero.ToArray()); + ((VM.Types.Array)ret)[0].GetSpan().ToArray().Should().BeEquivalentTo(UInt160.Zero.ToArray()); // Unblock with signature ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), "unblockAccount", new ContractParameter(ContractParameterType.Hash160) { Value = UInt160.Zero }); ret.Should().BeOfType(); - ret.GetBoolean().Should().BeTrue(); + ret.ToBoolean().Should().BeTrue(); ret = NativeContract.Policy.Call(snapshot, "getBlockedAccounts"); ret.Should().BeOfType(); diff --git a/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs similarity index 99% rename from neo.UnitTests/SmartContract/UT_ApplicationEngine.cs rename to tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs index fae3938a22..d8bdd8a857 100644 --- a/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs +++ b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs @@ -7,8 +7,7 @@ using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract; -using Neo.UnitTests.Ledger; -using Neo.VM; +using Neo.VM.Types; using System; namespace Neo.UnitTests.SmartContract diff --git a/neo.UnitTests/SmartContract/UT_ContainerPlaceholder.cs b/tests/neo.UnitTests/SmartContract/UT_ContainerPlaceholder.cs similarity index 72% rename from neo.UnitTests/SmartContract/UT_ContainerPlaceholder.cs rename to tests/neo.UnitTests/SmartContract/UT_ContainerPlaceholder.cs index e7ed55ac42..0ba48e78a9 100644 --- a/neo.UnitTests/SmartContract/UT_ContainerPlaceholder.cs +++ b/tests/neo.UnitTests/SmartContract/UT_ContainerPlaceholder.cs @@ -28,15 +28,7 @@ public void TestEquals() public void TestGetBoolean() { ContainerPlaceholder containerPlaceholder = new ContainerPlaceholder(); - Action action = () => containerPlaceholder.GetBoolean(); - action.Should().Throw(); - } - - [TestMethod] - public void TestGetByteArray() - { - ContainerPlaceholder containerPlaceholder = new ContainerPlaceholder(); - Action action = () => containerPlaceholder.GetByteArray(); + Action action = () => containerPlaceholder.ToBoolean(); action.Should().Throw(); } } diff --git a/neo.UnitTests/SmartContract/UT_Contract.cs b/tests/neo.UnitTests/SmartContract/UT_Contract.cs similarity index 100% rename from neo.UnitTests/SmartContract/UT_Contract.cs rename to tests/neo.UnitTests/SmartContract/UT_Contract.cs diff --git a/neo.UnitTests/SmartContract/UT_ContractParameter.cs b/tests/neo.UnitTests/SmartContract/UT_ContractParameter.cs similarity index 100% rename from neo.UnitTests/SmartContract/UT_ContractParameter.cs rename to tests/neo.UnitTests/SmartContract/UT_ContractParameter.cs diff --git a/neo.UnitTests/SmartContract/UT_ContractParameterContext.cs b/tests/neo.UnitTests/SmartContract/UT_ContractParameterContext.cs similarity index 100% rename from neo.UnitTests/SmartContract/UT_ContractParameterContext.cs rename to tests/neo.UnitTests/SmartContract/UT_ContractParameterContext.cs diff --git a/neo.UnitTests/SmartContract/UT_InteropDescriptor.cs b/tests/neo.UnitTests/SmartContract/UT_InteropDescriptor.cs similarity index 100% rename from neo.UnitTests/SmartContract/UT_InteropDescriptor.cs rename to tests/neo.UnitTests/SmartContract/UT_InteropDescriptor.cs diff --git a/neo.UnitTests/SmartContract/UT_InteropPrices.cs b/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs similarity index 100% rename from neo.UnitTests/SmartContract/UT_InteropPrices.cs rename to tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs diff --git a/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs similarity index 91% rename from neo.UnitTests/SmartContract/UT_InteropService.NEO.cs rename to tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index 703fc6241e..3e60b91591 100644 --- a/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -36,13 +36,13 @@ public void TestCheckSig() engine.CurrentContext.EvaluationStack.Push(pubkey.EncodePoint(false)); engine.CurrentContext.EvaluationStack.Push(StackItem.Null); InteropService.Invoke(engine, InteropService.Neo_Crypto_ECDsaVerify).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeTrue(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeTrue(); engine.CurrentContext.EvaluationStack.Push(signature); engine.CurrentContext.EvaluationStack.Push(new byte[70]); engine.CurrentContext.EvaluationStack.Push(StackItem.Null); InteropService.Invoke(engine, InteropService.Neo_Crypto_ECDsaVerify).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeFalse(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeFalse(); } [TestMethod] @@ -78,7 +78,7 @@ public void TestCrypto_CheckMultiSig() engine.CurrentContext.EvaluationStack.Push(pubkeys); engine.CurrentContext.EvaluationStack.Push(StackItem.Null); InteropService.Invoke(engine, InteropService.Neo_Crypto_ECDsaCheckMultiSig).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeTrue(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeTrue(); pubkeys = new VMArray(); engine.CurrentContext.EvaluationStack.Push(signatures); @@ -111,7 +111,7 @@ public void TestCrypto_CheckMultiSig() engine.CurrentContext.EvaluationStack.Push(pubkeys); engine.CurrentContext.EvaluationStack.Push(StackItem.Null); InteropService.Invoke(engine, InteropService.Neo_Crypto_ECDsaCheckMultiSig).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeFalse(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeFalse(); pubkeys = new VMArray { @@ -127,7 +127,7 @@ public void TestCrypto_CheckMultiSig() engine.CurrentContext.EvaluationStack.Push(pubkeys); engine.CurrentContext.EvaluationStack.Push(StackItem.Null); InteropService.Invoke(engine, InteropService.Neo_Crypto_ECDsaCheckMultiSig).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeFalse(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeFalse(); } [TestMethod] @@ -140,7 +140,7 @@ public void TestAccount_IsStandard() 0x01, 0x01, 0x01, 0x01, 0x01 }; engine.CurrentContext.EvaluationStack.Push(hash); InteropService.Invoke(engine, InteropService.Neo_Account_IsStandard).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeTrue(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeTrue(); var mockSnapshot = new Mock(); var state = TestUtils.GetContract(); @@ -149,7 +149,7 @@ public void TestAccount_IsStandard() engine.LoadScript(new byte[] { 0x01 }); engine.CurrentContext.EvaluationStack.Push(state.ScriptHash.ToArray()); InteropService.Invoke(engine, InteropService.Neo_Account_IsStandard).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeFalse(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeFalse(); } [TestMethod] @@ -240,6 +240,18 @@ public void TestContract_Update() engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Update).Should().BeTrue(); + + // Remove Storage flag with something stored + + state.Manifest.Features = ContractFeatures.NoProperty; + mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache(state.ScriptHash, state)); + mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache(storageKey, storageItem)); + + engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0); + engine.LoadScript(state.Script); + engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); + engine.CurrentContext.EvaluationStack.Push(script); + InteropService.Invoke(engine, InteropService.Neo_Contract_Update).Should().BeFalse(); } [TestMethod] @@ -274,7 +286,7 @@ public void TestStorage_Find() var iterator = ((InteropInterface)engine.CurrentContext.EvaluationStack.Pop()).GetInterface(); iterator.Next(); var ele = iterator.Value(); - ele.GetByteArray().ToHexString().Should().Be(storageItem.Value.ToHexString()); + ele.GetSpan().ToHexString().Should().Be(storageItem.Value.ToHexString()); engine.CurrentContext.EvaluationStack.Push(1); InteropService.Invoke(engine, InteropService.Neo_Storage_Find).Should().BeFalse(); @@ -292,7 +304,7 @@ public void TestEnumerator_Create() InteropService.Invoke(engine, InteropService.Neo_Enumerator_Create).Should().BeTrue(); var ret = (InteropInterface)engine.CurrentContext.EvaluationStack.Pop(); ret.GetInterface().Next(); - ret.GetInterface().Value().GetByteArray().ToHexString() + ret.GetInterface().Value().GetSpan().ToHexString() .Should().Be(new byte[] { 0x01 }.ToHexString()); engine.CurrentContext.EvaluationStack.Push(1); @@ -309,7 +321,7 @@ public void TestEnumerator_Next() }; engine.CurrentContext.EvaluationStack.Push(new InteropInterface(new ArrayWrapper(arr))); InteropService.Invoke(engine, InteropService.Neo_Enumerator_Next).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeTrue(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeTrue(); engine.CurrentContext.EvaluationStack.Push(1); InteropService.Invoke(engine, InteropService.Neo_Enumerator_Next).Should().BeFalse(); @@ -327,7 +339,7 @@ public void TestEnumerator_Value() wrapper.Next(); engine.CurrentContext.EvaluationStack.Push(new InteropInterface(wrapper)); InteropService.Invoke(engine, InteropService.Neo_Enumerator_Value).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetByteArray().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); + engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); engine.CurrentContext.EvaluationStack.Push(1); InteropService.Invoke(engine, InteropService.Neo_Enumerator_Value).Should().BeFalse(); @@ -352,7 +364,7 @@ public void TestEnumerator_Concat() InteropService.Invoke(engine, InteropService.Neo_Enumerator_Concat).Should().BeTrue(); var ret = ((InteropInterface)engine.CurrentContext.EvaluationStack.Pop()).GetInterface(); ret.Next().Should().BeTrue(); - ret.Value().GetByteArray().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); + ret.Value().GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); } [TestMethod] @@ -367,7 +379,7 @@ public void TestIterator_Create() InteropService.Invoke(engine, InteropService.Neo_Iterator_Create).Should().BeTrue(); var ret = (InteropInterface)engine.CurrentContext.EvaluationStack.Pop(); ret.GetInterface().Next(); - ret.GetInterface().Value().GetByteArray().ToHexString() + ret.GetInterface().Value().GetSpan().ToHexString() .Should().Be(new byte[] { 0x01 }.ToHexString()); var map = new Map @@ -436,7 +448,7 @@ public void TestIterator_Values() InteropService.Invoke(engine, InteropService.Neo_Iterator_Values).Should().BeTrue(); var ret = ((InteropInterface)engine.CurrentContext.EvaluationStack.Pop()).GetInterface(); ret.Next(); - ret.Value().GetByteArray().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); + ret.Value().GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); engine.CurrentContext.EvaluationStack.Push(1); InteropService.Invoke(engine, InteropService.Neo_Iterator_Values).Should().BeFalse(); @@ -461,7 +473,7 @@ public void TestIterator_Concat() InteropService.Invoke(engine, InteropService.Neo_Iterator_Concat).Should().BeTrue(); var ret = ((InteropInterface)engine.CurrentContext.EvaluationStack.Pop()).GetInterface(); ret.Next().Should().BeTrue(); - ret.Value().GetByteArray().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); + ret.Value().GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); } [TestMethod] diff --git a/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs similarity index 95% rename from neo.UnitTests/SmartContract/UT_InteropService.cs rename to tests/neo.UnitTests/SmartContract/UT_InteropService.cs index cc6eac738a..83f4a1485b 100644 --- a/neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs @@ -188,7 +188,7 @@ private void AssertNotification(StackItem stackItem, UInt160 scriptHash, string var array = (VM.Types.Array)stackItem; Assert.AreEqual(2, array.Count); - CollectionAssert.AreEqual(scriptHash.ToArray(), array[0].GetByteArray()); + CollectionAssert.AreEqual(scriptHash.ToArray(), array[0].GetSpan().ToArray()); Assert.AreEqual(notification, array[1].GetString()); } @@ -198,7 +198,7 @@ private void AssertNotification(StackItem stackItem, UInt160 scriptHash, int not var array = (VM.Types.Array)stackItem; Assert.AreEqual(2, array.Count); - CollectionAssert.AreEqual(scriptHash.ToArray(), array[0].GetByteArray()); + CollectionAssert.AreEqual(scriptHash.ToArray(), array[0].GetSpan().ToArray()); Assert.AreEqual(notification, array[1].GetBigInteger()); } @@ -209,7 +209,7 @@ public void TestExecutionEngine_GetScriptContainer() InteropService.Invoke(engine, InteropService.System_ExecutionEngine_GetScriptContainer).Should().BeTrue(); var stackItem = ((VM.Types.Array)engine.CurrentContext.EvaluationStack.Pop()).ToArray(); stackItem.Length.Should().Be(8); - stackItem[0].GetByteArray().ToHexString().Should().Be(TestUtils.GetTransaction().Hash.ToArray().ToHexString()); + stackItem[0].GetSpan().ToHexString().Should().Be(TestUtils.GetTransaction().Hash.ToArray().ToHexString()); } [TestMethod] @@ -217,7 +217,7 @@ public void TestExecutionEngine_GetExecutingScriptHash() { var engine = GetEngine(); InteropService.Invoke(engine, InteropService.System_ExecutionEngine_GetExecutingScriptHash).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetByteArray().ToHexString() + engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString() .Should().Be(engine.CurrentScriptHash.ToArray().ToHexString()); } @@ -231,7 +231,7 @@ public void TestExecutionEngine_GetCallingScriptHash() engine = GetEngine(true); engine.LoadScript(new byte[] { 0x01 }); InteropService.Invoke(engine, InteropService.System_ExecutionEngine_GetCallingScriptHash).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetByteArray().ToHexString() + engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString() .Should().Be(engine.CallingScriptHash.ToArray().ToHexString()); } @@ -240,7 +240,7 @@ public void TestExecutionEngine_GetEntryScriptHash() { var engine = GetEngine(); InteropService.Invoke(engine, InteropService.System_ExecutionEngine_GetEntryScriptHash).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetByteArray().ToHexString() + engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString() .Should().Be(engine.EntryScriptHash.ToArray().ToHexString()); } @@ -249,7 +249,7 @@ public void TestRuntime_Platform() { var engine = GetEngine(); InteropService.Invoke(engine, InteropService.System_Runtime_Platform).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetByteArray().ToHexString() + engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString() .Should().Be(Encoding.ASCII.GetBytes("NEO").ToHexString()); } @@ -276,12 +276,12 @@ public void TestRuntime_CheckWitness() engine.CurrentContext.EvaluationStack.Push(pubkey.EncodePoint(true)); InteropService.Invoke(engine, InteropService.System_Runtime_CheckWitness).Should().BeTrue(); engine.CurrentContext.EvaluationStack.Peek().GetType().Should().Be(typeof(Neo.VM.Types.Boolean)); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().Be(false); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().Be(false); engine.CurrentContext.EvaluationStack.Push(((Transaction)engine.ScriptContainer).Sender.ToArray()); InteropService.Invoke(engine, InteropService.System_Runtime_CheckWitness).Should().BeTrue(); engine.CurrentContext.EvaluationStack.Peek().GetType().Should().Be(typeof(Neo.VM.Types.Boolean)); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().Be(false); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().Be(false); engine.CurrentContext.EvaluationStack.Push(new byte[0]); InteropService.Invoke(engine, InteropService.System_Runtime_CheckWitness).Should().BeFalse(); @@ -317,7 +317,7 @@ public void TestRuntime_Serialize() var engine = GetEngine(); engine.CurrentContext.EvaluationStack.Push(100); InteropService.Invoke(engine, InteropService.System_Runtime_Serialize).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetByteArray().ToHexString() + engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString() .Should().Be(new byte[] { 0x02, 0x01, 0x64 }.ToHexString()); engine.CurrentContext.EvaluationStack.Push(new byte[1024 * 1024 * 2]); //Larger than MaxItemSize @@ -366,7 +366,7 @@ public void TestCrypto_Verify() engine.CurrentContext.EvaluationStack.Push(pubkey.EncodePoint(false)); engine.CurrentContext.EvaluationStack.Push(message); InteropService.Invoke(engine, InteropService.Neo_Crypto_ECDsaVerify).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeTrue(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeTrue(); byte[] wrongkey = pubkey.EncodePoint(false); wrongkey[0] = 5; @@ -374,7 +374,7 @@ public void TestCrypto_Verify() engine.CurrentContext.EvaluationStack.Push(wrongkey); engine.CurrentContext.EvaluationStack.Push(new InteropInterface(engine.ScriptContainer)); InteropService.Invoke(engine, InteropService.Neo_Crypto_ECDsaVerify).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Peek().GetBoolean().Should().BeFalse(); + engine.CurrentContext.EvaluationStack.Peek().ToBoolean().Should().BeFalse(); } [TestMethod] @@ -400,7 +400,7 @@ public void TestBlockchain_GetBlock() 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; engine.CurrentContext.EvaluationStack.Push(data1); InteropService.Invoke(engine, InteropService.System_Blockchain_GetBlock).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeFalse(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeFalse(); byte[] data2 = new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; engine.CurrentContext.EvaluationStack.Push(data2); @@ -417,7 +417,7 @@ public void TestBlockchain_GetTransaction() 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; engine.CurrentContext.EvaluationStack.Push(data1); InteropService.Invoke(engine, InteropService.System_Blockchain_GetTransaction).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetBoolean().Should().BeFalse(); + engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeFalse(); } [TestMethod] @@ -455,9 +455,9 @@ public void TestBlockchain_GetContract() var stackItems = ((VM.Types.Array)engine.CurrentContext.EvaluationStack.Pop()).ToArray(); stackItems.Length.Should().Be(3); stackItems[0].GetType().Should().Be(typeof(ByteArray)); - stackItems[0].GetByteArray().ToHexString().Should().Be(state.Script.ToHexString()); - stackItems[1].GetBoolean().Should().BeFalse(); - stackItems[2].GetBoolean().Should().BeFalse(); + stackItems[0].GetSpan().ToHexString().Should().Be(state.Script.ToHexString()); + stackItems[1].ToBoolean().Should().BeFalse(); + stackItems[2].ToBoolean().Should().BeFalse(); } [TestMethod] @@ -510,7 +510,7 @@ public void TestStorage_Get() IsReadOnly = false })); InteropService.Invoke(engine, InteropService.System_Storage_Get).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetByteArray().ToHexString().Should().Be(storageItem.Value.ToHexString()); + engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString().Should().Be(storageItem.Value.ToHexString()); mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache()); engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0); @@ -746,8 +746,8 @@ public void TestContract_Call() engine.CurrentContext.EvaluationStack.Push(method); engine.CurrentContext.EvaluationStack.Push(state.ScriptHash.ToArray()); InteropService.Invoke(engine, InteropService.System_Contract_Call).Should().BeTrue(); - engine.CurrentContext.EvaluationStack.Pop().GetByteArray().ToHexString().Should().Be(method.ToHexString()); - engine.CurrentContext.EvaluationStack.Pop().GetByteArray().ToHexString().Should().Be(args.ToHexString()); + engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString().Should().Be(method.ToHexString()); + engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString().Should().Be(args.ToHexString()); state.Manifest.Permissions[0].Methods = WildCardContainer.Create("a"); engine.CurrentContext.EvaluationStack.Push(args); @@ -838,7 +838,7 @@ private static ApplicationEngine GetEngine(bool hasContainer = false, bool hasSn internal class TestInteropInterface : InteropInterface { public override bool Equals(StackItem other) => true; - public override bool GetBoolean() => true; + public override bool ToBoolean() => true; public override T GetInterface() => throw new NotImplementedException(); } } diff --git a/neo.UnitTests/SmartContract/UT_JsonSerializer.cs b/tests/neo.UnitTests/SmartContract/UT_JsonSerializer.cs similarity index 97% rename from neo.UnitTests/SmartContract/UT_JsonSerializer.cs rename to tests/neo.UnitTests/SmartContract/UT_JsonSerializer.cs index ed9c9cd72b..788868622c 100644 --- a/neo.UnitTests/SmartContract/UT_JsonSerializer.cs +++ b/tests/neo.UnitTests/SmartContract/UT_JsonSerializer.cs @@ -31,7 +31,7 @@ public void JsonTest_WrongJson() Assert.ThrowsException(() => JObject.Parse(json)); json = @"{""length"":99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999}"; - Assert.ThrowsException(() => JObject.Parse(json)); + Assert.ThrowsException(() => JObject.Parse(json)); json = $"{{\"length\":{long.MaxValue}}}"; Assert.ThrowsException(() => JObject.Parse(json)); @@ -119,7 +119,7 @@ public void JsonTest_String() var json = @" ["""" , ""\b\f\t\n\r\/\\"" ]"; var parsed = JObject.Parse(json); - Assert.AreEqual(@"["""",""\b\f\t\n\r\/\\""]", parsed.ToString()); + Assert.AreEqual(@"["""",""\b\f\t\n\r/\\""]", parsed.ToString()); json = @"[""\uD834\uDD1E""]"; parsed = JObject.Parse(json); @@ -281,7 +281,7 @@ public void Deserialize_Array_Bool_Str_Num() var array = (VM.Types.Array)items; - Assert.IsTrue(array[0].GetBoolean()); + Assert.IsTrue(array[0].ToBoolean()); Assert.AreEqual(array[1].GetString(), "test"); Assert.AreEqual(array[2].GetBigInteger(), 123); } @@ -316,7 +316,7 @@ public void Deserialize_Array_OfArray() array = (VM.Types.Array)array[0]; Assert.AreEqual(array.Count, 3); - Assert.IsTrue(array[0].GetBoolean()); + Assert.IsTrue(array[0].ToBoolean()); Assert.AreEqual(array[1].GetString(), "test1"); Assert.AreEqual(array[2].GetBigInteger(), 123); @@ -324,7 +324,7 @@ public void Deserialize_Array_OfArray() array = (VM.Types.Array)array[1]; Assert.AreEqual(array.Count, 3); - Assert.IsTrue(array[0].GetBoolean()); + Assert.IsTrue(array[0].ToBoolean()); Assert.AreEqual(array[1].GetString(), "test2"); Assert.AreEqual(array[2].GetBigInteger(), 321); } diff --git a/neo.UnitTests/SmartContract/UT_LogEventArgs.cs b/tests/neo.UnitTests/SmartContract/UT_LogEventArgs.cs similarity index 100% rename from neo.UnitTests/SmartContract/UT_LogEventArgs.cs rename to tests/neo.UnitTests/SmartContract/UT_LogEventArgs.cs diff --git a/neo.UnitTests/SmartContract/UT_NefFile.cs b/tests/neo.UnitTests/SmartContract/UT_NefFile.cs similarity index 100% rename from neo.UnitTests/SmartContract/UT_NefFile.cs rename to tests/neo.UnitTests/SmartContract/UT_NefFile.cs diff --git a/neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs b/tests/neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs similarity index 93% rename from neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs rename to tests/neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs index a1dd95b6ee..1dfd6a6ec5 100644 --- a/neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs +++ b/tests/neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs @@ -1,8 +1,8 @@ -using FluentAssertions; +using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Network.P2P.Payloads; using Neo.SmartContract; -using Neo.VM; +using Neo.VM.Types; namespace Neo.UnitTests.SmartContract { diff --git a/neo.UnitTests/SmartContract/UT_OpCodePrices.cs b/tests/neo.UnitTests/SmartContract/UT_OpCodePrices.cs similarity index 100% rename from neo.UnitTests/SmartContract/UT_OpCodePrices.cs rename to tests/neo.UnitTests/SmartContract/UT_OpCodePrices.cs diff --git a/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs similarity index 98% rename from neo.UnitTests/SmartContract/UT_SmartContractHelper.cs rename to tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs index 8379fccd6b..8a85e7a4b4 100644 --- a/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs +++ b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs @@ -5,7 +5,6 @@ using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract; -using Neo.VM; using Neo.VM.Types; using Neo.Wallets; using System; @@ -169,7 +168,7 @@ public void TestSerialize() Assert.AreEqual(Encoding.Default.GetString(expectedArray7), Encoding.Default.GetString(result7)); StackItem stackItem81 = new VM.Types.Integer(1); - Dictionary list8 = new Dictionary + Dictionary list8 = new Dictionary { { new VM.Types.Integer(2), stackItem81 } }; @@ -180,7 +179,7 @@ public void TestSerialize() }; Assert.AreEqual(Encoding.Default.GetString(expectedArray8), Encoding.Default.GetString(result8)); - StackItem stackItem9 = new VM.Types.Integer(1); + Integer stackItem9 = new VM.Types.Integer(1); Map stackItem91 = new VM.Types.Map(); stackItem91.Add(stackItem9, stackItem91); Action action9 = () => Neo.SmartContract.Helper.Serialize(stackItem91); @@ -235,7 +234,7 @@ public void TestDeserializeStackItem() Assert.AreEqual(((VM.Types.Struct)stackItem62).GetEnumerator().Current, ((VM.Types.Struct)result6).GetEnumerator().Current); StackItem stackItem71 = new VM.Types.Integer(1); - Dictionary list7 = new Dictionary(); + Dictionary list7 = new Dictionary(); list7.Add(new VM.Types.Integer(2), stackItem71); StackItem stackItem72 = new VM.Types.Map(list7); byte[] byteArray7 = Neo.SmartContract.Helper.Serialize(stackItem72); diff --git a/neo.UnitTests/SmartContract/UT_StorageContext.cs b/tests/neo.UnitTests/SmartContract/UT_StorageContext.cs similarity index 100% rename from neo.UnitTests/SmartContract/UT_StorageContext.cs rename to tests/neo.UnitTests/SmartContract/UT_StorageContext.cs diff --git a/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs similarity index 92% rename from neo.UnitTests/SmartContract/UT_Syscalls.cs rename to tests/neo.UnitTests/SmartContract/UT_Syscalls.cs index b778f63d94..f54b533106 100644 --- a/neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -75,8 +75,8 @@ public void System_Blockchain_GetBlock() Assert.AreEqual(engine.Execute(), VMState.HALT); Assert.AreEqual(1, engine.ResultStack.Count); Assert.IsInstanceOfType(engine.ResultStack.Peek(), typeof(ByteArray)); - Assert.AreEqual(engine.ResultStack.Pop().GetByteArray().ToHexString(), - "5b22556168355c2f4b6f446d39723064555950636353714346745a30594f726b583164646e7334366e676e3962383d222c332c22414141414141414141414141414141414141414141414141414141414141414141414141414141414141413d222c22414141414141414141414141414141414141414141414141414141414141414141414141414141414141413d222c322c312c224141414141414141414141414141414141414141414141414141413d222c315d"); + Assert.AreEqual(engine.ResultStack.Pop().GetSpan().ToHexString(), + "5b22556168352f4b6f446d39723064555950636353714346745a30594f726b583164646e7334366e676e3962383d222c332c22414141414141414141414141414141414141414141414141414141414141414141414141414141414141413d222c22414141414141414141414141414141414141414141414141414141414141414141414141414141414141413d222c322c312c224141414141414141414141414141414141414141414141414141413d222c315d"); Assert.AreEqual(0, engine.ResultStack.Count); // Clean @@ -126,8 +126,8 @@ public void System_ExecutionEngine_GetScriptContainer() Assert.AreEqual(engine.Execute(), VMState.HALT); Assert.AreEqual(1, engine.ResultStack.Count); Assert.IsInstanceOfType(engine.ResultStack.Peek(), typeof(ByteArray)); - Assert.AreEqual(engine.ResultStack.Pop().GetByteArray().ToHexString(), - @"5b225c75303032426b53415959527a4c4b69685a676464414b50596f754655737a63544d7867445a6572584a3172784c37303d222c362c342c225c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f5c2f383d222c332c322c352c2241513d3d225d"); + Assert.AreEqual(engine.ResultStack.Pop().GetSpan().ToHexString(), + @"5b225c75303032426b53415959527a4c4b69685a676464414b50596f754655737a63544d7867445a6572584a3172784c37303d222c362c342c222f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f383d222c332c322c352c2241513d3d225d"); Assert.AreEqual(0, engine.ResultStack.Count); } } diff --git a/neo.UnitTests/TestBlockchain.cs b/tests/neo.UnitTests/TestBlockchain.cs similarity index 100% rename from neo.UnitTests/TestBlockchain.cs rename to tests/neo.UnitTests/TestBlockchain.cs diff --git a/neo.UnitTests/TestDataCache.cs b/tests/neo.UnitTests/TestDataCache.cs similarity index 100% rename from neo.UnitTests/TestDataCache.cs rename to tests/neo.UnitTests/TestDataCache.cs diff --git a/neo.UnitTests/TestMetaDataCache.cs b/tests/neo.UnitTests/TestMetaDataCache.cs similarity index 100% rename from neo.UnitTests/TestMetaDataCache.cs rename to tests/neo.UnitTests/TestMetaDataCache.cs diff --git a/neo.UnitTests/TestUtils.cs b/tests/neo.UnitTests/TestUtils.cs similarity index 100% rename from neo.UnitTests/TestUtils.cs rename to tests/neo.UnitTests/TestUtils.cs diff --git a/neo.UnitTests/TestVerifiable.cs b/tests/neo.UnitTests/TestVerifiable.cs similarity index 100% rename from neo.UnitTests/TestVerifiable.cs rename to tests/neo.UnitTests/TestVerifiable.cs diff --git a/neo.UnitTests/TestWalletAccount.cs b/tests/neo.UnitTests/TestWalletAccount.cs similarity index 100% rename from neo.UnitTests/TestWalletAccount.cs rename to tests/neo.UnitTests/TestWalletAccount.cs diff --git a/neo.UnitTests/UT_BigDecimal.cs b/tests/neo.UnitTests/UT_BigDecimal.cs similarity index 100% rename from neo.UnitTests/UT_BigDecimal.cs rename to tests/neo.UnitTests/UT_BigDecimal.cs diff --git a/neo.UnitTests/UT_Culture.cs b/tests/neo.UnitTests/UT_Culture.cs similarity index 100% rename from neo.UnitTests/UT_Culture.cs rename to tests/neo.UnitTests/UT_Culture.cs diff --git a/neo.UnitTests/UT_DataCache.cs b/tests/neo.UnitTests/UT_DataCache.cs similarity index 100% rename from neo.UnitTests/UT_DataCache.cs rename to tests/neo.UnitTests/UT_DataCache.cs diff --git a/neo.UnitTests/UT_Helper.cs b/tests/neo.UnitTests/UT_Helper.cs similarity index 100% rename from neo.UnitTests/UT_Helper.cs rename to tests/neo.UnitTests/UT_Helper.cs diff --git a/neo.UnitTests/UT_NeoSystem.cs b/tests/neo.UnitTests/UT_NeoSystem.cs similarity index 100% rename from neo.UnitTests/UT_NeoSystem.cs rename to tests/neo.UnitTests/UT_NeoSystem.cs diff --git a/neo.UnitTests/UT_ProtocolSettings.cs b/tests/neo.UnitTests/UT_ProtocolSettings.cs similarity index 100% rename from neo.UnitTests/UT_ProtocolSettings.cs rename to tests/neo.UnitTests/UT_ProtocolSettings.cs diff --git a/neo.UnitTests/UT_UInt160.cs b/tests/neo.UnitTests/UT_UInt160.cs similarity index 98% rename from neo.UnitTests/UT_UInt160.cs rename to tests/neo.UnitTests/UT_UInt160.cs index 99cf91a5c3..0a0eb0321e 100644 --- a/neo.UnitTests/UT_UInt160.cs +++ b/tests/neo.UnitTests/UT_UInt160.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1718 + using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; diff --git a/neo.UnitTests/UT_UInt256.cs b/tests/neo.UnitTests/UT_UInt256.cs similarity index 99% rename from neo.UnitTests/UT_UInt256.cs rename to tests/neo.UnitTests/UT_UInt256.cs index 179e991110..d263effdee 100644 --- a/neo.UnitTests/UT_UInt256.cs +++ b/tests/neo.UnitTests/UT_UInt256.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1718 + using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; diff --git a/neo.UnitTests/UT_UIntBase.cs b/tests/neo.UnitTests/UT_UIntBase.cs similarity index 100% rename from neo.UnitTests/UT_UIntBase.cs rename to tests/neo.UnitTests/UT_UIntBase.cs diff --git a/neo.UnitTests/UT_UIntBenchmarks.cs b/tests/neo.UnitTests/UT_UIntBenchmarks.cs similarity index 100% rename from neo.UnitTests/UT_UIntBenchmarks.cs rename to tests/neo.UnitTests/UT_UIntBenchmarks.cs diff --git a/tests/neo.UnitTests/UT_Utility.cs b/tests/neo.UnitTests/UT_Utility.cs new file mode 100644 index 0000000000..dd68da017c --- /dev/null +++ b/tests/neo.UnitTests/UT_Utility.cs @@ -0,0 +1,55 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.SmartContract; +using Neo.Wallets; +using System; + +namespace Neo.UnitTests +{ + [TestClass] + public class UT_Utility + { + private KeyPair keyPair; + private UInt160 scriptHash; + + [TestInitialize] + public void TestSetup() + { + keyPair = new KeyPair(Wallet.GetPrivateKeyFromWIF("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p")); + scriptHash = Contract.CreateSignatureRedeemScript(keyPair.PublicKey).ToScriptHash(); + } + + [TestMethod] + public void TestGetKeyPair() + { + string nul = null; + Assert.ThrowsException(() => Utility.GetKeyPair(nul)); + + string wif = "KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"; + var result = Utility.GetKeyPair(wif); + Assert.AreEqual(keyPair, result); + + string privateKey = keyPair.PrivateKey.ToHexString(); + result = Utility.GetKeyPair(privateKey); + Assert.AreEqual(keyPair, result); + } + + [TestMethod] + public void TestGetScriptHash() + { + string nul = null; + Assert.ThrowsException(() => Utility.GetScriptHash(nul)); + + string addr = scriptHash.ToAddress(); + var result = Utility.GetScriptHash(addr); + Assert.AreEqual(scriptHash, result); + + string hash = scriptHash.ToString(); + result = Utility.GetScriptHash(hash); + Assert.AreEqual(scriptHash, result); + + string publicKey = keyPair.PublicKey.ToString(); + result = Utility.GetScriptHash(publicKey); + Assert.AreEqual(scriptHash, result); + } + } +} diff --git a/neo.UnitTests/VM/UT_Helper.cs b/tests/neo.UnitTests/VM/UT_Helper.cs similarity index 96% rename from neo.UnitTests/VM/UT_Helper.cs rename to tests/neo.UnitTests/VM/UT_Helper.cs index 39f1ec104a..f394b63f0b 100644 --- a/neo.UnitTests/VM/UT_Helper.cs +++ b/tests/neo.UnitTests/VM/UT_Helper.cs @@ -2,14 +2,17 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; using Neo.SmartContract; +using Neo.SmartContract.Native; using Neo.VM; +using Neo.VM.Types; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; using System.Text; +using Array = System.Array; -namespace Neo.UnitTests.IO +namespace Neo.UnitTests.VMT { [TestClass] public class UT_Helper @@ -84,6 +87,15 @@ public void TestEmitAppCall3() Assert.AreEqual(Encoding.Default.GetString(tempArray), Encoding.Default.GetString(resultArray)); } + [TestMethod] + public void TestMakeScript() + { + byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero); + + Assert.AreEqual("14000000000000000000000000000000000000000051c10962616c616e63654f66142582d1b275e86c8f0e93a9b2facd5fdb760976a168627d5b52", + testScript.ToHexString()); + } + [TestMethod] public void TestToParameter() { @@ -102,7 +114,7 @@ public void TestToParameter() StackItem arrayItem = new VM.Types.Array(new[] { byteItem, boolItem, intItem, interopItem }); Assert.AreEqual(1000, (BigInteger)(arrayItem.ToParameter().Value as List)[2].Value); - StackItem mapItem = new VM.Types.Map(new Dictionary(new[] { new KeyValuePair(byteItem, intItem) })); + StackItem mapItem = new Map(new Dictionary { [(PrimitiveType)byteItem] = intItem }); Assert.AreEqual(1000, (BigInteger)(mapItem.ToParameter().Value as List>)[0].Value.Value); } @@ -113,7 +125,7 @@ public void TestToStackItem() Assert.AreEqual(30000000000000L, (long)byteParameter.ToStackItem().GetBigInteger()); ContractParameter boolParameter = new ContractParameter { Type = ContractParameterType.Boolean, Value = false }; - Assert.AreEqual(false, boolParameter.ToStackItem().GetBoolean()); + Assert.AreEqual(false, boolParameter.ToStackItem().ToBoolean()); ContractParameter intParameter = new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1000) }; Assert.AreEqual(1000, intParameter.ToStackItem().GetBigInteger()); @@ -125,10 +137,10 @@ public void TestToStackItem() Assert.AreEqual(0, h256Parameter.ToStackItem().GetBigInteger()); ContractParameter pkParameter = new ContractParameter { Type = ContractParameterType.PublicKey, Value = ECPoint.Parse("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575", ECCurve.Secp256r1) }; - Assert.AreEqual("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575", pkParameter.ToStackItem().GetByteArray().ToHexString()); + Assert.AreEqual("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575", pkParameter.ToStackItem().GetSpan().ToHexString()); ContractParameter strParameter = new ContractParameter { Type = ContractParameterType.String, Value = "test😂👍" }; - Assert.AreEqual("test😂👍", Encoding.UTF8.GetString(strParameter.ToStackItem().GetByteArray())); + Assert.AreEqual("test😂👍", strParameter.ToStackItem().GetString()); ContractParameter interopParameter = new ContractParameter { Type = ContractParameterType.InteropInterface }; Assert.AreEqual(null, interopParameter.ToStackItem()); diff --git a/neo.UnitTests/Wallets/NEP6/UT_NEP6Account.cs b/tests/neo.UnitTests/Wallets/NEP6/UT_NEP6Account.cs similarity index 97% rename from neo.UnitTests/Wallets/NEP6/UT_NEP6Account.cs rename to tests/neo.UnitTests/Wallets/NEP6/UT_NEP6Account.cs index 0477b8a595..10dd9ba015 100644 --- a/neo.UnitTests/Wallets/NEP6/UT_NEP6Account.cs +++ b/tests/neo.UnitTests/Wallets/NEP6/UT_NEP6Account.cs @@ -121,7 +121,7 @@ public void TestToJson() json["isDefault"].ToString().Should().Be("false"); json["lock"].ToString().Should().Be("false"); json["key"].Should().BeNull(); - json["contract"]["script"].ToString().Should().Be("\"IQNgPziA63rqCtRQCJOSXkpC\\/qSKRO5viYoQs8fOBdKiZ6w=\""); + json["contract"]["script"].ToString().Should().Be(@"""IQNgPziA63rqCtRQCJOSXkpC/qSKRO5viYoQs8fOBdKiZ6w="""); json["extra"].Should().BeNull(); _account.Contract = null; diff --git a/neo.UnitTests/Wallets/NEP6/UT_NEP6Contract.cs b/tests/neo.UnitTests/Wallets/NEP6/UT_NEP6Contract.cs similarity index 100% rename from neo.UnitTests/Wallets/NEP6/UT_NEP6Contract.cs rename to tests/neo.UnitTests/Wallets/NEP6/UT_NEP6Contract.cs diff --git a/neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs b/tests/neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs similarity index 100% rename from neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs rename to tests/neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs diff --git a/neo.UnitTests/Wallets/NEP6/UT_ScryptParameters.cs b/tests/neo.UnitTests/Wallets/NEP6/UT_ScryptParameters.cs similarity index 100% rename from neo.UnitTests/Wallets/NEP6/UT_ScryptParameters.cs rename to tests/neo.UnitTests/Wallets/NEP6/UT_ScryptParameters.cs diff --git a/neo.UnitTests/Wallets/SQLite/UT_Account.cs b/tests/neo.UnitTests/Wallets/SQLite/UT_Account.cs similarity index 100% rename from neo.UnitTests/Wallets/SQLite/UT_Account.cs rename to tests/neo.UnitTests/Wallets/SQLite/UT_Account.cs diff --git a/neo.UnitTests/Wallets/SQLite/UT_Address.cs b/tests/neo.UnitTests/Wallets/SQLite/UT_Address.cs similarity index 100% rename from neo.UnitTests/Wallets/SQLite/UT_Address.cs rename to tests/neo.UnitTests/Wallets/SQLite/UT_Address.cs diff --git a/neo.UnitTests/Wallets/SQLite/UT_Contract.cs b/tests/neo.UnitTests/Wallets/SQLite/UT_Contract.cs similarity index 100% rename from neo.UnitTests/Wallets/SQLite/UT_Contract.cs rename to tests/neo.UnitTests/Wallets/SQLite/UT_Contract.cs diff --git a/neo.UnitTests/Wallets/SQLite/UT_Key.cs b/tests/neo.UnitTests/Wallets/SQLite/UT_Key.cs similarity index 100% rename from neo.UnitTests/Wallets/SQLite/UT_Key.cs rename to tests/neo.UnitTests/Wallets/SQLite/UT_Key.cs diff --git a/neo.UnitTests/Wallets/SQLite/UT_UserWallet.cs b/tests/neo.UnitTests/Wallets/SQLite/UT_UserWallet.cs similarity index 100% rename from neo.UnitTests/Wallets/SQLite/UT_UserWallet.cs rename to tests/neo.UnitTests/Wallets/SQLite/UT_UserWallet.cs diff --git a/neo.UnitTests/Wallets/SQLite/UT_UserWalletAccount.cs b/tests/neo.UnitTests/Wallets/SQLite/UT_UserWalletAccount.cs similarity index 100% rename from neo.UnitTests/Wallets/SQLite/UT_UserWalletAccount.cs rename to tests/neo.UnitTests/Wallets/SQLite/UT_UserWalletAccount.cs diff --git a/neo.UnitTests/Wallets/SQLite/UT_VerificationContract.cs b/tests/neo.UnitTests/Wallets/SQLite/UT_VerificationContract.cs similarity index 100% rename from neo.UnitTests/Wallets/SQLite/UT_VerificationContract.cs rename to tests/neo.UnitTests/Wallets/SQLite/UT_VerificationContract.cs diff --git a/neo.UnitTests/Wallets/UT_AssetDescriptor.cs b/tests/neo.UnitTests/Wallets/UT_AssetDescriptor.cs similarity index 100% rename from neo.UnitTests/Wallets/UT_AssetDescriptor.cs rename to tests/neo.UnitTests/Wallets/UT_AssetDescriptor.cs diff --git a/neo.UnitTests/Wallets/UT_KeyPair.cs b/tests/neo.UnitTests/Wallets/UT_KeyPair.cs similarity index 100% rename from neo.UnitTests/Wallets/UT_KeyPair.cs rename to tests/neo.UnitTests/Wallets/UT_KeyPair.cs diff --git a/neo.UnitTests/Wallets/UT_Wallet.cs b/tests/neo.UnitTests/Wallets/UT_Wallet.cs similarity index 100% rename from neo.UnitTests/Wallets/UT_Wallet.cs rename to tests/neo.UnitTests/Wallets/UT_Wallet.cs diff --git a/neo.UnitTests/Wallets/UT_WalletAccount.cs b/tests/neo.UnitTests/Wallets/UT_WalletAccount.cs similarity index 100% rename from neo.UnitTests/Wallets/UT_WalletAccount.cs rename to tests/neo.UnitTests/Wallets/UT_WalletAccount.cs diff --git a/neo.UnitTests/Wallets/UT_Wallets_Helper.cs b/tests/neo.UnitTests/Wallets/UT_Wallets_Helper.cs similarity index 100% rename from neo.UnitTests/Wallets/UT_Wallets_Helper.cs rename to tests/neo.UnitTests/Wallets/UT_Wallets_Helper.cs diff --git a/neo.UnitTests/neo.UnitTests.csproj b/tests/neo.UnitTests/neo.UnitTests.csproj similarity index 78% rename from neo.UnitTests/neo.UnitTests.csproj rename to tests/neo.UnitTests/neo.UnitTests.csproj index 2da1ba4968..5857ea504f 100644 --- a/neo.UnitTests/neo.UnitTests.csproj +++ b/tests/neo.UnitTests/neo.UnitTests.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.2 + netcoreapp3.0 Neo.UnitTests Neo.UnitTests true @@ -16,16 +16,16 @@ - + - - - + + + - + diff --git a/neo.UnitTests/protocol.json b/tests/neo.UnitTests/protocol.json similarity index 100% rename from neo.UnitTests/protocol.json rename to tests/neo.UnitTests/protocol.json