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
28 changes: 27 additions & 1 deletion src/RpcServer/RpcServer.SmartContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
using Neo.Persistence;
using Neo.SmartContract;
using Neo.VM;
using Neo.VM.Types;
using System;
using System.Collections;
using System.IO;
using System.Linq;
using Array = Neo.VM.Types.Array;

namespace Neo.Plugins
{
Expand Down Expand Up @@ -60,7 +63,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();
stackItems = ConvertIEnumeratorToArray(stackItems); // convert InteropInterface<IEnumerator> to Array for RpcClient to digest
json["stack"] = new JArray(stackItems.Select(p => p.ToParameter().ToJson()));
joeqian10 marked this conversation as resolved.
Show resolved Hide resolved
}
catch (InvalidOperationException)
{
Expand All @@ -70,6 +75,27 @@ private JObject GetInvokeResult(byte[] script, IVerifiable checkWitnessHashes =
return json;
}

public static StackItem[] ConvertIEnumeratorToArray(StackItem[] stackItems)
Copy link
Member

Choose a reason for hiding this comment

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

If we change the items in the same array, we should not return an array, because it's the same.

{
for (int i = 0; i < stackItems.Length; i++)
{
if (stackItems[i] is InteropInterface interopInterface)
{
if (interopInterface.TryGetInterface<IEnumerator>(out IEnumerator enumerator))
{
Array array = new Array();
while (enumerator.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 = enumerator.Current;
array.Add(current is StackItem stackItem ? stackItem : current is IInteroperable interoperable ? interoperable.ToStackItem(null) : new InteropInterface(current));
Copy link
Contributor

Choose a reason for hiding this comment

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

This line is too line to read, it's better to split into multiple lines.

}
stackItems[i] = array;
}
}
}
return stackItems;
}

[RpcMethod]
private JObject InvokeFunction(JArray _params)
{
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
29 changes: 29 additions & 0 deletions tests/Neo.Network.RPC.Tests/UT_RpcServer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Plugins;
using Neo.SmartContract.Native.Tokens;
using Neo.VM.Types;

namespace Neo.Network.RPC.Tests
{
[TestClass]
public class UT_RpcServer
{
[TestMethod]
public void Test_ConvertIEnumeratorToArray()
{
StackItem[] stackItems = new StackItem[]
{
12345,
"hello",
new InteropInterface(new int[] { 1, 2, 3 }.GetEnumerator()),
new InteropInterface(new Nep5AccountState[] {new Nep5AccountState()}.GetEnumerator())
Copy link
Contributor

Choose a reason for hiding this comment

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

Could add a StorageMap type here, which used in nep11, see neo-project/neo-devpack-dotnet#268

};

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

var newStackItems = RpcServer.ConvertIEnumeratorToArray(stackItems);

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