Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Neo Plugin UT] Add a dbft unit test system #3371

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
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
7 changes: 7 additions & 0 deletions neo.sln
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TokensTracker", "src\Plugin
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RpcClient", "src\Plugins\RpcClient\RpcClient.csproj", "{185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Plugins.DBFTPlugin.Tests", "tests\Neo.Plugins.DBFTPlugin.Tests\Neo.Plugins.DBFTPlugin.Tests.csproj", "{4E42A911-8B39-41BE-A8C8-8463D82E0D45}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -216,6 +218,10 @@ Global
{185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0}.Release|Any CPU.Build.0 = Release|Any CPU
{4E42A911-8B39-41BE-A8C8-8463D82E0D45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E42A911-8B39-41BE-A8C8-8463D82E0D45}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E42A911-8B39-41BE-A8C8-8463D82E0D45}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E42A911-8B39-41BE-A8C8-8463D82E0D45}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -255,6 +261,7 @@ Global
{FF76D8A4-356B-461A-8471-BC1B83E57BBC} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{5E4947F3-05D3-4806-B0F3-30DAC71B5986} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{4E42A911-8B39-41BE-A8C8-8463D82E0D45} = {7F257712-D033-47FF-B439-9D4320D06599}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BCBA19D9-F868-4C6D-8061-A2B91E06E3EC}
Expand Down
1 change: 1 addition & 0 deletions src/Neo/Neo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<InternalsVisibleTo Include="Neo.SmartContract.Testing" />
<InternalsVisibleTo Include="Neo.SmartContract.TestEngine" />
<InternalsVisibleTo Include="Neo.Plugins.RpcServer.Tests" />
<InternalsVisibleTo Include="Neo.Plugins.DBFTPlugin.Tests" />
</ItemGroup>

</Project>
8 changes: 8 additions & 0 deletions src/Plugins/DBFTPlugin/DBFTPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ public DBFTPlugin()
RemoteNode.MessageReceived += ((IMessageReceivedHandler)this).RemoteNode_MessageReceived_Handler;
}

#if DEBUG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if debug?

internal DBFTPlugin(NeoSystem neoSystem, IWalletProvider wallet) : this()
{
this.neoSystem = neoSystem;
walletProvider = wallet;
}
#endif

public DBFTPlugin(Settings settings) : this()
{
this.settings = settings;
Expand Down
4 changes: 4 additions & 0 deletions src/Plugins/DBFTPlugin/DBFTPlugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@
</None>
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="Neo.Plugins.DBFTPlugin.Tests" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Neo.Plugins.DBFTPlugin.Tests</RootNamespace>
<AssemblyName>Neo.Plugins.DBFTPlugin.Tests</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Neo\Neo.csproj" />
<ProjectReference Include="..\..\src\Plugins\DBFTPlugin\DBFTPlugin.csproj" />
<ProjectReference Include="..\..\src\Plugins\RpcServer\RpcServer.csproj" />
<ProjectReference Include="..\Neo.UnitTests\Neo.UnitTests.csproj" />
</ItemGroup>

</Project>
21 changes: 21 additions & 0 deletions tests/Neo.Plugins.DBFTPlugin.Tests/TestMemoryStoreProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// TestMemoryStoreProvider.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 Neo.Persistence;

namespace Neo.Plugins.DBFTPlugin.Tests;

public class TestMemoryStoreProvider(MemoryStore memoryStore) : IStoreProvider
{
public MemoryStore MemoryStore { get; init; } = memoryStore;
public string Name => nameof(MemoryStore);
public IStore GetStore(string path) => MemoryStore;
}
55 changes: 55 additions & 0 deletions tests/Neo.Plugins.DBFTPlugin.Tests/TestP2PSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// TestP2PSettings.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.

namespace Neo.Plugins.DBFTPlugin.Tests;

public class TestP2PSettings
{
public ushort Port { get; init; }
public int MinDesiredConnections { get; } = 5;
public int MaxConnections { get; } = 20;
public int MaxConnectionsPerAddress { get; } = 10;

public static readonly TestP2PSettings Node1 = new()
cschuchardt88 marked this conversation as resolved.
Show resolved Hide resolved
{
Port = 30333
};

public static readonly TestP2PSettings Node2 = new()
{
Port = 30334
};

public static readonly TestP2PSettings Node3 = new()
{
Port = 30335
};

public static readonly TestP2PSettings Node4 = new()
{
Port = 30336
};

public static readonly TestP2PSettings Node5 = new()
{
Port = 30337
};

public static readonly TestP2PSettings Node6 = new()
{
Port = 30338
};

public static readonly TestP2PSettings Node7 = new()
{
Port = 30339
};
}
68 changes: 68 additions & 0 deletions tests/Neo.Plugins.DBFTPlugin.Tests/TestProtocolSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// TestProtocolSettings.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 Neo.Cryptography.ECC;

namespace Neo.Plugins.DBFTPlugin.Tests
{
public static class TestProtocolSettings
{
public static readonly ProtocolSettings Default = new()
{
Network = 0x334F454Eu,
AddressVersion = ProtocolSettings.Default.AddressVersion,
StandbyCommittee = new[]
{
//Validators
ECPoint.Parse(" 0327708fd7a39d384cd1cc48803a084a43d3b5013ada9de299a12e7b7afccfa013", ECCurve.Secp256r1),
ECPoint.Parse(" 02e691f222d1867098643aca188a3d290c2da98af9e1bcf94b35d67322c034988d", ECCurve.Secp256r1),
ECPoint.Parse(" 03e556db7d519f65f43437251e8fd7df476f2d02a0e3ef3052c298791b7b1d812d", ECCurve.Secp256r1),
ECPoint.Parse(" 030459831e43793a1f7a104692cd944eaa475b03a0c5298d9fbbca136c8268f978", ECCurve.Secp256r1),
ECPoint.Parse(" 03f01c078f19887a525897ec6503f310170deab72c4ae672eef0ac45f46b082eee", ECCurve.Secp256r1),
ECPoint.Parse(" 02226db3e9fe07d83ccedae8fd8f8cc12aff4ef541f06fedf9caa1828683829b9e", ECCurve.Secp256r1),
ECPoint.Parse(" 03cce2da0e69b79d1aa5bec1378497be41567feac5f2dfb754b46fa421ec08c49e", ECCurve.Secp256r1),

//Other Members
ECPoint.Parse("023a36c72844610b4d34d1968662424011bf783ca9d984efa19a20babf5582f3fe", ECCurve.Secp256r1),
ECPoint.Parse("03708b860c1de5d87f5b151a12c2a99feebd2e8b315ee8e7cf8aa19692a9e18379", ECCurve.Secp256r1),
ECPoint.Parse("03c6aa6e12638b36e88adc1ccdceac4db9929575c3e03576c617c49cce7114a050", ECCurve.Secp256r1),
ECPoint.Parse("03204223f8c86b8cd5c89ef12e4f0dbb314172e9241e30c9ef2293790793537cf0", ECCurve.Secp256r1),
ECPoint.Parse("02a62c915cf19c7f19a50ec217e79fac2439bbaad658493de0c7d8ffa92ab0aa62", ECCurve.Secp256r1),
ECPoint.Parse("03409f31f0d66bdc2f70a9730b66fe186658f84a8018204db01c106edc36553cd0", ECCurve.Secp256r1),
ECPoint.Parse("0288342b141c30dc8ffcde0204929bb46aed5756b41ef4a56778d15ada8f0c6654", ECCurve.Secp256r1),
ECPoint.Parse("020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639", ECCurve.Secp256r1),
ECPoint.Parse("0222038884bbd1d8ff109ed3bdef3542e768eef76c1247aea8bc8171f532928c30", ECCurve.Secp256r1),
ECPoint.Parse("03d281b42002647f0113f36c7b8efb30db66078dfaaa9ab3ff76d043a98d512fde", ECCurve.Secp256r1),
ECPoint.Parse("02504acbc1f4b3bdad1d86d6e1a08603771db135a73e61c9d565ae06a1938cd2ad", ECCurve.Secp256r1),
ECPoint.Parse("0226933336f1b75baa42d42b71d9091508b638046d19abd67f4e119bf64a7cfb4d", ECCurve.Secp256r1),
ECPoint.Parse("03cdcea66032b82f5c30450e381e5295cae85c5e6943af716cc6b646352a6067dc", ECCurve.Secp256r1),
ECPoint.Parse("02cd5a5547119e24feaa7c2a0f37b8c9366216bab7054de0065c9be42084003c8a", ECCurve.Secp256r1)
},
ValidatorsCount = 7,
SeedList =
[
"127.0.0.1:30333",
"127.0.0.1:30334",
"127.0.0.1:30335",
"127.0.0.1:30336",
"127.0.0.1:30337",
"127.0.0.1:30338",
"127.0.0.1:30339",
],
MillisecondsPerBlock = ProtocolSettings.Default.MillisecondsPerBlock,
MaxTransactionsPerBlock = ProtocolSettings.Default.MaxTransactionsPerBlock,
MemoryPoolMaxTransactions = ProtocolSettings.Default.MemoryPoolMaxTransactions,
MaxTraceableBlocks = ProtocolSettings.Default.MaxTraceableBlocks,
InitialGasDistribution = ProtocolSettings.Default.InitialGasDistribution,
Hardforks = ProtocolSettings.Default.Hardforks
};
}
}
34 changes: 34 additions & 0 deletions tests/Neo.Plugins.DBFTPlugin.Tests/TestWalletProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// TestWalletProvider.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 Neo.UnitTests;
using Neo.Wallets;
using System;

namespace Neo.Plugins.DBFTPlugin.Tests;

public class TestWalletProvider(string wif) : IWalletProvider
{
public event EventHandler<Wallet> WalletChanged;

private Wallet Wallet
{
get
{
var wallet = TestUtils.GenerateTestWallet("123");
var privateKey = Wallet.GetPrivateKeyFromWIF(wif);
wallet.CreateAccount(privateKey);
return wallet;
}
}

public Wallet GetWallet() => Wallet;
}
124 changes: 124 additions & 0 deletions tests/Neo.Plugins.DBFTPlugin.Tests/UT_DBFT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// UT_RpcServer.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 Akka.Actor;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Network.P2P;
using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.Wallets;
using Neo.Wallets.NEP6;
using System.Net;

namespace Neo.Plugins.DBFTPlugin.Tests
{
[TestClass]
public class UT_DBFT
{
private NeoSystem[] _neoSystems;
private TestMemoryStoreProvider[] _memoryStoreProviders;
private MemoryStore[] _memoryStores;
private TestWalletProvider[] _walletProviders;
private NEP6Wallet[] _wallets;
private WalletAccount[] _walletAccounts;
private DBFTPlugin[] _dbftPlugins;

private readonly string[] _testWifs =
[
"L4Bh3SH8btGSXDGwjhmpCsNhkYctahNgkuTF1uDJpKkeyZFJpsEi",
"L2zWf8HxYmJCH4hXE97aLaDpppgEvyk19pwC4h8bP2z7gSSdRZy8",
"L2zXV5idFea5x7j3LCNquUdWj2GkE9nG4TxbB2MbURRN6KtwhHzN",
"KyyUEPaufpbFLLdHJNJhgx7X69ionpv8RG7MeNrQFQqQhD3agcXS",
"L1XoPCmNhXAdGqfWKZ5Bo3k9DmJTa3wRaf2oYrcYE1tT6C2NJx5B",
"L3HinHgao6N8YiXMxDDxbGsXQWu4x4v5kWcs5C7u8r1cLttdbQGj",
"L5Sdps5JkWAAkpF2t8du5eNFYtEaBcJL5CWcvWBHuouuQP3PBEc9",
"Kye4GjtsifdMyLN8KvWyEQgPgqvEwtwR6a2ePxZLacPcKJkBGpug",
"L2SLACky8ZXQkm2bjS6fTVP5JipKzDLToAQK8dqQc3g2S3LLvLtB",
"Kx6NX7mcCUG6VoTpV3SmojweHBoFwCUVJ3mVPjRy4fk9C3LP5pVg"
];

[TestInitialize]
public void TestSetup()
{
_neoSystems = new NeoSystem[7];
_memoryStoreProviders = new TestMemoryStoreProvider[7];
_memoryStores = new MemoryStore[7];
_walletProviders = new TestWalletProvider[7];
var p2PSettings = new[]
{
TestP2PSettings.Node1,
TestP2PSettings.Node2,
TestP2PSettings.Node3,
TestP2PSettings.Node4,
TestP2PSettings.Node5,
TestP2PSettings.Node6,
TestP2PSettings.Node7,
};

for (int i = 0; i < 7; i++)
{
_walletProviders[i] = new TestWalletProvider(_testWifs[i]);
_wallets[i] = _walletProviders[i].GetWallet() as NEP6Wallet;
_walletAccounts[i] = _wallets[i].CreateAccount();
}

for (var i = 0; i < 7; i++)
{
_memoryStores[i] = new MemoryStore();
_memoryStoreProviders[i] = new TestMemoryStoreProvider(_memoryStores[i]);
var protocolSettings = TestProtocolSettings.Default;
_neoSystems[i] = new NeoSystem(protocolSettings, _memoryStoreProviders[i]);
_ = _neoSystems[i].LocalNode.Ask<LocalNode>(new LocalNode.GetInstance()).Result;

_dbftPlugins[i] = new DBFTPlugin(_neoSystems[i], _walletProviders[i]);
_dbftPlugins[i].Start(_walletProviders[i].GetWallet());

var channelConfig = new ChannelsConfig
{
Tcp = new IPEndPoint(IPAddress.Any, p2PSettings[i].Port),
MinDesiredConnections = p2PSettings[i].MinDesiredConnections,
MaxConnections = p2PSettings[i].MaxConnections,
MaxConnectionsPerAddress = p2PSettings[i].MaxConnectionsPerAddress
};
_neoSystems[i].StartNode(channelConfig);

var snapshot = _neoSystems[i].GetSnapshot();

// Assign every single consensus node some GAS
for (var j = 0; j < 7; j++)
{
var key = new KeyBuilder(NativeContract.GAS.Id, 20).Add(_walletAccounts[j].ScriptHash);
var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));
entry.GetInteroperable<AccountState>().Balance = 100_000_000 * NativeContract.GAS.Factor;
}
snapshot.Commit();
}
}

[TestCleanup]
public void TestCleanup()
{
for (var i = 0; i < 7; i++)
{
_memoryStores[i].Reset();
var snapshot = _neoSystems[i].GetSnapshot();
for (var j = 0; j < 7; j++)
{
var key = new KeyBuilder(NativeContract.GAS.Id, 20).Add(_walletAccounts[i].ScriptHash);
var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));
entry.GetInteroperable<AccountState>().Balance = 100_000_000 * NativeContract.GAS.Factor;
}
snapshot.Commit();
}
}
}
}
Loading
Loading