From 2a4f3cbe8027871b29a5fe93bcd03767f0a5051f Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Wed, 28 Oct 2020 11:36:14 +0800 Subject: [PATCH 01/18] Add Fee Ratio --- src/neo/Ledger/Blockchain.cs | 3 ++- src/neo/Network/P2P/Payloads/Transaction.cs | 2 +- src/neo/Network/P2P/Payloads/Witness.cs | 2 +- src/neo/SmartContract/ApplicationEngine.cs | 14 +++++++----- src/neo/SmartContract/Helper.cs | 12 ++++++---- .../SmartContract/Native/PolicyContract.cs | 19 ++++++++++++++++ src/neo/Wallets/Wallet.cs | 4 ++-- .../Network/P2P/Payloads/UT_Transaction.cs | 22 ++++++++++++++++++- 8 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index 8600414e06..dddfa09da4 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -446,6 +446,7 @@ private void Persist(Block block) all_application_executed.Add(application_executed); } snapshot.Blocks.Add(block.Hash, block.Trim()); + uint ratio = NativeContract.Policy.GetFeeRatio(snapshot); StoreView clonedSnapshot = snapshot.Clone(); // Warning: Do not write into variable snapshot directly. Write into variable clonedSnapshot and commit instead. foreach (Transaction tx in block.Transactions) @@ -459,7 +460,7 @@ private void Persist(Block block) clonedSnapshot.Transactions.Add(tx.Hash, state); clonedSnapshot.Transactions.Commit(); - using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee)) + using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee * ratio)) { engine.LoadScript(tx.Script); state.VMState = engine.Execute(); diff --git a/src/neo/Network/P2P/Payloads/Transaction.cs b/src/neo/Network/P2P/Payloads/Transaction.cs index 54860c6a86..d896b7126e 100644 --- a/src/neo/Network/P2P/Payloads/Transaction.cs +++ b/src/neo/Network/P2P/Payloads/Transaction.cs @@ -294,7 +294,7 @@ public virtual VerifyResult VerifyStateDependent(StoreView snapshot, Transaction foreach (TransactionAttribute attribute in Attributes) if (!attribute.Verify(snapshot, this)) return VerifyResult.Invalid; - long net_fee = NetworkFee - Size * NativeContract.Policy.GetFeePerByte(snapshot); + long net_fee = NetworkFee * NativeContract.Policy.GetFeeRatio(snapshot) - Size * NativeContract.Policy.GetFeePerByte(snapshot); if (!this.VerifyWitnesses(snapshot, net_fee, WitnessFlag.StateDependent)) return VerifyResult.Invalid; return VerifyResult.Succeed; diff --git a/src/neo/Network/P2P/Payloads/Witness.cs b/src/neo/Network/P2P/Payloads/Witness.cs index 7ae2d51d70..b6888c3cbb 100644 --- a/src/neo/Network/P2P/Payloads/Witness.cs +++ b/src/neo/Network/P2P/Payloads/Witness.cs @@ -22,7 +22,7 @@ public class Witness : ISerializable public byte[] InvocationScript; public byte[] VerificationScript; - internal long GasConsumed { get; set; } + internal long GasConsumedWithRatio { get; set; } private UInt160 _scriptHash; public virtual UInt160 ScriptHash diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs index b6eccabcf2..7916d4beb0 100644 --- a/src/neo/SmartContract/ApplicationEngine.cs +++ b/src/neo/SmartContract/ApplicationEngine.cs @@ -3,6 +3,7 @@ using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.Plugins; +using Neo.SmartContract.Native; using Neo.VM; using Neo.VM.Types; using System; @@ -42,7 +43,7 @@ private class InvocationState private static IApplicationEngineProvider applicationEngineProvider; private static Dictionary services; - private readonly long gas_amount; + private readonly long gas_amount_with_ratio; private List notifications; private List disposables; private readonly Dictionary invocationCounter = new Dictionary(); @@ -53,8 +54,9 @@ private class InvocationState public TriggerType Trigger { get; } public IVerifiable ScriptContainer { get; } public StoreView Snapshot { get; } - public long GasConsumed { get; private set; } = 0; - public long GasLeft => gas_amount - GasConsumed; + public long GasConsumedWithRatio = 0; + public long GasConsumed => GasConsumedWithRatio / NativeContract.Policy.GetFeeRatio(Snapshot); + public long GasLeft => (gas_amount_with_ratio - GasConsumedWithRatio) / NativeContract.Policy.GetFeeRatio(Snapshot); public Exception FaultException { get; private set; } public UInt160 CurrentScriptHash => CurrentContext?.GetScriptHash(); public UInt160 CallingScriptHash => CurrentContext?.GetState().CallingScriptHash; @@ -66,13 +68,13 @@ protected ApplicationEngine(TriggerType trigger, IVerifiable container, StoreVie this.Trigger = trigger; this.ScriptContainer = container; this.Snapshot = snapshot; - this.gas_amount = gas; + this.gas_amount_with_ratio = gas; } protected internal void AddGas(long gas) { - GasConsumed = checked(GasConsumed + gas); - if (GasConsumed > gas_amount) + GasConsumedWithRatio = checked(GasConsumedWithRatio + gas); + if (GasConsumedWithRatio > gas_amount_with_ratio) throw new InvalidOperationException("Insufficient GAS."); } diff --git a/src/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs index d3f841b84d..851909047c 100644 --- a/src/neo/SmartContract/Helper.cs +++ b/src/neo/SmartContract/Helper.cs @@ -133,7 +133,11 @@ public static UInt160 ToScriptHash(this ReadOnlySpan script) internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All) { if (gas < 0) return false; - if (gas > MaxVerificationGas) gas = MaxVerificationGas; + if (snapshot == null) + { + gas = MaxVerificationGas; + } + else if (gas > MaxVerificationGas) gas = MaxVerificationGas; UInt160[] hashes; try @@ -150,7 +154,7 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap WitnessFlag flag = verifiable.Witnesses[i].StateDependent ? WitnessFlag.StateDependent : WitnessFlag.StateIndependent; if (!filter.HasFlag(flag)) { - gas -= verifiable.Witnesses[i].GasConsumed; + gas -= verifiable.Witnesses[i].GasConsumedWithRatio; if (gas < 0) return false; continue; } @@ -192,8 +196,8 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None); if (engine.Execute() == VMState.FAULT) return false; if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return false; - gas -= engine.GasConsumed; - verifiable.Witnesses[i].GasConsumed = engine.GasConsumed; + gas -= engine.GasConsumedWithRatio; + verifiable.Witnesses[i].GasConsumedWithRatio = engine.GasConsumedWithRatio; } } return true; diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs index 1002debb7c..5b9f4adc8c 100644 --- a/src/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -20,6 +20,7 @@ public sealed class PolicyContract : NativeContract private const byte Prefix_BlockedAccount = 15; private const byte Prefix_MaxBlockSize = 12; private const byte Prefix_MaxBlockSystemFee = 17; + private const byte Prefix_FeeRatio = 34; public PolicyContract() { @@ -64,6 +65,14 @@ public bool IsBlocked(StoreView snapshot, UInt160 account) return snapshot.Storages.Contains(CreateStorageKey(Prefix_BlockedAccount).Add(account)); } + [ContractMethod(0_01000000, CallFlags.AllowStates)] + public uint GetFeeRatio(StoreView snapshot) + { + StorageItem item = snapshot.Storages.TryGet(CreateStorageKey(Prefix_FeeRatio)); + if (item is null) return 1; + return (uint)(BigInteger)item; + } + [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] private bool SetMaxBlockSize(ApplicationEngine engine, uint value) { @@ -127,5 +136,15 @@ private bool UnblockAccount(ApplicationEngine engine, UInt160 account) engine.Snapshot.Storages.Delete(key); return true; } + + [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] + private bool SetFeeRatio(ApplicationEngine engine, uint value) + { + if (value == 0) throw new ArgumentOutOfRangeException(nameof(value)); + if (!CheckCommittee(engine)) return false; + StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_FeeRatio), () => new StorageItem()); + storage.Set(value); + return true; + } } } diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index 614688f768..4dd8d1970f 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -405,7 +405,7 @@ public long CalculateNetworkFee(StoreView snapshot, Transaction tx) if (engine.Execute() == VMState.FAULT) throw new ArgumentException($"Smart contract {contract.ScriptHash} verification fault."); if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) throw new ArgumentException($"Smart contract {contract.ScriptHash} returns false."); - networkFee += engine.GasConsumed; + networkFee += engine.GasConsumedWithRatio; } else if (witness_script.IsSignatureContract()) { @@ -430,7 +430,7 @@ public long CalculateNetworkFee(StoreView snapshot, Transaction tx) } } networkFee += size * NativeContract.Policy.GetFeePerByte(snapshot); - return networkFee; + return networkFee / NativeContract.Policy.GetFeeRatio(snapshot); } public bool Sign(ContractParametersContext context) diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index c8e4c4e028..7574270720 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -5,6 +5,7 @@ using Neo.IO.Json; using Neo.Ledger; using Neo.Network.P2P.Payloads; +using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.SmartContract.Native.Tokens; @@ -1260,9 +1261,15 @@ public void Test_Verify() var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash); var entry = snapshot.Storages.GetAndChange(key, () => new StorageItem(new AccountState())); - entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; + entry.GetInteroperable().Balance = NativeContract.GAS.Factor / 10; + + snapshot.Commit(); + //Change FeeRatio + StorageItem storage = snapshot.Storages.GetAndChange(new KeyBuilder(-3, 34), () => new StorageItem()); + storage.Set(2); snapshot.Commit(); + NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(2); // Make transaction @@ -1285,6 +1292,19 @@ public void Test_Verify() tx.Witnesses = data.GetWitnesses(); tx.Verify(snapshot, new TransactionVerificationContext()).Should().Be(VerifyResult.Succeed); + + using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, tx.SystemFee * NativeContract.Policy.GetFeeRatio(snapshot))) + { + engine.LoadScript(tx.Script); + VMState state = engine.Execute(); + Assert.AreEqual(state, VMState.HALT); + } + + //Revert FeeRatio + storage = snapshot.Storages.GetAndChange(new KeyBuilder(-3, 34), () => new StorageItem()); + storage.Set(1); + snapshot.Commit(); + NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(1); } } } From 36305112e2d5c131399fcf06fd3110e88df23c37 Mon Sep 17 00:00:00 2001 From: Tommo-L Date: Wed, 28 Oct 2020 15:12:25 +0800 Subject: [PATCH 02/18] optimize --- src/neo/SmartContract/Helper.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs index 851909047c..e101939687 100644 --- a/src/neo/SmartContract/Helper.cs +++ b/src/neo/SmartContract/Helper.cs @@ -133,10 +133,7 @@ public static UInt160 ToScriptHash(this ReadOnlySpan script) internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All) { if (gas < 0) return false; - if (snapshot == null) - { - gas = MaxVerificationGas; - } + if (snapshot is null) gas = MaxVerificationGas; else if (gas > MaxVerificationGas) gas = MaxVerificationGas; UInt160[] hashes; From fe9d3e1cbce751fc2e066af1ce998fb2fe646f08 Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Thu, 29 Oct 2020 11:55:47 +0800 Subject: [PATCH 03/18] Set ratio range --- src/neo/Ledger/Blockchain.cs | 2 +- src/neo/Network/P2P/Payloads/Transaction.cs | 2 +- src/neo/SmartContract/ApplicationEngine.cs | 4 ++-- src/neo/SmartContract/Native/PolicyContract.cs | 7 +++++-- src/neo/Wallets/Wallet.cs | 2 +- .../Network/P2P/Payloads/UT_Transaction.cs | 10 +++++----- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index dddfa09da4..e1cc1bd1c0 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -460,7 +460,7 @@ private void Persist(Block block) clonedSnapshot.Transactions.Add(tx.Hash, state); clonedSnapshot.Transactions.Commit(); - using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee * ratio)) + using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee * PolicyContract.MaximumRatioVariety / ratio)) { engine.LoadScript(tx.Script); state.VMState = engine.Execute(); diff --git a/src/neo/Network/P2P/Payloads/Transaction.cs b/src/neo/Network/P2P/Payloads/Transaction.cs index d896b7126e..91b41933c3 100644 --- a/src/neo/Network/P2P/Payloads/Transaction.cs +++ b/src/neo/Network/P2P/Payloads/Transaction.cs @@ -294,7 +294,7 @@ public virtual VerifyResult VerifyStateDependent(StoreView snapshot, Transaction foreach (TransactionAttribute attribute in Attributes) if (!attribute.Verify(snapshot, this)) return VerifyResult.Invalid; - long net_fee = NetworkFee * NativeContract.Policy.GetFeeRatio(snapshot) - Size * NativeContract.Policy.GetFeePerByte(snapshot); + long net_fee = (NetworkFee * PolicyContract.MaximumRatioVariety / NativeContract.Policy.GetFeeRatio(snapshot)) - (Size * NativeContract.Policy.GetFeePerByte(snapshot)); if (!this.VerifyWitnesses(snapshot, net_fee, WitnessFlag.StateDependent)) return VerifyResult.Invalid; return VerifyResult.Succeed; diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs index 7916d4beb0..8cb95e5928 100644 --- a/src/neo/SmartContract/ApplicationEngine.cs +++ b/src/neo/SmartContract/ApplicationEngine.cs @@ -55,8 +55,8 @@ private class InvocationState public IVerifiable ScriptContainer { get; } public StoreView Snapshot { get; } public long GasConsumedWithRatio = 0; - public long GasConsumed => GasConsumedWithRatio / NativeContract.Policy.GetFeeRatio(Snapshot); - public long GasLeft => (gas_amount_with_ratio - GasConsumedWithRatio) / NativeContract.Policy.GetFeeRatio(Snapshot); + public long GasConsumed => GasConsumedWithRatio * NativeContract.Policy.GetFeeRatio(Snapshot) / PolicyContract.MaximumRatioVariety; + public long GasLeft => (gas_amount_with_ratio - GasConsumedWithRatio) * NativeContract.Policy.GetFeeRatio(Snapshot) / PolicyContract.MaximumRatioVariety; public Exception FaultException { get; private set; } public UInt160 CurrentScriptHash => CurrentContext?.GetScriptHash(); public UInt160 CallingScriptHash => CurrentContext?.GetState().CallingScriptHash; diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs index 5b9f4adc8c..66f93629c8 100644 --- a/src/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -15,6 +15,9 @@ public sealed class PolicyContract : NativeContract public override string Name => "Policy"; public override int Id => -3; + public const uint MaximumRatioVariety = 100; + private const uint MaximumRatio = MaximumRatioVariety * MaximumRatioVariety; + private const byte Prefix_MaxTransactionsPerBlock = 23; private const byte Prefix_FeePerByte = 10; private const byte Prefix_BlockedAccount = 15; @@ -69,7 +72,7 @@ public bool IsBlocked(StoreView snapshot, UInt160 account) public uint GetFeeRatio(StoreView snapshot) { StorageItem item = snapshot.Storages.TryGet(CreateStorageKey(Prefix_FeeRatio)); - if (item is null) return 1; + if (item is null) return 100; return (uint)(BigInteger)item; } @@ -140,7 +143,7 @@ private bool UnblockAccount(ApplicationEngine engine, UInt160 account) [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] private bool SetFeeRatio(ApplicationEngine engine, uint value) { - if (value == 0) throw new ArgumentOutOfRangeException(nameof(value)); + if (value == 0 || value > MaximumRatio) throw new ArgumentOutOfRangeException(nameof(value)); if (!CheckCommittee(engine)) return false; StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_FeeRatio), () => new StorageItem()); storage.Set(value); diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index ad23393c95..f70b90ecd1 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -431,7 +431,7 @@ public long CalculateNetworkFee(StoreView snapshot, Transaction tx) } } networkFee += size * NativeContract.Policy.GetFeePerByte(snapshot); - return networkFee / NativeContract.Policy.GetFeeRatio(snapshot); + return networkFee * NativeContract.Policy.GetFeeRatio(snapshot) / PolicyContract.MaximumRatioVariety; } public bool Sign(ContractParametersContext context) diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index 7574270720..ae23b91d1e 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -1267,9 +1267,9 @@ public void Test_Verify() //Change FeeRatio StorageItem storage = snapshot.Storages.GetAndChange(new KeyBuilder(-3, 34), () => new StorageItem()); - storage.Set(2); + storage.Set(50); snapshot.Commit(); - NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(2); + NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(50); // Make transaction @@ -1293,7 +1293,7 @@ public void Test_Verify() tx.Witnesses = data.GetWitnesses(); tx.Verify(snapshot, new TransactionVerificationContext()).Should().Be(VerifyResult.Succeed); - using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, tx.SystemFee * NativeContract.Policy.GetFeeRatio(snapshot))) + using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, tx.SystemFee * PolicyContract.MaximumRatioVariety / NativeContract.Policy.GetFeeRatio(snapshot))) { engine.LoadScript(tx.Script); VMState state = engine.Execute(); @@ -1302,9 +1302,9 @@ public void Test_Verify() //Revert FeeRatio storage = snapshot.Storages.GetAndChange(new KeyBuilder(-3, 34), () => new StorageItem()); - storage.Set(1); + storage.Set(100); snapshot.Commit(); - NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(1); + NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(100); } } } From 79702008362171b4e22d5a4970fff6e27447949f Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Tue, 3 Nov 2020 14:52:48 +0800 Subject: [PATCH 04/18] Redefine all prices --- src/neo/Ledger/Blockchain.cs | 2 +- src/neo/Network/P2P/Payloads/BlockBase.cs | 2 +- .../Network/P2P/Payloads/ConsensusPayload.cs | 2 +- src/neo/Network/P2P/Payloads/Transaction.cs | 2 +- .../SmartContract/ApplicationEngine.Binary.cs | 12 +- .../ApplicationEngine.Blockchain.cs | 12 +- .../ApplicationEngine.Callback.cs | 8 +- .../ApplicationEngine.Contract.cs | 12 +- .../SmartContract/ApplicationEngine.Crypto.cs | 6 +- .../ApplicationEngine.Enumerator.cs | 8 +- .../ApplicationEngine.Iterator.cs | 10 +- .../SmartContract/ApplicationEngine.Json.cs | 4 +- .../ApplicationEngine.OpCodePrices.cs | 364 +++++++++--------- .../ApplicationEngine.Runtime.cs | 26 +- .../ApplicationEngine.Storage.cs | 12 +- src/neo/SmartContract/ApplicationEngine.cs | 6 +- src/neo/SmartContract/Helper.cs | 2 +- .../Native/Designate/DesignateContract.cs | 2 +- .../Native/Oracle/OracleContract.cs | 6 +- .../SmartContract/Native/PolicyContract.cs | 34 +- .../SmartContract/Native/Tokens/NeoToken.cs | 18 +- .../SmartContract/Native/Tokens/Nep5Token.cs | 6 +- src/neo/Wallets/AssetDescriptor.cs | 2 +- src/neo/Wallets/Wallet.cs | 4 +- .../Network/P2P/Payloads/UT_Transaction.cs | 48 +-- .../SmartContract/Native/UT_PolicyContract.cs | 4 +- .../SmartContract/UT_InteropPrices.cs | 15 +- .../SmartContract/UT_SmartContractHelper.cs | 6 +- .../SmartContract/UT_Syscalls.cs | 7 +- 29 files changed, 321 insertions(+), 321 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index 160733ce19..c05f5e7e27 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -460,7 +460,7 @@ private void Persist(Block block) clonedSnapshot.Transactions.Add(tx.Hash, state); clonedSnapshot.Transactions.Commit(); - using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee * PolicyContract.MaximumRatioVariety / ratio)) + using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee / ratio)) { engine.LoadScript(tx.Script); state.VMState = engine.Execute(); diff --git a/src/neo/Network/P2P/Payloads/BlockBase.cs b/src/neo/Network/P2P/Payloads/BlockBase.cs index b724f5e074..3465032ebd 100644 --- a/src/neo/Network/P2P/Payloads/BlockBase.cs +++ b/src/neo/Network/P2P/Payloads/BlockBase.cs @@ -118,7 +118,7 @@ public virtual bool Verify(StoreView snapshot) if (prev_header == null) return false; if (prev_header.Index + 1 != Index) return false; if (prev_header.Timestamp >= Timestamp) return false; - if (!this.VerifyWitnesses(snapshot, 1_00000000)) return false; + if (!this.VerifyWitnesses(snapshot, 0_03333333)) return false; return true; } } diff --git a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs index dbf2732fbc..80e2f40ffb 100644 --- a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs +++ b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs @@ -124,7 +124,7 @@ public bool Verify(StoreView snapshot) { if (BlockIndex <= snapshot.Height) return false; - return this.VerifyWitnesses(snapshot, 0_02000000); + return this.VerifyWitnesses(snapshot, 0_00066667); } } } diff --git a/src/neo/Network/P2P/Payloads/Transaction.cs b/src/neo/Network/P2P/Payloads/Transaction.cs index 91b41933c3..f050b9fca7 100644 --- a/src/neo/Network/P2P/Payloads/Transaction.cs +++ b/src/neo/Network/P2P/Payloads/Transaction.cs @@ -294,7 +294,7 @@ public virtual VerifyResult VerifyStateDependent(StoreView snapshot, Transaction foreach (TransactionAttribute attribute in Attributes) if (!attribute.Verify(snapshot, this)) return VerifyResult.Invalid; - long net_fee = (NetworkFee * PolicyContract.MaximumRatioVariety / NativeContract.Policy.GetFeeRatio(snapshot)) - (Size * NativeContract.Policy.GetFeePerByte(snapshot)); + long net_fee = (NetworkFee / NativeContract.Policy.GetFeeRatio(snapshot)) - (Size * NativeContract.Policy.GetFeePerByte(snapshot)); if (!this.VerifyWitnesses(snapshot, net_fee, WitnessFlag.StateDependent)) return VerifyResult.Invalid; return VerifyResult.Succeed; diff --git a/src/neo/SmartContract/ApplicationEngine.Binary.cs b/src/neo/SmartContract/ApplicationEngine.Binary.cs index 263fe3d49f..5050398358 100644 --- a/src/neo/SmartContract/ApplicationEngine.Binary.cs +++ b/src/neo/SmartContract/ApplicationEngine.Binary.cs @@ -6,12 +6,12 @@ namespace Neo.SmartContract { partial class ApplicationEngine { - public static readonly InteropDescriptor System_Binary_Serialize = Register("System.Binary.Serialize", nameof(BinarySerialize), 0_00100000, CallFlags.None, true); - public static readonly InteropDescriptor System_Binary_Deserialize = Register("System.Binary.Deserialize", nameof(BinaryDeserialize), 0_00500000, CallFlags.None, true); - public static readonly InteropDescriptor System_Binary_Base64Encode = Register("System.Binary.Base64Encode", nameof(Base64Encode), 0_00100000, CallFlags.None, true); - public static readonly InteropDescriptor System_Binary_Base64Decode = Register("System.Binary.Base64Decode", nameof(Base64Decode), 0_00100000, CallFlags.None, true); - public static readonly InteropDescriptor System_Binary_Base58Encode = Register("System.Binary.Base58Encode", nameof(Base58Encode), 0_00100000, CallFlags.None, true); - public static readonly InteropDescriptor System_Binary_Base58Decode = Register("System.Binary.Base58Decode", nameof(Base58Decode), 0_00100000, CallFlags.None, true); + public static readonly InteropDescriptor System_Binary_Serialize = Register("System.Binary.Serialize", nameof(BinarySerialize), 0_00003333, CallFlags.None, true); + public static readonly InteropDescriptor System_Binary_Deserialize = Register("System.Binary.Deserialize", nameof(BinaryDeserialize), 0_00016667, CallFlags.None, true); + public static readonly InteropDescriptor System_Binary_Base64Encode = Register("System.Binary.Base64Encode", nameof(Base64Encode), 0_00003333, CallFlags.None, true); + public static readonly InteropDescriptor System_Binary_Base64Decode = Register("System.Binary.Base64Decode", nameof(Base64Decode), 0_00003333, CallFlags.None, true); + public static readonly InteropDescriptor System_Binary_Base58Encode = Register("System.Binary.Base58Encode", nameof(Base58Encode), 0_00003333, CallFlags.None, true); + public static readonly InteropDescriptor System_Binary_Base58Decode = Register("System.Binary.Base58Decode", nameof(Base58Decode), 0_00003333, CallFlags.None, true); protected internal byte[] BinarySerialize(StackItem item) { diff --git a/src/neo/SmartContract/ApplicationEngine.Blockchain.cs b/src/neo/SmartContract/ApplicationEngine.Blockchain.cs index dad192c29f..c1aa65a0ba 100644 --- a/src/neo/SmartContract/ApplicationEngine.Blockchain.cs +++ b/src/neo/SmartContract/ApplicationEngine.Blockchain.cs @@ -10,12 +10,12 @@ partial class ApplicationEngine { public const uint MaxTraceableBlocks = Transaction.MaxValidUntilBlockIncrement; - public static readonly InteropDescriptor System_Blockchain_GetHeight = Register("System.Blockchain.GetHeight", nameof(GetBlockchainHeight), 0_00000400, CallFlags.AllowStates, true); - public static readonly InteropDescriptor System_Blockchain_GetBlock = Register("System.Blockchain.GetBlock", nameof(GetBlock), 0_02500000, CallFlags.AllowStates, true); - public static readonly InteropDescriptor System_Blockchain_GetTransaction = Register("System.Blockchain.GetTransaction", nameof(GetTransaction), 0_01000000, CallFlags.AllowStates, true); - public static readonly InteropDescriptor System_Blockchain_GetTransactionHeight = Register("System.Blockchain.GetTransactionHeight", nameof(GetTransactionHeight), 0_01000000, CallFlags.AllowStates, true); - public static readonly InteropDescriptor System_Blockchain_GetTransactionFromBlock = Register("System.Blockchain.GetTransactionFromBlock", nameof(GetTransactionFromBlock), 0_01000000, CallFlags.AllowStates, true); - public static readonly InteropDescriptor System_Blockchain_GetContract = Register("System.Blockchain.GetContract", nameof(GetContract), 0_01000000, CallFlags.AllowStates, true); + public static readonly InteropDescriptor System_Blockchain_GetHeight = Register("System.Blockchain.GetHeight", nameof(GetBlockchainHeight), 0_00000013, CallFlags.AllowStates, true); + public static readonly InteropDescriptor System_Blockchain_GetBlock = Register("System.Blockchain.GetBlock", nameof(GetBlock), 0_00083333, CallFlags.AllowStates, true); + public static readonly InteropDescriptor System_Blockchain_GetTransaction = Register("System.Blockchain.GetTransaction", nameof(GetTransaction), 0_00033333, CallFlags.AllowStates, true); + public static readonly InteropDescriptor System_Blockchain_GetTransactionHeight = Register("System.Blockchain.GetTransactionHeight", nameof(GetTransactionHeight), 0_00033333, CallFlags.AllowStates, true); + public static readonly InteropDescriptor System_Blockchain_GetTransactionFromBlock = Register("System.Blockchain.GetTransactionFromBlock", nameof(GetTransactionFromBlock), 0_00033333, CallFlags.AllowStates, true); + public static readonly InteropDescriptor System_Blockchain_GetContract = Register("System.Blockchain.GetContract", nameof(GetContract), 0_00033333, CallFlags.AllowStates, true); protected internal uint GetBlockchainHeight() { diff --git a/src/neo/SmartContract/ApplicationEngine.Callback.cs b/src/neo/SmartContract/ApplicationEngine.Callback.cs index 10e4191b3d..7d2e8fb83a 100644 --- a/src/neo/SmartContract/ApplicationEngine.Callback.cs +++ b/src/neo/SmartContract/ApplicationEngine.Callback.cs @@ -7,10 +7,10 @@ namespace Neo.SmartContract { partial class ApplicationEngine { - public static readonly InteropDescriptor System_Callback_Create = Register("System.Callback.Create", nameof(CreateCallback), 0_00000400, CallFlags.None, false); - public static readonly InteropDescriptor System_Callback_CreateFromMethod = Register("System.Callback.CreateFromMethod", nameof(CreateCallbackFromMethod), 0_01000000, CallFlags.None, false); - public static readonly InteropDescriptor System_Callback_CreateFromSyscall = Register("System.Callback.CreateFromSyscall", nameof(CreateCallbackFromSyscall), 0_00000400, CallFlags.None, false); - public static readonly InteropDescriptor System_Callback_Invoke = Register("System.Callback.Invoke", nameof(InvokeCallback), 0_01000000, CallFlags.None, false); + public static readonly InteropDescriptor System_Callback_Create = Register("System.Callback.Create", nameof(CreateCallback), 0_00000013, CallFlags.None, false); + public static readonly InteropDescriptor System_Callback_CreateFromMethod = Register("System.Callback.CreateFromMethod", nameof(CreateCallbackFromMethod), 0_00033333, CallFlags.None, false); + public static readonly InteropDescriptor System_Callback_CreateFromSyscall = Register("System.Callback.CreateFromSyscall", nameof(CreateCallbackFromSyscall), 0_00000013, CallFlags.None, false); + public static readonly InteropDescriptor System_Callback_Invoke = Register("System.Callback.Invoke", nameof(InvokeCallback), 0_00033333, CallFlags.None, false); protected internal void InvokeCallback(CallbackBase callback, Array args) { diff --git a/src/neo/SmartContract/ApplicationEngine.Contract.cs b/src/neo/SmartContract/ApplicationEngine.Contract.cs index 2c69660fee..8a80bd87a8 100644 --- a/src/neo/SmartContract/ApplicationEngine.Contract.cs +++ b/src/neo/SmartContract/ApplicationEngine.Contract.cs @@ -17,16 +17,16 @@ partial class ApplicationEngine public static readonly InteropDescriptor System_Contract_Create = Register("System.Contract.Create", nameof(CreateContract), 0, CallFlags.AllowModifyStates, false); public static readonly InteropDescriptor System_Contract_Update = Register("System.Contract.Update", nameof(UpdateContract), 0, CallFlags.AllowModifyStates, false); - public static readonly InteropDescriptor System_Contract_Destroy = Register("System.Contract.Destroy", nameof(DestroyContract), 0_01000000, CallFlags.AllowModifyStates, false); - public static readonly InteropDescriptor System_Contract_Call = Register("System.Contract.Call", nameof(CallContract), 0_01000000, CallFlags.AllowCall, false); - public static readonly InteropDescriptor System_Contract_CallEx = Register("System.Contract.CallEx", nameof(CallContractEx), 0_01000000, CallFlags.AllowCall, false); - public static readonly InteropDescriptor System_Contract_IsStandard = Register("System.Contract.IsStandard", nameof(IsStandardContract), 0_00030000, CallFlags.AllowStates, true); - public static readonly InteropDescriptor System_Contract_GetCallFlags = Register("System.Contract.GetCallFlags", nameof(GetCallFlags), 0_00030000, CallFlags.None, false); + public static readonly InteropDescriptor System_Contract_Destroy = Register("System.Contract.Destroy", nameof(DestroyContract), 0_00033333, CallFlags.AllowModifyStates, false); + public static readonly InteropDescriptor System_Contract_Call = Register("System.Contract.Call", nameof(CallContract), 0_00033333, CallFlags.AllowCall, false); + public static readonly InteropDescriptor System_Contract_CallEx = Register("System.Contract.CallEx", nameof(CallContractEx), 0_00033333, CallFlags.AllowCall, false); + public static readonly InteropDescriptor System_Contract_IsStandard = Register("System.Contract.IsStandard", nameof(IsStandardContract), 0_00001000, CallFlags.AllowStates, true); + public static readonly InteropDescriptor System_Contract_GetCallFlags = Register("System.Contract.GetCallFlags", nameof(GetCallFlags), 0_00001000, CallFlags.None, false); /// /// Calculate corresponding account scripthash for given public key /// Warning: check first that input public key is valid, before creating the script. /// - public static readonly InteropDescriptor System_Contract_CreateStandardAccount = Register("System.Contract.CreateStandardAccount", nameof(CreateStandardAccount), 0_00010000, CallFlags.None, true); + public static readonly InteropDescriptor System_Contract_CreateStandardAccount = Register("System.Contract.CreateStandardAccount", nameof(CreateStandardAccount), 0_00000333, CallFlags.None, true); protected internal void CreateContract(byte[] script, byte[] manifest) { diff --git a/src/neo/SmartContract/ApplicationEngine.Crypto.cs b/src/neo/SmartContract/ApplicationEngine.Crypto.cs index 2c7a312855..750b4b4625 100644 --- a/src/neo/SmartContract/ApplicationEngine.Crypto.cs +++ b/src/neo/SmartContract/ApplicationEngine.Crypto.cs @@ -9,10 +9,10 @@ namespace Neo.SmartContract { partial class ApplicationEngine { - public const long ECDsaVerifyPrice = 0_01000000; + public const long ECDsaVerifyPrice = 0_00033333; - public static readonly InteropDescriptor Neo_Crypto_RIPEMD160 = Register("Neo.Crypto.RIPEMD160", nameof(RIPEMD160), 0_01000000, CallFlags.None, true); - public static readonly InteropDescriptor Neo_Crypto_SHA256 = Register("Neo.Crypto.SHA256", nameof(Sha256), 0_01000000, CallFlags.None, true); + public static readonly InteropDescriptor Neo_Crypto_RIPEMD160 = Register("Neo.Crypto.RIPEMD160", nameof(RIPEMD160), 0_00033333, CallFlags.None, true); + public static readonly InteropDescriptor Neo_Crypto_SHA256 = Register("Neo.Crypto.SHA256", nameof(Sha256), 0_00033333, CallFlags.None, true); public static readonly InteropDescriptor Neo_Crypto_VerifyWithECDsaSecp256r1 = Register("Neo.Crypto.VerifyWithECDsaSecp256r1", nameof(VerifyWithECDsaSecp256r1), ECDsaVerifyPrice, CallFlags.None, true); public static readonly InteropDescriptor Neo_Crypto_VerifyWithECDsaSecp256k1 = Register("Neo.Crypto.VerifyWithECDsaSecp256k1", nameof(VerifyWithECDsaSecp256k1), ECDsaVerifyPrice, CallFlags.None, true); public static readonly InteropDescriptor Neo_Crypto_CheckMultisigWithECDsaSecp256r1 = Register("Neo.Crypto.CheckMultisigWithECDsaSecp256r1", nameof(CheckMultisigWithECDsaSecp256r1), 0, CallFlags.None, true); diff --git a/src/neo/SmartContract/ApplicationEngine.Enumerator.cs b/src/neo/SmartContract/ApplicationEngine.Enumerator.cs index 4a53381038..b31091aacf 100644 --- a/src/neo/SmartContract/ApplicationEngine.Enumerator.cs +++ b/src/neo/SmartContract/ApplicationEngine.Enumerator.cs @@ -8,10 +8,10 @@ namespace Neo.SmartContract { partial class ApplicationEngine { - public static readonly InteropDescriptor System_Enumerator_Create = Register("System.Enumerator.Create", nameof(CreateEnumerator), 0_00000400, CallFlags.None, false); - public static readonly InteropDescriptor System_Enumerator_Next = Register("System.Enumerator.Next", nameof(EnumeratorNext), 0_01000000, CallFlags.None, false); - public static readonly InteropDescriptor System_Enumerator_Value = Register("System.Enumerator.Value", nameof(EnumeratorValue), 0_00000400, CallFlags.None, false); - public static readonly InteropDescriptor System_Enumerator_Concat = Register("System.Enumerator.Concat", nameof(ConcatEnumerators), 0_00000400, CallFlags.None, false); + public static readonly InteropDescriptor System_Enumerator_Create = Register("System.Enumerator.Create", nameof(CreateEnumerator), 0_00000013, CallFlags.None, false); + public static readonly InteropDescriptor System_Enumerator_Next = Register("System.Enumerator.Next", nameof(EnumeratorNext), 0_00033333, CallFlags.None, false); + public static readonly InteropDescriptor System_Enumerator_Value = Register("System.Enumerator.Value", nameof(EnumeratorValue), 0_00000013, CallFlags.None, false); + public static readonly InteropDescriptor System_Enumerator_Concat = Register("System.Enumerator.Concat", nameof(ConcatEnumerators), 0_00000013, CallFlags.None, false); protected internal IEnumerator CreateEnumerator(StackItem item) { diff --git a/src/neo/SmartContract/ApplicationEngine.Iterator.cs b/src/neo/SmartContract/ApplicationEngine.Iterator.cs index 66d5edf085..55de5a219d 100644 --- a/src/neo/SmartContract/ApplicationEngine.Iterator.cs +++ b/src/neo/SmartContract/ApplicationEngine.Iterator.cs @@ -8,11 +8,11 @@ namespace Neo.SmartContract { partial class ApplicationEngine { - public static readonly InteropDescriptor System_Iterator_Create = Register("System.Iterator.Create", nameof(CreateIterator), 0_00000400, CallFlags.None, false); - public static readonly InteropDescriptor System_Iterator_Key = Register("System.Iterator.Key", nameof(IteratorKey), 0_00000400, CallFlags.None, false); - public static readonly InteropDescriptor System_Iterator_Keys = Register("System.Iterator.Keys", nameof(IteratorKeys), 0_00000400, CallFlags.None, false); - public static readonly InteropDescriptor System_Iterator_Values = Register("System.Iterator.Values", nameof(IteratorValues), 0_00000400, CallFlags.None, false); - public static readonly InteropDescriptor System_Iterator_Concat = Register("System.Iterator.Concat", nameof(ConcatIterators), 0_00000400, CallFlags.None, false); + public static readonly InteropDescriptor System_Iterator_Create = Register("System.Iterator.Create", nameof(CreateIterator), 0_00000013, CallFlags.None, false); + public static readonly InteropDescriptor System_Iterator_Key = Register("System.Iterator.Key", nameof(IteratorKey), 0_00000013, CallFlags.None, false); + public static readonly InteropDescriptor System_Iterator_Keys = Register("System.Iterator.Keys", nameof(IteratorKeys), 0_00000013, CallFlags.None, false); + public static readonly InteropDescriptor System_Iterator_Values = Register("System.Iterator.Values", nameof(IteratorValues), 0_00000013, CallFlags.None, false); + public static readonly InteropDescriptor System_Iterator_Concat = Register("System.Iterator.Concat", nameof(ConcatIterators), 0_00000013, CallFlags.None, false); protected internal IIterator CreateIterator(StackItem item) { diff --git a/src/neo/SmartContract/ApplicationEngine.Json.cs b/src/neo/SmartContract/ApplicationEngine.Json.cs index 48ff632123..b68d17773d 100644 --- a/src/neo/SmartContract/ApplicationEngine.Json.cs +++ b/src/neo/SmartContract/ApplicationEngine.Json.cs @@ -5,8 +5,8 @@ namespace Neo.SmartContract { partial class ApplicationEngine { - public static readonly InteropDescriptor System_Json_Serialize = Register("System.Json.Serialize", nameof(JsonSerialize), 0_00100000, CallFlags.None, true); - public static readonly InteropDescriptor System_Json_Deserialize = Register("System.Json.Deserialize", nameof(JsonDeserialize), 0_00500000, CallFlags.None, true); + public static readonly InteropDescriptor System_Json_Serialize = Register("System.Json.Serialize", nameof(JsonSerialize), 0_00003333, CallFlags.None, true); + public static readonly InteropDescriptor System_Json_Deserialize = Register("System.Json.Deserialize", nameof(JsonDeserialize), 0_00016667, CallFlags.None, true); protected internal byte[] JsonSerialize(StackItem item) { diff --git a/src/neo/SmartContract/ApplicationEngine.OpCodePrices.cs b/src/neo/SmartContract/ApplicationEngine.OpCodePrices.cs index 41bd1f7a29..6fa573f03b 100644 --- a/src/neo/SmartContract/ApplicationEngine.OpCodePrices.cs +++ b/src/neo/SmartContract/ApplicationEngine.OpCodePrices.cs @@ -7,190 +7,190 @@ partial class ApplicationEngine { public static readonly IReadOnlyDictionary OpCodePrices = new Dictionary { - [OpCode.PUSHINT8] = 30, - [OpCode.PUSHINT16] = 30, - [OpCode.PUSHINT32] = 30, - [OpCode.PUSHINT64] = 30, - [OpCode.PUSHINT128] = 120, - [OpCode.PUSHINT256] = 120, - [OpCode.PUSHA] = 120, - [OpCode.PUSHNULL] = 30, - [OpCode.PUSHDATA1] = 180, - [OpCode.PUSHDATA2] = 13000, - [OpCode.PUSHDATA4] = 110000, - [OpCode.PUSHM1] = 30, - [OpCode.PUSH0] = 30, - [OpCode.PUSH1] = 30, - [OpCode.PUSH2] = 30, - [OpCode.PUSH3] = 30, - [OpCode.PUSH4] = 30, - [OpCode.PUSH5] = 30, - [OpCode.PUSH6] = 30, - [OpCode.PUSH7] = 30, - [OpCode.PUSH8] = 30, - [OpCode.PUSH9] = 30, - [OpCode.PUSH10] = 30, - [OpCode.PUSH11] = 30, - [OpCode.PUSH12] = 30, - [OpCode.PUSH13] = 30, - [OpCode.PUSH14] = 30, - [OpCode.PUSH15] = 30, - [OpCode.PUSH16] = 30, - [OpCode.NOP] = 30, - [OpCode.JMP] = 70, - [OpCode.JMP_L] = 70, - [OpCode.JMPIF] = 70, - [OpCode.JMPIF_L] = 70, - [OpCode.JMPIFNOT] = 70, - [OpCode.JMPIFNOT_L] = 70, - [OpCode.JMPEQ] = 70, - [OpCode.JMPEQ_L] = 70, - [OpCode.JMPNE] = 70, - [OpCode.JMPNE_L] = 70, - [OpCode.JMPGT] = 70, - [OpCode.JMPGT_L] = 70, - [OpCode.JMPGE] = 70, - [OpCode.JMPGE_L] = 70, - [OpCode.JMPLT] = 70, - [OpCode.JMPLT_L] = 70, - [OpCode.JMPLE] = 70, - [OpCode.JMPLE_L] = 70, - [OpCode.CALL] = 22000, - [OpCode.CALL_L] = 22000, - [OpCode.CALLA] = 22000, - [OpCode.ABORT] = 30, - [OpCode.ASSERT] = 30, - [OpCode.THROW] = 22000, - [OpCode.TRY] = 100, - [OpCode.TRY_L] = 100, - [OpCode.ENDTRY] = 100, - [OpCode.ENDTRY_L] = 100, - [OpCode.ENDFINALLY] = 100, + [OpCode.PUSHINT8] = 1, + [OpCode.PUSHINT16] = 1, + [OpCode.PUSHINT32] = 1, + [OpCode.PUSHINT64] = 1, + [OpCode.PUSHINT128] = 4, + [OpCode.PUSHINT256] = 4, + [OpCode.PUSHA] = 4, + [OpCode.PUSHNULL] = 1, + [OpCode.PUSHDATA1] = 6, + [OpCode.PUSHDATA2] = 433, + [OpCode.PUSHDATA4] = 3667, + [OpCode.PUSHM1] = 1, + [OpCode.PUSH0] = 1, + [OpCode.PUSH1] = 1, + [OpCode.PUSH2] = 1, + [OpCode.PUSH3] = 1, + [OpCode.PUSH4] = 1, + [OpCode.PUSH5] = 1, + [OpCode.PUSH6] = 1, + [OpCode.PUSH7] = 1, + [OpCode.PUSH8] = 1, + [OpCode.PUSH9] = 1, + [OpCode.PUSH10] = 1, + [OpCode.PUSH11] = 1, + [OpCode.PUSH12] = 1, + [OpCode.PUSH13] = 1, + [OpCode.PUSH14] = 1, + [OpCode.PUSH15] = 1, + [OpCode.PUSH16] = 1, + [OpCode.NOP] = 1, + [OpCode.JMP] = 2, + [OpCode.JMP_L] = 2, + [OpCode.JMPIF] = 2, + [OpCode.JMPIF_L] = 2, + [OpCode.JMPIFNOT] = 2, + [OpCode.JMPIFNOT_L] = 2, + [OpCode.JMPEQ] = 2, + [OpCode.JMPEQ_L] = 2, + [OpCode.JMPNE] = 2, + [OpCode.JMPNE_L] = 2, + [OpCode.JMPGT] = 2, + [OpCode.JMPGT_L] = 2, + [OpCode.JMPGE] = 2, + [OpCode.JMPGE_L] = 2, + [OpCode.JMPLT] = 2, + [OpCode.JMPLT_L] = 2, + [OpCode.JMPLE] = 2, + [OpCode.JMPLE_L] = 2, + [OpCode.CALL] = 733, + [OpCode.CALL_L] = 733, + [OpCode.CALLA] = 733, + [OpCode.ABORT] = 1, + [OpCode.ASSERT] = 1, + [OpCode.THROW] = 733, + [OpCode.TRY] = 3, + [OpCode.TRY_L] = 3, + [OpCode.ENDTRY] = 3, + [OpCode.ENDTRY_L] = 3, + [OpCode.ENDFINALLY] = 3, [OpCode.RET] = 0, [OpCode.SYSCALL] = 0, - [OpCode.DEPTH] = 60, - [OpCode.DROP] = 60, - [OpCode.NIP] = 60, - [OpCode.XDROP] = 400, - [OpCode.CLEAR] = 400, - [OpCode.DUP] = 60, - [OpCode.OVER] = 60, - [OpCode.PICK] = 60, - [OpCode.TUCK] = 60, - [OpCode.SWAP] = 60, - [OpCode.ROT] = 60, - [OpCode.ROLL] = 400, - [OpCode.REVERSE3] = 60, - [OpCode.REVERSE4] = 60, - [OpCode.REVERSEN] = 400, - [OpCode.INITSSLOT] = 400, - [OpCode.INITSLOT] = 800, - [OpCode.LDSFLD0] = 60, - [OpCode.LDSFLD1] = 60, - [OpCode.LDSFLD2] = 60, - [OpCode.LDSFLD3] = 60, - [OpCode.LDSFLD4] = 60, - [OpCode.LDSFLD5] = 60, - [OpCode.LDSFLD6] = 60, - [OpCode.LDSFLD] = 60, - [OpCode.STSFLD0] = 60, - [OpCode.STSFLD1] = 60, - [OpCode.STSFLD2] = 60, - [OpCode.STSFLD3] = 60, - [OpCode.STSFLD4] = 60, - [OpCode.STSFLD5] = 60, - [OpCode.STSFLD6] = 60, - [OpCode.STSFLD] = 60, - [OpCode.LDLOC0] = 60, - [OpCode.LDLOC1] = 60, - [OpCode.LDLOC2] = 60, - [OpCode.LDLOC3] = 60, - [OpCode.LDLOC4] = 60, - [OpCode.LDLOC5] = 60, - [OpCode.LDLOC6] = 60, - [OpCode.LDLOC] = 60, - [OpCode.STLOC0] = 60, - [OpCode.STLOC1] = 60, - [OpCode.STLOC2] = 60, - [OpCode.STLOC3] = 60, - [OpCode.STLOC4] = 60, - [OpCode.STLOC5] = 60, - [OpCode.STLOC6] = 60, - [OpCode.STLOC] = 60, - [OpCode.LDARG0] = 60, - [OpCode.LDARG1] = 60, - [OpCode.LDARG2] = 60, - [OpCode.LDARG3] = 60, - [OpCode.LDARG4] = 60, - [OpCode.LDARG5] = 60, - [OpCode.LDARG6] = 60, - [OpCode.LDARG] = 60, - [OpCode.STARG0] = 60, - [OpCode.STARG1] = 60, - [OpCode.STARG2] = 60, - [OpCode.STARG3] = 60, - [OpCode.STARG4] = 60, - [OpCode.STARG5] = 60, - [OpCode.STARG6] = 60, - [OpCode.STARG] = 60, - [OpCode.NEWBUFFER] = 80000, - [OpCode.MEMCPY] = 80000, - [OpCode.CAT] = 80000, - [OpCode.SUBSTR] = 80000, - [OpCode.LEFT] = 80000, - [OpCode.RIGHT] = 80000, - [OpCode.INVERT] = 100, - [OpCode.AND] = 200, - [OpCode.OR] = 200, - [OpCode.XOR] = 200, - [OpCode.EQUAL] = 200, - [OpCode.NOTEQUAL] = 200, - [OpCode.SIGN] = 100, - [OpCode.ABS] = 100, - [OpCode.NEGATE] = 100, - [OpCode.INC] = 100, - [OpCode.DEC] = 100, - [OpCode.ADD] = 200, - [OpCode.SUB] = 200, - [OpCode.MUL] = 300, - [OpCode.DIV] = 300, - [OpCode.MOD] = 300, - [OpCode.SHL] = 300, - [OpCode.SHR] = 300, - [OpCode.NOT] = 100, - [OpCode.BOOLAND] = 200, - [OpCode.BOOLOR] = 200, - [OpCode.NZ] = 100, - [OpCode.NUMEQUAL] = 200, - [OpCode.NUMNOTEQUAL] = 200, - [OpCode.LT] = 200, - [OpCode.LE] = 200, - [OpCode.GT] = 200, - [OpCode.GE] = 200, - [OpCode.MIN] = 200, - [OpCode.MAX] = 200, - [OpCode.WITHIN] = 200, - [OpCode.PACK] = 7000, - [OpCode.UNPACK] = 7000, - [OpCode.NEWARRAY0] = 400, - [OpCode.NEWARRAY] = 15000, - [OpCode.NEWARRAY_T] = 15000, - [OpCode.NEWSTRUCT0] = 400, - [OpCode.NEWSTRUCT] = 15000, - [OpCode.NEWMAP] = 200, - [OpCode.SIZE] = 150, - [OpCode.HASKEY] = 270000, - [OpCode.KEYS] = 500, - [OpCode.VALUES] = 7000, - [OpCode.PICKITEM] = 270000, - [OpCode.APPEND] = 15000, - [OpCode.SETITEM] = 270000, - [OpCode.REVERSEITEMS] = 500, - [OpCode.REMOVE] = 500, - [OpCode.CLEARITEMS] = 400, - [OpCode.ISNULL] = 60, - [OpCode.ISTYPE] = 60, - [OpCode.CONVERT] = 80000, + [OpCode.DEPTH] = 2, + [OpCode.DROP] = 2, + [OpCode.NIP] = 2, + [OpCode.XDROP] = 13, + [OpCode.CLEAR] = 13, + [OpCode.DUP] = 2, + [OpCode.OVER] = 2, + [OpCode.PICK] = 2, + [OpCode.TUCK] = 2, + [OpCode.SWAP] = 2, + [OpCode.ROT] = 2, + [OpCode.ROLL] = 13, + [OpCode.REVERSE3] = 2, + [OpCode.REVERSE4] = 2, + [OpCode.REVERSEN] = 13, + [OpCode.INITSSLOT] = 13, + [OpCode.INITSLOT] = 27, + [OpCode.LDSFLD0] = 2, + [OpCode.LDSFLD1] = 2, + [OpCode.LDSFLD2] = 2, + [OpCode.LDSFLD3] = 2, + [OpCode.LDSFLD4] = 2, + [OpCode.LDSFLD5] = 2, + [OpCode.LDSFLD6] = 2, + [OpCode.LDSFLD] = 2, + [OpCode.STSFLD0] = 2, + [OpCode.STSFLD1] = 2, + [OpCode.STSFLD2] = 2, + [OpCode.STSFLD3] = 2, + [OpCode.STSFLD4] = 2, + [OpCode.STSFLD5] = 2, + [OpCode.STSFLD6] = 2, + [OpCode.STSFLD] = 2, + [OpCode.LDLOC0] = 2, + [OpCode.LDLOC1] = 2, + [OpCode.LDLOC2] = 2, + [OpCode.LDLOC3] = 2, + [OpCode.LDLOC4] = 2, + [OpCode.LDLOC5] = 2, + [OpCode.LDLOC6] = 2, + [OpCode.LDLOC] = 2, + [OpCode.STLOC0] = 2, + [OpCode.STLOC1] = 2, + [OpCode.STLOC2] = 2, + [OpCode.STLOC3] = 2, + [OpCode.STLOC4] = 2, + [OpCode.STLOC5] = 2, + [OpCode.STLOC6] = 2, + [OpCode.STLOC] = 2, + [OpCode.LDARG0] = 2, + [OpCode.LDARG1] = 2, + [OpCode.LDARG2] = 2, + [OpCode.LDARG3] = 2, + [OpCode.LDARG4] = 2, + [OpCode.LDARG5] = 2, + [OpCode.LDARG6] = 2, + [OpCode.LDARG] = 2, + [OpCode.STARG0] = 2, + [OpCode.STARG1] = 2, + [OpCode.STARG2] = 2, + [OpCode.STARG3] = 2, + [OpCode.STARG4] = 2, + [OpCode.STARG5] = 2, + [OpCode.STARG6] = 2, + [OpCode.STARG] = 2, + [OpCode.NEWBUFFER] = 2667, + [OpCode.MEMCPY] = 2667, + [OpCode.CAT] = 2667, + [OpCode.SUBSTR] = 2667, + [OpCode.LEFT] = 2667, + [OpCode.RIGHT] = 2667, + [OpCode.INVERT] = 3, + [OpCode.AND] = 7, + [OpCode.OR] = 7, + [OpCode.XOR] = 7, + [OpCode.EQUAL] = 7, + [OpCode.NOTEQUAL] = 7, + [OpCode.SIGN] = 3, + [OpCode.ABS] = 3, + [OpCode.NEGATE] = 3, + [OpCode.INC] = 3, + [OpCode.DEC] = 3, + [OpCode.ADD] = 7, + [OpCode.SUB] = 7, + [OpCode.MUL] = 10, + [OpCode.DIV] = 10, + [OpCode.MOD] = 10, + [OpCode.SHL] = 10, + [OpCode.SHR] = 10, + [OpCode.NOT] = 3, + [OpCode.BOOLAND] = 7, + [OpCode.BOOLOR] = 7, + [OpCode.NZ] = 3, + [OpCode.NUMEQUAL] = 7, + [OpCode.NUMNOTEQUAL] = 7, + [OpCode.LT] = 7, + [OpCode.LE] = 7, + [OpCode.GT] = 7, + [OpCode.GE] = 7, + [OpCode.MIN] = 7, + [OpCode.MAX] = 7, + [OpCode.WITHIN] = 7, + [OpCode.PACK] = 233, + [OpCode.UNPACK] = 233, + [OpCode.NEWARRAY0] = 13, + [OpCode.NEWARRAY] = 500, + [OpCode.NEWARRAY_T] = 500, + [OpCode.NEWSTRUCT0] = 13, + [OpCode.NEWSTRUCT] = 500, + [OpCode.NEWMAP] = 7, + [OpCode.SIZE] = 5, + [OpCode.HASKEY] = 9000, + [OpCode.KEYS] = 17, + [OpCode.VALUES] = 233, + [OpCode.PICKITEM] = 9000, + [OpCode.APPEND] = 500, + [OpCode.SETITEM] = 9000, + [OpCode.REVERSEITEMS] = 17, + [OpCode.REMOVE] = 17, + [OpCode.CLEARITEMS] = 13, + [OpCode.ISNULL] = 2, + [OpCode.ISTYPE] = 2, + [OpCode.CONVERT] = 2667, }; } } diff --git a/src/neo/SmartContract/ApplicationEngine.Runtime.cs b/src/neo/SmartContract/ApplicationEngine.Runtime.cs index 674a0cea9e..9401374e75 100644 --- a/src/neo/SmartContract/ApplicationEngine.Runtime.cs +++ b/src/neo/SmartContract/ApplicationEngine.Runtime.cs @@ -16,19 +16,19 @@ partial class ApplicationEngine public const int MaxEventName = 32; public const int MaxNotificationSize = 1024; - public static readonly InteropDescriptor System_Runtime_Platform = Register("System.Runtime.Platform", nameof(GetPlatform), 0_00000250, CallFlags.None, true); - public static readonly InteropDescriptor System_Runtime_GetTrigger = Register("System.Runtime.GetTrigger", nameof(Trigger), 0_00000250, CallFlags.None, true); - public static readonly InteropDescriptor System_Runtime_GetTime = Register("System.Runtime.GetTime", nameof(GetTime), 0_00000250, CallFlags.AllowStates, true); - public static readonly InteropDescriptor System_Runtime_GetScriptContainer = Register("System.Runtime.GetScriptContainer", nameof(GetScriptContainer), 0_00000250, CallFlags.None, true); - public static readonly InteropDescriptor System_Runtime_GetExecutingScriptHash = Register("System.Runtime.GetExecutingScriptHash", nameof(CurrentScriptHash), 0_00000400, CallFlags.None, true); - public static readonly InteropDescriptor System_Runtime_GetCallingScriptHash = Register("System.Runtime.GetCallingScriptHash", nameof(CallingScriptHash), 0_00000400, CallFlags.None, true); - public static readonly InteropDescriptor System_Runtime_GetEntryScriptHash = Register("System.Runtime.GetEntryScriptHash", nameof(EntryScriptHash), 0_00000400, CallFlags.None, true); - public static readonly InteropDescriptor System_Runtime_CheckWitness = Register("System.Runtime.CheckWitness", nameof(CheckWitness), 0_00030000, CallFlags.None, true); - public static readonly InteropDescriptor System_Runtime_GetInvocationCounter = Register("System.Runtime.GetInvocationCounter", nameof(GetInvocationCounter), 0_00000400, CallFlags.None, true); - public static readonly InteropDescriptor System_Runtime_Log = Register("System.Runtime.Log", nameof(RuntimeLog), 0_01000000, CallFlags.AllowNotify, false); - public static readonly InteropDescriptor System_Runtime_Notify = Register("System.Runtime.Notify", nameof(RuntimeNotify), 0_01000000, CallFlags.AllowNotify, false); - public static readonly InteropDescriptor System_Runtime_GetNotifications = Register("System.Runtime.GetNotifications", nameof(GetNotifications), 0_00010000, CallFlags.None, true); - public static readonly InteropDescriptor System_Runtime_GasLeft = Register("System.Runtime.GasLeft", nameof(GasLeft), 0_00000400, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_Platform = Register("System.Runtime.Platform", nameof(GetPlatform), 0_00000008, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_GetTrigger = Register("System.Runtime.GetTrigger", nameof(Trigger), 0_00000008, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_GetTime = Register("System.Runtime.GetTime", nameof(GetTime), 0_00000008, CallFlags.AllowStates, true); + public static readonly InteropDescriptor System_Runtime_GetScriptContainer = Register("System.Runtime.GetScriptContainer", nameof(GetScriptContainer), 0_00000008, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_GetExecutingScriptHash = Register("System.Runtime.GetExecutingScriptHash", nameof(CurrentScriptHash), 0_00000013, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_GetCallingScriptHash = Register("System.Runtime.GetCallingScriptHash", nameof(CallingScriptHash), 0_00000013, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_GetEntryScriptHash = Register("System.Runtime.GetEntryScriptHash", nameof(EntryScriptHash), 0_00000013, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_CheckWitness = Register("System.Runtime.CheckWitness", nameof(CheckWitness), 0_00001000, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_GetInvocationCounter = Register("System.Runtime.GetInvocationCounter", nameof(GetInvocationCounter), 0_00000013, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_Log = Register("System.Runtime.Log", nameof(RuntimeLog), 0_00033333, CallFlags.AllowNotify, false); + public static readonly InteropDescriptor System_Runtime_Notify = Register("System.Runtime.Notify", nameof(RuntimeNotify), 0_00033333, CallFlags.AllowNotify, false); + public static readonly InteropDescriptor System_Runtime_GetNotifications = Register("System.Runtime.GetNotifications", nameof(GetNotifications), 0_00000333, CallFlags.None, true); + public static readonly InteropDescriptor System_Runtime_GasLeft = Register("System.Runtime.GasLeft", nameof(GasLeft), 0_00000013, CallFlags.None, true); private static bool CheckItemForNotification(StackItem state) { diff --git a/src/neo/SmartContract/ApplicationEngine.Storage.cs b/src/neo/SmartContract/ApplicationEngine.Storage.cs index ce87bc6211..8f7309f27a 100644 --- a/src/neo/SmartContract/ApplicationEngine.Storage.cs +++ b/src/neo/SmartContract/ApplicationEngine.Storage.cs @@ -7,15 +7,15 @@ namespace Neo.SmartContract { partial class ApplicationEngine { - public const long StoragePrice = 100000; + public const long StoragePrice = 3333; public const int MaxStorageKeySize = 64; public const int MaxStorageValueSize = ushort.MaxValue; - public static readonly InteropDescriptor System_Storage_GetContext = Register("System.Storage.GetContext", nameof(GetStorageContext), 0_00000400, CallFlags.AllowStates, false); - public static readonly InteropDescriptor System_Storage_GetReadOnlyContext = Register("System.Storage.GetReadOnlyContext", nameof(GetReadOnlyContext), 0_00000400, CallFlags.AllowStates, false); - public static readonly InteropDescriptor System_Storage_AsReadOnly = Register("System.Storage.AsReadOnly", nameof(AsReadOnly), 0_00000400, CallFlags.AllowStates, false); - public static readonly InteropDescriptor System_Storage_Get = Register("System.Storage.Get", nameof(Get), 0_01000000, CallFlags.AllowStates, false); - public static readonly InteropDescriptor System_Storage_Find = Register("System.Storage.Find", nameof(Find), 0_01000000, CallFlags.AllowStates, false); + public static readonly InteropDescriptor System_Storage_GetContext = Register("System.Storage.GetContext", nameof(GetStorageContext), 0_00000013, CallFlags.AllowStates, false); + public static readonly InteropDescriptor System_Storage_GetReadOnlyContext = Register("System.Storage.GetReadOnlyContext", nameof(GetReadOnlyContext), 0_00000013, CallFlags.AllowStates, false); + public static readonly InteropDescriptor System_Storage_AsReadOnly = Register("System.Storage.AsReadOnly", nameof(AsReadOnly), 0_00000013, CallFlags.AllowStates, false); + public static readonly InteropDescriptor System_Storage_Get = Register("System.Storage.Get", nameof(Get), 0_00033333, CallFlags.AllowStates, false); + public static readonly InteropDescriptor System_Storage_Find = Register("System.Storage.Find", nameof(Find), 0_00033333, CallFlags.AllowStates, false); public static readonly InteropDescriptor System_Storage_Put = Register("System.Storage.Put", nameof(Put), 0, CallFlags.AllowModifyStates, false); public static readonly InteropDescriptor System_Storage_PutEx = Register("System.Storage.PutEx", nameof(PutEx), 0, CallFlags.AllowModifyStates, false); public static readonly InteropDescriptor System_Storage_Delete = Register("System.Storage.Delete", nameof(Delete), 1 * StoragePrice, CallFlags.AllowModifyStates, false); diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs index 8cb95e5928..c57715d126 100644 --- a/src/neo/SmartContract/ApplicationEngine.cs +++ b/src/neo/SmartContract/ApplicationEngine.cs @@ -36,7 +36,7 @@ private class InvocationState /// /// This constant can be used for testing scripts. /// - private const long TestModeGas = 20_00000000; + private const long TestModeGas = 66666667; public static event EventHandler Notify; public static event EventHandler Log; @@ -55,8 +55,8 @@ private class InvocationState public IVerifiable ScriptContainer { get; } public StoreView Snapshot { get; } public long GasConsumedWithRatio = 0; - public long GasConsumed => GasConsumedWithRatio * NativeContract.Policy.GetFeeRatio(Snapshot) / PolicyContract.MaximumRatioVariety; - public long GasLeft => (gas_amount_with_ratio - GasConsumedWithRatio) * NativeContract.Policy.GetFeeRatio(Snapshot) / PolicyContract.MaximumRatioVariety; + public long GasConsumed => GasConsumedWithRatio * NativeContract.Policy.GetFeeRatio(Snapshot); + public long GasLeft => (gas_amount_with_ratio - GasConsumedWithRatio) * NativeContract.Policy.GetFeeRatio(Snapshot); public Exception FaultException { get; private set; } public UInt160 CurrentScriptHash => CurrentContext?.GetScriptHash(); public UInt160 CallingScriptHash => CurrentContext?.GetState().CallingScriptHash; diff --git a/src/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs index e101939687..df72c128da 100644 --- a/src/neo/SmartContract/Helper.cs +++ b/src/neo/SmartContract/Helper.cs @@ -14,7 +14,7 @@ namespace Neo.SmartContract { public static class Helper { - private const long MaxVerificationGas = 0_50000000; + private const long MaxVerificationGas = 0_01666667; public static UInt160 GetScriptHash(this ExecutionContext context) { diff --git a/src/neo/SmartContract/Native/Designate/DesignateContract.cs b/src/neo/SmartContract/Native/Designate/DesignateContract.cs index 8959b48078..5258d9a914 100644 --- a/src/neo/SmartContract/Native/Designate/DesignateContract.cs +++ b/src/neo/SmartContract/Native/Designate/DesignateContract.cs @@ -32,7 +32,7 @@ internal override void Initialize(ApplicationEngine engine) } } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public ECPoint[] GetDesignatedByRole(StoreView snapshot, Role role) { if (!Enum.IsDefined(typeof(Role), role)) diff --git a/src/neo/SmartContract/Native/Oracle/OracleContract.cs b/src/neo/SmartContract/Native/Oracle/OracleContract.cs index 6f94698b45..13d236ed27 100644 --- a/src/neo/SmartContract/Native/Oracle/OracleContract.cs +++ b/src/neo/SmartContract/Native/Oracle/OracleContract.cs @@ -26,7 +26,7 @@ public sealed class OracleContract : NativeContract private const byte Prefix_Request = 7; private const byte Prefix_IdList = 6; - private const long OracleRequestPrice = 0_50000000; + private const long OracleRequestPrice = 0_01666667; public override int Id => -4; public override string Name => "Oracle"; @@ -130,7 +130,7 @@ private void Request(ApplicationEngine engine, string url, string filter, string if (Utility.StrictUTF8.GetByteCount(url) > MaxUrlLength || (filter != null && Utility.StrictUTF8.GetByteCount(filter) > MaxFilterLength) || Utility.StrictUTF8.GetByteCount(callback) > MaxCallbackLength - || gasForResponse < 0_10000000) + || gasForResponse < 0_00333333) throw new ArgumentException(); //Mint gas for the response @@ -163,7 +163,7 @@ private void Request(ApplicationEngine engine, string url, string filter, string list.Add(id); } - [ContractMethod(0_01000000, CallFlags.None)] + [ContractMethod(0_00033333, CallFlags.None)] private bool Verify(ApplicationEngine engine) { Transaction tx = (Transaction)engine.ScriptContainer; diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs index 66f93629c8..a2b97f1a5c 100644 --- a/src/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -15,9 +15,7 @@ public sealed class PolicyContract : NativeContract public override string Name => "Policy"; public override int Id => -3; - public const uint MaximumRatioVariety = 100; - private const uint MaximumRatio = MaximumRatioVariety * MaximumRatioVariety; - + private const uint MaximumRatio = 10000; private const byte Prefix_MaxTransactionsPerBlock = 23; private const byte Prefix_FeePerByte = 10; private const byte Prefix_BlockedAccount = 15; @@ -30,7 +28,7 @@ public PolicyContract() Manifest.Features = ContractFeatures.HasStorage; } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public uint GetMaxTransactionsPerBlock(StoreView snapshot) { StorageItem item = snapshot.Storages.TryGet(CreateStorageKey(Prefix_MaxTransactionsPerBlock)); @@ -38,7 +36,7 @@ public uint GetMaxTransactionsPerBlock(StoreView snapshot) return (uint)(BigInteger)item; } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public uint GetMaxBlockSize(StoreView snapshot) { StorageItem item = snapshot.Storages.TryGet(CreateStorageKey(Prefix_MaxBlockSize)); @@ -46,7 +44,7 @@ public uint GetMaxBlockSize(StoreView snapshot) return (uint)(BigInteger)item; } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public long GetMaxBlockSystemFee(StoreView snapshot) { StorageItem item = snapshot.Storages.TryGet(CreateStorageKey(Prefix_MaxBlockSystemFee)); @@ -54,29 +52,29 @@ public long GetMaxBlockSystemFee(StoreView snapshot) return (long)(BigInteger)item; } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public long GetFeePerByte(StoreView snapshot) { StorageItem item = snapshot.Storages.TryGet(CreateStorageKey(Prefix_FeePerByte)); - if (item is null) return 1000; + if (item is null) return 33; return (long)(BigInteger)item; } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public bool IsBlocked(StoreView snapshot, UInt160 account) { return snapshot.Storages.Contains(CreateStorageKey(Prefix_BlockedAccount).Add(account)); } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public uint GetFeeRatio(StoreView snapshot) { StorageItem item = snapshot.Storages.TryGet(CreateStorageKey(Prefix_FeeRatio)); - if (item is null) return 100; + if (item is null) return 30; return (uint)(BigInteger)item; } - [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00100000, CallFlags.AllowModifyStates)] private bool SetMaxBlockSize(ApplicationEngine engine, uint value) { if (value > Message.PayloadMaxSize) throw new ArgumentOutOfRangeException(nameof(value)); @@ -86,7 +84,7 @@ private bool SetMaxBlockSize(ApplicationEngine engine, uint value) return true; } - [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00100000, CallFlags.AllowModifyStates)] private bool SetMaxTransactionsPerBlock(ApplicationEngine engine, uint value) { if (value > Block.MaxTransactionsPerBlock) throw new ArgumentOutOfRangeException(nameof(value)); @@ -96,7 +94,7 @@ private bool SetMaxTransactionsPerBlock(ApplicationEngine engine, uint value) return true; } - [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00100000, CallFlags.AllowModifyStates)] private bool SetMaxBlockSystemFee(ApplicationEngine engine, long value) { if (value <= 4007600) throw new ArgumentOutOfRangeException(nameof(value)); @@ -106,7 +104,7 @@ private bool SetMaxBlockSystemFee(ApplicationEngine engine, long value) return true; } - [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00100000, CallFlags.AllowModifyStates)] private bool SetFeePerByte(ApplicationEngine engine, long value) { if (value < 0 || value > 1_00000000) throw new ArgumentOutOfRangeException(nameof(value)); @@ -116,7 +114,7 @@ private bool SetFeePerByte(ApplicationEngine engine, long value) return true; } - [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00100000, CallFlags.AllowModifyStates)] private bool BlockAccount(ApplicationEngine engine, UInt160 account) { if (!CheckCommittee(engine)) return false; @@ -128,7 +126,7 @@ private bool BlockAccount(ApplicationEngine engine, UInt160 account) return true; } - [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00100000, CallFlags.AllowModifyStates)] private bool UnblockAccount(ApplicationEngine engine, UInt160 account) { if (!CheckCommittee(engine)) return false; @@ -140,7 +138,7 @@ private bool UnblockAccount(ApplicationEngine engine, UInt160 account) return true; } - [ContractMethod(0_03000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00100000, CallFlags.AllowModifyStates)] private bool SetFeeRatio(ApplicationEngine engine, uint value) { if (value == 0 || value > MaximumRatio) throw new ArgumentOutOfRangeException(nameof(value)); diff --git a/src/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs index eb5b0f14e4..85a2338a95 100644 --- a/src/neo/SmartContract/Native/Tokens/NeoToken.cs +++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs @@ -181,7 +181,7 @@ protected override void PostPersist(ApplicationEngine engine) } } - [ContractMethod(0_05000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00166667, CallFlags.AllowModifyStates)] private bool SetGasPerBlock(ApplicationEngine engine, BigInteger gasPerBlock) { if (gasPerBlock < 0 || gasPerBlock > 10 * GAS.Factor) @@ -194,7 +194,7 @@ private bool SetGasPerBlock(ApplicationEngine engine, BigInteger gasPerBlock) return true; } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public BigInteger GetGasPerBlock(StoreView snapshot) { return GetSortedGasRecords(snapshot, snapshot.PersistingBlock.Index).First().GasPerBlock; @@ -208,7 +208,7 @@ public BigInteger GetGasPerBlock(StoreView snapshot) .Select(u => (BinaryPrimitives.ReadUInt32BigEndian(u.Key.Key.AsSpan(^sizeof(uint))), (BigInteger)u.Value)); } - [ContractMethod(0_03000000, CallFlags.AllowStates)] + [ContractMethod(0_00100000, CallFlags.AllowStates)] public BigInteger UnclaimedGas(StoreView snapshot, UInt160 account, uint end) { StorageItem storage = snapshot.Storages.TryGet(CreateStorageKey(Prefix_Account).Add(account)); @@ -217,7 +217,7 @@ public BigInteger UnclaimedGas(StoreView snapshot, UInt160 account, uint end) return CalculateBonus(snapshot, state.VoteTo, state.Balance, state.BalanceHeight, end); } - [ContractMethod(0_05000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00166667, CallFlags.AllowModifyStates)] private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey) { if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash())) @@ -229,7 +229,7 @@ private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey) return true; } - [ContractMethod(0_05000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00166667, CallFlags.AllowModifyStates)] private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey) { if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash())) @@ -243,7 +243,7 @@ private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey) return true; } - [ContractMethod(0_05000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00166667, CallFlags.AllowModifyStates)] private bool Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo) { if (!engine.CheckWitnessInternal(account)) return false; @@ -281,7 +281,7 @@ private bool Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo) return true; } - [ContractMethod(1_00000000, CallFlags.AllowStates)] + [ContractMethod(0_03333333, CallFlags.AllowStates)] public (ECPoint PublicKey, BigInteger Votes)[] GetCandidates(StoreView snapshot) { byte[] prefix_key = CreateStorageKey(Prefix_Candidate).ToArray(); @@ -292,7 +292,7 @@ private bool Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo) )).Where(p => p.Item2.Registered).Select(p => (p.Item1, p.Item2.Votes)).ToArray(); } - [ContractMethod(1_00000000, CallFlags.AllowStates)] + [ContractMethod(0_03333333, CallFlags.AllowStates)] public ECPoint[] GetCommittee(StoreView snapshot) { return GetCommitteeFromCache(snapshot).Select(p => p.PublicKey).OrderBy(p => p).ToArray(); @@ -324,7 +324,7 @@ internal ECPoint[] ComputeNextBlockValidators(StoreView snapshot) return candidates.OrderByDescending(p => p.Votes).ThenBy(p => p.PublicKey).Take(ProtocolSettings.Default.CommitteeMembersCount); } - [ContractMethod(1_00000000, CallFlags.AllowStates)] + [ContractMethod(0_03333333, CallFlags.AllowStates)] public ECPoint[] GetNextBlockValidators(StoreView snapshot) { return GetCommitteeFromCache(snapshot) diff --git a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs index ed4308b73c..5239a80d8b 100644 --- a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs +++ b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs @@ -89,7 +89,7 @@ internal protected virtual void Burn(ApplicationEngine engine, UInt160 account, engine.SendNotification(Hash, "Transfer", new Array { account.ToArray(), StackItem.Null, amount }); } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public virtual BigInteger TotalSupply(StoreView snapshot) { StorageItem storage = snapshot.Storages.TryGet(CreateStorageKey(Prefix_TotalSupply)); @@ -97,7 +97,7 @@ public virtual BigInteger TotalSupply(StoreView snapshot) return storage; } - [ContractMethod(0_01000000, CallFlags.AllowStates)] + [ContractMethod(0_00033333, CallFlags.AllowStates)] public virtual BigInteger BalanceOf(StoreView snapshot, UInt160 account) { StorageItem storage = snapshot.Storages.TryGet(CreateStorageKey(Prefix_Account).Add(account)); @@ -105,7 +105,7 @@ public virtual BigInteger BalanceOf(StoreView snapshot, UInt160 account) return storage.GetInteroperable().Balance; } - [ContractMethod(0_08000000, CallFlags.AllowModifyStates)] + [ContractMethod(0_00266667, CallFlags.AllowModifyStates)] protected virtual bool Transfer(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount) { if (amount.Sign < 0) throw new ArgumentOutOfRangeException(nameof(amount)); diff --git a/src/neo/Wallets/AssetDescriptor.cs b/src/neo/Wallets/AssetDescriptor.cs index 9f6a4d4c18..776c0e9388 100644 --- a/src/neo/Wallets/AssetDescriptor.cs +++ b/src/neo/Wallets/AssetDescriptor.cs @@ -19,7 +19,7 @@ public AssetDescriptor(UInt160 asset_id) sb.EmitAppCall(asset_id, "name"); script = sb.ToArray(); } - using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 3_000_000); + using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 100_000); if (engine.State.HasFlag(VMState.FAULT)) throw new ArgumentException(); this.AssetId = asset_id; this.AssetName = engine.ResultStack.Pop().GetString(); diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index f70b90ecd1..ffee250bfb 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -145,7 +145,7 @@ public BigDecimal GetBalance(UInt160 asset_id, params UInt160[] accounts) sb.EmitAppCall(asset_id, "decimals"); script = sb.ToArray(); } - using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 20000000L * accounts.Length); + using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 666667L * accounts.Length); if (engine.State.HasFlag(VMState.FAULT)) return new BigDecimal(0, 0); byte decimals = (byte)engine.ResultStack.Pop().GetInteger(); @@ -431,7 +431,7 @@ public long CalculateNetworkFee(StoreView snapshot, Transaction tx) } } networkFee += size * NativeContract.Policy.GetFeePerByte(snapshot); - return networkFee * NativeContract.Policy.GetFeeRatio(snapshot) / PolicyContract.MaximumRatioVariety; + return networkFee * NativeContract.Policy.GetFeeRatio(snapshot); } public bool Sign(ContractParametersContext context) diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index ae23b91d1e..d65137ac39 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -177,9 +177,9 @@ public void FeeIsMultiSigContract() } var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); - Assert.AreEqual(2000810, verificationGas); - Assert.AreEqual(347000, sizeGas); - Assert.AreEqual(2347810, tx.NetworkFee); + Assert.AreEqual(2000790, verificationGas); + Assert.AreEqual(11451, sizeGas); + Assert.AreEqual(2344320, tx.NetworkFee); } } @@ -220,7 +220,7 @@ public void FeeIsSignatureContractDetailed() Assert.IsNull(tx.Witnesses); // check pre-computed network fee (already guessing signature sizes) - tx.NetworkFee.Should().Be(1244390L); + tx.NetworkFee.Should().Be(1241940L); // ---- // Sign @@ -257,7 +257,7 @@ public void FeeIsSignatureContractDetailed() verificationGas += engine.GasConsumed; } } - Assert.AreEqual(verificationGas, 1000390); + Assert.AreEqual(verificationGas, 1000380); // ------------------ // check tx_size cost @@ -281,12 +281,12 @@ public void FeeIsSignatureContractDetailed() // I + II + III + IV Assert.AreEqual(25 + 22 + 1 + 86 + 110, tx.Size); - Assert.AreEqual(1000, NativeContract.Policy.GetFeePerByte(snapshot)); - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + Assert.AreEqual(33, NativeContract.Policy.GetFeePerByte(snapshot)); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); // final check: verification_cost and tx_size - Assert.AreEqual(244000, sizeGas); - Assert.AreEqual(1000390, verificationGas); + Assert.AreEqual(241560, sizeGas); + Assert.AreEqual(1000380, verificationGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); @@ -371,9 +371,9 @@ public void FeeIsSignatureContract_TestScope_Global() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1244390, verificationGas + sizeGas); + Assert.AreEqual(1241940, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -458,9 +458,9 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1265390, verificationGas + sizeGas); + Assert.AreEqual(1262730, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -548,9 +548,9 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1265390, verificationGas + sizeGas); + Assert.AreEqual(1262730, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -690,9 +690,9 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1285390, verificationGas + sizeGas); + Assert.AreEqual(1282530, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -1040,9 +1040,9 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1244390, verificationGas + sizeGas); + Assert.AreEqual(1241940, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -1267,9 +1267,9 @@ public void Test_Verify() //Change FeeRatio StorageItem storage = snapshot.Storages.GetAndChange(new KeyBuilder(-3, 34), () => new StorageItem()); - storage.Set(50); + storage.Set(15); snapshot.Commit(); - NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(50); + NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(15); // Make transaction @@ -1293,7 +1293,7 @@ public void Test_Verify() tx.Witnesses = data.GetWitnesses(); tx.Verify(snapshot, new TransactionVerificationContext()).Should().Be(VerifyResult.Succeed); - using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, tx.SystemFee * PolicyContract.MaximumRatioVariety / NativeContract.Policy.GetFeeRatio(snapshot))) + using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, tx.SystemFee / NativeContract.Policy.GetFeeRatio(snapshot))) { engine.LoadScript(tx.Script); VMState state = engine.Execute(); @@ -1302,9 +1302,9 @@ public void Test_Verify() //Revert FeeRatio storage = snapshot.Storages.GetAndChange(new KeyBuilder(-3, 34), () => new StorageItem()); - storage.Set(100); + storage.Set(30); snapshot.Commit(); - NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(100); + NativeContract.Policy.GetFeeRatio(snapshot).Should().Be(30); } } } diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index 16e2ae9efd..fe74519a25 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -39,7 +39,7 @@ public void Check_Default() ret = NativeContract.Policy.Call(snapshot, "getFeePerByte"); ret.Should().BeOfType(); - ret.GetInteger().Should().Be(1000); + ret.GetInteger().Should().Be(33); } [TestMethod] @@ -196,7 +196,7 @@ public void Check_SetFeePerByte() ret = NativeContract.Policy.Call(snapshot, "getFeePerByte"); ret.Should().BeOfType(); - ret.GetInteger().Should().Be(1000); + ret.GetInteger().Should().Be(33); // With signature UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot); diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs b/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs index 00e3d09444..e7965cabe2 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs @@ -3,6 +3,7 @@ using Neo.Ledger; using Neo.SmartContract; using Neo.SmartContract.Manifest; +using Neo.SmartContract.Native; using Neo.VM; namespace Neo.UnitTests.SmartContract @@ -24,7 +25,7 @@ public void ApplicationEngineFixedPrices() using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, null, 0)) { ae.LoadScript(SyscallSystemRuntimeCheckWitnessHash); - ApplicationEngine.System_Runtime_CheckWitness.FixedPrice.Should().Be(0_00030000L); + ApplicationEngine.System_Runtime_CheckWitness.FixedPrice.Should().Be(0_00001000L); } // System.Storage.GetContext: 9bf667ce (price is 1) @@ -32,7 +33,7 @@ public void ApplicationEngineFixedPrices() using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, null, 0)) { ae.LoadScript(SyscallSystemStorageGetContextHash); - ApplicationEngine.System_Storage_GetContext.FixedPrice.Should().Be(0_00000400L); + ApplicationEngine.System_Storage_GetContext.FixedPrice.Should().Be(0_00000013L); } // System.Storage.Get: 925de831 (price is 100) @@ -40,7 +41,7 @@ public void ApplicationEngineFixedPrices() using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, null, 0)) { ae.LoadScript(SyscallSystemStorageGetHash); - ApplicationEngine.System_Storage_Get.FixedPrice.Should().Be(0_01000000L); + ApplicationEngine.System_Storage_Get.FixedPrice.Should().Be(0_00033333L); } } @@ -74,7 +75,7 @@ public void ApplicationEngineRegularPut() debugger.StepInto(); var setupPrice = ae.GasConsumed; debugger.Execute(); - (ae.GasConsumed - setupPrice).Should().Be(ApplicationEngine.StoragePrice * (1 + value.Length)); + (ae.GasConsumed - setupPrice).Should().Be(ApplicationEngine.StoragePrice * (1 + value.Length) * NativeContract.Policy.GetFeeRatio(snapshot)); } } @@ -108,7 +109,7 @@ public void ApplicationEngineReusedStorage_FullReuse() debugger.StepInto(); var setupPrice = applicationEngine.GasConsumed; debugger.Execute(); - (applicationEngine.GasConsumed - setupPrice).Should().Be(1 * ApplicationEngine.StoragePrice); + (applicationEngine.GasConsumed - setupPrice).Should().Be(1 * ApplicationEngine.StoragePrice * NativeContract.Policy.GetFeeRatio(snapshot)); } } @@ -145,7 +146,7 @@ public void ApplicationEngineReusedStorage_PartialReuse() var setupPrice = ae.GasConsumed; debugger.StepInto(); debugger.StepInto(); - (ae.GasConsumed - setupPrice).Should().Be((1 + (oldValue.Length / 4) + value.Length - oldValue.Length) * ApplicationEngine.StoragePrice); + (ae.GasConsumed - setupPrice).Should().Be((1 + (oldValue.Length / 4) + value.Length - oldValue.Length) * ApplicationEngine.StoragePrice * NativeContract.Policy.GetFeeRatio(snapshot)); } } @@ -185,7 +186,7 @@ public void ApplicationEngineReusedStorage_PartialReuseTwice() debugger.StepInto(); //syscall Storage.GetContext var setupPrice = ae.GasConsumed; debugger.StepInto(); //syscall Storage.Put - (ae.GasConsumed - setupPrice).Should().Be((sItem.Value.Length / 4 + 1) * ApplicationEngine.StoragePrice); // = PUT basic fee + (ae.GasConsumed - setupPrice).Should().Be((sItem.Value.Length / 4 + 1) * ApplicationEngine.StoragePrice * NativeContract.Policy.GetFeeRatio(snapshot)); // = PUT basic fee } } diff --git a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs index 1c3f430a45..8139d91f24 100644 --- a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs +++ b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs @@ -119,7 +119,7 @@ public void TestVerifyWitnesses() UInt256 index1 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); snapshot1.Blocks.Add(index1, new TrimmedBlock()); snapshot1.Blocks.Delete(index1); - Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, snapshot1, 100)); + Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, snapshot1, 3)); var snapshot2 = Blockchain.Singleton.GetSnapshot(); UInt256 index2 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); @@ -130,7 +130,7 @@ public void TestVerifyWitnesses() snapshot2.Contracts.Add(UInt160.Zero, new ContractState()); snapshot2.Contracts.Delete(UInt160.Zero); - Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header2, snapshot2, 100)); + Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header2, snapshot2, 3)); var snapshot3 = Blockchain.Singleton.GetSnapshot(); UInt256 index3 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); @@ -151,7 +151,7 @@ public void TestVerifyWitnesses() Script = Array.Empty(), Manifest = TestUtils.CreateManifest(UInt160.Zero, "verify", ContractParameterType.Boolean, ContractParameterType.Signature), }); - Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 100)); + Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 3)); // Smart contract verification diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs index 654b686160..f3d04f11c0 100644 --- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -3,6 +3,7 @@ using Neo.Ledger; using Neo.Network.P2P.Payloads; using Neo.SmartContract; +using Neo.SmartContract.Native; using Neo.VM; using Neo.VM.Types; using System.Linq; @@ -278,7 +279,7 @@ public void System_Runtime_GasLeft() // Execute - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 100_000_000); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 100_000_000 / NativeContract.Policy.GetFeeRatio(snapshot)); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -287,7 +288,7 @@ public void System_Runtime_GasLeft() CollectionAssert.AreEqual ( engine.ResultStack.Select(u => (int)u.GetInteger()).ToArray(), - new int[] { 99_999_570, 99_999_140, 99_998_650 } + new int[] { 99_999_570, 99_999_150, 99_998_670 } ); } @@ -307,7 +308,7 @@ public void System_Runtime_GasLeft() Assert.AreEqual(engine.Execute(), VMState.HALT); Assert.AreEqual(1, engine.ResultStack.Count); Assert.IsInstanceOfType(engine.ResultStack.Peek(), typeof(Integer)); - Assert.AreEqual(1999999600, engine.ResultStack.Pop().GetInteger()); + Assert.AreEqual(1999999620, engine.ResultStack.Pop().GetInteger()); } } From 9aace9f62aa0e9df5132293d0f2d9ba3447ee3f1 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 4 Nov 2020 15:43:04 +0800 Subject: [PATCH 05/18] Optimize --- src/neo/Network/P2P/Payloads/BlockBase.cs | 6 ++- .../Network/P2P/Payloads/ConsensusPayload.cs | 6 ++- src/neo/Network/P2P/Payloads/Transaction.cs | 8 ++-- src/neo/Network/P2P/Payloads/Witness.cs | 1 + .../ApplicationEngine.Contract.cs | 4 +- .../ApplicationEngine.Storage.cs | 6 +-- src/neo/SmartContract/ApplicationEngine.cs | 26 +++++++++---- src/neo/SmartContract/Helper.cs | 38 +++++++++++-------- src/neo/SmartContract/InteropDescriptor.cs | 4 +- .../Native/Designate/DesignateContract.cs | 2 +- src/neo/Wallets/Wallet.cs | 4 +- .../Network/P2P/Payloads/UT_Transaction.cs | 14 +++---- .../SmartContract/UT_InteropPrices.cs | 8 ++-- .../SmartContract/UT_SmartContractHelper.cs | 8 ++-- 14 files changed, 84 insertions(+), 51 deletions(-) diff --git a/src/neo/Network/P2P/Payloads/BlockBase.cs b/src/neo/Network/P2P/Payloads/BlockBase.cs index 3465032ebd..5bff5bcf0c 100644 --- a/src/neo/Network/P2P/Payloads/BlockBase.cs +++ b/src/neo/Network/P2P/Payloads/BlockBase.cs @@ -3,6 +3,7 @@ using Neo.IO.Json; using Neo.Persistence; using Neo.SmartContract; +using Neo.SmartContract.Native; using Neo.Wallets; using System; using System.IO; @@ -118,7 +119,10 @@ public virtual bool Verify(StoreView snapshot) if (prev_header == null) return false; if (prev_header.Index + 1 != Index) return false; if (prev_header.Timestamp >= Timestamp) return false; - if (!this.VerifyWitnesses(snapshot, 0_03333333)) return false; + long remains = this.VerifyWitnesses(snapshot, 1_00000000); + if (remains < 0) return false; + remains = this.VerifyWitnesses(snapshot, remains, WitnessFlag.None, false); + if (remains < 0) return false; return true; } } diff --git a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs index 80e2f40ffb..c24ca75c69 100644 --- a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs +++ b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs @@ -124,7 +124,11 @@ public bool Verify(StoreView snapshot) { if (BlockIndex <= snapshot.Height) return false; - return this.VerifyWitnesses(snapshot, 0_00066667); + long remains = this.VerifyWitnesses(snapshot, 0_20000000); + if (remains < 0) return false; + remains = this.VerifyWitnesses(snapshot, remains, WitnessFlag.None, false); + if (remains < 0) return false; + return true; } } } diff --git a/src/neo/Network/P2P/Payloads/Transaction.cs b/src/neo/Network/P2P/Payloads/Transaction.cs index f050b9fca7..b95eed2053 100644 --- a/src/neo/Network/P2P/Payloads/Transaction.cs +++ b/src/neo/Network/P2P/Payloads/Transaction.cs @@ -295,8 +295,10 @@ public virtual VerifyResult VerifyStateDependent(StoreView snapshot, Transaction if (!attribute.Verify(snapshot, this)) return VerifyResult.Invalid; long net_fee = (NetworkFee / NativeContract.Policy.GetFeeRatio(snapshot)) - (Size * NativeContract.Policy.GetFeePerByte(snapshot)); - if (!this.VerifyWitnesses(snapshot, net_fee, WitnessFlag.StateDependent)) - return VerifyResult.Invalid; + long remains = this.VerifyWitnesses(snapshot, net_fee, WitnessFlag.StateDependent); + if (remains < 0) return VerifyResult.Invalid; + remains = this.VerifyWitnesses(snapshot, remains * NativeContract.Policy.GetFeeRatio(snapshot), WitnessFlag.None, false); + if (remains < 0) return VerifyResult.Invalid; return VerifyResult.Succeed; } @@ -304,7 +306,7 @@ public virtual VerifyResult VerifyStateIndependent() { if (Size > MaxTransactionSize) return VerifyResult.Invalid; - if (!this.VerifyWitnesses(null, NetworkFee, WitnessFlag.StateIndependent)) + if (this.VerifyWitnesses(null, NetworkFee, WitnessFlag.StateIndependent) < 0) return VerifyResult.Invalid; return VerifyResult.Succeed; } diff --git a/src/neo/Network/P2P/Payloads/Witness.cs b/src/neo/Network/P2P/Payloads/Witness.cs index b6888c3cbb..69246f75d2 100644 --- a/src/neo/Network/P2P/Payloads/Witness.cs +++ b/src/neo/Network/P2P/Payloads/Witness.cs @@ -23,6 +23,7 @@ public class Witness : ISerializable public byte[] VerificationScript; internal long GasConsumedWithRatio { get; set; } + internal long GasConsumedWithoutRatio { get; set; } private UInt160 _scriptHash; public virtual UInt160 ScriptHash diff --git a/src/neo/SmartContract/ApplicationEngine.Contract.cs b/src/neo/SmartContract/ApplicationEngine.Contract.cs index 8a80bd87a8..b1a018c776 100644 --- a/src/neo/SmartContract/ApplicationEngine.Contract.cs +++ b/src/neo/SmartContract/ApplicationEngine.Contract.cs @@ -35,7 +35,7 @@ protected internal void CreateContract(byte[] script, byte[] manifest) if (manifest.Length == 0 || manifest.Length > ContractManifest.MaxLength) throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}"); - AddGas(StoragePrice * (script.Length + manifest.Length)); + AddGas(StoragePrice * (script.Length + manifest.Length), false); UInt160 hash = script.ToScriptHash(); ContractState contract = Snapshot.Contracts.TryGet(hash); @@ -66,7 +66,7 @@ protected internal void UpdateContract(byte[] script, byte[] manifest) { if (script is null && manifest is null) throw new ArgumentException(); - AddGas(StoragePrice * ((script?.Length ?? 0) + (manifest?.Length ?? 0))); + AddGas(StoragePrice * ((script?.Length ?? 0) + (manifest?.Length ?? 0)), false); var contract = Snapshot.Contracts.TryGet(CurrentScriptHash); if (contract is null) throw new InvalidOperationException($"Updating Contract Does Not Exist: {CurrentScriptHash}"); diff --git a/src/neo/SmartContract/ApplicationEngine.Storage.cs b/src/neo/SmartContract/ApplicationEngine.Storage.cs index 8f7309f27a..a15dbf3968 100644 --- a/src/neo/SmartContract/ApplicationEngine.Storage.cs +++ b/src/neo/SmartContract/ApplicationEngine.Storage.cs @@ -7,7 +7,7 @@ namespace Neo.SmartContract { partial class ApplicationEngine { - public const long StoragePrice = 3333; + public const long StoragePrice = 100000; public const int MaxStorageKeySize = 64; public const int MaxStorageValueSize = ushort.MaxValue; @@ -18,7 +18,7 @@ partial class ApplicationEngine public static readonly InteropDescriptor System_Storage_Find = Register("System.Storage.Find", nameof(Find), 0_00033333, CallFlags.AllowStates, false); public static readonly InteropDescriptor System_Storage_Put = Register("System.Storage.Put", nameof(Put), 0, CallFlags.AllowModifyStates, false); public static readonly InteropDescriptor System_Storage_PutEx = Register("System.Storage.PutEx", nameof(PutEx), 0, CallFlags.AllowModifyStates, false); - public static readonly InteropDescriptor System_Storage_Delete = Register("System.Storage.Delete", nameof(Delete), 1 * StoragePrice, CallFlags.AllowModifyStates, false); + public static readonly InteropDescriptor System_Storage_Delete = Register("System.Storage.Delete", nameof(Delete), 1 * StoragePrice, CallFlags.AllowModifyStates, false, false); protected internal StorageContext GetStorageContext() { @@ -107,7 +107,7 @@ private void PutExInternal(StorageContext context, byte[] key, byte[] value, Sto else newDataSize = (item.Value.Length - 1) / 4 + 1 + value.Length - item.Value.Length; } - AddGas(newDataSize * StoragePrice); + AddGas(newDataSize * StoragePrice, false); item.Value = value; item.IsConstant = flags.HasFlag(StorageFlags.Constant); diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs index c57715d126..ce4aa3e81a 100644 --- a/src/neo/SmartContract/ApplicationEngine.cs +++ b/src/neo/SmartContract/ApplicationEngine.cs @@ -55,8 +55,11 @@ private class InvocationState public IVerifiable ScriptContainer { get; } public StoreView Snapshot { get; } public long GasConsumedWithRatio = 0; - public long GasConsumed => GasConsumedWithRatio * NativeContract.Policy.GetFeeRatio(Snapshot); - public long GasLeft => (gas_amount_with_ratio - GasConsumedWithRatio) * NativeContract.Policy.GetFeeRatio(Snapshot); + public long GasConsumedWithoutRatio = 0; + public long GasConsumed => GasConsumedWithRatio * NativeContract.Policy.GetFeeRatio(Snapshot) + GasConsumedWithoutRatio; + public long GasLeft => Snapshot == null + ? gas_amount_with_ratio - GasConsumedWithRatio + : (gas_amount_with_ratio - GasConsumedWithRatio) * NativeContract.Policy.GetFeeRatio(Snapshot) - GasConsumedWithoutRatio; public Exception FaultException { get; private set; } public UInt160 CurrentScriptHash => CurrentContext?.GetScriptHash(); public UInt160 CallingScriptHash => CurrentContext?.GetState().CallingScriptHash; @@ -71,10 +74,17 @@ protected ApplicationEngine(TriggerType trigger, IVerifiable container, StoreVie this.gas_amount_with_ratio = gas; } - protected internal void AddGas(long gas) + protected internal void AddGas(long gas, bool withRatio = true) { - GasConsumedWithRatio = checked(GasConsumedWithRatio + gas); - if (GasConsumedWithRatio > gas_amount_with_ratio) + if (withRatio) + { + GasConsumedWithRatio = checked(GasConsumedWithRatio + gas); + } + else + { + GasConsumedWithoutRatio = checked(GasConsumedWithoutRatio + gas); + } + if (GasLeft < 0) throw new InvalidOperationException("Insufficient GAS."); } @@ -258,7 +268,7 @@ protected override void OnSysCall(uint method) { InteropDescriptor descriptor = services[method]; ValidateCallFlags(descriptor); - AddGas(descriptor.FixedPrice); + AddGas(descriptor.FixedPrice, descriptor.WithRatio); List parameters = descriptor.Parameters.Count > 0 ? new List() : null; @@ -296,11 +306,11 @@ private static Block CreateDummyBlock(StoreView snapshot) }; } - private static InteropDescriptor Register(string name, string handler, long fixedPrice, CallFlags requiredCallFlags, bool allowCallback) + private static InteropDescriptor Register(string name, string handler, long fixedPrice, CallFlags requiredCallFlags, bool allowCallback, bool withRatio = true) { MethodInfo method = typeof(ApplicationEngine).GetMethod(handler, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) ?? typeof(ApplicationEngine).GetProperty(handler, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetMethod; - InteropDescriptor descriptor = new InteropDescriptor(name, method, fixedPrice, requiredCallFlags, allowCallback); + InteropDescriptor descriptor = new InteropDescriptor(name, method, fixedPrice, requiredCallFlags, allowCallback, withRatio); services ??= new Dictionary(); services.Add(descriptor.Hash, descriptor); return descriptor; diff --git a/src/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs index df72c128da..24f0bd6ad6 100644 --- a/src/neo/SmartContract/Helper.cs +++ b/src/neo/SmartContract/Helper.cs @@ -130,11 +130,10 @@ public static UInt160 ToScriptHash(this ReadOnlySpan script) return new UInt160(Crypto.Hash160(script)); } - internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All) + internal static long VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All, bool withRatio = true) { - if (gas < 0) return false; - if (snapshot is null) gas = MaxVerificationGas; - else if (gas > MaxVerificationGas) gas = MaxVerificationGas; + if (gas < 0) return gas; + if (snapshot is null || gas > MaxVerificationGas) gas = MaxVerificationGas; UInt160[] hashes; try @@ -143,16 +142,24 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap } catch (InvalidOperationException) { - return false; + return -1; } - if (hashes.Length != verifiable.Witnesses.Length) return false; + if (hashes.Length != verifiable.Witnesses.Length) return -1; for (int i = 0; i < hashes.Length; i++) { WitnessFlag flag = verifiable.Witnesses[i].StateDependent ? WitnessFlag.StateDependent : WitnessFlag.StateIndependent; if (!filter.HasFlag(flag)) { - gas -= verifiable.Witnesses[i].GasConsumedWithRatio; - if (gas < 0) return false; + if (withRatio) + { + gas -= verifiable.Witnesses[i].GasConsumedWithRatio; + if (gas < 0) return gas; + } + else + { + gas -= verifiable.Witnesses[i].GasConsumedWithoutRatio; + if (gas < 0) return gas; + } continue; } @@ -162,17 +169,17 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap if (verification.Length == 0) { ContractState cs = snapshot.Contracts.TryGet(hashes[i]); - if (cs is null) return false; + if (cs is null) return -1; ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod("verify"); - if (md is null) return false; + if (md is null) return -1; verification = cs.Script; offset = md.Offset; init = cs.Manifest.Abi.GetMethod("_initialize"); } else { - if (NativeContract.IsNative(hashes[i])) return false; - if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return false; + if (NativeContract.IsNative(hashes[i])) return -1; + if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return -1; offset = 0; } using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.Clone(), gas)) @@ -191,13 +198,14 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap engine.LoadContext(context.Clone(init.Offset), false); } engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None); - if (engine.Execute() == VMState.FAULT) return false; - if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return false; + if (engine.Execute() == VMState.FAULT) return -1; + if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return -1; gas -= engine.GasConsumedWithRatio; verifiable.Witnesses[i].GasConsumedWithRatio = engine.GasConsumedWithRatio; + verifiable.Witnesses[i].GasConsumedWithoutRatio = engine.GasConsumedWithoutRatio; } } - return true; + return gas; } } } diff --git a/src/neo/SmartContract/InteropDescriptor.cs b/src/neo/SmartContract/InteropDescriptor.cs index 690fac884c..8c5002aa06 100644 --- a/src/neo/SmartContract/InteropDescriptor.cs +++ b/src/neo/SmartContract/InteropDescriptor.cs @@ -16,8 +16,9 @@ public class InteropDescriptor public long FixedPrice { get; } public CallFlags RequiredCallFlags { get; } public bool AllowCallback { get; } + public bool WithRatio { get; } - internal InteropDescriptor(string name, MethodInfo handler, long fixedPrice, CallFlags requiredCallFlags, bool allowCallback) + internal InteropDescriptor(string name, MethodInfo handler, long fixedPrice, CallFlags requiredCallFlags, bool allowCallback, bool withRatio) { this.Name = name; this.Hash = BitConverter.ToUInt32(Encoding.ASCII.GetBytes(name).Sha256(), 0); @@ -26,6 +27,7 @@ internal InteropDescriptor(string name, MethodInfo handler, long fixedPrice, Cal this.FixedPrice = fixedPrice; this.RequiredCallFlags = requiredCallFlags; this.AllowCallback = allowCallback; + this.WithRatio = withRatio; } public static implicit operator uint(InteropDescriptor descriptor) diff --git a/src/neo/SmartContract/Native/Designate/DesignateContract.cs b/src/neo/SmartContract/Native/Designate/DesignateContract.cs index 10e6dce561..5a1b6febe8 100644 --- a/src/neo/SmartContract/Native/Designate/DesignateContract.cs +++ b/src/neo/SmartContract/Native/Designate/DesignateContract.cs @@ -24,7 +24,7 @@ internal DesignateContract() { Manifest.Features = ContractFeatures.HasStorage; } - + [ContractMethod(0_00033333, CallFlags.AllowStates)] public ECPoint[] GetDesignatedByRole(StoreView snapshot, Role role, uint index) { diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index ffee250bfb..bee952cdcd 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -369,6 +369,7 @@ public long CalculateNetworkFee(StoreView snapshot, Transaction tx) // base size for transaction: includes const_header + signers + attributes + script + hashes int size = Transaction.HeaderSize + tx.Signers.GetVarSize() + tx.Attributes.GetVarSize() + tx.Script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length); long networkFee = 0; + long networkFeeWithoutRatio = 0; foreach (UInt160 hash in hashes) { byte[] witness_script = GetAccount(hash)?.Contract?.Script; @@ -407,6 +408,7 @@ public long CalculateNetworkFee(StoreView snapshot, Transaction tx) if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) throw new ArgumentException($"Smart contract {contract.ScriptHash} returns false."); networkFee += engine.GasConsumedWithRatio; + networkFeeWithoutRatio = engine.GasConsumedWithoutRatio; } else if (witness_script.IsSignatureContract()) { @@ -431,7 +433,7 @@ public long CalculateNetworkFee(StoreView snapshot, Transaction tx) } } networkFee += size * NativeContract.Policy.GetFeePerByte(snapshot); - return networkFee * NativeContract.Policy.GetFeeRatio(snapshot); + return networkFee * NativeContract.Policy.GetFeeRatio(snapshot) + networkFeeWithoutRatio; } public bool Sign(ContractParametersContext context) diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index d65137ac39..aae78fd7bd 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -158,7 +158,7 @@ public void FeeIsMultiSigContract() // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); // Check @@ -240,7 +240,7 @@ public void FeeIsSignatureContractDetailed() // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); // Check @@ -354,7 +354,7 @@ public void FeeIsSignatureContract_TestScope_Global() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); // Check long verificationGas = 0; @@ -441,7 +441,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); // Check long verificationGas = 0; @@ -531,7 +531,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); // Check long verificationGas = 0; @@ -673,7 +673,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() tx.Signers.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); // Check long verificationGas = 0; @@ -1023,7 +1023,7 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); // Check long verificationGas = 0; diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs b/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs index e7965cabe2..3f74f7eaf7 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs @@ -75,7 +75,7 @@ public void ApplicationEngineRegularPut() debugger.StepInto(); var setupPrice = ae.GasConsumed; debugger.Execute(); - (ae.GasConsumed - setupPrice).Should().Be(ApplicationEngine.StoragePrice * (1 + value.Length) * NativeContract.Policy.GetFeeRatio(snapshot)); + (ae.GasConsumed - setupPrice).Should().Be(ApplicationEngine.StoragePrice * (1 + value.Length)); } } @@ -109,7 +109,7 @@ public void ApplicationEngineReusedStorage_FullReuse() debugger.StepInto(); var setupPrice = applicationEngine.GasConsumed; debugger.Execute(); - (applicationEngine.GasConsumed - setupPrice).Should().Be(1 * ApplicationEngine.StoragePrice * NativeContract.Policy.GetFeeRatio(snapshot)); + (applicationEngine.GasConsumed - setupPrice).Should().Be(1 * ApplicationEngine.StoragePrice); } } @@ -146,7 +146,7 @@ public void ApplicationEngineReusedStorage_PartialReuse() var setupPrice = ae.GasConsumed; debugger.StepInto(); debugger.StepInto(); - (ae.GasConsumed - setupPrice).Should().Be((1 + (oldValue.Length / 4) + value.Length - oldValue.Length) * ApplicationEngine.StoragePrice * NativeContract.Policy.GetFeeRatio(snapshot)); + (ae.GasConsumed - setupPrice).Should().Be((1 + (oldValue.Length / 4) + value.Length - oldValue.Length) * ApplicationEngine.StoragePrice); } } @@ -186,7 +186,7 @@ public void ApplicationEngineReusedStorage_PartialReuseTwice() debugger.StepInto(); //syscall Storage.GetContext var setupPrice = ae.GasConsumed; debugger.StepInto(); //syscall Storage.Put - (ae.GasConsumed - setupPrice).Should().Be((sItem.Value.Length / 4 + 1) * ApplicationEngine.StoragePrice * NativeContract.Policy.GetFeeRatio(snapshot)); // = PUT basic fee + (ae.GasConsumed - setupPrice).Should().Be((sItem.Value.Length / 4 + 1) * ApplicationEngine.StoragePrice); // = PUT basic fee } } diff --git a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs index 8139d91f24..fe3c6032e1 100644 --- a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs +++ b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs @@ -119,7 +119,7 @@ public void TestVerifyWitnesses() UInt256 index1 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); snapshot1.Blocks.Add(index1, new TrimmedBlock()); snapshot1.Blocks.Delete(index1); - Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, snapshot1, 3)); + Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, snapshot1, 3) < 0); var snapshot2 = Blockchain.Singleton.GetSnapshot(); UInt256 index2 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); @@ -130,7 +130,7 @@ public void TestVerifyWitnesses() snapshot2.Contracts.Add(UInt160.Zero, new ContractState()); snapshot2.Contracts.Delete(UInt160.Zero); - Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header2, snapshot2, 3)); + Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(header2, snapshot2, 3) < 0); var snapshot3 = Blockchain.Singleton.GetSnapshot(); UInt256 index3 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); @@ -151,7 +151,7 @@ public void TestVerifyWitnesses() Script = Array.Empty(), Manifest = TestUtils.CreateManifest(UInt160.Zero, "verify", ContractParameterType.Boolean, ContractParameterType.Signature), }); - Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 3)); + Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 3) < 0); // Smart contract verification @@ -166,7 +166,7 @@ public void TestVerifyWitnesses() Witnesses = new Witness[] { new Witness() { InvocationScript = new byte[0], VerificationScript = new byte[0] } } }; - Assert.AreEqual(true, Neo.SmartContract.Helper.VerifyWitnesses(tx, snapshot3, 1000)); + Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(tx, snapshot3, 1000) >= 0); } } } From 1abfc6f867f86c95da0cf1800d8171d0fe2aec0d Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 4 Nov 2020 16:26:04 +0800 Subject: [PATCH 06/18] format --- src/neo/Network/P2P/Payloads/BlockBase.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/neo/Network/P2P/Payloads/BlockBase.cs b/src/neo/Network/P2P/Payloads/BlockBase.cs index 5bff5bcf0c..00848dc8d7 100644 --- a/src/neo/Network/P2P/Payloads/BlockBase.cs +++ b/src/neo/Network/P2P/Payloads/BlockBase.cs @@ -1,9 +1,7 @@ -using Neo.Cryptography; using Neo.IO; using Neo.IO.Json; using Neo.Persistence; using Neo.SmartContract; -using Neo.SmartContract.Native; using Neo.Wallets; using System; using System.IO; From 9c0ad3aebebf39a856cdd11dd143837b1ff41616 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Thu, 5 Nov 2020 11:13:21 +0800 Subject: [PATCH 07/18] Fix typo --- src/neo/Network/P2P/Payloads/ConsensusPayload.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs index c24ca75c69..25c85dd894 100644 --- a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs +++ b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs @@ -124,7 +124,7 @@ public bool Verify(StoreView snapshot) { if (BlockIndex <= snapshot.Height) return false; - long remains = this.VerifyWitnesses(snapshot, 0_20000000); + long remains = this.VerifyWitnesses(snapshot, 0_02000000); if (remains < 0) return false; remains = this.VerifyWitnesses(snapshot, remains, WitnessFlag.None, false); if (remains < 0) return false; From 7e67f44bb3339b81aef598e150888797618c2bc5 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Thu, 5 Nov 2020 14:07:21 +0800 Subject: [PATCH 08/18] fee adjust --- src/neo/Network/P2P/Payloads/BlockBase.cs | 2 +- src/neo/Network/P2P/Payloads/ConsensusPayload.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/neo/Network/P2P/Payloads/BlockBase.cs b/src/neo/Network/P2P/Payloads/BlockBase.cs index 00848dc8d7..7afb523ad8 100644 --- a/src/neo/Network/P2P/Payloads/BlockBase.cs +++ b/src/neo/Network/P2P/Payloads/BlockBase.cs @@ -117,7 +117,7 @@ public virtual bool Verify(StoreView snapshot) if (prev_header == null) return false; if (prev_header.Index + 1 != Index) return false; if (prev_header.Timestamp >= Timestamp) return false; - long remains = this.VerifyWitnesses(snapshot, 1_00000000); + long remains = this.VerifyWitnesses(snapshot, 0_03333333); if (remains < 0) return false; remains = this.VerifyWitnesses(snapshot, remains, WitnessFlag.None, false); if (remains < 0) return false; diff --git a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs index 25c85dd894..33ab951bdd 100644 --- a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs +++ b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs @@ -124,7 +124,7 @@ public bool Verify(StoreView snapshot) { if (BlockIndex <= snapshot.Height) return false; - long remains = this.VerifyWitnesses(snapshot, 0_02000000); + long remains = this.VerifyWitnesses(snapshot, 0_00066666); if (remains < 0) return false; remains = this.VerifyWitnesses(snapshot, remains, WitnessFlag.None, false); if (remains < 0) return false; From cb59e8fdedf2cb721166d85d43739f2592f4d915 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Thu, 5 Nov 2020 14:13:21 +0800 Subject: [PATCH 09/18] fee adjust --- src/neo/Network/P2P/Payloads/BlockBase.cs | 3 ++- src/neo/Network/P2P/Payloads/ConsensusPayload.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/neo/Network/P2P/Payloads/BlockBase.cs b/src/neo/Network/P2P/Payloads/BlockBase.cs index 7afb523ad8..bb80dfa0e2 100644 --- a/src/neo/Network/P2P/Payloads/BlockBase.cs +++ b/src/neo/Network/P2P/Payloads/BlockBase.cs @@ -2,6 +2,7 @@ using Neo.IO.Json; using Neo.Persistence; using Neo.SmartContract; +using Neo.SmartContract.Native; using Neo.Wallets; using System; using System.IO; @@ -119,7 +120,7 @@ public virtual bool Verify(StoreView snapshot) if (prev_header.Timestamp >= Timestamp) return false; long remains = this.VerifyWitnesses(snapshot, 0_03333333); if (remains < 0) return false; - remains = this.VerifyWitnesses(snapshot, remains, WitnessFlag.None, false); + remains = this.VerifyWitnesses(snapshot, remains * NativeContract.Policy.GetFeeRatio(snapshot), WitnessFlag.None, false); if (remains < 0) return false; return true; } diff --git a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs index 33ab951bdd..7fb949092d 100644 --- a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs +++ b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs @@ -126,7 +126,7 @@ public bool Verify(StoreView snapshot) return false; long remains = this.VerifyWitnesses(snapshot, 0_00066666); if (remains < 0) return false; - remains = this.VerifyWitnesses(snapshot, remains, WitnessFlag.None, false); + remains = this.VerifyWitnesses(snapshot, remains * NativeContract.Policy.GetFeeRatio(snapshot), WitnessFlag.None, false); if (remains < 0) return false; return true; } From ee56bf625d085335d432c30caff2c1dfc90b1f06 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 11 Nov 2020 12:07:56 +0800 Subject: [PATCH 10/18] Rewrite logic --- src/neo/Ledger/Blockchain.cs | 3 +- src/neo/Ledger/MemoryPool.cs | 5 +- src/neo/Network/P2P/Payloads/BlockBase.cs | 5 +- .../Network/P2P/Payloads/ConsensusPayload.cs | 6 +-- src/neo/Network/P2P/Payloads/Transaction.cs | 10 ++-- src/neo/Network/P2P/Payloads/Witness.cs | 3 +- src/neo/SmartContract/ApplicationEngine.cs | 36 +++++++------ src/neo/SmartContract/Helper.cs | 42 +++++++--------- .../Native/Oracle/OracleContract.cs | 3 +- .../SmartContract/Native/PolicyContract.cs | 4 +- src/neo/Wallets/AssetDescriptor.cs | 6 ++- src/neo/Wallets/Wallet.cs | 21 ++++---- .../Network/P2P/Payloads/UT_Transaction.cs | 50 +++++++++---------- .../SmartContract/Native/UT_PolicyContract.cs | 4 +- .../SmartContract/UT_SmartContractHelper.cs | 8 +-- .../SmartContract/UT_Syscalls.cs | 4 +- 16 files changed, 98 insertions(+), 112 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index c05f5e7e27..4418e461d8 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -446,7 +446,6 @@ private void Persist(Block block) all_application_executed.Add(application_executed); } snapshot.Blocks.Add(block.Hash, block.Trim()); - uint ratio = NativeContract.Policy.GetFeeRatio(snapshot); StoreView clonedSnapshot = snapshot.Clone(); // Warning: Do not write into variable snapshot directly. Write into variable clonedSnapshot and commit instead. foreach (Transaction tx in block.Transactions) @@ -460,7 +459,7 @@ private void Persist(Block block) clonedSnapshot.Transactions.Add(tx.Hash, state); clonedSnapshot.Transactions.Commit(); - using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee / ratio)) + using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee)) { engine.LoadScript(tx.Script); state.VMState = engine.Execute(); diff --git a/src/neo/Ledger/MemoryPool.cs b/src/neo/Ledger/MemoryPool.cs index 998b56e3a2..555f79528a 100644 --- a/src/neo/Ledger/MemoryPool.cs +++ b/src/neo/Ledger/MemoryPool.cs @@ -62,6 +62,7 @@ public class MemoryPool : IReadOnlyCollection private int _maxTxPerBlock; private long _feePerByte; + private uint _feeRatio; /// /// Total maximum capacity of transactions the pool can hold. @@ -109,8 +110,10 @@ internal bool LoadPolicy(StoreView snapshot) { _maxTxPerBlock = (int)NativeContract.Policy.GetMaxTransactionsPerBlock(snapshot); long newFeePerByte = NativeContract.Policy.GetFeePerByte(snapshot); - bool policyChanged = newFeePerByte > _feePerByte; + uint newFeeRatio = NativeContract.Policy.GetFeeRatio(snapshot); + bool policyChanged = newFeePerByte > _feePerByte || newFeeRatio > _feeRatio; _feePerByte = newFeePerByte; + _feeRatio = newFeeRatio; return policyChanged; } diff --git a/src/neo/Network/P2P/Payloads/BlockBase.cs b/src/neo/Network/P2P/Payloads/BlockBase.cs index bb80dfa0e2..8d091b075b 100644 --- a/src/neo/Network/P2P/Payloads/BlockBase.cs +++ b/src/neo/Network/P2P/Payloads/BlockBase.cs @@ -118,10 +118,7 @@ public virtual bool Verify(StoreView snapshot) if (prev_header == null) return false; if (prev_header.Index + 1 != Index) return false; if (prev_header.Timestamp >= Timestamp) return false; - long remains = this.VerifyWitnesses(snapshot, 0_03333333); - if (remains < 0) return false; - remains = this.VerifyWitnesses(snapshot, remains * NativeContract.Policy.GetFeeRatio(snapshot), WitnessFlag.None, false); - if (remains < 0) return false; + if (!this.VerifyWitnesses(snapshot, 0_03333333 * NativeContract.Policy.GetFeeRatio(snapshot))) return false; return true; } } diff --git a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs index 7fb949092d..e55b3ac7b0 100644 --- a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs +++ b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs @@ -124,11 +124,7 @@ public bool Verify(StoreView snapshot) { if (BlockIndex <= snapshot.Height) return false; - long remains = this.VerifyWitnesses(snapshot, 0_00066666); - if (remains < 0) return false; - remains = this.VerifyWitnesses(snapshot, remains * NativeContract.Policy.GetFeeRatio(snapshot), WitnessFlag.None, false); - if (remains < 0) return false; - return true; + return this.VerifyWitnesses(snapshot, 0_00066666 * NativeContract.Policy.GetFeeRatio(snapshot)); } } } diff --git a/src/neo/Network/P2P/Payloads/Transaction.cs b/src/neo/Network/P2P/Payloads/Transaction.cs index 6a267d53ca..fabb005c9a 100644 --- a/src/neo/Network/P2P/Payloads/Transaction.cs +++ b/src/neo/Network/P2P/Payloads/Transaction.cs @@ -294,11 +294,9 @@ public virtual VerifyResult VerifyStateDependent(StoreView snapshot, Transaction foreach (TransactionAttribute attribute in Attributes) if (!attribute.Verify(snapshot, this)) return VerifyResult.Invalid; - long net_fee = (NetworkFee / NativeContract.Policy.GetFeeRatio(snapshot)) - (Size * NativeContract.Policy.GetFeePerByte(snapshot)); - long remains = this.VerifyWitnesses(snapshot, net_fee, WitnessFlag.StateDependent); - if (remains < 0) return VerifyResult.Invalid; - remains = this.VerifyWitnesses(snapshot, remains * NativeContract.Policy.GetFeeRatio(snapshot), WitnessFlag.None, false); - if (remains < 0) return VerifyResult.Invalid; + long net_fee = NetworkFee - Size * NativeContract.Policy.GetFeePerByte(snapshot); + if (!this.VerifyWitnesses(snapshot, net_fee, WitnessFlag.StateDependent)) + return VerifyResult.Invalid; return VerifyResult.Succeed; } @@ -306,7 +304,7 @@ public virtual VerifyResult VerifyStateIndependent() { if (Size > MaxTransactionSize) return VerifyResult.Invalid; - if (this.VerifyWitnesses(null, NetworkFee, WitnessFlag.StateIndependent) < 0) + if (!this.VerifyWitnesses(null, NetworkFee, WitnessFlag.StateIndependent)) return VerifyResult.Invalid; return VerifyResult.Succeed; } diff --git a/src/neo/Network/P2P/Payloads/Witness.cs b/src/neo/Network/P2P/Payloads/Witness.cs index 69246f75d2..7ae2d51d70 100644 --- a/src/neo/Network/P2P/Payloads/Witness.cs +++ b/src/neo/Network/P2P/Payloads/Witness.cs @@ -22,8 +22,7 @@ public class Witness : ISerializable public byte[] InvocationScript; public byte[] VerificationScript; - internal long GasConsumedWithRatio { get; set; } - internal long GasConsumedWithoutRatio { get; set; } + internal long GasConsumed { get; set; } private UInt160 _scriptHash; public virtual UInt160 ScriptHash diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs index a29e2fb9a5..dea1033de9 100644 --- a/src/neo/SmartContract/ApplicationEngine.cs +++ b/src/neo/SmartContract/ApplicationEngine.cs @@ -43,23 +43,20 @@ private class InvocationState private static IApplicationEngineProvider applicationEngineProvider; private static Dictionary services; - private readonly long gas_amount_with_ratio; + private readonly long gas_amount; private List notifications; private List disposables; private readonly Dictionary invocationCounter = new Dictionary(); private readonly Dictionary invocationStates = new Dictionary(); + private readonly uint feeRatio; public static IReadOnlyDictionary Services => services; private List Disposables => disposables ??= new List(); public TriggerType Trigger { get; } public IVerifiable ScriptContainer { get; } public StoreView Snapshot { get; } - public long GasConsumedWithRatio = 0; - public long GasConsumedWithoutRatio = 0; - public long GasConsumed => GasConsumedWithRatio * NativeContract.Policy.GetFeeRatio(Snapshot) + GasConsumedWithoutRatio; - public long GasLeft => Snapshot == null - ? gas_amount_with_ratio - GasConsumedWithRatio - : (gas_amount_with_ratio - GasConsumedWithRatio) * NativeContract.Policy.GetFeeRatio(Snapshot) - GasConsumedWithoutRatio; + public long GasConsumed { get; private set; } = 0; + public long GasLeft => gas_amount - GasConsumed; public Exception FaultException { get; private set; } public UInt160 CurrentScriptHash => CurrentContext?.GetScriptHash(); public UInt160 CallingScriptHash => CurrentContext?.GetState().CallingScriptHash; @@ -71,20 +68,15 @@ protected ApplicationEngine(TriggerType trigger, IVerifiable container, StoreVie this.Trigger = trigger; this.ScriptContainer = container; this.Snapshot = snapshot; - this.gas_amount_with_ratio = gas; + this.gas_amount = gas; + this.feeRatio = snapshot is null ? 1 : NativeContract.Policy.GetFeeRatio(Snapshot); } protected internal void AddGas(long gas, bool withRatio = true) { - if (withRatio) - { - GasConsumedWithRatio = checked(GasConsumedWithRatio + gas); - } - else - { - GasConsumedWithoutRatio = checked(GasConsumedWithoutRatio + gas); - } - if (GasLeft < 0) + if (withRatio && Snapshot != null) gas *= feeRatio; + GasConsumed = checked(GasConsumed + gas); + if (GasConsumed > gas_amount) throw new InvalidOperationException("Insufficient GAS."); } @@ -146,8 +138,13 @@ protected override void ContextUnloaded(ExecutionContext context) } } - public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas = TestModeGas) + public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas = -1) { + if (gas == -1) + { + if (snapshot != null) gas = TestModeGas * NativeContract.Policy.GetFeeRatio(snapshot); + else gas = TestModeGas; + } return applicationEngineProvider?.Create(trigger, container, snapshot, gas) ?? new ApplicationEngine(trigger, container, snapshot, gas); } @@ -321,7 +318,7 @@ internal static void ResetApplicationEngineProvider() Exchange(ref applicationEngineProvider, null); } - public static ApplicationEngine Run(byte[] script, StoreView snapshot = null, IVerifiable container = null, Block persistingBlock = null, int offset = 0, long gas = TestModeGas) + public static ApplicationEngine Run(byte[] script, StoreView snapshot = null, IVerifiable container = null, Block persistingBlock = null, int offset = 0, long gas = -1) { SnapshotView disposable = null; if (snapshot is null) @@ -329,6 +326,7 @@ public static ApplicationEngine Run(byte[] script, StoreView snapshot = null, IV disposable = Blockchain.Singleton.GetSnapshot(); snapshot = disposable; } + if (gas == -1) gas = TestModeGas * NativeContract.Policy.GetFeeRatio(snapshot); snapshot.PersistingBlock = persistingBlock ?? snapshot.PersistingBlock ?? CreateDummyBlock(snapshot); ApplicationEngine engine = Create(TriggerType.Application, container, snapshot, gas); if (disposable != null) engine.Disposables.Add(disposable); diff --git a/src/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs index 24f0bd6ad6..0b95e20c17 100644 --- a/src/neo/SmartContract/Helper.cs +++ b/src/neo/SmartContract/Helper.cs @@ -14,7 +14,7 @@ namespace Neo.SmartContract { public static class Helper { - private const long MaxVerificationGas = 0_01666667; + private const long MaxVerificationGas = 0_50000000; public static UInt160 GetScriptHash(this ExecutionContext context) { @@ -130,9 +130,9 @@ public static UInt160 ToScriptHash(this ReadOnlySpan script) return new UInt160(Crypto.Hash160(script)); } - internal static long VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All, bool withRatio = true) + internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All, bool withRatio = true) { - if (gas < 0) return gas; + if (gas < 0) return false; if (snapshot is null || gas > MaxVerificationGas) gas = MaxVerificationGas; UInt160[] hashes; @@ -142,24 +142,17 @@ internal static long VerifyWitnesses(this IVerifiable verifiable, StoreView snap } catch (InvalidOperationException) { - return -1; + return false; } - if (hashes.Length != verifiable.Witnesses.Length) return -1; + if (hashes.Length != verifiable.Witnesses.Length) return false; for (int i = 0; i < hashes.Length; i++) { WitnessFlag flag = verifiable.Witnesses[i].StateDependent ? WitnessFlag.StateDependent : WitnessFlag.StateIndependent; if (!filter.HasFlag(flag)) { - if (withRatio) - { - gas -= verifiable.Witnesses[i].GasConsumedWithRatio; - if (gas < 0) return gas; - } - else - { - gas -= verifiable.Witnesses[i].GasConsumedWithoutRatio; - if (gas < 0) return gas; - } + if (snapshot == null) gas -= verifiable.Witnesses[i].GasConsumed; + else gas -= verifiable.Witnesses[i].GasConsumed * NativeContract.Policy.GetFeeRatio(snapshot); + if (gas < 0) return false; continue; } @@ -169,17 +162,17 @@ internal static long VerifyWitnesses(this IVerifiable verifiable, StoreView snap if (verification.Length == 0) { ContractState cs = snapshot.Contracts.TryGet(hashes[i]); - if (cs is null) return -1; + if (cs is null) return false; ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod("verify"); - if (md is null) return -1; + if (md is null) return false; verification = cs.Script; offset = md.Offset; init = cs.Manifest.Abi.GetMethod("_initialize"); } else { - if (NativeContract.IsNative(hashes[i])) return -1; - if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return -1; + if (NativeContract.IsNative(hashes[i])) return false; + if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return false; offset = 0; } using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.Clone(), gas)) @@ -198,14 +191,13 @@ internal static long VerifyWitnesses(this IVerifiable verifiable, StoreView snap engine.LoadContext(context.Clone(init.Offset), false); } engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None); - if (engine.Execute() == VMState.FAULT) return -1; - if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return -1; - gas -= engine.GasConsumedWithRatio; - verifiable.Witnesses[i].GasConsumedWithRatio = engine.GasConsumedWithRatio; - verifiable.Witnesses[i].GasConsumedWithoutRatio = engine.GasConsumedWithoutRatio; + if (engine.Execute() == VMState.FAULT) return false; + if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return false; + gas -= engine.GasConsumed; + verifiable.Witnesses[i].GasConsumed = engine.GasConsumed; } } - return gas; + return true; } } } diff --git a/src/neo/SmartContract/Native/Oracle/OracleContract.cs b/src/neo/SmartContract/Native/Oracle/OracleContract.cs index 0e19d75172..a165c4af6e 100644 --- a/src/neo/SmartContract/Native/Oracle/OracleContract.cs +++ b/src/neo/SmartContract/Native/Oracle/OracleContract.cs @@ -1,5 +1,6 @@ #pragma warning disable IDE0051 +using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Neo.Cryptography; using Neo.IO; using Neo.Ledger; @@ -182,7 +183,7 @@ private void Request(ApplicationEngine engine, string url, string filter, string if (Utility.StrictUTF8.GetByteCount(url) > MaxUrlLength || (filter != null && Utility.StrictUTF8.GetByteCount(filter) > MaxFilterLength) || Utility.StrictUTF8.GetByteCount(callback) > MaxCallbackLength - || gasForResponse < 0_00333333) + || gasForResponse < 0_00333333 * Policy.GetFeeRatio(engine.Snapshot)) throw new ArgumentException(); //Mint gas for the response diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs index a2b97f1a5c..905ee912fa 100644 --- a/src/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -15,7 +15,7 @@ public sealed class PolicyContract : NativeContract public override string Name => "Policy"; public override int Id => -3; - private const uint MaximumRatio = 10000; + private const uint MaximumRatio = 1000; private const byte Prefix_MaxTransactionsPerBlock = 23; private const byte Prefix_FeePerByte = 10; private const byte Prefix_BlockedAccount = 15; @@ -56,7 +56,7 @@ public long GetMaxBlockSystemFee(StoreView snapshot) public long GetFeePerByte(StoreView snapshot) { StorageItem item = snapshot.Storages.TryGet(CreateStorageKey(Prefix_FeePerByte)); - if (item is null) return 33; + if (item is null) return 1000; return (long)(BigInteger)item; } diff --git a/src/neo/Wallets/AssetDescriptor.cs b/src/neo/Wallets/AssetDescriptor.cs index 776c0e9388..018113c76f 100644 --- a/src/neo/Wallets/AssetDescriptor.cs +++ b/src/neo/Wallets/AssetDescriptor.cs @@ -1,4 +1,7 @@ +using Neo.Ledger; +using Neo.Persistence; using Neo.SmartContract; +using Neo.SmartContract.Native; using Neo.VM; using System; @@ -19,7 +22,8 @@ public AssetDescriptor(UInt160 asset_id) sb.EmitAppCall(asset_id, "name"); script = sb.ToArray(); } - using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 100_000); + StoreView snapshot = Blockchain.Singleton.GetSnapshot(); + using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 100_000 * NativeContract.Policy.GetFeeRatio(snapshot)); if (engine.State.HasFlag(VMState.FAULT)) throw new ArgumentException(); this.AssetId = asset_id; this.AssetName = engine.ResultStack.Pop().GetString(); diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index bee952cdcd..b014c2a79d 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -145,7 +145,7 @@ public BigDecimal GetBalance(UInt160 asset_id, params UInt160[] accounts) sb.EmitAppCall(asset_id, "decimals"); script = sb.ToArray(); } - using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 666667L * accounts.Length); + using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 20000000L * accounts.Length); if (engine.State.HasFlag(VMState.FAULT)) return new BigDecimal(0, 0); byte decimals = (byte)engine.ResultStack.Pop().GetInteger(); @@ -407,33 +407,32 @@ public long CalculateNetworkFee(StoreView snapshot, Transaction tx) if (engine.Execute() == VMState.FAULT) throw new ArgumentException($"Smart contract {contract.ScriptHash} verification fault."); if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) throw new ArgumentException($"Smart contract {contract.ScriptHash} returns false."); - networkFee += engine.GasConsumedWithRatio; - networkFeeWithoutRatio = engine.GasConsumedWithoutRatio; + networkFee += engine.GasConsumed; } else if (witness_script.IsSignatureContract()) { size += 67 + witness_script.GetVarSize(); - networkFee += ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHNULL] + ApplicationEngine.ECDsaVerifyPrice; + networkFeeWithoutRatio += ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHNULL] + ApplicationEngine.ECDsaVerifyPrice; } else if (witness_script.IsMultiSigContract(out int m, out int n)) { int size_inv = 66 * m; size += IO.Helper.GetVarSize(size_inv) + size_inv + witness_script.GetVarSize(); - networkFee += ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] * m; + networkFeeWithoutRatio += ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] * m; using (ScriptBuilder sb = new ScriptBuilder()) - networkFee += ApplicationEngine.OpCodePrices[(OpCode)sb.EmitPush(m).ToArray()[0]]; - networkFee += ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] * n; + networkFeeWithoutRatio += ApplicationEngine.OpCodePrices[(OpCode)sb.EmitPush(m).ToArray()[0]]; + networkFeeWithoutRatio += ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] * n; using (ScriptBuilder sb = new ScriptBuilder()) - networkFee += ApplicationEngine.OpCodePrices[(OpCode)sb.EmitPush(n).ToArray()[0]]; - networkFee += ApplicationEngine.OpCodePrices[OpCode.PUSHNULL] + ApplicationEngine.ECDsaVerifyPrice * n; + networkFeeWithoutRatio += ApplicationEngine.OpCodePrices[(OpCode)sb.EmitPush(n).ToArray()[0]]; + networkFeeWithoutRatio += ApplicationEngine.OpCodePrices[OpCode.PUSHNULL] + ApplicationEngine.ECDsaVerifyPrice * n; } else { //We can support more contract types in the future. } } - networkFee += size * NativeContract.Policy.GetFeePerByte(snapshot); - return networkFee * NativeContract.Policy.GetFeeRatio(snapshot) + networkFeeWithoutRatio; + networkFee += size * NativeContract.Policy.GetFeePerByte(snapshot) + networkFeeWithoutRatio * NativeContract.Policy.GetFeeRatio(snapshot); + return networkFee; } public bool Sign(ContractParametersContext context) diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index aae78fd7bd..c7c974bbb9 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -158,7 +158,7 @@ public void FeeIsMultiSigContract() // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); // Check @@ -177,9 +177,9 @@ public void FeeIsMultiSigContract() } var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); - Assert.AreEqual(2000790, verificationGas); - Assert.AreEqual(11451, sizeGas); - Assert.AreEqual(2344320, tx.NetworkFee); + Assert.AreEqual(2024280, verificationGas); + Assert.AreEqual(347000, sizeGas); + Assert.AreEqual(2347790, tx.NetworkFee); } } @@ -220,7 +220,7 @@ public void FeeIsSignatureContractDetailed() Assert.IsNull(tx.Witnesses); // check pre-computed network fee (already guessing signature sizes) - tx.NetworkFee.Should().Be(1241940L); + tx.NetworkFee.Should().Be(1244380L); // ---- // Sign @@ -240,7 +240,7 @@ public void FeeIsSignatureContractDetailed() // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); // Check @@ -281,11 +281,11 @@ public void FeeIsSignatureContractDetailed() // I + II + III + IV Assert.AreEqual(25 + 22 + 1 + 86 + 110, tx.Size); - Assert.AreEqual(33, NativeContract.Policy.GetFeePerByte(snapshot)); - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); + Assert.AreEqual(1000, NativeContract.Policy.GetFeePerByte(snapshot)); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check: verification_cost and tx_size - Assert.AreEqual(241560, sizeGas); + Assert.AreEqual(244000, sizeGas); Assert.AreEqual(1000380, verificationGas); // final assert @@ -354,7 +354,7 @@ public void FeeIsSignatureContract_TestScope_Global() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); // Check long verificationGas = 0; @@ -371,9 +371,9 @@ public void FeeIsSignatureContract_TestScope_Global() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1241940, verificationGas + sizeGas); + Assert.AreEqual(1244380, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -441,7 +441,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); // Check long verificationGas = 0; @@ -458,9 +458,9 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1262730, verificationGas + sizeGas); + Assert.AreEqual(1265380, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -531,7 +531,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); // Check long verificationGas = 0; @@ -548,9 +548,9 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1262730, verificationGas + sizeGas); + Assert.AreEqual(1265380, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -673,7 +673,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() tx.Signers.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); // Check long verificationGas = 0; @@ -690,9 +690,9 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1282530, verificationGas + sizeGas); + Assert.AreEqual(1285380, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -1023,7 +1023,7 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() tx.Witnesses.Length.Should().Be(1); // Fast check - Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee) >= 0); + Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee)); // Check long verificationGas = 0; @@ -1040,9 +1040,9 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() } } // get sizeGas - var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot) * NativeContract.Policy.GetFeeRatio(snapshot); + var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1241940, verificationGas + sizeGas); + Assert.AreEqual(1244380, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -1293,7 +1293,7 @@ public void Test_Verify() tx.Witnesses = data.GetWitnesses(); tx.Verify(snapshot, new TransactionVerificationContext()).Should().Be(VerifyResult.Succeed); - using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, tx.SystemFee / NativeContract.Policy.GetFeeRatio(snapshot))) + using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, tx.SystemFee)) { engine.LoadScript(tx.Script); VMState state = engine.Execute(); diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index fe74519a25..16e2ae9efd 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -39,7 +39,7 @@ public void Check_Default() ret = NativeContract.Policy.Call(snapshot, "getFeePerByte"); ret.Should().BeOfType(); - ret.GetInteger().Should().Be(33); + ret.GetInteger().Should().Be(1000); } [TestMethod] @@ -196,7 +196,7 @@ public void Check_SetFeePerByte() ret = NativeContract.Policy.Call(snapshot, "getFeePerByte"); ret.Should().BeOfType(); - ret.GetInteger().Should().Be(33); + ret.GetInteger().Should().Be(1000); // With signature UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot); diff --git a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs index fe3c6032e1..dd0cf54262 100644 --- a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs +++ b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs @@ -119,7 +119,7 @@ public void TestVerifyWitnesses() UInt256 index1 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); snapshot1.Blocks.Add(index1, new TrimmedBlock()); snapshot1.Blocks.Delete(index1); - Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, snapshot1, 3) < 0); + Assert.IsFalse(Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, snapshot1, 3)); var snapshot2 = Blockchain.Singleton.GetSnapshot(); UInt256 index2 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); @@ -130,7 +130,7 @@ public void TestVerifyWitnesses() snapshot2.Contracts.Add(UInt160.Zero, new ContractState()); snapshot2.Contracts.Delete(UInt160.Zero); - Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(header2, snapshot2, 3) < 0); + Assert.IsFalse(Neo.SmartContract.Helper.VerifyWitnesses(header2, snapshot2, 3)); var snapshot3 = Blockchain.Singleton.GetSnapshot(); UInt256 index3 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); @@ -151,7 +151,7 @@ public void TestVerifyWitnesses() Script = Array.Empty(), Manifest = TestUtils.CreateManifest(UInt160.Zero, "verify", ContractParameterType.Boolean, ContractParameterType.Signature), }); - Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 3) < 0); + Assert.IsFalse(Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 3)); // Smart contract verification @@ -166,7 +166,7 @@ public void TestVerifyWitnesses() Witnesses = new Witness[] { new Witness() { InvocationScript = new byte[0], VerificationScript = new byte[0] } } }; - Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(tx, snapshot3, 1000) >= 0); + Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(tx, snapshot3, 1000)); } } } diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs index def4f8a467..faa7874ab1 100644 --- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -279,7 +279,7 @@ public void System_Runtime_GasLeft() // Execute - var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 100_000_000 / NativeContract.Policy.GetFeeRatio(snapshot)); + var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 100_000_000); engine.LoadScript(script.ToArray()); Assert.AreEqual(engine.Execute(), VMState.HALT); @@ -288,7 +288,7 @@ public void System_Runtime_GasLeft() CollectionAssert.AreEqual ( engine.ResultStack.Select(u => (int)u.GetInteger()).ToArray(), - new int[] { 99_999_570, 99_999_150, 99_998_670 } + new int[] { 99_999_580, 99_999_160, 99_998_680 } ); } From dab166b2d84270c5a310300d42c3731c47b541f7 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 11 Nov 2020 12:12:58 +0800 Subject: [PATCH 11/18] fix ut --- tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index c7c974bbb9..5cfa92a62f 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -177,7 +177,7 @@ public void FeeIsMultiSigContract() } var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); - Assert.AreEqual(2024280, verificationGas); + Assert.AreEqual(2000790, verificationGas); Assert.AreEqual(347000, sizeGas); Assert.AreEqual(2347790, tx.NetworkFee); } From d3a36e6ab3a83ac32ae506b431ed2d1db2054016 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 11 Nov 2020 14:28:54 +0800 Subject: [PATCH 12/18] fix OracleRequestPrice --- src/neo/SmartContract/Native/Oracle/OracleContract.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/SmartContract/Native/Oracle/OracleContract.cs b/src/neo/SmartContract/Native/Oracle/OracleContract.cs index a165c4af6e..4e6f51e914 100644 --- a/src/neo/SmartContract/Native/Oracle/OracleContract.cs +++ b/src/neo/SmartContract/Native/Oracle/OracleContract.cs @@ -164,7 +164,7 @@ protected override void PostPersist(ApplicationEngine engine) if (nodes.Length > 0) { int index = (int)(response.Id % (ulong)nodes.Length); - nodes[index].GAS += OracleRequestPrice; + nodes[index].GAS += OracleRequestPrice * Policy.GetFeeRatio(engine.Snapshot); } } if (nodes != null) From de87b08fb2e079be07a66e3fe80a13fe85202383 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 11 Nov 2020 15:08:59 +0800 Subject: [PATCH 13/18] Revert ut --- .../neo.UnitTests/SmartContract/UT_SmartContractHelper.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs index dd0cf54262..1c3f430a45 100644 --- a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs +++ b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs @@ -119,7 +119,7 @@ public void TestVerifyWitnesses() UInt256 index1 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); snapshot1.Blocks.Add(index1, new TrimmedBlock()); snapshot1.Blocks.Delete(index1); - Assert.IsFalse(Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, snapshot1, 3)); + Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, snapshot1, 100)); var snapshot2 = Blockchain.Singleton.GetSnapshot(); UInt256 index2 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); @@ -130,7 +130,7 @@ public void TestVerifyWitnesses() snapshot2.Contracts.Add(UInt160.Zero, new ContractState()); snapshot2.Contracts.Delete(UInt160.Zero); - Assert.IsFalse(Neo.SmartContract.Helper.VerifyWitnesses(header2, snapshot2, 3)); + Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header2, snapshot2, 100)); var snapshot3 = Blockchain.Singleton.GetSnapshot(); UInt256 index3 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); @@ -151,7 +151,7 @@ public void TestVerifyWitnesses() Script = Array.Empty(), Manifest = TestUtils.CreateManifest(UInt160.Zero, "verify", ContractParameterType.Boolean, ContractParameterType.Signature), }); - Assert.IsFalse(Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 3)); + Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 100)); // Smart contract verification @@ -166,7 +166,7 @@ public void TestVerifyWitnesses() Witnesses = new Witness[] { new Witness() { InvocationScript = new byte[0], VerificationScript = new byte[0] } } }; - Assert.IsTrue(Neo.SmartContract.Helper.VerifyWitnesses(tx, snapshot3, 1000)); + Assert.AreEqual(true, Neo.SmartContract.Helper.VerifyWitnesses(tx, snapshot3, 1000)); } } } From 379e7aed42aa6b1e789eb4f7c3076ea2d01f9e55 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 11 Nov 2020 15:27:00 +0800 Subject: [PATCH 14/18] fix GetBalance --- src/neo/Wallets/AssetDescriptor.cs | 2 +- src/neo/Wallets/Wallet.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/neo/Wallets/AssetDescriptor.cs b/src/neo/Wallets/AssetDescriptor.cs index 018113c76f..86602e7d44 100644 --- a/src/neo/Wallets/AssetDescriptor.cs +++ b/src/neo/Wallets/AssetDescriptor.cs @@ -22,7 +22,7 @@ public AssetDescriptor(UInt160 asset_id) sb.EmitAppCall(asset_id, "name"); script = sb.ToArray(); } - StoreView snapshot = Blockchain.Singleton.GetSnapshot(); + using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 100_000 * NativeContract.Policy.GetFeeRatio(snapshot)); if (engine.State.HasFlag(VMState.FAULT)) throw new ArgumentException(); this.AssetId = asset_id; diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index b014c2a79d..a46c45ef95 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -145,7 +145,8 @@ public BigDecimal GetBalance(UInt160 asset_id, params UInt160[] accounts) sb.EmitAppCall(asset_id, "decimals"); script = sb.ToArray(); } - using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 20000000L * accounts.Length); + using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); + using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 666667L * NativeContract.Policy.GetFeeRatio(snapshot) * accounts.Length); if (engine.State.HasFlag(VMState.FAULT)) return new BigDecimal(0, 0); byte decimals = (byte)engine.ResultStack.Pop().GetInteger(); From c23472c6d793b671b3a67ab3e5589215db3f5c0d Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 11 Nov 2020 17:35:23 +0800 Subject: [PATCH 15/18] Optimize --- src/neo/Wallets/AssetDescriptor.cs | 2 +- src/neo/Wallets/Wallet.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/neo/Wallets/AssetDescriptor.cs b/src/neo/Wallets/AssetDescriptor.cs index 86602e7d44..748c682632 100644 --- a/src/neo/Wallets/AssetDescriptor.cs +++ b/src/neo/Wallets/AssetDescriptor.cs @@ -23,7 +23,7 @@ public AssetDescriptor(UInt160 asset_id) script = sb.ToArray(); } using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); - using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 100_000 * NativeContract.Policy.GetFeeRatio(snapshot)); + using ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, gas: 100_000 * NativeContract.Policy.GetFeeRatio(snapshot)); if (engine.State.HasFlag(VMState.FAULT)) throw new ArgumentException(); this.AssetId = asset_id; this.AssetName = engine.ResultStack.Pop().GetString(); diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index a46c45ef95..5e18964404 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -146,7 +146,7 @@ public BigDecimal GetBalance(UInt160 asset_id, params UInt160[] accounts) script = sb.ToArray(); } using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); - using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 666667L * NativeContract.Policy.GetFeeRatio(snapshot) * accounts.Length); + using ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, gas: 666667L * NativeContract.Policy.GetFeeRatio(snapshot) * accounts.Length); if (engine.State.HasFlag(VMState.FAULT)) return new BigDecimal(0, 0); byte decimals = (byte)engine.ResultStack.Pop().GetInteger(); From a082979acdc2e30f6ff14fd00ee77fcca1d92568 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 11 Nov 2020 17:44:23 +0800 Subject: [PATCH 16/18] format --- src/neo/SmartContract/Native/Oracle/OracleContract.cs | 1 - tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs | 1 - tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs | 1 - tests/neo.UnitTests/SmartContract/UT_Syscalls.cs | 1 - 4 files changed, 4 deletions(-) diff --git a/src/neo/SmartContract/Native/Oracle/OracleContract.cs b/src/neo/SmartContract/Native/Oracle/OracleContract.cs index 4e6f51e914..91c06dee6d 100644 --- a/src/neo/SmartContract/Native/Oracle/OracleContract.cs +++ b/src/neo/SmartContract/Native/Oracle/OracleContract.cs @@ -1,6 +1,5 @@ #pragma warning disable IDE0051 -using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Neo.Cryptography; using Neo.IO; using Neo.Ledger; diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index 5cfa92a62f..a64abe056d 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -5,7 +5,6 @@ using Neo.IO.Json; using Neo.Ledger; using Neo.Network.P2P.Payloads; -using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.SmartContract.Native.Tokens; diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs b/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs index 3f74f7eaf7..989bf46a8e 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs @@ -3,7 +3,6 @@ using Neo.Ledger; using Neo.SmartContract; using Neo.SmartContract.Manifest; -using Neo.SmartContract.Native; using Neo.VM; namespace Neo.UnitTests.SmartContract diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs index faa7874ab1..b757260015 100644 --- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -3,7 +3,6 @@ using Neo.Ledger; using Neo.Network.P2P.Payloads; using Neo.SmartContract; -using Neo.SmartContract.Native; using Neo.VM; using Neo.VM.Types; using System.Linq; From 0df79156099c79418c74353347fa3be033154883 Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 11 Nov 2020 18:35:14 +0800 Subject: [PATCH 17/18] fix MaxVerificationGas --- src/neo/SmartContract/Helper.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs index 0b95e20c17..7ace9d5f58 100644 --- a/src/neo/SmartContract/Helper.cs +++ b/src/neo/SmartContract/Helper.cs @@ -133,7 +133,15 @@ public static UInt160 ToScriptHash(this ReadOnlySpan script) internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All, bool withRatio = true) { if (gas < 0) return false; - if (snapshot is null || gas > MaxVerificationGas) gas = MaxVerificationGas; + if (snapshot is null) + { + gas = MaxVerificationGas; + } + else + { + long MaxVerificationGasWithRatio = MaxVerificationGas * NativeContract.Policy.GetFeeRatio(snapshot); + if (gas > MaxVerificationGasWithRatio) gas = MaxVerificationGasWithRatio; + } UInt160[] hashes; try From e49b8253dc9b625690afba275934d11d352a1d6d Mon Sep 17 00:00:00 2001 From: Qiao Jin Date: Wed, 11 Nov 2020 18:41:55 +0800 Subject: [PATCH 18/18] fix MaxVerificationGas --- src/neo/SmartContract/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs index 7ace9d5f58..68e9d9fa49 100644 --- a/src/neo/SmartContract/Helper.cs +++ b/src/neo/SmartContract/Helper.cs @@ -14,7 +14,7 @@ namespace Neo.SmartContract { public static class Helper { - private const long MaxVerificationGas = 0_50000000; + private const long MaxVerificationGas = 0_01666667; public static UInt160 GetScriptHash(this ExecutionContext context) {