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 Plugins UT] Add RpcServer Unit Tests Part Blockchain. #3339

Merged
merged 24 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion src/Neo/SmartContract/Native/NeoToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ private async ContractTask<bool> Vote(ApplicationEngine engine, UInt160 account,
/// <param name="snapshot">The snapshot used to read data.</param>
/// <returns>All the registered candidates.</returns>
[ContractMethod(CpuFee = 1 << 22, RequiredCallFlags = CallFlags.ReadStates)]
private (ECPoint PublicKey, BigInteger Votes)[] GetCandidates(DataCache snapshot)
internal (ECPoint PublicKey, BigInteger Votes)[] GetCandidates(DataCache snapshot)
{
return GetCandidatesInternal(snapshot)
.Select(p => (p.PublicKey, p.State.Votes))
Expand Down
127 changes: 112 additions & 15 deletions src/Plugins/RpcServer/RpcServer.Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,28 @@ namespace Neo.Plugins.RpcServer
{
partial class RpcServer
{
/// <summary>
/// Gets the hash of the best (most recent) block.
/// </summary>
/// <param name="_params">An empty array; no parameters are required.</param>
/// <returns>The hash of the best block as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetBestBlockHash(JArray _params)
protected internal virtual JToken GetBestBlockHash(JArray _params)
{
return NativeContract.Ledger.CurrentHash(system.StoreView).ToString();
}

/// <summary>
/// Gets a block by its hash or index.
/// </summary>
/// <param name="_params">
/// An array containing the block hash or index as the first element,
/// and an optional boolean indicating whether to return verbose information.
/// </param>
/// <returns>The block data as a <see cref="JToken"/>. If the second item of _params is true, then
/// block data is json format, otherwise, the return type is Base64-encoded byte array.</returns>
[RpcMethod]
protected virtual JToken GetBlock(JArray _params)
protected internal virtual JToken GetBlock(JArray _params)
{
JToken key = Result.Ok_Or(() => _params[0], RpcError.InvalidParams.WithData($"Invalid Block Hash or Index: {_params[0]}"));
bool verbose = _params.Count >= 2 && _params[1].AsBoolean();
Expand Down Expand Up @@ -60,20 +74,35 @@ protected virtual JToken GetBlock(JArray _params)
return Convert.ToBase64String(block.ToArray());
}

/// <summary>
/// Gets the number of block headers in the blockchain.
/// </summary>
/// <param name="_params">An empty array; no parameters are required.</param>
/// <returns>The count of block headers as a <see cref="JToken"/>.</returns>
[RpcMethod]
internal virtual JToken GetBlockHeaderCount(JArray _params)
{
return (system.HeaderCache.Last?.Index ?? NativeContract.Ledger.CurrentIndex(system.StoreView)) + 1;
}

/// <summary>
/// Gets the number of blocks in the blockchain.
/// </summary>
/// <param name="_params">An empty array; no parameters are required.</param>
/// <returns>The count of blocks as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetBlockCount(JArray _params)
protected internal virtual JToken GetBlockCount(JArray _params)
{
return NativeContract.Ledger.CurrentIndex(system.StoreView) + 1;
}

/// <summary>
/// Gets the hash of the block at the specified height.
/// </summary>
/// <param name="_params">An array containing the block height as the first element.</param>
/// <returns>The hash of the block at the specified height as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetBlockHash(JArray _params)
protected internal virtual JToken GetBlockHash(JArray _params)
{
uint height = Result.Ok_Or(() => uint.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid Height: {_params[0]}"));
var snapshot = system.StoreView;
Expand All @@ -84,8 +113,16 @@ protected virtual JToken GetBlockHash(JArray _params)
throw new RpcException(RpcError.UnknownHeight);
}

/// <summary>
/// Gets a block header by its hash or index.
/// </summary>
/// <param name="_params">
/// An array containing the block header hash or index as the first element,
/// and an optional boolean indicating whether to return verbose information.
/// </param>
/// <returns>The block header data as a <see cref="JToken"/>. In json format if the second item of _params is true, otherwise Base64-encoded byte array.</returns>
[RpcMethod]
protected virtual JToken GetBlockHeader(JArray _params)
protected internal virtual JToken GetBlockHeader(JArray _params)
{
JToken key = _params[0];
bool verbose = _params.Count >= 2 && _params[1].AsBoolean();
Expand Down Expand Up @@ -114,8 +151,13 @@ protected virtual JToken GetBlockHeader(JArray _params)
return Convert.ToBase64String(header.ToArray());
}

/// <summary>
/// Gets the state of a contract by its ID or script hash or (only for native contracts) by case-insensitive name.
/// </summary>
/// <param name="_params">An array containing the contract ID or script hash or case-insensitive native contract name as the first element.</param>
/// <returns>The contract state in json format as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetContractState(JArray _params)
protected internal virtual JToken GetContractState(JArray _params)
{
if (int.TryParse(_params[0].AsString(), out int contractId))
{
Expand All @@ -139,8 +181,13 @@ private static UInt160 ToScriptHash(string keyword)
return UInt160.Parse(keyword);
}

/// <summary>
/// Gets the current memory pool transactions.
/// </summary>
/// <param name="_params">An array containing an optional boolean indicating whether to include unverified transactions.</param>
/// <returns>The memory pool transactions in json format as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetRawMemPool(JArray _params)
protected internal virtual JToken GetRawMemPool(JArray _params)
{
bool shouldGetUnverified = _params.Count >= 1 && _params[0].AsBoolean();
if (!shouldGetUnverified)
Expand All @@ -156,8 +203,16 @@ protected virtual JToken GetRawMemPool(JArray _params)
return json;
}

/// <summary>
/// Gets a transaction by its hash.
/// </summary>
/// <param name="_params">
/// An array containing the transaction hash as the first element,
/// and an optional boolean indicating whether to return verbose information.
/// </param>
/// <returns>The transaction data as a <see cref="JToken"/>. In json format if the second item of _params is true, otherwise base64string. </returns>
Copy link
Member

Choose a reason for hiding this comment

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

I see the base64string pattern being repeated, so it's probably intentionally.

[RpcMethod]
protected virtual JToken GetRawTransaction(JArray _params)
protected internal virtual JToken GetRawTransaction(JArray _params)
{
UInt256 hash = Result.Ok_Or(() => UInt256.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid Transaction Hash: {_params[0]}"));
bool verbose = _params.Count >= 2 && _params[1].AsBoolean();
Expand All @@ -179,8 +234,16 @@ protected virtual JToken GetRawTransaction(JArray _params)
return json;
}

/// <summary>
/// Gets the storage item by contract ID or script hash and key.
/// </summary>
/// <param name="_params">
/// An array containing the contract ID or script hash as the first element,
/// and the storage key as the second element.
/// </param>
/// <returns>The storage item as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetStorage(JArray _params)
protected internal virtual JToken GetStorage(JArray _params)
{
using var snapshot = system.GetSnapshot();
if (!int.TryParse(_params[0].AsString(), out int id))
Expand All @@ -198,8 +261,17 @@ protected virtual JToken GetStorage(JArray _params)
return Convert.ToBase64String(item.Value.Span);
}

/// <summary>
/// Finds storage items by contract ID or script hash and prefix.
/// </summary>
/// <param name="_params">
/// An array containing the contract ID or script hash as the first element,
/// the Base64-encoded storage key prefix as the second element,
/// and an optional start index as the third element.
/// </param>
/// <returns>The found storage items <see cref="StorageItem"/> as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken FindStorage(JArray _params)
protected internal virtual JToken FindStorage(JArray _params)
{
using var snapshot = system.GetSnapshot();
if (!int.TryParse(_params[0].AsString(), out int id))
Expand Down Expand Up @@ -247,17 +319,27 @@ protected virtual JToken FindStorage(JArray _params)
return json;
}

/// <summary>
/// Gets the height of a transaction by its hash.
/// </summary>
/// <param name="_params">An array containing the transaction hash as the first element.</param>
/// <returns>The height of the transaction as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetTransactionHeight(JArray _params)
protected internal virtual JToken GetTransactionHeight(JArray _params)
{
UInt256 hash = Result.Ok_Or(() => UInt256.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid Transaction Hash: {_params[0]}"));
uint? height = NativeContract.Ledger.GetTransactionState(system.StoreView, hash)?.BlockIndex;
if (height.HasValue) return height.Value;
throw new RpcException(RpcError.UnknownTransaction);
}

/// <summary>
/// Gets the next block validators.
/// </summary>
/// <param name="_params">An empty array; no parameters are required.</param>
/// <returns>The next block validators as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetNextBlockValidators(JArray _params)
protected internal virtual JToken GetNextBlockValidators(JArray _params)
{
using var snapshot = system.GetSnapshot();
var validators = NativeContract.NEO.GetNextBlockValidators(snapshot, system.Settings.ValidatorsCount);
Expand All @@ -270,8 +352,13 @@ protected virtual JToken GetNextBlockValidators(JArray _params)
}).ToArray();
}

/// <summary>
/// Gets the list of candidates for the next block validators.
/// </summary>
/// <param name="_params">An empty array; no parameters are required.</param>
/// <returns>The candidates public key list as a JToken.</returns>
[RpcMethod]
protected virtual JToken GetCandidates(JArray _params)
protected internal virtual JToken GetCandidates(JArray _params)
{
using var snapshot = system.GetSnapshot();
byte[] script;
Expand Down Expand Up @@ -322,14 +409,24 @@ protected virtual JToken GetCandidates(JArray _params)
return json;
}

/// <summary>
/// Gets the list of committee members.
/// </summary>
/// <param name="_params">An empty array; no parameters are required.</param>
/// <returns>The committee members publickeys as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetCommittee(JArray _params)
protected internal virtual JToken GetCommittee(JArray _params)
{
return new JArray(NativeContract.NEO.GetCommittee(system.StoreView).Select(p => (JToken)p.ToString()));
}

/// <summary>
/// Gets the list of native contracts.
/// </summary>
/// <param name="_params">An empty array; no parameters are required.</param>
/// <returns>The native contract states <see cref="ContractState"/> as a <see cref="JToken"/>.</returns>
[RpcMethod]
protected virtual JToken GetNativeContracts(JArray _params)
protected internal virtual JToken GetNativeContracts(JArray _params)
{
return new JArray(NativeContract.Contracts.Select(p => NativeContract.ContractManagement.GetContract(system.StoreView, p.Hash).ToJson()));
}
Expand Down
34 changes: 0 additions & 34 deletions tests/Neo.Plugins.RpcServer.Tests/MockNeoSystem.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Neo.Plugins.RpcServer.Tests</RootNamespace>
<AssemblyName>Neo.Plugins.RpcServer.Tests</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
Expand All @@ -16,6 +17,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\Neo\Neo.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.RpcServer.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.RpcServer.Tests;

public class TestMemoryStoreProvider(MemoryStore memoryStore) : IStoreProvider
{
public MemoryStore MemoryStore { get; init; } = memoryStore;
public string Name => nameof(MemoryStore);
public IStore GetStore(string path) => MemoryStore;
}
Loading
Loading