Skip to content

Commit

Permalink
Update to Neo.VM.3.0.0-CI00226 (neo-project#1713)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang authored and Tommo-L committed Jun 22, 2020
1 parent 33e93b0 commit d49b446
Show file tree
Hide file tree
Showing 14 changed files with 41 additions and 75 deletions.
6 changes: 2 additions & 4 deletions src/neo/SmartContract/ApplicationEngine.Contract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ internal ContractState CreateContract(byte[] script, byte[] manifest)
if (script.Length == 0 || script.Length > MaxContractLength || manifest.Length == 0 || manifest.Length > ContractManifest.MaxLength)
throw new ArgumentException();

if (!AddGas(StoragePrice * (script.Length + manifest.Length)))
throw new InvalidOperationException();
AddGas(StoragePrice * (script.Length + manifest.Length));

UInt160 hash = script.ToScriptHash();
ContractState contract = Snapshot.Contracts.TryGet(hash);
Expand All @@ -53,8 +52,7 @@ internal ContractState CreateContract(byte[] script, byte[] manifest)

internal void UpdateContract(byte[] script, byte[] manifest)
{
if (!AddGas(StoragePrice * (script?.Length ?? 0 + manifest?.Length ?? 0)))
throw new InvalidOperationException();
AddGas(StoragePrice * (script?.Length ?? 0 + manifest?.Length ?? 0));

var contract = Snapshot.Contracts.TryGet(CurrentScriptHash);
if (contract is null) throw new InvalidOperationException();
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/ApplicationEngine.Crypto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private bool CheckMultiSigWithECDsa(StackItem item0, byte[][] pubkeys, byte[][]
_ => item0.GetSpan()
};
if (n == 0 || m == 0 || m > n) throw new ArgumentException();
if (!AddGas(ECDsaVerifyPrice * n)) throw new InvalidOperationException();
AddGas(ECDsaVerifyPrice * n);
try
{
for (int i = 0, j = 0; i < m && j < n;)
Expand Down
3 changes: 1 addition & 2 deletions src/neo/SmartContract/ApplicationEngine.Native.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ internal void DeployNativeContracts()

internal void CallNativeContract(string name)
{
if (!NativeContract.GetContract(name).Invoke(this))
throw new InvalidOperationException();
NativeContract.GetContract(name).Invoke(this);
}
}
}
2 changes: 1 addition & 1 deletion src/neo/SmartContract/ApplicationEngine.Storage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ private void PutExInternal(StorageContext context, byte[] key, byte[] value, Sto
else
newDataSize = value.Length - item.Value.Length;
}
if (!AddGas(newDataSize * StoragePrice)) throw new InvalidOperationException();
AddGas(newDataSize * StoragePrice);

item.Value = value;
item.IsConstant = flags.HasFlag(StorageFlags.Constant);
Expand Down
40 changes: 11 additions & 29 deletions src/neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Text;
using Array = System.Array;
using VMArray = Neo.VM.Types.Array;

Expand Down Expand Up @@ -49,10 +48,11 @@ public ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView s
this.Snapshot = snapshot;
}

internal bool AddGas(long gas)
internal void AddGas(long gas)
{
GasConsumed = checked(GasConsumed + gas);
return testMode || GasConsumed <= gas_amount;
if (!testMode && GasConsumed > gas_amount)
throw new InvalidOperationException("Insufficient GAS.");
}

protected override void ContextUnloaded(ExecutionContext context)
Expand Down Expand Up @@ -146,17 +146,15 @@ public override void Dispose()
base.Dispose();
}

protected override bool OnSysCall(uint method)
protected override void OnSysCall(uint method)
{
if (!services.TryGetValue(method, out InteropDescriptor descriptor))
return false;
InteropDescriptor descriptor = services[method];
if (!descriptor.AllowedTriggers.HasFlag(Trigger))
return false;
throw new InvalidOperationException($"Cannot call this SYSCALL with the trigger {Trigger}.");
ExecutionContextState state = CurrentContext.GetState<ExecutionContextState>();
if (!state.CallFlags.HasFlag(descriptor.RequiredCallFlags))
return false;
if (!AddGas(descriptor.FixedPrice))
return false;
throw new InvalidOperationException($"Cannot call this SYSCALL with the flag {state.CallFlags}.");
AddGas(descriptor.FixedPrice);
List<object> parameters = descriptor.Parameters.Length > 0
? new List<object>()
: null;
Expand All @@ -165,14 +163,12 @@ protected override bool OnSysCall(uint method)
object returnValue = descriptor.Handler.Invoke(this, parameters?.ToArray());
if (descriptor.Handler.ReturnType != typeof(void))
Push(Convert(returnValue));
return true;
}

protected override bool PreExecuteInstruction()
protected override void PreExecuteInstruction()
{
if (CurrentContext.InstructionPointer >= CurrentContext.Script.Length)
return true;
return AddGas(OpCodePrices[CurrentContext.CurrentInstruction.OpCode]);
if (CurrentContext.InstructionPointer < CurrentContext.Script.Length)
AddGas(OpCodePrices[CurrentContext.CurrentInstruction.OpCode]);
}

private static Block CreateDummyBlock(StoreView snapshot)
Expand Down Expand Up @@ -223,19 +219,5 @@ public static ApplicationEngine Run(byte[] script, IVerifiable container = null,
return Run(script, snapshot, container, persistingBlock, offset, testMode, extraGAS);
}
}

public bool TryPop(out string s)
{
if (TryPop(out ReadOnlySpan<byte> b))
{
s = Encoding.UTF8.GetString(b);
return true;
}
else
{
s = default;
return false;
}
}
}
}
2 changes: 1 addition & 1 deletion src/neo/SmartContract/ContainerPlaceholder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public ContainerPlaceholder(StackItemType type, int count)
ElementCount = count;
}

public override bool Equals(object obj) => throw new NotSupportedException();
public override bool Equals(StackItem other) => throw new NotSupportedException();

public override int GetHashCode() => throw new NotSupportedException();

Expand Down
3 changes: 1 addition & 2 deletions src/neo/SmartContract/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using Neo.Persistence;
using Neo.SmartContract.Manifest;
using Neo.VM;
using Neo.VM.Types;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
Expand Down Expand Up @@ -165,7 +164,7 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap
engine.LoadScript(verification, CallFlags.ReadOnly).InstructionPointer = offset;
engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None);
if (engine.Execute() == VMState.FAULT) return false;
if (!engine.ResultStack.TryPop(out StackItem result) || !result.ToBoolean()) return false;
if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().ToBoolean()) return false;
gas -= engine.GasConsumed;
}
}
Expand Down
17 changes: 9 additions & 8 deletions src/neo/SmartContract/Native/NativeContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,17 @@ public static NativeContract GetContract(string name)
return contract;
}

internal bool Invoke(ApplicationEngine engine)
internal void Invoke(ApplicationEngine engine)
{
if (!engine.CurrentScriptHash.Equals(Hash)) return false;
if (!engine.TryPop(out string operation)) return false;
if (!engine.TryPop(out Array args)) return false;
if (!methods.TryGetValue(operation, out ContractMethodMetadata method)) return false;
if (!engine.CurrentScriptHash.Equals(Hash))
throw new InvalidOperationException("It is not allowed to use Neo.Native.Call directly to call native contracts. System.Contract.Call should be used.");
string operation = engine.PopString();
Array args = engine.Pop<Array>();
ContractMethodMetadata method = methods[operation];
ExecutionContextState state = engine.CurrentContext.GetState<ExecutionContextState>();
if (!state.CallFlags.HasFlag(method.RequiredCallFlags)) return false;
if (!engine.AddGas(method.Price)) return false;
if (!state.CallFlags.HasFlag(method.RequiredCallFlags))
throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}.");
engine.AddGas(method.Price);
List<object> parameters = new List<object>();
if (method.NeedApplicationEngine) parameters.Add(engine);
if (method.NeedSnapshot) parameters.Add(engine.Snapshot);
Expand All @@ -128,7 +130,6 @@ internal bool Invoke(ApplicationEngine engine)
object returnValue = method.Handler.Invoke(this, parameters.ToArray());
if (method.Handler.ReturnType != typeof(void))
engine.Push(engine.Convert(returnValue));
return true;
}

public static bool IsNative(UInt160 hash)
Expand Down
2 changes: 1 addition & 1 deletion src/neo/neo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.3" />
<PackageReference Include="Neo.VM" Version="3.0.0-CI00224" />
<PackageReference Include="Neo.VM" Version="3.0.0-CI00226" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public void Check_BadScript()
script.Emit(OpCode.NOP);
engine.LoadScript(script.ToArray());

NativeContract.GAS.Invoke(engine).Should().BeFalse();
Assert.ThrowsException<InvalidOperationException>(() => NativeContract.GAS.Invoke(engine));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public void Check_BadScript()
script.Emit(OpCode.NOP);
engine.LoadScript(script.ToArray());

NativeContract.NEO.Invoke(engine).Should().BeFalse();
Assert.ThrowsException<InvalidOperationException>(() => NativeContract.NEO.Invoke(engine));
}

[TestMethod]
Expand Down Expand Up @@ -283,7 +283,7 @@ public void TestGetRegisteredValidators1()
{
using (ApplicationEngine engine = NativeContract.NEO.TestCall("getCandidates"))
{
engine.ResultStack.TryPop(out VM.Types.Array array).Should().BeTrue();
var array = engine.ResultStack.Pop<VM.Types.Array>();
array.Count.Should().Be(21);
((VM.Types.Struct)array[0])[0].GetSpan().ToHexString().Should().Be("020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639");
((VM.Types.Struct)array[0])[1].GetBigInteger().Should().Be(new BigInteger(1785714));
Expand Down
5 changes: 3 additions & 2 deletions tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Neo.SmartContract.Native;
using Neo.VM.Types;
using System;
using System.Collections.Generic;
using VMArray = Neo.VM.Types.Array;

namespace Neo.UnitTests.SmartContract.Native
Expand Down Expand Up @@ -38,13 +39,13 @@ public void TestInvoke()
VMArray args1 = new VMArray();
engine.CurrentContext.EvaluationStack.Push(args1);
engine.CurrentContext.EvaluationStack.Push(method1);
testNativeContract.Invoke(engine).Should().BeFalse();
Assert.ThrowsException<KeyNotFoundException>(() => testNativeContract.Invoke(engine));

ByteString method2 = new ByteString(System.Text.Encoding.Default.GetBytes("onPersist"));
VMArray args2 = new VMArray();
engine.CurrentContext.EvaluationStack.Push(args2);
engine.CurrentContext.EvaluationStack.Push(method2);
testNativeContract.Invoke(engine).Should().BeTrue();
testNativeContract.Invoke(engine);
}

[TestMethod]
Expand Down
14 changes: 0 additions & 14 deletions tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using Neo.IO;
using Neo.IO.Caching;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.SmartContract;

namespace Neo.UnitTests.SmartContract
Expand Down Expand Up @@ -78,18 +76,6 @@ public void TestCreateDummyBlock()
}
}

public class TestApplicationEngine : ApplicationEngine
{
public TestApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false) : base(trigger, container, snapshot, gas, testMode)
{
}

public bool GetOnSysCall(uint method)
{
return OnSysCall(method);
}
}

public class TestMetaDataCache<T> : MetaDataCache<T> where T : class, ICloneable<T>, ISerializable, new()
{
public TestMetaDataCache()
Expand Down
14 changes: 7 additions & 7 deletions tests/neo.UnitTests/SmartContract/UT_Syscalls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ public void Json_Deserialize()
Assert.AreEqual(engine.Execute(), VMState.HALT);
Assert.AreEqual(2, engine.ResultStack.Count);

Assert.IsTrue(engine.ResultStack.TryPop<Null>(out _));
Assert.IsTrue(engine.ResultStack.TryPop<Integer>(out var i) && i.GetBigInteger() == 123);
engine.ResultStack.Pop<Null>();
Assert.IsTrue(engine.ResultStack.Pop<Integer>().GetBigInteger() == 123);
}
}

Expand Down Expand Up @@ -194,11 +194,11 @@ public void Json_Serialize()
Assert.AreEqual(engine.Execute(), VMState.HALT);
Assert.AreEqual(5, engine.ResultStack.Count);

Assert.IsTrue(engine.ResultStack.TryPop<ByteString>(out var m) && m.GetString() == "{\"key\":\"dmFsdWU=\"}");
Assert.IsTrue(engine.ResultStack.TryPop<ByteString>(out var n) && n.GetString() == "null");
Assert.IsTrue(engine.ResultStack.TryPop<ByteString>(out var s) && s.GetString() == "\"dGVzdA==\"");
Assert.IsTrue(engine.ResultStack.TryPop<ByteString>(out var b) && b.GetString() == "true");
Assert.IsTrue(engine.ResultStack.TryPop<ByteString>(out var i) && i.GetString() == "5");
Assert.IsTrue(engine.ResultStack.Pop<ByteString>().GetString() == "{\"key\":\"dmFsdWU=\"}");
Assert.IsTrue(engine.ResultStack.Pop<ByteString>().GetString() == "null");
Assert.IsTrue(engine.ResultStack.Pop<ByteString>().GetString() == "\"dGVzdA==\"");
Assert.IsTrue(engine.ResultStack.Pop<ByteString>().GetString() == "true");
Assert.IsTrue(engine.ResultStack.Pop<ByteString>().GetString() == "5");
}
}

Expand Down

0 comments on commit d49b446

Please sign in to comment.