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

IApplicationEngineProvider #1758

Merged
merged 10 commits into from
Jul 11, 2020
Merged
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
4 changes: 2 additions & 2 deletions src/neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ private void Persist(Block block)
snapshot.PersistingBlock = block;
if (block.Index > 0)
{
using (ApplicationEngine engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0, true))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.System, null, snapshot, 0, true))
{
engine.LoadScript(onPersistNativeContractScript);
if (engine.Execute() != VMState.HALT) throw new InvalidOperationException();
Expand All @@ -434,7 +434,7 @@ private void Persist(Block block)
clonedSnapshot.Transactions.Add(tx.Hash, state);
clonedSnapshot.Transactions.Commit();

using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee))
{
engine.LoadScript(tx.Script);
state.VMState = engine.Execute();
Expand Down
11 changes: 11 additions & 0 deletions src/neo/Plugins/IApplicationEngineProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.SmartContract;

namespace Neo.Plugins
{
public interface IApplicationEngineProvider
{
ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Neo.Plugins
{
public interface IStoragePlugin
public interface IStorageProvider
{
IStore GetStore();
}
Expand Down
6 changes: 4 additions & 2 deletions src/neo/Plugins/Plugin.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Configuration;
using Neo.SmartContract;
using System;
using System.Collections.Generic;
using System.IO;
Expand All @@ -13,7 +14,7 @@ public abstract class Plugin : IDisposable
{
public static readonly List<Plugin> Plugins = new List<Plugin>();
internal static readonly List<ILogPlugin> Loggers = new List<ILogPlugin>();
internal static readonly Dictionary<string, IStoragePlugin> Storages = new Dictionary<string, IStoragePlugin>();
internal static readonly Dictionary<string, IStorageProvider> Storages = new Dictionary<string, IStorageProvider>();
internal static readonly List<IPersistencePlugin> PersistencePlugins = new List<IPersistencePlugin>();
internal static readonly List<IP2PPlugin> P2PPlugins = new List<IP2PPlugin>();
internal static readonly List<IMemoryPoolTxObserverPlugin> TxObserverPlugins = new List<IMemoryPoolTxObserverPlugin>();
Expand Down Expand Up @@ -50,10 +51,11 @@ protected Plugin()
Plugins.Add(this);

if (this is ILogPlugin logger) Loggers.Add(logger);
if (this is IStoragePlugin storage) Storages.Add(Name, storage);
if (this is IStorageProvider storage) Storages.Add(Name, storage);
if (this is IP2PPlugin p2p) P2PPlugins.Add(p2p);
if (this is IPersistencePlugin persistence) PersistencePlugins.Add(persistence);
if (this is IMemoryPoolTxObserverPlugin txObserver) TxObserverPlugins.Add(txObserver);
if (this is IApplicationEngineProvider provider) ApplicationEngine.SetApplicationEngineProvider(provider);

Configure();
}
Expand Down
21 changes: 19 additions & 2 deletions src/neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.Plugins;
using Neo.VM;
using Neo.VM.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Reflection;
using static System.Threading.Interlocked;
using Array = System.Array;
using VMArray = Neo.VM.Types.Array;

Expand All @@ -26,6 +28,7 @@ private class InvocationState
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;
Expand All @@ -46,7 +49,7 @@ private class InvocationState
public UInt160 EntryScriptHash => EntryContext?.GetState<ExecutionContextState>().ScriptHash;
public IReadOnlyList<NotifyEventArgs> Notifications => notifications ?? (IReadOnlyList<NotifyEventArgs>)Array.Empty<NotifyEventArgs>();

public ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
protected ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
{
this.Trigger = trigger;
this.ScriptContainer = container;
Expand Down Expand Up @@ -108,6 +111,10 @@ 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);

private InvocationState GetInvocationState(ExecutionContext context)
{
if (!invocationStates.TryGetValue(context, out InvocationState state))
Expand Down Expand Up @@ -266,11 +273,16 @@ private static InteropDescriptor Register(string name, string handler, long fixe
return descriptor;
}

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)
{
snapshot.PersistingBlock = persistingBlock ?? snapshot.PersistingBlock ?? CreateDummyBlock(snapshot);
ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, container, snapshot, gas, testMode);
ApplicationEngine engine = Create(TriggerType.Application, container, snapshot, gas, testMode);
engine.LoadScript(script).InstructionPointer = offset;
engine.Execute();
return engine;
Expand All @@ -283,5 +295,10 @@ public static ApplicationEngine Run(byte[] script, IVerifiable container = null,
return Run(script, snapshot, container, persistingBlock, offset, testMode, gas);
}
}

internal static bool SetApplicationEngineProvider(IApplicationEngineProvider provider)
{
return CompareExchange(ref applicationEngineProvider, provider, null) is null;
}
}
}
2 changes: 1 addition & 1 deletion src/neo/SmartContract/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap
if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return false;
offset = 0;
}
using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, verifiable, snapshot, gas))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot, gas))
{
engine.LoadScript(verification, CallFlags.ReadOnly).InstructionPointer = offset;
engine.LoadScript(verifiable.Witnesses[i].InvocationScript, 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 = new ApplicationEngine(TriggerType.Application, container, snapshot, 0, true);
var engine = ApplicationEngine.Create(TriggerType.Application, container, snapshot, 0, true);

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 @@ -42,7 +42,7 @@ public void SerializeUnsigned(BinaryWriter writer) { }

public static bool Transfer(this NativeContract contract, StoreView snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom)
{
var engine = new ApplicationEngine(TriggerType.Application,
var engine = ApplicationEngine.Create(TriggerType.Application,
new ManualWitness(signFrom ? new UInt160(from) : null), snapshot, 0, true);

engine.LoadScript(contract.Script);
Expand All @@ -69,7 +69,7 @@ public static bool Transfer(this NativeContract contract, StoreView snapshot, by

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

engine.LoadScript(contract.Script);

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

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

engine.LoadScript(contract.Script);

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

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

engine.LoadScript(contract.Script);

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

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

engine.LoadScript(contract.Script);

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

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

engine.LoadScript(contract.Script);

Expand Down
2 changes: 1 addition & 1 deletion tests/neo.UnitTests/Ledger/UT_MemoryPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public void BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered()
SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, sender);

ApplicationEngine applicationEngine = new ApplicationEngine(TriggerType.All, block, snapshot, (long)balance);
ApplicationEngine applicationEngine = ApplicationEngine.Create(TriggerType.All, block, snapshot, (long)balance);
NativeContract.GAS.Burn(applicationEngine, sender, balance);
NativeContract.GAS.Mint(applicationEngine, sender, txFee * 30); // Set the balance to meet 30 txs only

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 = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
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 = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
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 = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
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 = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
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 = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
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 = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
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 = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public void Check_BalanceOfTransferAndBurn()

// Burn

var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0);
keyCount = snapshot.Storages.GetChangeSet().Count();

Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
Expand Down Expand Up @@ -124,7 +124,7 @@ public void Check_BalanceOfTransferAndBurn()
[TestMethod]
public void Check_BadScript()
{
var engine = new ApplicationEngine(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
var engine = ApplicationEngine.Create(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);

var script = new ScriptBuilder();
script.Emit(OpCode.NOP);
Expand Down
12 changes: 6 additions & 6 deletions tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public void Check_Initialize()
[TestMethod]
public void Check_BadScript()
{
var engine = new ApplicationEngine(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
var engine = ApplicationEngine.Create(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);

var script = new ScriptBuilder();
script.Emit(OpCode.NOP);
Expand Down Expand Up @@ -424,7 +424,7 @@ public void TestVote()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
snapshot.PersistingBlock = Blockchain.GenesisBlock;
var engine = new ApplicationEngine(TriggerType.Application, Blockchain.GenesisBlock, snapshot, 0, true);
var engine = ApplicationEngine.Create(TriggerType.Application, Blockchain.GenesisBlock, snapshot, 0, true);
ScriptBuilder sb = new ScriptBuilder();
var tmp = engine.ScriptContainer.GetScriptHashesForVerifying(engine.Snapshot);
UInt160 from = engine.ScriptContainer.GetScriptHashesForVerifying(engine.Snapshot)[0];
Expand Down Expand Up @@ -455,7 +455,7 @@ public void TestVote()

internal static (bool State, bool Result) Check_Vote(StoreView snapshot, byte[] account, byte[] pubkey, bool signAccount)
{
var engine = new ApplicationEngine(TriggerType.Application,
var engine = ApplicationEngine.Create(TriggerType.Application,
new Nep5NativeContractExtensions.ManualWitness(signAccount ? new UInt160(account) : UInt160.Zero), snapshot, 0, true);

engine.LoadScript(NativeContract.NEO.Script);
Expand Down Expand Up @@ -485,7 +485,7 @@ internal static (bool State, bool Result) Check_Vote(StoreView snapshot, byte[]

internal static (bool State, bool Result) Check_RegisterValidator(StoreView snapshot, byte[] pubkey)
{
var engine = new ApplicationEngine(TriggerType.Application,
var engine = ApplicationEngine.Create(TriggerType.Application,
new Nep5NativeContractExtensions.ManualWitness(Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(pubkey, ECCurve.Secp256r1)).ToScriptHash()), snapshot, 0, true);

engine.LoadScript(NativeContract.NEO.Script);
Expand All @@ -510,7 +510,7 @@ internal static (bool State, bool Result) Check_RegisterValidator(StoreView snap

internal static ECPoint[] Check_GetValidators(StoreView snapshot)
{
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);

engine.LoadScript(NativeContract.NEO.Script);

Expand All @@ -530,7 +530,7 @@ internal static ECPoint[] Check_GetValidators(StoreView snapshot)

internal static (BigInteger Value, bool State) Check_UnclaimedGas(StoreView snapshot, byte[] address)
{
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);

engine.LoadScript(NativeContract.NEO.Script);

Expand Down
Loading