Skip to content

Commit

Permalink
Merge branch 'master' into notary-assisted
Browse files Browse the repository at this point in the history
  • Loading branch information
AnnaShaleva committed Jan 23, 2025
2 parents ab422d7 + befe7f6 commit 4af93c8
Show file tree
Hide file tree
Showing 326 changed files with 1,799 additions and 852 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# https://github.com/dotnet/dotnet-docker/blob/main/README.sdk.md
# https://mcr.microsoft.com/en-us/artifact/mar/dotnet/sdk/tags <-- this shows all images
FROM mcr.microsoft.com/dotnet/sdk:9.0.101-noble
FROM mcr.microsoft.com/dotnet/sdk:9.0.102-noble

# Install the libleveldb-dev package
RUN apt-get update && apt-get install -y libleveldb-dev
4 changes: 4 additions & 0 deletions benchmarks/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<AnalysisLevel>latest</AnalysisLevel>
</PropertyGroup>

</Project>
59 changes: 59 additions & 0 deletions benchmarks/Neo.Benchmarks/Persistence/Bechmarks_LevelDB.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (C) 2015-2025 The Neo Project.
//
// Bechmarks_LevelDB.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using BenchmarkDotNet.Attributes;
using Neo.Persistence;
using Neo.Plugins.Storage;
using Neo.SmartContract;
using System.Diagnostics;

namespace Neo.Benchmarks.Persistence.Benchmarks
{
public class Bechmarks_LevelDB
{
// avoid allocations in benchmarks
private static StorageKey key1;
private static readonly byte[] value = new UInt256().GetSpan().ToArray();

private const string PathLevelDB = "Data_LevelDB_Benchmarks";

private static readonly LevelDBStore levelDb = new();
private static ISnapshot snapshot;

[GlobalSetup]
public void Setup()
{
if (Directory.Exists(PathLevelDB))
Directory.Delete(PathLevelDB, true);

key1 = new KeyBuilder(1, 1).Add(new UInt160());

var levelDbStore = levelDb.GetStore(PathLevelDB);
snapshot = levelDbStore.GetSnapshot();
}

[GlobalCleanup]
public void Cleanup()
{
snapshot.Dispose();
levelDb.Dispose();
if (Directory.Exists(PathLevelDB))
Directory.Delete(PathLevelDB, true);
}

[Benchmark]
public void LevelDBSnapshotWrites()
{
snapshot.Put(key1.ToArray(), value);
snapshot.Delete(key1.ToArray());
}
}
}
1 change: 1 addition & 0 deletions benchmarks/Neo.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@
BenchmarkRunner.Run<Benchmarks_Hash>();
BenchmarkRunner.Run<Benchmarks_StorageKey>();
BenchmarkRunner.Run<Bechmarks_ReadOnlyStoreView>();
BenchmarkRunner.Run<Bechmarks_LevelDB>();
84 changes: 38 additions & 46 deletions benchmarks/Neo.Json.Benchmarks/Benchmark_JsonDeserialize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,28 +45,29 @@ public void Setup()
[Benchmark]
public List<RpcTestCase> NeoJson_Deserialize()
{
var result = new List<RpcTestCase>();

// Parses into JArray
var neoJsonObject = Neo.Json.JArray.Parse(_jsonString);
if (JToken.Parse(_jsonString) is not JArray neoJsonObject)
return [];

foreach (var item in neoJsonObject as JArray)
var result = new List<RpcTestCase>();

foreach (var item in neoJsonObject)
{
var testCase = new RpcTestCase
{
Name = item["Name"]?.GetString(),
Name = item?["Name"]?.GetString(),
Request = new RpcRequest
{
JsonRpc = item["Request"]?["jsonrpc"]?.GetString(),
Method = item["Request"]?["method"]?.GetString(),
Params = ConvertToJTokenArray(item["Request"]?["params"]),
Id = (int)item["Request"]?["id"].GetNumber()
JsonRpc = item?["Request"]?["jsonrpc"]?.GetString(),
Method = item?["Request"]?["method"]?.GetString(),
Params = ConvertToJTokenArray(item?["Request"]?["params"]),
Id = item?["Request"]?["id"]?.GetNumber()
},
Response = new RpcResponse
{
JsonRpc = item["Response"]?["jsonrpc"].GetString(),
Id = (int)item["Response"]?["id"]?.GetNumber(),
Result = item["Response"]?["result"]
JsonRpc = item?["Response"]?["jsonrpc"]?.GetString(),
Id = item?["Response"]?["id"]?.GetNumber(),
Result = item?["Response"]?["result"]
}
};
result.Add(testCase);
Expand All @@ -77,19 +78,19 @@ public List<RpcTestCase> NeoJson_Deserialize()
/// <summary>
/// Recursively parsing params and stack arrays
/// </summary>
private List<object> ParseParams(Neo.Json.JToken token)
private List<object?> ParseParams(JToken? token)
{
var result = new List<object>();
var result = new List<object?>();

if (token is Neo.Json.JArray array)
if (token is JArray array)
{
// Parsing JArray correctly with foreach
foreach (var item in array)
{
result.Add(ParseParams(item));
}
}
else if (token is Neo.Json.JObject obj)
else if (token is JObject obj)
{
// Properties traversal with Neo.Json.JObject
var dict = new Dictionary<string, object?>();
Expand All @@ -102,7 +103,7 @@ private List<object> ParseParams(Neo.Json.JToken token)
else
{
// If it's a normal value, it's straightforward to add
result.Add(token.GetString());
result.Add(token?.GetString());
}

return result;
Expand All @@ -111,26 +112,24 @@ private List<object> ParseParams(Neo.Json.JToken token)
/// <summary>
/// Parses any type of JSON into a JToken[] (for nested structures)
/// </summary>
private Neo.Json.JToken[] ConvertToJTokenArray(Neo.Json.JToken token)
private JToken[] ConvertToJTokenArray(JToken? token)
{
var result = new List<Neo.Json.JToken>();
var result = new List<JToken?>();

if (token is Neo.Json.JArray array)
if (token is JArray array)
{
// If it's a JArray, parse it one by one and add it to the result
foreach (var item in array)
{
result.AddRange(ConvertToJTokenArray(item));
}
}
else if (token is Neo.Json.JObject obj)
else if (token is JObject obj)
{
// Convert JObject to JToken (Dictionary type)
var newObj = new Neo.Json.JObject();
var newObj = new JObject();
foreach (var property in obj.Properties)
{
newObj[property.Key] = new Neo.Json.JString(property.Value?.GetString());
}
newObj[property.Key] = property.Value as JString;
result.Add(newObj);
}
else
Expand All @@ -139,28 +138,21 @@ private Neo.Json.JToken[] ConvertToJTokenArray(Neo.Json.JToken token)
result.Add(token);
}

return result.ToArray(); // Converting a List to an Array of JTokens
return [.. result]; // Converting a List to an Array of JTokens
}
}
}

/// BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2605)
/// 13th Gen Intel Core i9-13900H, 1 CPU, 20 logical and 14 physical cores
/// .NET SDK 9.0.101
/// [Host] : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2 [AttachedDebugger]
/// DefaultJob: .NET 9.0.0(9.0.24.52809), X64 RyuJIT AVX2
///
/// | Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
/// |----------------------- |---------:|---------:|----------:|--------:|--------:|--------:|----------:|
/// | Newtonsoft_Deserialize | 627.4 us | 9.10 us | 8.07 us | 79.1016 | 53.7109 | - | 978.52 KB |
/// | NeoJson_Deserialize | 635.8 us | 41.54 us | 122.49 us | 73.2422 | 36.1328 | 36.1328 | 919.45 KB |

/// | Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
/// |----------------------- |---------:|--------:|---------:|--------:|--------:|--------:|----------:|
/// | Newtonsoft_Deserialize | 627.8 us | 7.35 us | 10.54 us | 79.1016 | 53.7109 | - | 978.52 KB |
/// | NeoJson_Deserialize | 497.8 us | 8.37 us | 7.42 us | 73.2422 | 36.1328 | 36.1328 | 919.45 KB |

/// | Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
/// |----------------------- |---------:|--------:|---------:|--------:|--------:|--------:|----------:|
/// | Newtonsoft_Deserialize | 634.6 us | 7.48 us | 7.00 us | 79.1016 | 53.7109 | - | 978.52 KB |
/// | NeoJson_Deserialize | 484.5 us | 9.49 us | 10.93 us | 73.7305 | 36.6211 | 36.6211 | 919.45 KB |
// This is benchmark after bug fix.

// BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2894)
// Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
// .NET SDK 9.0.102
// [Host] : .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2
// DefaultJob: .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2


// | Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
// | ----------------------- |-----------:| ---------:| ---------:| ---------:| ---------:| --------:| ----------:|
// | Newtonsoft_Deserialize | 1,066.7 us | 19.89 us | 34.84 us | 158.2031 | 115.2344 | - | 978.52 KB |
// | NeoJson_Deserialize | 777.9 us | 11.27 us | 9.41 us | 144.5313 | 70.3125 | 35.1563 | 919.27 KB |
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,12 @@ namespace Neo.Json.Benchmarks
[MarkdownExporter]
public class Benchmark_OrderedDictionary
{
private OrderedDictionary<string, uint> _od;

[GlobalSetup]
public void Setup()
{
_od = new OrderedDictionary<string, uint>
private readonly OrderedDictionary<string, uint> _od = new()
{
{ "a", 1 },
{ "b", 2 },
{ "c", 3 }
};
}

[Benchmark]
public void TestClear()
Expand Down
1 change: 0 additions & 1 deletion benchmarks/Neo.Json.Benchmarks/Neo.Json.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

<ItemGroup>
<ProjectReference Include="..\..\src\Neo.Json\Neo.Json.csproj" />
<ProjectReference Include="..\..\tests\Neo.Network.RPC.Tests\Neo.Network.RPC.Tests.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/Neo.Json.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ public class Program
{
public static void Main(string[] args)
{
//BenchmarkRunner.Run<Benchmark_JsonDeserialize>();
BenchmarkRunner.Run<Benchmark_JsonDeserialize>();
//BenchmarkRunner.Run<Benchmark_OrderedDictionary>();
//BenchmarkRunner.Run<Benchmark_JBoolean>();
//BenchmarkRunner.Run<Benchmark_JNumber>();
//BenchmarkRunner.Run<Benchmark_JObject>();
//BenchmarkRunner.Run<Benchmark_JPath>();
//BenchmarkRunner.Run<Benchmark_JString>();
BenchmarkRunner.Run<Benchmark_JsonArray>();
//BenchmarkRunner.Run<Benchmark_JsonArray>();
}
}
}
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "9.0.100",
"version": "9.0.102",
"rollForward": "latestFeature",
"allowPrerelease": false
}
Expand Down
3 changes: 3 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
<Company>The Neo Project</Company>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<VersionPrefix>3.7.5</VersionPrefix>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<AnalysisLevel>latest</AnalysisLevel>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions src/Neo.CLI/CLI/MainService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ internal UInt160 StringToAddress(string input, byte version)

if (input.IndexOf('.') > 0 && input.LastIndexOf('.') < input.Length)
{
return ResolveNeoNameServiceAddress(input);
return ResolveNeoNameServiceAddress(input) ?? UInt160.Zero;
}

// Try to parse as UInt160
Expand Down Expand Up @@ -697,7 +697,7 @@ static string GetExceptionMessage(Exception exception)
return exception.Message;
}

public UInt160 ResolveNeoNameServiceAddress(string domain)
public UInt160? ResolveNeoNameServiceAddress(string domain)
{
if (Settings.Default.Contracts.NeoNameService == UInt160.Zero)
throw new Exception("Neo Name Service (NNS): is disabled on this network.");
Expand All @@ -717,7 +717,7 @@ public UInt160 ResolveNeoNameServiceAddress(string domain)
if (UInt160.TryParse(addressData, out var address))
return address;
else
return addressData.ToScriptHash(NeoSystem.Settings.AddressVersion);
return addressData?.ToScriptHash(NeoSystem.Settings.AddressVersion);
}
catch { }
}
Expand Down
10 changes: 5 additions & 5 deletions src/Neo.Extensions/ByteExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ public static int XxHash3_32(this byte[] value, long seed = DefaultXxHash3Seed)
/// <returns>The converted hex <see cref="string"/>.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="value"/> is null.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string ToHexString(this byte[] value)
public static string ToHexString(this byte[]? value)
{
#if NET9_0_OR_GREATER
return Convert.ToHexStringLower(value);
#else
if (value is null)
throw new ArgumentNullException(nameof(value));

#if NET9_0_OR_GREATER
return Convert.ToHexStringLower(value);
#else
return string.Create(value.Length * 2, value, (span, bytes) =>
{
for (var i = 0; i < bytes.Length; i++)
Expand All @@ -80,7 +80,7 @@ public static string ToHexString(this byte[] value)
/// <returns>The converted hex <see cref="string"/>.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="value"/> is null.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string ToHexString(this byte[] value, bool reverse = false)
public static string ToHexString(this byte[]? value, bool reverse = false)
{
if (!reverse)
return ToHexString(value);
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.Extensions/Collections/CollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static void RemoveWhere<TKey, TValue>(
/// <returns>An enumerable of arrays, each containing a chunk of the source collection.</returns>
/// <exception cref="ArgumentNullException">Thrown when the source collection is null.</exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the chunk size is less than or equal to 0.</exception>
public static IEnumerable<T[]> Chunk<T>(this IReadOnlyCollection<T> source, int chunkSize)
public static IEnumerable<T[]> Chunk<T>(this IReadOnlyCollection<T>? source, int chunkSize)
{
if (source is null)
throw new ArgumentNullException(nameof(source));
Expand Down
4 changes: 3 additions & 1 deletion src/Neo.Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@
// modifications are permitted.

using System;
#if !NET9_0_OR_GREATER
using System.Globalization;
#endif
using System.Runtime.CompilerServices;

namespace Neo.Extensions
{
public static class StringExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte[] HexToBytes(this string value) => HexToBytes(value.AsSpan());
public static byte[] HexToBytes(this string? value) => HexToBytes(value.AsSpan());

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte[] HexToBytesReversed(this ReadOnlySpan<char> value)
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.GUI/GUI/BulkPayDialog.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/Neo.GUI/GUI/ChangePasswordDialog.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/Neo.GUI/GUI/ConsoleForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4af93c8

Please sign in to comment.