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

Convert InteropInterface<IEnumerator> to Array for RpcClient to digest #245

Closed
wants to merge 13 commits into from
2 changes: 1 addition & 1 deletion src/LevelDBStore/LevelDBStore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Neo" Version="3.0.0-CI00909" />
<PackageReference Include="Neo" Version="3.0.0-CI00929" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/RocksDBStore/RocksDBStore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Neo" Version="3.0.0-CI00909" />
<PackageReference Include="Neo" Version="3.0.0-CI00929" />
<PackageReference Include="RocksDbNative" Version="6.2.2" />
<PackageReference Include="RocksDbSharp" Version="6.2.2" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/RpcClient/RpcClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Neo" Version="3.0.0-CI00909" />
<PackageReference Include="Neo" Version="3.0.0-CI00929" />
</ItemGroup>

</Project>
50 changes: 45 additions & 5 deletions src/RpcServer/RpcServer.SmartContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
#pragma warning disable IDE0060

using Neo.IO.Json;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
using Neo.VM.Types;
using Neo.Wallets;
using System;
using System.IO;
using System.Linq;
using Neo.IO;
using Neo.Ledger;
using Neo.SmartContract.Native;
using Neo.Wallets;
using Array = Neo.VM.Types.Array;

namespace Neo.Plugins
{
Expand Down Expand Up @@ -64,7 +65,9 @@ private JObject GetInvokeResult(byte[] script, IVerifiable checkWitnessHashes =
json["gas_consumed"] = engine.GasConsumed.ToString();
try
{
json["stack"] = new JArray(engine.ResultStack.Select(p => p.ToParameter().ToJson()));
var stackItems = engine.ResultStack.ToArray();
ConvertIEnumeratorToArray(stackItems); // convert InteropInterface<IEnumerator> to Array for RpcClient to digest
json["stack"] = new JArray(stackItems.Select(p => p.ToJson()));
}
catch (InvalidOperationException)
{
Expand All @@ -74,6 +77,43 @@ private JObject GetInvokeResult(byte[] script, IVerifiable checkWitnessHashes =
return json;
}

public static void ConvertIEnumeratorToArray(StackItem[] stackItems)
{
for (int i = 0; i < stackItems.Length; i++)
{
if (stackItems[i] is InteropInterface interopInterface)
{
if (interopInterface.TryGetInterface(out System.Collections.IEnumerator sysEnum))
{
Array array = new Array();
while (sysEnum.MoveNext())
{
Copy link
Member

Choose a reason for hiding this comment

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

maxPage in config?

var current = sysEnum.Current;
if (!(current is StackItem))
{
if (current is IInteroperable interoperable)
current = interoperable.ToStackItem(null);
else
current = new InteropInterface(current);
}
array.Add((StackItem)current);
}
stackItems[i] = array;
continue;
}
if (interopInterface.TryGetInterface(out Neo.SmartContract.Enumerators.IEnumerator neoEnum))
{
Array array = new Array();
while (neoEnum.Next())
{
array.Add(neoEnum.Value());
}
stackItems[i] = array;
}
}
}
}

[RpcMethod]
private JObject InvokeFunction(JArray _params)
{
Expand Down
2 changes: 1 addition & 1 deletion src/StatesDumper/StatesDumper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Neo" Version="3.0.0-CI00909" />
<PackageReference Include="Neo" Version="3.0.0-CI00929" />
<PackageReference Include="Neo.ConsoleService" Version="1.0.0" />
</ItemGroup>

Expand Down
1 change: 1 addition & 0 deletions tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

<ItemGroup>
<ProjectReference Include="..\..\src\RpcClient\RpcClient.csproj" />
<ProjectReference Include="..\..\src\RpcServer\RpcServer.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
78 changes: 78 additions & 0 deletions tests/Neo.Network.RPC.Tests/UT_RpcServer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO;
using Neo.Plugins;
using Neo.SmartContract.Iterators;
using Neo.SmartContract.Native.Tokens;
using Neo.VM.Types;
using Neo.Wallets;
using System;
using System.Collections.Generic;

namespace Neo.Network.RPC.Tests
{
[TestClass]
public class UT_RpcServer
{
[TestMethod]
public void Test_ConvertIEnumeratorToArray()
{
IReadOnlyList<byte[]> values = new byte[1][] { "NeHNBbeLNtiCEeaFQ6tLLpXkr5Xw6esKnV".ToScriptHash().ToArray() };
IIterator iterator = new TestIterator(values);

StackItem[] stackItems = new StackItem[]
{
12345,
"hello",
new InteropInterface(new int[] { 1, 2, 3 }.GetEnumerator()),
new InteropInterface(new AccountState[] {new AccountState()}.GetEnumerator()),
new InteropInterface(iterator)
};

Assert.AreEqual(stackItems[3].Type, StackItemType.InteropInterface);
Assert.AreEqual(stackItems[4].Type, StackItemType.InteropInterface);

RpcServer.ConvertIEnumeratorToArray(stackItems);

Assert.AreEqual(stackItems[3].Type, StackItemType.Array);
Assert.AreEqual(stackItems[4].Type, StackItemType.Array);
}
}

internal class TestIterator : IIterator
{
private readonly IReadOnlyList<byte[]> values;
private int index = -1;

public TestIterator(IReadOnlyList<byte[]> vs)
{
this.values = vs;
}

public PrimitiveType Key()
{
if (index < 0)
throw new InvalidOperationException();
return index;
}

public bool Next()
{
int next = index + 1;
if (next >= values.Count)
return false;
index = next;
return true;
}

public StackItem Value()
{
if (index < 0)
throw new InvalidOperationException();
return values[index];
}

public void Dispose()
{
}
}
}
2 changes: 1 addition & 1 deletion tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public void TestSign()

Assert.IsTrue(Crypto.VerifySignature(tx.GetHashData(), signature, keyPair1.PublicKey));
// verify network fee and system fee
long networkFee = tx.Size * (long)1000 + ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHNULL] + InteropService.GetPrice(InteropService.Crypto.VerifyWithECDsaSecp256r1, null, null);
long networkFee = tx.Size * (long)1000 + ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHNULL] + InteropService.Crypto.VerifyWithECDsaSecp256r1.FixedPrice;
Assert.AreEqual(networkFee, tx.NetworkFee);
Assert.AreEqual(100, tx.SystemFee);

Expand Down