Skip to content
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
30 changes: 28 additions & 2 deletions neo.UnitTests/UT_SpentCointState.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO;
using Neo.Ledger;
using System.Collections.Generic;
using System.IO;
Expand All @@ -24,6 +25,31 @@ public void TransactionHash_Get()
uut.TransactionHash.Should().BeNull();
}

[TestMethod]
public void TestFromReplica()
{
uut.Items = new Dictionary<ushort, uint>();
uut.Items.Add(1, 3);

var a = ((ICloneable<SpentCoinState>)uut).Clone();
var b = new SpentCoinState();

((ICloneable<SpentCoinState>)b).FromReplica(uut);

CollectionAssert.AreEqual(a.Items.Keys, uut.Items.Keys);
CollectionAssert.AreEqual(a.Items.Values, uut.Items.Values);
CollectionAssert.AreEqual(b.Items.Keys, uut.Items.Keys);
CollectionAssert.AreEqual(b.Items.Values, uut.Items.Values);

a.Items.Clear();
b.Items.Clear();

CollectionAssert.AreNotEqual(a.Items.Keys, uut.Items.Keys);
CollectionAssert.AreNotEqual(b.Items.Keys, uut.Items.Keys);
CollectionAssert.AreNotEqual(a.Items.Values, uut.Items.Values);
CollectionAssert.AreNotEqual(b.Items.Values, uut.Items.Values);
}

[TestMethod]
public void TransactionHash_Set()
{
Expand Down Expand Up @@ -98,8 +124,8 @@ private void setupSpentCoinStateWithValues(SpentCoinState spentCoinState, out UI
[TestMethod]
public void DeserializeSCS()
{
byte[] dataArray = new byte[] { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 42, 3, 44, 45, 1, 42, 0, 0, 0, 0, 0 };
byte[] dataArray = new byte[] { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 42, 3, 44, 45, 1, 42, 0, 0, 0, 0, 0 };
using (Stream stream = new MemoryStream(dataArray))
{
using (BinaryReader reader = new BinaryReader(stream))
Expand Down
2 changes: 1 addition & 1 deletion neo/Ledger/SpentCoinState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void ICloneable<SpentCoinState>.FromReplica(SpentCoinState replica)
{
TransactionHash = replica.TransactionHash;
TransactionHeight = replica.TransactionHeight;
Items = replica.Items;
Items = new Dictionary<ushort, uint>(replica.Items);
}

public override void Serialize(BinaryWriter writer)
Expand Down
83 changes: 72 additions & 11 deletions neo/Network/RPC/RpcServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,48 @@ namespace Neo.Network.RPC
{
public sealed class RpcServer : IDisposable
{
private class CheckWitnessHashes : IVerifiable
{
private readonly UInt160[] _scriptHashesForVerifying;
public Witness[] Witnesses { get; set; }
public int Size { get; }

public CheckWitnessHashes(UInt160[] scriptHashesForVerifying)
{
_scriptHashesForVerifying = scriptHashesForVerifying;
}

public void Serialize(BinaryWriter writer)
{
throw new NotImplementedException();
}

public void Deserialize(BinaryReader reader)
{
throw new NotImplementedException();
}

public void DeserializeUnsigned(BinaryReader reader)
{
throw new NotImplementedException();
}

public UInt160[] GetScriptHashesForVerifying(Snapshot snapshot)
{
return _scriptHashesForVerifying;
}

public void SerializeUnsigned(BinaryWriter writer)
{
throw new NotImplementedException();
}

public byte[] GetMessage()
{
throw new NotImplementedException();
}
}

public Wallet Wallet { get; set; }
public Fixed8 MaxGasInvoke { get; }
public int MaxConcurrentConnections { get; }
Expand Down Expand Up @@ -73,9 +115,9 @@ public void Dispose()
}
}

private JObject GetInvokeResult(byte[] script)
private JObject GetInvokeResult(byte[] script, IVerifiable checkWitnessHashes = null)
{
using (ApplicationEngine engine = ApplicationEngine.Run(script, extraGAS: MaxGasInvoke))
using (ApplicationEngine engine = ApplicationEngine.Run(script, checkWitnessHashes, extraGAS: MaxGasInvoke))
{
JObject json = new JObject();
json["script"] = script.ToHexString();
Expand All @@ -89,6 +131,7 @@ private JObject GetInvokeResult(byte[] script)
{
json["stack"] = "error: recursive reference";
}

return json;
}
}
Expand Down Expand Up @@ -211,19 +254,37 @@ private JObject Process(string method, JArray _params)
{
UInt160 script_hash = UInt160.Parse(_params[0].AsString());
ContractParameter[] parameters = ((JArray)_params[1]).Select(p => ContractParameter.FromJson(p)).ToArray();
return Invoke(script_hash, parameters);
CheckWitnessHashes checkWitnessHashes = null;
if (_params.Count > 2)
{
UInt160[] scriptHashesForVerifying = _params.Skip(2).Select(u => UInt160.Parse(u.AsString())).ToArray();
checkWitnessHashes = new CheckWitnessHashes(scriptHashesForVerifying);
}
return Invoke(script_hash, parameters, checkWitnessHashes);
}
case "invokefunction":
{
UInt160 script_hash = UInt160.Parse(_params[0].AsString());
string operation = _params[1].AsString();
ContractParameter[] args = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0];
return InvokeFunction(script_hash, operation, args);
CheckWitnessHashes checkWitnessHashes = null;
if (_params.Count > 3)
{
UInt160[] scriptHashesForVerifying = _params.Skip(3).Select(u => UInt160.Parse(u.AsString())).ToArray();
checkWitnessHashes = new CheckWitnessHashes(scriptHashesForVerifying);
}
return InvokeFunction(script_hash, operation, args, checkWitnessHashes);
}
case "invokescript":
{
byte[] script = _params[0].AsString().HexToBytes();
return InvokeScript(script);
CheckWitnessHashes checkWitnessHashes = null;
if (_params.Count > 1)
{
UInt160[] scriptHashesForVerifying = _params.Skip(1).Select(u => UInt160.Parse(u.AsString())).ToArray();
checkWitnessHashes = new CheckWitnessHashes(scriptHashesForVerifying);
}
return InvokeScript(script, checkWitnessHashes);
}
case "listplugins":
{
Expand Down Expand Up @@ -620,29 +681,29 @@ private JObject GetVersion()
return json;
}

private JObject Invoke(UInt160 script_hash, ContractParameter[] parameters)
private JObject Invoke(UInt160 script_hash, ContractParameter[] parameters, IVerifiable checkWitnessHashes = null)
{
byte[] script;
using (ScriptBuilder sb = new ScriptBuilder())
{
script = sb.EmitAppCall(script_hash, parameters).ToArray();
}
return GetInvokeResult(script);
return GetInvokeResult(script, checkWitnessHashes);
}

private JObject InvokeFunction(UInt160 script_hash, string operation, ContractParameter[] args)
private JObject InvokeFunction(UInt160 script_hash, string operation, ContractParameter[] args, IVerifiable checkWitnessHashes = null)
{
byte[] script;
using (ScriptBuilder sb = new ScriptBuilder())
{
script = sb.EmitAppCall(script_hash, operation, args).ToArray();
}
return GetInvokeResult(script);
return GetInvokeResult(script, checkWitnessHashes);
}

private JObject InvokeScript(byte[] script)
private JObject InvokeScript(byte[] script, IVerifiable checkWitnessHashes = null)
{
return GetInvokeResult(script);
return GetInvokeResult(script, checkWitnessHashes);
}

private JObject ListPlugins()
Expand Down