Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
</PropertyGroup>

<PropertyGroup>
<BlockchainToolkitLibraryVersion>3.4.13</BlockchainToolkitLibraryVersion>
<!-- <BlockchainToolkitLibraryVersion>3.4.13</BlockchainToolkitLibraryVersion> -->
<BlockchainToolkitLibraryVersion>local</BlockchainToolkitLibraryVersion>
<!-- <BlockchainToolkitLibraryVersion>local</BlockchainToolkitLibraryVersion> -->
<BlockchainToolkitLibraryLocalPath>..\..\..\lib-bctk</BlockchainToolkitLibraryLocalPath>
<!-- <BlockchainToolkitLibraryLocalPath>..\..\..\lib-bctk</BlockchainToolkitLibraryLocalPath> -->
<BlockchainToolkitLibraryLocalPath>../../../neo-blockchaintoolkit-library/</BlockchainToolkitLibraryLocalPath>
<NeoVersion>3.4.0</NeoVersion>
<NeoMonorepoPath>..\..\..\..\official\3neo-monorepo</NeoMonorepoPath>

Expand All @@ -42,4 +44,4 @@
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
</ItemGroup>

</Project>
</Project>
8 changes: 8 additions & 0 deletions src/test-harness/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Linq.Expressions;
using Neo;
using Neo.BlockchainToolkit;
using Neo.BlockchainToolkit.Persistence;
using Neo.BlockchainToolkit.Utilities;
using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native;
Expand Down Expand Up @@ -227,5 +229,11 @@ public static SnapshotCache GetSnapshot(this CheckpointFixture fixture)
{
return new SnapshotCache(fixture.CheckpointStore);
}

public static SnapshotCache GetSnapshot(this WorkNetFixture fixture)
{
var store = new MemoryTrackingStore(fixture.WorkNetStore);
return new SnapshotCache(store);
}
}
}
16 changes: 16 additions & 0 deletions src/test-harness/PrefetchContractAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace NeoTestHarness
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class PrefetchContractAttribute : Attribute
{
public string Name { get; init; } = string.Empty;

public PrefetchContractAttribute(string name)
{
Name = name;
}
}
}

37 changes: 37 additions & 0 deletions src/test-harness/WorkNetConfigAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.IO;
using Neo;

namespace NeoTestHarness
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class WorkNetConfigAttribute : Attribute
{
public string RpcUri { get; init; } = string.Empty;
public string Height { get; init; } = string.Empty;
public string DbPath { get; init; } = string.Empty;
public ProtocolSettings Settings { get; init; }

public WorkNetConfigAttribute(string uri, string height = "", string dbPath = "", string settingsPath = "")
{
RpcUri = uri;
Height = height;

if (dbPath == "tmp")
{
dbPath = Path.GetTempPath() + "data";
}

DbPath = dbPath;

ProtocolSettings settings = null;
if (File.Exists(settingsPath))
{
settings = ProtocolSettings.Load(settingsPath);
}

Settings = settings;
}
}
}

115 changes: 115 additions & 0 deletions src/test-harness/WorkNetFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Neo;
using Neo.BlockchainToolkit;
using Neo.BlockchainToolkit.Models;
using Neo.BlockchainToolkit.Persistence;
using Neo.Network.RPC;
using Neo.Persistence;
using Xunit;

namespace NeoTestHarness
{
public abstract class WorkNetFixture : IAsyncLifetime
{
private readonly static Lazy<IFileSystem> defaultFileSystem = new Lazy<IFileSystem>(() => new FileSystem());
private StateServiceStore workNetStore;
private RocksDbSharp.RocksDb db;
private ProtocolSettings settings;
private uint height;
private RpcClient client;
private WorkNetConfigAttribute workNetConfig;
private string[] prefetchContracts;
private Dictionary<UInt160, string> contractNameCache = new();

public IReadOnlyStore WorkNetStore => workNetStore;
public ProtocolSettings ProtocolSettings => workNetStore.Settings;

public WorkNetFixture(
string[] prefetchContracts,
WorkNetConfigAttribute cfg)
{
this.workNetConfig = cfg;
this.prefetchContracts = prefetchContracts;

settings = workNetConfig.Settings ?? ProtocolSettings.Default with
{
Network = 7630401, // mainnet
AddressVersion = 0x35,
MillisecondsPerBlock = 15000,
};

client = new RpcClient(new Uri((workNetConfig.RpcUri)), null, null, settings);

if (workNetConfig.Height == "latest")
{
height = client.GetBlockCountAsync().GetAwaiter().GetResult() - 1;
}
else
{
if (!UInt32.TryParse(workNetConfig.Height, out height))
{
throw new Exception($"");
}
}
}

public async Task InitializeAsync()
{
var branchInfo = await StateServiceStore.GetBranchInfoAsync(client, height);

db = RocksDbUtility.OpenDb(workNetConfig.DbPath);
workNetStore = new StateServiceStore(client, branchInfo, db);

var options = new ParallelOptions { MaxDegreeOfParallelism = 3 };
var nativeContracts = branchInfo.Contracts.Where( x => x.Id < 0);
await Parallel.ForEachAsync(nativeContracts, options, async (contract, token) =>
{
var contractHash = contract.Hash ?? throw new Exception("Null contract address in branch info");
contractNameCache.Add(contractHash, contract.Name);
await workNetStore.PrefetchAsync(contractHash, CancellationToken.None,
( foundStates ) =>
{
Console.WriteLine($"found states for (native) {GetContractName(contractHash)}");
});
});

await Parallel.ForEachAsync(prefetchContracts, options, async (contractName, token) =>
{
var contract = branchInfo.Contracts.Where( x => x.Name == contractName ).FirstOrDefault();
contractNameCache.Add(contract.Hash, contract.Name);
await workNetStore.PrefetchAsync(contract.Hash, CancellationToken.None,
( foundStates ) =>
{
Console.WriteLine($"found states for {GetContractName(contract.Hash)}");
});
});
}

private string GetContractName(UInt160 hash)
{
if (contractNameCache.TryGetValue(hash, out string name))
{
return name;
}

return "unknown_" + hash;
}

public Task DisposeAsync()
{
workNetStore.Dispose();
client.Dispose();

return Task.CompletedTask;
}

public ExpressChain FindChain(string fileName = Constants.DEFAULT_EXPRESS_FILENAME, IFileSystem? fileSystem = null, string? searchFolder = null)
=> (fileSystem ?? defaultFileSystem.Value).FindChain(fileName, searchFolder);
}
}

32 changes: 32 additions & 0 deletions src/test-harness/WorkNetFixtureOfT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Linq;

namespace NeoTestHarness
{
public class WorkNetFixture<T> : WorkNetFixture
{
static string[] GetPrefetchContracts()
{
var attribs = Attribute.GetCustomAttributes(typeof(T), typeof(PrefetchContractAttribute)) as PrefetchContractAttribute[];

if (attribs is null || attribs.Length == 0)
{
throw new Exception("No prefetch contracts defined, need at least one");
}

return attribs?.Select( x => x.Name).ToArray();
}

static WorkNetConfigAttribute GetWorkNetConfig()
{
var attrib = Attribute.GetCustomAttribute(typeof(T), typeof(WorkNetConfigAttribute)) as WorkNetConfigAttribute;

return attrib ?? throw new Exception($"Missing {nameof(WorkNetConfigAttribute)} on {typeof(T).Name}");
}

public WorkNetFixture() : base(GetPrefetchContracts(), GetWorkNetConfig())
{
}
}
}

6 changes: 5 additions & 1 deletion src/test-harness/test-harness.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@
</Otherwise>
</Choose>

</Project>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.2" />
</ItemGroup>

</Project>