diff --git a/src/Neo/Network/P2P/Peer.cs b/src/Neo/Network/P2P/Peer.cs
index 074c5cf3ba..bf6b23901f 100644
--- a/src/Neo/Network/P2P/Peer.cs
+++ b/src/Neo/Network/P2P/Peer.cs
@@ -146,7 +146,7 @@ static Peer()
/// Tries to add a set of peers to the immutable ImmutableHashSet of UnconnectedPeers.
///
/// Peers that the method will try to add (union) to (with) UnconnectedPeers.
- protected void AddPeers(IEnumerable peers)
+ protected internal void AddPeers(IEnumerable peers)
{
if (UnconnectedPeers.Count < UnconnectedMax)
{
diff --git a/src/Plugins/RpcServer/RpcServer.Node.cs b/src/Plugins/RpcServer/RpcServer.Node.cs
index 716125e2cf..c1b5397c5b 100644
--- a/src/Plugins/RpcServer/RpcServer.Node.cs
+++ b/src/Plugins/RpcServer/RpcServer.Node.cs
@@ -24,13 +24,13 @@ namespace Neo.Plugins.RpcServer
partial class RpcServer
{
[RpcMethod]
- protected virtual JToken GetConnectionCount(JArray _params)
+ protected internal virtual JToken GetConnectionCount(JArray _params)
{
return localNode.ConnectedCount;
}
[RpcMethod]
- protected virtual JToken GetPeers(JArray _params)
+ protected internal virtual JToken GetPeers(JArray _params)
{
JObject json = new();
json["unconnected"] = new JArray(localNode.GetUnconnectedPeers().Select(p =>
diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs
index 2fbb2f6f3f..b04b5e33d4 100644
--- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs
+++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs
@@ -11,7 +11,9 @@
using Akka.Actor;
using Akka.Util.Internal;
+using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Neo.Cryptography.ECC;
using Neo.IO;
using Neo.Json;
using Neo.Ledger;
@@ -23,6 +25,8 @@
using Neo.UnitTests.Extensions;
using System;
using System.Linq;
+using System.Security.Policy;
+using static Neo.SmartContract.Native.NeoToken;
namespace Neo.Plugins.RpcServer.Tests
{
@@ -61,6 +65,11 @@ public void TestGetBlockByHash()
{
Assert.AreEqual(VerifyResult.Succeed, tx.VerifyStateIndependent(UnitTests.TestProtocolSettings.Default));
});
+
+ result = _rpcServer.GetBlock(new BlockHashOrIndex(block.Hash), true);
+ var block3 = block.ToJson(UnitTests.TestProtocolSettings.Default);
+ block3["confirmations"] = NativeContract.Ledger.CurrentIndex(snapshot) - block.Index + 1;
+ result.ToString().Should().Be(block3.ToString());
}
[TestMethod]
@@ -78,6 +87,11 @@ public void TestGetBlockByIndex()
{
Assert.AreEqual(VerifyResult.Succeed, tx.VerifyStateIndependent(UnitTests.TestProtocolSettings.Default));
});
+
+ result = _rpcServer.GetBlock(new BlockHashOrIndex(block.Index), true);
+ var block3 = block.ToJson(UnitTests.TestProtocolSettings.Default);
+ block3["confirmations"] = NativeContract.Ledger.CurrentIndex(snapshot) - block.Index + 1;
+ result.ToString().Should().Be(block3.ToString());
}
[TestMethod]
@@ -120,6 +134,11 @@ public void TestGetBlockHeader()
var header = block.Header.ToJson(_neoSystem.Settings);
header["confirmations"] = NativeContract.Ledger.CurrentIndex(snapshot) - block.Index + 1;
Assert.AreEqual(header.ToString(), result.ToString());
+
+ result = _rpcServer.GetBlockHeader(new BlockHashOrIndex(block.Hash), false);
+ var headerArr = Convert.FromBase64String(result.AsString());
+ var header2 = headerArr.AsSerializable();
+ header2.ToJson(_neoSystem.Settings).ToString().Should().Be(block.Header.ToJson(_neoSystem.Settings).ToString());
}
[TestMethod]
@@ -129,9 +148,23 @@ public void TestGetContractState()
var contractState = TestUtils.GetContract();
snapshot.AddContract(contractState.Hash, contractState);
snapshot.Commit();
+
var result = _rpcServer.GetContractState(new ContractNameOrHashOrId(contractState.Hash));
+ Assert.AreEqual(contractState.ToJson().ToString(), result.ToString());
+ result = _rpcServer.GetContractState(new ContractNameOrHashOrId(contractState.Id));
Assert.AreEqual(contractState.ToJson().ToString(), result.ToString());
+
+ var byId = _rpcServer.GetContractState(new ContractNameOrHashOrId(-1));
+ var byName = _rpcServer.GetContractState(new ContractNameOrHashOrId("ContractManagement"));
+ byId.ToString().Should().Be(byName.ToString());
+
+ snapshot.DeleteContract(contractState.Hash);
+ snapshot.Commit();
+ Action act = () => _rpcServer.GetContractState(new ContractNameOrHashOrId(contractState.Hash));
+ act.Should().Throw().WithMessage(RpcError.UnknownContract.Message);
+ act = () => _rpcServer.GetContractState(new ContractNameOrHashOrId(contractState.Id));
+ act.Should().Throw().WithMessage(RpcError.UnknownContract.Message);
}
[TestMethod]
@@ -143,8 +176,10 @@ public void TestGetRawMemPool()
_neoSystem.MemPool.TryAdd(tx, snapshot);
var result = _rpcServer.GetRawMemPool();
-
Assert.IsTrue(((JArray)result).Any(p => p.AsString() == tx.Hash.ToString()));
+
+ result = _rpcServer.GetRawMemPool(true);
+ Assert.IsTrue(((JArray)result["verified"]).Any(p => p.AsString() == tx.Hash.ToString()));
}
[TestMethod]
@@ -154,10 +189,14 @@ public void TestGetRawTransaction()
var tx = TestUtils.CreateValidTx(snapshot, _wallet, _walletAccount);
_neoSystem.MemPool.TryAdd(tx, snapshot);
snapshot.Commit();
- var result = _rpcServer.GetRawTransaction(tx.Hash, true);
+ var result = _rpcServer.GetRawTransaction(tx.Hash, true);
var json = Utility.TransactionToJson(tx, _neoSystem.Settings);
Assert.AreEqual(json.ToString(), result.ToString());
+
+ result = _rpcServer.GetRawTransaction(tx.Hash, false);
+ var tx2 = Convert.FromBase64String(result.AsString()).AsSerializable();
+ tx2.ToJson(_neoSystem.Settings).ToString().Should().Be(tx.ToJson(_neoSystem.Settings).ToString());
}
[TestMethod]
@@ -197,6 +236,15 @@ public void TestFindStorage()
json["next"] = 1;
json["results"] = jarr;
Assert.AreEqual(json.ToString(), result.ToString());
+
+ var result2 = _rpcServer.FindStorage(new ContractNameOrHashOrId(contractState.Hash), Convert.ToBase64String(key));
+ result2.ToString().Should().Be(result.ToString());
+
+ Enumerable.Range(0, 51).ToList().ForEach(i => TestUtils.StorageItemAdd(snapshot, contractState.Id, new byte[] { 0x01, (byte)i }, new byte[] { 0x02 }));
+ snapshot.Commit();
+ var result4 = _rpcServer.FindStorage(new ContractNameOrHashOrId(contractState.Hash), Convert.ToBase64String(new byte[] { 0x01 }), 0);
+ result4["next"].Should().Be(RpcServerSettings.Default.FindStoragePageSize);
+ (result4["truncated"]).AsBoolean().Should().Be(true);
}
[TestMethod]
@@ -232,12 +280,16 @@ public void TestGetNextBlockValidators()
public void TestGetCandidates()
{
var snapshot = _neoSystem.GetSnapshotCache();
+
var result = _rpcServer.GetCandidates();
var json = new JArray();
var validators = NativeContract.NEO.GetNextBlockValidators(snapshot, _neoSystem.Settings.ValidatorsCount);
+
+ var key = new KeyBuilder(NativeContract.NEO.Id, 33).Add(ECPoint.Parse("02237309a0633ff930d51856db01d17c829a5b2e5cc2638e9c03b4cfa8e9c9f971", ECCurve.Secp256r1));
+ snapshot.Add(key, new StorageItem(new CandidateState() { Registered = true, Votes = 10000 }));
snapshot.Commit();
var candidates = NativeContract.NEO.GetCandidates(_neoSystem.GetSnapshotCache());
-
+ result = _rpcServer.GetCandidates();
foreach (var candidate in candidates)
{
var item = new JObject();
@@ -350,7 +402,8 @@ public void TestGetBlockHashInvalidIndex()
var block = TestUtils.CreateBlockWithValidTransactions(snapshot, _wallet, _walletAccount, 3);
TestUtils.BlocksAdd(snapshot, block.Hash, block);
snapshot.Commit();
- Assert.ThrowsException(() => _rpcServer.GetBlockHash(block.Index + 1));
+ Action act = () => _rpcServer.GetBlockHash(block.Index + 1);
+ act.Should().Throw();
}
[TestMethod]
diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs
index c8b655024c..cf674a449c 100644
--- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs
+++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs
@@ -9,18 +9,50 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
+using Akka.Actor;
+using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO;
using Neo.Json;
+using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
using Neo.SmartContract.Native;
using Neo.UnitTests;
using System;
+using System.Collections.Generic;
+using System.Net;
namespace Neo.Plugins.RpcServer.Tests
{
partial class UT_RpcServer
{
+ [TestMethod]
+ public void TestGetConnectionCount()
+ {
+ var result = _rpcServer.GetConnectionCount(new JArray());
+ result.GetType().Should().Be(typeof(JNumber));
+ }
+
+ [TestMethod]
+ public void TestGetPeers()
+ {
+ var settings = TestProtocolSettings.SoleNode;
+ var neoSystem = new NeoSystem(settings, _memoryStoreProvider);
+ var localNode = neoSystem.LocalNode.Ask(new LocalNode.GetInstance()).Result;
+ localNode.AddPeers(new List() { new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 11332) });
+ localNode.AddPeers(new List() { new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 12332) });
+ localNode.AddPeers(new List() { new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 13332) });
+ var rpcServer = new RpcServer(neoSystem, RpcServerSettings.Default);
+
+ var result = rpcServer.GetPeers(new JArray());
+ Assert.IsInstanceOfType(result, typeof(JObject));
+ var json = (JObject)result;
+ json.ContainsProperty("unconnected").Should().BeTrue();
+ (json["unconnected"] as JArray).Count.Should().Be(3);
+ json.ContainsProperty("bad").Should().BeTrue();
+ json.ContainsProperty("connected").Should().BeTrue();
+ }
+
[TestMethod]
public void TestGetVersion()
{
diff --git a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs
index 9a282759a9..c205a7e4bd 100644
--- a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs
+++ b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs
@@ -9,6 +9,8 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
+using FluentAssertions;
+using Neo.IO;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.SmartContract;
@@ -100,14 +102,26 @@ public static void DestroyContract(this DataCache snapshot, UInt160 callingScrip
public static void AddContract(this DataCache snapshot, UInt160 hash, ContractState state)
{
+ //key: hash, value: ContractState
var key = new KeyBuilder(NativeContract.ContractManagement.Id, 8).Add(hash);
snapshot.Add(key, new StorageItem(state));
+ //key: id, value: hash
+ var key2 = new KeyBuilder(NativeContract.ContractManagement.Id, 12).AddBigEndian(state.Id);
+ if (!snapshot.Contains(key2)) snapshot.Add(key2, new StorageItem(hash.ToArray()));
}
public static void DeleteContract(this DataCache snapshot, UInt160 hash)
{
+ //key: hash, value: ContractState
var key = new KeyBuilder(NativeContract.ContractManagement.Id, 8).Add(hash);
+ var value = snapshot.TryGet(key)?.GetInteroperable();
snapshot.Delete(key);
+ if (value != null)
+ {
+ //key: id, value: hash
+ var key2 = new KeyBuilder(NativeContract.ContractManagement.Id, 12).AddBigEndian(value.Id);
+ snapshot.Delete(key2);
+ }
}
public static StackItem Call(this NativeContract contract, DataCache snapshot, string method, params ContractParameter[] args)