From a103714578016896abce55ef54c297f8cc4f5e71 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 10 Dec 2021 09:16:38 +0200 Subject: [PATCH] Increase NEAR Gas for ft_on_transfer (#389) --- engine-sdk/src/env.rs | 11 ++++++++++- engine-sdk/src/near_runtime.rs | 4 ++++ engine-standalone-storage/src/relayer_db/mod.rs | 3 ++- engine-standalone-storage/src/sync/mod.rs | 4 +++- .../src/test_utils/standalone/mocks/mod.rs | 6 +++++- engine-tests/src/test_utils/standalone/mod.rs | 2 ++ engine-tests/src/tests/standalone/sanity.rs | 2 ++ engine-types/src/types.rs | 8 ++++++++ engine/src/connector.rs | 6 +++++- engine/src/fungible_token.rs | 9 +++++++-- engine/src/lib.rs | 14 ++++++++++++-- 11 files changed, 60 insertions(+), 9 deletions(-) diff --git a/engine-sdk/src/env.rs b/engine-sdk/src/env.rs index 63617d71a..b0d73d0ea 100644 --- a/engine-sdk/src/env.rs +++ b/engine-sdk/src/env.rs @@ -1,7 +1,9 @@ use crate::error::{OneYoctoAttachError, PrivateCallError}; -use crate::prelude::H256; +use crate::prelude::{NearGas, H256}; use aurora_engine_types::account_id::AccountId; +pub const DEFAULT_PREPAID_GAS: NearGas = NearGas::new(300_000_000_000_000); + /// Timestamp represented by the number of nanoseconds since the Unix Epoch. #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord)] pub struct Timestamp(u64); @@ -43,6 +45,8 @@ pub trait Env { fn attached_deposit(&self) -> u128; /// Random seed generated for the current block fn random_seed(&self) -> H256; + /// Prepaid NEAR Gas + fn prepaid_gas(&self) -> NearGas; fn assert_private_call(&self) -> Result<(), PrivateCallError> { if self.predecessor_account_id() == self.current_account_id() { @@ -72,6 +76,7 @@ pub struct Fixed { pub block_timestamp: Timestamp, pub attached_deposit: u128, pub random_seed: H256, + pub prepaid_gas: NearGas, } impl Env for Fixed { @@ -102,4 +107,8 @@ impl Env for Fixed { fn random_seed(&self) -> H256 { self.random_seed } + + fn prepaid_gas(&self) -> NearGas { + self.prepaid_gas + } } diff --git a/engine-sdk/src/near_runtime.rs b/engine-sdk/src/near_runtime.rs index ee3b7239c..00926399f 100644 --- a/engine-sdk/src/near_runtime.rs +++ b/engine-sdk/src/near_runtime.rs @@ -237,6 +237,10 @@ impl crate::env::Env for Runtime { bytes } } + + fn prepaid_gas(&self) -> NearGas { + NearGas::new(unsafe { exports::prepaid_gas() }) + } } impl crate::promise::PromiseHandler for Runtime { diff --git a/engine-standalone-storage/src/relayer_db/mod.rs b/engine-standalone-storage/src/relayer_db/mod.rs index 5fcc3f191..6b838a616 100644 --- a/engine-standalone-storage/src/relayer_db/mod.rs +++ b/engine-standalone-storage/src/relayer_db/mod.rs @@ -1,6 +1,6 @@ use aurora_engine::engine; use aurora_engine::transaction::EthTransactionKind; -use aurora_engine_sdk::env::{self, Env}; +use aurora_engine_sdk::env::{self, Env, DEFAULT_PREPAID_GAS}; use aurora_engine_types::account_id::AccountId; use aurora_engine_types::H256; use postgres::fallible_iterator::FallibleIterator; @@ -81,6 +81,7 @@ where block_timestamp: env::Timestamp::new(0), attached_deposit: 0, random_seed: H256::zero(), + prepaid_gas: DEFAULT_PREPAID_GAS, }; let mut handler = crate::promise::Noop; diff --git a/engine-standalone-storage/src/sync/mod.rs b/engine-standalone-storage/src/sync/mod.rs index 6113d1b31..4c4ce3b19 100644 --- a/engine-standalone-storage/src/sync/mod.rs +++ b/engine-standalone-storage/src/sync/mod.rs @@ -1,5 +1,5 @@ use aurora_engine::{connector, engine, parameters}; -use aurora_engine_sdk::env::{self, Env}; +use aurora_engine_sdk::env::{self, Env, DEFAULT_PREPAID_GAS}; use aurora_engine_types::TryFrom; use borsh::BorshDeserialize; @@ -46,6 +46,7 @@ pub fn consume_message(storage: &mut crate::Storage, message: Message) -> Result block_timestamp: block_metadata.timestamp, attached_deposit: transaction_message.attached_near, random_seed: block_metadata.random_seed, + prepaid_gas: DEFAULT_PREPAID_GAS, }; let io = storage.access_engine_storage_at_position(block_height, transaction_position, &[]); @@ -143,6 +144,7 @@ pub fn consume_message(storage: &mut crate::Storage, message: Message) -> Result env.predecessor_account_id(), env.current_account_id(), finish_args, + env.prepaid_gas, )?; if let Some(promise_args) = maybe_promise_args { diff --git a/engine-tests/src/test_utils/standalone/mocks/mod.rs b/engine-tests/src/test_utils/standalone/mocks/mod.rs index d3f293fe5..07a5d5355 100644 --- a/engine-tests/src/test_utils/standalone/mocks/mod.rs +++ b/engine-tests/src/test_utils/standalone/mocks/mod.rs @@ -1,10 +1,12 @@ use aurora_engine::engine; use aurora_engine::fungible_token::FungibleTokenMetadata; use aurora_engine::parameters::{FinishDepositCallArgs, InitCallArgs, NewCallArgs}; -use aurora_engine_sdk::env::Env; +use aurora_engine_sdk::env::{Env, DEFAULT_PREPAID_GAS}; use aurora_engine_sdk::io::IO; +use aurora_engine_types::types::NearGas; use aurora_engine_types::{account_id::AccountId, types::Wei, Address, H256, U256}; use engine_standalone_storage::{BlockMetadata, Storage}; +use near_sdk_sim::DEFAULT_GAS; use crate::test_utils; @@ -44,6 +46,7 @@ pub fn default_env(block_height: u64) -> aurora_engine_sdk::env::Fixed { block_timestamp: aurora_engine_sdk::env::Timestamp::new(0), attached_deposit: 0, random_seed: H256::zero(), + prepaid_gas: DEFAULT_PREPAID_GAS, } } @@ -117,6 +120,7 @@ pub fn mint_evm_account( aurora_account_id.clone(), aurora_account_id.clone(), deposit_args, + NearGas::new(DEFAULT_GAS), ) .map_err(unsafe_to_string) .unwrap(); diff --git a/engine-tests/src/test_utils/standalone/mod.rs b/engine-tests/src/test_utils/standalone/mod.rs index af9ab159a..f2f3b59ac 100644 --- a/engine-tests/src/test_utils/standalone/mod.rs +++ b/engine-tests/src/test_utils/standalone/mod.rs @@ -2,6 +2,7 @@ use aurora_engine::engine; use aurora_engine::parameters::{CallArgs, DeployErc20TokenArgs, SubmitResult, TransactionStatus}; use aurora_engine::transaction::legacy::{LegacyEthSignedTransaction, TransactionLegacy}; use aurora_engine_sdk::env::{self, Env}; +use aurora_engine_types::types::NearGas; use aurora_engine_types::{types::Wei, Address, H256, U256}; use borsh::BorshDeserialize; use engine_standalone_storage::engine_state; @@ -148,6 +149,7 @@ impl StandaloneRunner { env.predecessor_account_id = ctx.predecessor_account_id.as_ref().parse().unwrap(); env.current_account_id = ctx.current_account_id.as_ref().parse().unwrap(); env.signer_account_id = ctx.signer_account_id.as_ref().parse().unwrap(); + env.prepaid_gas = NearGas::new(ctx.prepaid_gas); let storage = &mut self.storage; if method_name == test_utils::SUBMIT { diff --git a/engine-tests/src/tests/standalone/sanity.rs b/engine-tests/src/tests/standalone/sanity.rs index 251c25724..b043e6607 100644 --- a/engine-tests/src/tests/standalone/sanity.rs +++ b/engine-tests/src/tests/standalone/sanity.rs @@ -1,5 +1,6 @@ use crate::test_utils::standalone::mocks::{promise, storage}; use aurora_engine::engine; +use aurora_engine_sdk::env::DEFAULT_PREPAID_GAS; use aurora_engine_types::types::Wei; use aurora_engine_types::{account_id::AccountId, Address, H256, U256}; use std::sync::RwLock; @@ -30,6 +31,7 @@ fn test_deploy_code() { block_timestamp: aurora_engine_sdk::env::Timestamp::new(0), attached_deposit: 0, random_seed: H256::zero(), + prepaid_gas: DEFAULT_PREPAID_GAS, }; let mut handler = promise::PromiseTracker::default(); let mut engine = engine::Engine::new_with_state(state, origin, owner_id, io, &env); diff --git a/engine-types/src/types.rs b/engine-types/src/types.rs index 90ab6699d..e37f04b8d 100644 --- a/engine-types/src/types.rs +++ b/engine-types/src/types.rs @@ -20,6 +20,14 @@ pub type WeiU256 = [u8; 32]; /// Near gas type which wraps an underlying u64. pub struct NearGas(u64); +impl Sub for NearGas { + type Output = NearGas; + + fn sub(self, rhs: NearGas) -> Self::Output { + Self(self.0 - rhs.0) + } +} + impl Display for NearGas { fn fmt(&self, f: &mut Formatter<'_>) -> crate::fmt::Result { self.0.fmt(f) diff --git a/engine/src/connector.rs b/engine/src/connector.rs index ff9a1e74b..959dd8e7d 100644 --- a/engine/src/connector.rs +++ b/engine/src/connector.rs @@ -24,7 +24,7 @@ pub const ERR_NOT_ENOUGH_BALANCE_FOR_FEE: &str = "ERR_NOT_ENOUGH_BALANCE_FOR_FEE /// Indicate zero attached balance for promise call pub const ZERO_ATTACHED_BALANCE: Balance = 0; /// NEAR Gas for calling `fininsh_deposit` promise. Used in the `deposit` logic. -const GAS_FOR_FINISH_DEPOSIT: NearGas = NearGas::new(50_000_000_000_000); +pub const GAS_FOR_FINISH_DEPOSIT: NearGas = NearGas::new(50_000_000_000_000); /// NEAR Gas for calling `verify_log_entry` promise. Used in the `deposit` logic. // Note: Is 40Tgas always enough? const GAS_FOR_VERIFY_LOG_ENTRY: NearGas = NearGas::new(40_000_000_000_000); @@ -250,6 +250,7 @@ impl EthConnectorContract { predecessor_account_id: AccountId, current_account_id: AccountId, data: FinishDepositCallArgs, + prepaid_gas: NearGas, ) -> Result, error::FinishDepositError> { sdk::log!(&format!("Finish deposit with the amount: {}", data.amount)); @@ -266,6 +267,7 @@ impl EthConnectorContract { predecessor_account_id, current_account_id, transfer_call_args, + prepaid_gas, )?; Ok(Some(promise)) } else { @@ -472,6 +474,7 @@ impl EthConnectorContract { predecessor_account_id: AccountId, current_account_id: AccountId, args: TransferCallCallArgs, + prepaid_gas: NearGas, ) -> Result { sdk::log!(&format!( "Transfer call to {} amount {}", @@ -520,6 +523,7 @@ impl EthConnectorContract { &args.memo, args.msg, current_account_id, + prepaid_gas, ) .map_err(Into::into) } diff --git a/engine/src/fungible_token.rs b/engine/src/fungible_token.rs index 78644eb32..74f220ce2 100644 --- a/engine/src/fungible_token.rs +++ b/engine/src/fungible_token.rs @@ -11,8 +11,10 @@ use crate::prelude::{ }; use aurora_engine_sdk::io::{StorageIntermediate, IO}; +/// Gas for `resolve_transfer`: 5 TGas const GAS_FOR_RESOLVE_TRANSFER: NearGas = NearGas::new(5_000_000_000_000); -const GAS_FOR_FT_ON_TRANSFER: NearGas = NearGas::new(10_000_000_000_000); +/// Gas for `ft_on_transfer` +const GAS_FOR_FT_TRANSFER_CALL: NearGas = NearGas::new(35_000_000_000_000); #[derive(Debug, Default, BorshDeserialize, BorshSerialize)] pub struct FungibleToken { @@ -287,6 +289,7 @@ impl FungibleTokenOps { self.get_account_eth_balance(account_id).unwrap_or(0) } + #[allow(clippy::too_many_arguments)] pub fn ft_transfer_call( &mut self, sender_id: AccountId, @@ -295,6 +298,7 @@ impl FungibleTokenOps { memo: &Option, msg: String, current_account_id: AccountId, + prepaid_gas: NearGas, ) -> Result { // Special case for Aurora transfer itself - we shouldn't transfer if sender_id != receiver_id { @@ -321,7 +325,8 @@ impl FungibleTokenOps { method: "ft_on_transfer".to_string(), args: data1.into_bytes(), attached_balance: ZERO_ATTACHED_BALANCE, - attached_gas: GAS_FOR_FT_ON_TRANSFER.into_u64(), + attached_gas: (prepaid_gas - GAS_FOR_FT_TRANSFER_CALL - GAS_FOR_RESOLVE_TRANSFER) + .into_u64(), }; let ft_resolve_transfer_call = PromiseCreateArgs { target_account_id: current_account_id, diff --git a/engine/src/lib.rs b/engine/src/lib.rs index 7079cadeb..04dc19285 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -612,7 +612,12 @@ mod contract { let current_account_id = io.current_account_id(); let predecessor_account_id = io.predecessor_account_id(); let maybe_promise_args = EthConnectorContract::init_instance(io) - .finish_deposit(predecessor_account_id, current_account_id, data) + .finish_deposit( + predecessor_account_id, + current_account_id, + data, + io.prepaid_gas(), + ) .sdk_unwrap(); if let Some(promise_args) = maybe_promise_args { @@ -711,7 +716,12 @@ mod contract { let current_account_id = io.current_account_id(); let predecessor_account_id = io.predecessor_account_id(); let promise_args = EthConnectorContract::init_instance(io) - .ft_transfer_call(predecessor_account_id, current_account_id, args) + .ft_transfer_call( + predecessor_account_id, + current_account_id, + args, + io.prepaid_gas(), + ) .sdk_unwrap(); let promise_id = io.promise_crate_with_callback(&promise_args); io.promise_return(promise_id);