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

Remove testmode from ApplicationEngine #1819

Merged
merged 13 commits into from
Aug 6, 2020
2 changes: 1 addition & 1 deletion src/neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ private void Persist(Block block)
snapshot.PersistingBlock = block;
if (block.Index > 0)
{
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.System, null, snapshot, 0, true))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.System, null, snapshot))
{
engine.LoadScript(onPersistNativeContractScript);
if (engine.Execute() != VMState.HALT) throw new InvalidOperationException();
Expand Down
2 changes: 1 addition & 1 deletion src/neo/Plugins/IApplicationEngineProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ namespace Neo.Plugins
{
public interface IApplicationEngineProvider
{
ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false);
ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas);
}
}
4 changes: 1 addition & 3 deletions src/neo/SmartContract/ApplicationEngine.Storage.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Neo.Ledger;
using Neo.SmartContract.Iterators;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Neo.SmartContract
Expand Down Expand Up @@ -67,8 +66,7 @@ protected internal IIterator Find(StorageContext context, byte[] prefix)
{
byte[] prefix_key = StorageKey.CreateSearchPrefix(context.Id, prefix);
StorageIterator iterator = new StorageIterator(Snapshot.Storages.Find(prefix_key).Where(p => p.Key.Key.AsSpan().StartsWith(prefix)).GetEnumerator());
disposables ??= new List<IDisposable>();
disposables.Add(iterator);
Disposables.Add(iterator);
return iterator;
}

Expand Down
42 changes: 23 additions & 19 deletions src/neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,47 @@ private class InvocationState
public bool NeedCheckReturnValue;
}

/// <summary>
/// This constant can be used for testing scripts, by default has the same value as max block system fee.
/// </summary>
private const long TestModeGas = 20_00000000;

public static event EventHandler<NotifyEventArgs> Notify;
public static event EventHandler<LogEventArgs> Log;

private static IApplicationEngineProvider applicationEngineProvider;
private static Dictionary<uint, InteropDescriptor> services;
private readonly long gas_amount;
private readonly bool testMode;
private List<NotifyEventArgs> notifications;
private List<IDisposable> disposables;
private readonly Dictionary<UInt160, int> invocationCounter = new Dictionary<UInt160, int>();
private readonly Dictionary<ExecutionContext, InvocationState> invocationStates = new Dictionary<ExecutionContext, InvocationState>();

public static IReadOnlyDictionary<uint, InteropDescriptor> Services => services;
private List<IDisposable> Disposables => disposables ??= new List<IDisposable>();
public TriggerType Trigger { get; }
public IVerifiable ScriptContainer { get; }
public StoreView Snapshot { get; }
public long GasConsumed { get; private set; } = 0;
public long GasLeft => testMode ? -1 : gas_amount - GasConsumed;
public long GasLeft => gas_amount - GasConsumed;
public Exception FaultException { get; private set; }
public UInt160 CurrentScriptHash => CurrentContext?.GetState<ExecutionContextState>().ScriptHash;
public UInt160 CallingScriptHash => CurrentContext?.GetState<ExecutionContextState>().CallingScriptHash;
public UInt160 EntryScriptHash => EntryContext?.GetState<ExecutionContextState>().ScriptHash;
public IReadOnlyList<NotifyEventArgs> Notifications => notifications ?? (IReadOnlyList<NotifyEventArgs>)Array.Empty<NotifyEventArgs>();

protected ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
protected ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas)
{
this.Trigger = trigger;
this.ScriptContainer = container;
this.Snapshot = snapshot;
this.gas_amount = gas;
this.testMode = testMode;
}

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

Expand Down Expand Up @@ -111,9 +115,11 @@ protected override void ContextUnloaded(ExecutionContext context)
}
}

public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
=> applicationEngineProvider?.Create(trigger, container, snapshot, gas, testMode)
?? new ApplicationEngine(trigger, container, snapshot, gas, testMode);
public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas = TestModeGas)
{
return applicationEngineProvider?.Create(trigger, container, snapshot, gas)
?? new ApplicationEngine(trigger, container, snapshot, gas);
}

private InvocationState GetInvocationState(ExecutionContext context)
{
Expand Down Expand Up @@ -281,24 +287,22 @@ internal static void ResetApplicationEngineProvider()
Exchange(ref applicationEngineProvider, null);
}

public static ApplicationEngine Run(byte[] script, StoreView snapshot,
IVerifiable container = null, Block persistingBlock = null, int offset = 0, bool testMode = false, long gas = default)
public static ApplicationEngine Run(byte[] script, StoreView snapshot = null, IVerifiable container = null, Block persistingBlock = null, int offset = 0, long gas = TestModeGas)
{
SnapshotView disposable = null;
if (snapshot is null)
{
disposable = Blockchain.Singleton.GetSnapshot();
snapshot = disposable;
}
snapshot.PersistingBlock = persistingBlock ?? snapshot.PersistingBlock ?? CreateDummyBlock(snapshot);
ApplicationEngine engine = Create(TriggerType.Application, container, snapshot, gas, testMode);
ApplicationEngine engine = Create(TriggerType.Application, container, snapshot, gas);
if (disposable != null) engine.Disposables.Add(disposable);
engine.LoadScript(script).InstructionPointer = offset;
engine.Execute();
return engine;
}

public static ApplicationEngine Run(byte[] script, IVerifiable container = null, Block persistingBlock = null, int offset = 0, bool testMode = false, long gas = default)
{
using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
{
return Run(script, snapshot, container, persistingBlock, offset, testMode, gas);
}
}

internal static bool SetApplicationEngineProvider(IApplicationEngineProvider provider)
{
return CompareExchange(ref applicationEngineProvider, provider, null) is null;
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/Native/NativeContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public ApplicationEngine TestCall(string operation, params object[] args)
using (ScriptBuilder sb = new ScriptBuilder())
{
sb.EmitAppCall(Hash, operation, args);
return ApplicationEngine.Run(sb.ToArray(), testMode: true);
return ApplicationEngine.Run(sb.ToArray());
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/neo/Wallets/Wallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public Transaction MakeTransaction(TransferOutput[] outputs, UInt160 from = null
using (ScriptBuilder sb2 = new ScriptBuilder())
{
sb2.EmitAppCall(assetId, "balanceOf", account);
using (ApplicationEngine engine = ApplicationEngine.Run(sb2.ToArray(), snapshot, testMode: true))
using (ApplicationEngine engine = ApplicationEngine.Run(sb2.ToArray(), snapshot))
{
if (engine.State.HasFlag(VMState.FAULT))
throw new InvalidOperationException($"Execution for {assetId.ToString()}.balanceOf('{account.ToString()}' fault");
Expand Down Expand Up @@ -346,7 +346,7 @@ private Transaction MakeTransaction(StoreView snapshot, byte[] script, Signer[]
};

// will try to execute 'transfer' script to check if it works
using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot.Clone(), tx, testMode: true))
using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot.Clone(), tx))
{
if (engine.State == VMState.FAULT)
{
Expand Down Expand Up @@ -383,7 +383,7 @@ public long CalculateNetworkFee(StoreView snapshot, Transaction tx)
ContractMethodDescriptor verify = contract.Manifest.Abi.GetMethod("verify");
if (verify is null) throw new ArgumentException($"The smart contract {contract.ScriptHash} haven't got verify method");
ContractMethodDescriptor init = contract.Manifest.Abi.GetMethod("_initialize");
using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.Clone(), 0, testMode: true);
using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.Clone());
engine.LoadScript(contract.Script, CallFlags.None).InstructionPointer = verify.Offset;
if (init != null) engine.LoadClonedContext(init.Offset);
engine.LoadScript(Array.Empty<byte>(), CallFlags.None);
Expand Down
2 changes: 1 addition & 1 deletion tests/neo.UnitTests/Extensions/NativeContractExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static StackItem Call(this NativeContract contract, StoreView snapshot, s

public static StackItem Call(this NativeContract contract, StoreView snapshot, IVerifiable container, string method, params ContractParameter[] args)
{
var engine = ApplicationEngine.Create(TriggerType.Application, container, snapshot, 0, true);
var engine = ApplicationEngine.Create(TriggerType.Application, container, snapshot);

engine.LoadScript(contract.Script);

Expand Down
12 changes: 6 additions & 6 deletions tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public ManualWitness(params UInt160[] hashForVerify)
public static bool Transfer(this NativeContract contract, StoreView snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom)
{
var engine = ApplicationEngine.Create(TriggerType.Application,
new ManualWitness(signFrom ? new UInt160(from) : null), snapshot, 0, true);
new ManualWitness(signFrom ? new UInt160(from) : null), snapshot);

engine.LoadScript(contract.Script);

Expand All @@ -64,7 +64,7 @@ public static bool Transfer(this NativeContract contract, StoreView snapshot, by

public static BigInteger TotalSupply(this NativeContract contract, StoreView snapshot)
{
var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

engine.LoadScript(contract.Script);

Expand All @@ -84,7 +84,7 @@ public static BigInteger TotalSupply(this NativeContract contract, StoreView sna

public static BigInteger BalanceOf(this NativeContract contract, StoreView snapshot, byte[] account)
{
var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

engine.LoadScript(contract.Script);

Expand All @@ -105,7 +105,7 @@ public static BigInteger BalanceOf(this NativeContract contract, StoreView snaps

public static BigInteger Decimals(this NativeContract contract)
{
var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, testMode: true);
var engine = ApplicationEngine.Create(TriggerType.Application, null, null);

engine.LoadScript(contract.Script);

Expand All @@ -125,7 +125,7 @@ public static BigInteger Decimals(this NativeContract contract)

public static string Symbol(this NativeContract contract)
{
var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, testMode: true);
var engine = ApplicationEngine.Create(TriggerType.Application, null, null);

engine.LoadScript(contract.Script);

Expand All @@ -145,7 +145,7 @@ public static string Symbol(this NativeContract contract)

public static string Name(this NativeContract contract)
{
var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, testMode: true);
var engine = ApplicationEngine.Create(TriggerType.Application, null, null);

engine.LoadScript(contract.Script);

Expand Down
14 changes: 7 additions & 7 deletions tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void FeeIsMultiSigContract()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
Expand Down Expand Up @@ -227,7 +227,7 @@ public void FeeIsSignatureContractDetailed()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
Expand Down Expand Up @@ -340,7 +340,7 @@ public void FeeIsSignatureContract_TestScope_Global()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
Expand Down Expand Up @@ -427,7 +427,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
Expand Down Expand Up @@ -517,7 +517,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
Expand Down Expand Up @@ -659,7 +659,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
Expand Down Expand Up @@ -1009,7 +1009,7 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
Expand Down
Loading