diff --git a/src/neo/Oracle/OracleResponse.cs b/src/neo/Oracle/OracleResponse.cs index 094e7e59d0..67380b01ae 100644 --- a/src/neo/Oracle/OracleResponse.cs +++ b/src/neo/Oracle/OracleResponse.cs @@ -9,7 +9,6 @@ namespace Neo.Oracle public class OracleResponse : ISerializable { private UInt160 _hash; - private bool _alreadyPayed; /// /// Request hash @@ -49,25 +48,6 @@ public UInt160 Hash public int Size => UInt160.Length + sizeof(byte) + Result.GetVarSize() + sizeof(long); - /// - /// Filter cost that it could be consumed only once - /// - public long FilterCostOnce() - { - if (_alreadyPayed) return 0; - - _alreadyPayed = true; - return FilterCost; - } - - /// - /// Reset the _alreadyPayed flag - /// - public void ResetFilterCostOnce() - { - _alreadyPayed = false; - } - /// /// Create error result /// diff --git a/src/neo/SmartContract/Native/Oracle/OracleContract.cs b/src/neo/SmartContract/Native/Oracle/OracleContract.cs index f307feadb5..866463b107 100644 --- a/src/neo/SmartContract/Native/Oracle/OracleContract.cs +++ b/src/neo/SmartContract/Native/Oracle/OracleContract.cs @@ -82,19 +82,24 @@ public bool ContainsResponse(StoreView snapshot, UInt256 txHash) /// /// Consume Oracle Response /// - /// Snapshot + /// Engine /// Transaction Hash - public OracleExecutionCache ConsumeOracleResponse(StoreView snapshot, UInt256 txHash) + public OracleExecutionCache ConsumeOracleResponse(ApplicationEngine engine, UInt256 txHash) { StorageKey key = CreateStorageKey(Prefix_OracleResponse, txHash.ToArray()); - StorageItem storage = snapshot.Storages.TryGet(key); + StorageItem storage = engine.Snapshot.Storages.TryGet(key); if (storage == null) return null; OracleExecutionCache ret = storage.Value.AsSerializable(); // It should be cached by the ApplicationEngine so we can save space removing it - snapshot.Storages.Delete(key); + engine.Snapshot.Storages.Delete(key); + + // Pay for the filter + + if (!engine.AddGas(ret.FilterCost)) throw new ArgumentException("OutOfGas"); + return ret; } @@ -348,7 +353,7 @@ private StackItem Get(ApplicationEngine engine, Array args) { // Read Oracle Response - engine.OracleCache = Oracle.ConsumeOracleResponse(engine.Snapshot, tx.Hash); + engine.OracleCache = Oracle.ConsumeOracleResponse(engine, tx.Hash); // If it doesn't exist, fault @@ -415,8 +420,6 @@ private StackItem Get(ApplicationEngine engine, Array args) { // Add the gas filter cost - if (!engine.AddGas(response.FilterCostOnce())) return false; - return response.Result ?? StackItem.Null; } diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index b02631b225..e26d0f87b6 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -334,17 +334,6 @@ private Transaction MakeTransaction(StoreView snapshot, byte[] script, Transacti Cosigners = cosigners }; - if (oracleCache != null) - { - // We need to reset if we already consumed the fiter price - // otherwise we can have a wrong gas computation - - foreach (var entry in oracleCache.Responses) - { - entry.ResetFilterCostOnce(); - } - } - // will try to execute 'transfer' script to check if it works using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot.Clone(), tx, testMode: true, oracle: oracleCache)) { @@ -357,6 +346,9 @@ private Transaction MakeTransaction(StoreView snapshot, byte[] script, Transacti if (oracleRequests?.Count > 0) { + // Increase filter cost + + tx.SystemFee += oracleCache.FilterCost; tx.Version = TransactionVersion.OracleRequest; if (oracle == OracleWalletBehaviour.OracleWithAssert)