Skip to content
35 changes: 32 additions & 3 deletions evm_loader/program/src/entrypoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,20 +376,25 @@ fn process_instruction<'a>(
let storage_info = next_account_info(account_info_iter)?;

let operator_sol_info = next_account_info(account_info_iter)?;
let operator_eth_info = next_account_info(account_info_iter)?;
let user_eth_info = next_account_info(account_info_iter)?;
let incinerator_info = next_account_info(account_info_iter)?;
let system_info = next_account_info(account_info_iter)?;

let trx_accounts = &accounts[4..];
let trx_accounts = &accounts[6..];

if !operator_sol_info.is_signer {
return Err!(ProgramError::InvalidAccountData);
}

let storage = StorageAccount::restore(storage_info, operator_sol_info)?;

let storage = StorageAccount::restore(storage_info, operator_sol_info).map_err(|err| {
if err == ProgramError::InvalidAccountData {EvmLoaderError::StorageAccountUninitialized.into()}
else {err}
})?;
storage.check_accounts(program_id, trx_accounts)?;

let account_storage = ProgramAccountStorage::new(program_id, trx_accounts)?;

let mut caller_info_data = AccountData::unpack(&account_storage.get_caller_account_info().ok_or_else(||E!(ProgramError::InvalidArgument))?.data.borrow())?;
match caller_info_data {
AccountData::Account(ref mut acc) => {
Expand All @@ -405,6 +410,30 @@ fn process_instruction<'a>(
_ => return Err!(ProgramError::InvalidAccountData),
};

let executor = Machine::restore(&storage, &account_storage);
debug_print!("Executor restored");

let executor_state = executor.into_state();
let used_gas = executor_state.substate().metadata().gasometer().used_gas();

let (gas_limit, gas_price) = storage.get_gas_params()?;
if used_gas > gas_limit {
return Err!(ProgramError::InvalidArgument);
}
let gas_price_wei = U256::from(gas_price);
let fee = U256::from(used_gas)
.checked_mul(gas_price_wei).ok_or_else(||E!(ProgramError::InvalidArgument))?;

let caller_info= account_storage.get_caller_account_info().ok_or_else(||E!(ProgramError::InvalidArgument))?;

token::transfer_token(
accounts,
user_eth_info,
operator_eth_info,
caller_info,
account_storage.get_caller_account().ok_or_else(||E!(ProgramError::InvalidArgument))?,
&fee)?;

payment::burn_operators_deposit(
storage_info,
incinerator_info,
Expand Down
2 changes: 1 addition & 1 deletion evm_loader/program/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,4 @@ pub fn transfer_token(
invoke_signed(&instruction, accounts, &[&program_seeds[..]])?;

Ok(())
}
}
13 changes: 11 additions & 2 deletions evm_loader/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def setUpClass(cls):
if getBalance(cls.caller) == 0:
print("Create caller account...")
_ = cls.loader.createEtherAccount(cls.caller_ether)
cls.token.transfer(ETH_TOKEN_MINT_ID, 2000, get_associated_token_address(PublicKey(cls.caller), ETH_TOKEN_MINT_ID))
print("Done\n")
cls.token.transfer(ETH_TOKEN_MINT_ID, 2000, cls.caller_token)

print('Account:', cls.acc.public_key(), bytes(cls.acc.public_key()).hex())
print("Caller:", cls.caller_ether.hex(), cls.caller_nonce, "->", cls.caller,
Expand Down Expand Up @@ -143,6 +143,12 @@ def sol_instr_12_cancel(self, storage_account):

# Operator address:
AccountMeta(pubkey=self.acc.public_key(), is_signer=True, is_writable=True),
# Operator ETH address (stub for now):
AccountMeta(pubkey=get_associated_token_address(self.acc.public_key(), ETH_TOKEN_MINT_ID),
is_signer=False, is_writable=True),
# User ETH address (stub for now):
AccountMeta(pubkey=get_associated_token_address(PublicKey(self.caller), ETH_TOKEN_MINT_ID),
is_signer=False, is_writable=True),
# Incenirator
AccountMeta(pubkey=PublicKey(incinerator), is_signer=False, is_writable=True),
# System program account:
Expand Down Expand Up @@ -407,13 +413,16 @@ def test_caseSuccessRunOtherTransactionAfterCancel(self):
storage = self.create_storage_account(sign[:8].hex())

caller_balance_before_cancel = self.token.balance(self.caller_token)
operator_balance_before_cancel = self.token.balance(get_associated_token_address(self.acc.public_key(), ETH_TOKEN_MINT_ID))

result = self.call_begin(storage, 10, msg, instruction)
result = self.call_continue(storage, 10)
result = self.call_cancel(storage)

caller_balance_after_cancel = self.token.balance(self.caller_token)
self.assertEqual(caller_balance_after_cancel, caller_balance_before_cancel)
operator_balance_after_cancel = self.token.balance(get_associated_token_address(self.acc.public_key(), ETH_TOKEN_MINT_ID))
self.assertNotEqual(caller_balance_after_cancel, caller_balance_before_cancel)
self.assertEqual(caller_balance_before_cancel+operator_balance_before_cancel, caller_balance_after_cancel+operator_balance_after_cancel)

self.call_partial_signed(input)

Expand Down