diff --git a/src/emulator/src/lib.rs b/src/emulator/src/lib.rs index b8d8fdcc..26e19019 100644 --- a/src/emulator/src/lib.rs +++ b/src/emulator/src/lib.rs @@ -233,12 +233,11 @@ pub extern "C" fn transaction_emulator_set_prev_blocks_info( match SliceData::load_cell(info_cell).and_then(|mut slice| read_stack_item(&mut slice)) { Ok(info) => { - if info.is_tuple() { - transaction_emulator.prev_blocks_info = PrevBlocksInfo::Tuple(info); + transaction_emulator.prev_blocks_info = if info.is_tuple() { + PrevBlocksInfo::Tuple(info) } else { - transaction_emulator.prev_blocks_info = - PrevBlocksInfo::Tuple(StackItem::tuple(Vec::new())); - } + PrevBlocksInfo::Tuple(StackItem::tuple(Vec::new())) + }; } Err(err) => { log::error!("Failed to parse info_cell: {err}"); diff --git a/src/executor/src/transaction_executor.rs b/src/executor/src/transaction_executor.rs index 88fda3a2..595d2e4e 100644 --- a/src/executor/src/transaction_executor.rs +++ b/src/executor/src/transaction_executor.rs @@ -147,6 +147,7 @@ pub trait TransactionExecutor { /// If account does not exist - phase skipped. /// Calculates storage fees and substracts them from account balance. /// If account balance becomes negative after that, then account is frozen. + /// is_special - flag indicating that account is in list of special smart contracts, for which storage fees are not applied fn storage_phase( &self, acc: &mut Account, @@ -159,23 +160,11 @@ pub trait TransactionExecutor { if tr.now() < acc.last_paid() { fail!("transaction timestamp must be greater then account timestamp") } - - if is_special { - log::debug!(target: "executor", "Special account: AccStatusChange::Unchanged"); - return Ok(TrStoragePhase::with_params( - Coins::zero(), - acc.due_payment().cloned(), - AccStatusChange::Unchanged, - )); - } let mut fee = match acc.storage_info() { - Some(storage_info) => { + Some(storage_info) if !is_special => { self.config().calc_storage_fees(storage_info, is_masterchain, tr.now())? } - None => { - log::debug!(target: "executor", "Account::None"); - return Ok(Default::default()); - } + _ => Default::default(), }; if let Some(due_payment) = acc.due_payment() { fee.add(due_payment)?; @@ -192,6 +181,15 @@ pub trait TransactionExecutor { let storage_fees_collected = std::mem::take(&mut acc_balance.coins); tr.add_fee_coins(&storage_fees_collected)?; fee.sub(&storage_fees_collected)?; + if is_special { + log::debug!(target: "executor", "special account, due payment {fee} still active"); + acc.set_due_payment(Some(fee)); + return Ok(TrStoragePhase::with_params( + storage_fees_collected, + Some(fee), + AccStatusChange::Unchanged, + )); + } let need_freeze = acc.is_active() && fee > self.config().get_gas_config(is_masterchain).freeze_due_limit; let need_delete = (acc.is_uninit() || acc.is_frozen())