Skip to content

Commit

Permalink
NDEV-3380 pass 'transaction step of the first solana call' from emula…
Browse files Browse the repository at this point in the history
…tor to the Proxy
  • Loading branch information
artem-yazkov committed Nov 19, 2024
1 parent 95f37f3 commit a292047
Show file tree
Hide file tree
Showing 12 changed files with 58 additions and 20 deletions.
4 changes: 4 additions & 0 deletions evm_loader/lib/src/account_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,10 @@ impl<T: Rpc> AccountStorage for EmulatorAccountStorage<'_, T> {
.unwrap()
}

fn is_on_emulator(&self) -> bool {
true
}

fn is_valid_chain_id(&self, chain_id: u64) -> bool {
for chain in &self.chains {
if chain.id == chain_id {
Expand Down
21 changes: 15 additions & 6 deletions evm_loader/lib/src/commands/emulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,17 @@ async fn transfer_gas_limit<'rpc, T: Rpc + BuildConfigSimulator>(

async fn calculate_response<T: Rpc + BuildConfigSimulator, Tr: Tracer>(
steps_executed: u64,
step_on_solana: Option<u64>,
exit_status: ExitStatus,
storage: &EmulatorAccountStorage<'_, T>,
tracer: Option<Tr>,
provide_account_info: &Option<AccountInfoLevel>,
) -> NeonResult<(EmulateResponse, Option<Value>)> {
debug!("Execute done, result={exit_status:?}");
debug!("{steps_executed} steps executed");
if let Some(step) = step_on_solana {
debug!("Got Solana call on {step}");
}

let logs = storage.logs();
let execute_status = storage.execute_status;
Expand Down Expand Up @@ -322,7 +326,7 @@ async fn emulate_trx_single_step<'rpc, T: Tracer>(
) -> NeonResult<(EmulateResponse, Option<Value>)> {
let origin = emulate_request.tx.from;

let (exit_status, steps_executed, tracer) = {
let (exit_status, steps_executed, step_on_solana, tracer) = {
let mut backend = SyncedExecutorState::new(storage);
let mut evm = match Machine::new(tx, origin, &mut backend, tracer).await {
Ok(evm) => evm,
Expand All @@ -332,7 +336,8 @@ async fn emulate_trx_single_step<'rpc, T: Tracer>(
}
};

let (exit_status, steps_executed, tracer) = evm.execute(step_limit, &mut backend).await?;
let (exit_status, steps_executed, step_on_solana, tracer) =
evm.execute(step_limit, &mut backend).await?;

if exit_status == ExitStatus::StepLimit {
error!("Step_limit={step_limit} exceeded");
Expand All @@ -341,11 +346,12 @@ async fn emulate_trx_single_step<'rpc, T: Tracer>(
None,
));
}
(exit_status, steps_executed, tracer)
(exit_status, steps_executed, step_on_solana, tracer)
};

calculate_response(
steps_executed,
step_on_solana,
exit_status,
storage,
tracer,
Expand Down Expand Up @@ -390,7 +396,7 @@ async fn emulate_trx_multiple_steps<'rpc, T: Tracer>(

transfer_gas_limit(&mut storage, &tx, &origin, chain_id, increase_gas_limit).await?;

let (exit_status, steps_executed, tracer) = {
let (exit_status, steps_executed, step_on_solana, tracer) = {
let mut backend = SyncedExecutorState::new(&mut storage);
let mut evm = match Machine::new(&tx, origin, &mut backend, tracer).await {
Ok(evm) => evm,
Expand All @@ -402,6 +408,7 @@ async fn emulate_trx_multiple_steps<'rpc, T: Tracer>(

let mut exit_status: ExitStatus = ExitStatus::Stop;
let mut steps_executed = 0u64;
let mut step_on_solana = None;
let mut tracer_result: Option<T> = None;
for (pos, execution_step) in execution_map.iter().enumerate() {
if execution_step.steps == 0 && !execution_step.is_cancel {
Expand Down Expand Up @@ -455,12 +462,13 @@ async fn emulate_trx_multiple_steps<'rpc, T: Tracer>(
evm.set_tracer(tracer_result);
}

let (local_exit_status, local_steps_executed, local_tracer) = evm
let (local_exit_status, local_steps_executed, local_step_on_solana, local_tracer) = evm
.execute(u64::from(execution_step.steps), &mut backend)
.await?;

exit_status = local_exit_status;
steps_executed += local_steps_executed;
step_on_solana = local_step_on_solana;
tracer_result = local_tracer;
}

Expand All @@ -472,11 +480,12 @@ async fn emulate_trx_multiple_steps<'rpc, T: Tracer>(
));
}

(exit_status, steps_executed, tracer_result)
(exit_status, steps_executed, step_on_solana, tracer_result)
};

calculate_response(
steps_executed,
step_on_solana,
exit_status,
&storage,
tracer,
Expand Down
4 changes: 4 additions & 0 deletions evm_loader/program/src/account_storage/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ impl<'a> AccountStorage for ProgramAccountStorage<'a> {
.map_or(U256::ZERO, |a| a.balance())
}

fn is_on_emulator(&self) -> bool {
false
}

fn is_valid_chain_id(&self, chain_id: u64) -> bool {
crate::config::CHAIN_ID_LIST
.binary_search_by_key(&chain_id, |c| c.0)
Expand Down
1 change: 1 addition & 0 deletions evm_loader/program/src/account_storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub trait AccountStorage: LogCollector {
/// Get account balance
async fn balance(&self, address: Address, chain_id: u64) -> U256;

fn is_on_emulator(&self) -> bool;
fn is_valid_chain_id(&self, chain_id: u64) -> bool;
fn chain_id_to_token(&self, chain_id: u64) -> Pubkey;
fn default_chain_id(&self) -> u64;
Expand Down
1 change: 1 addition & 0 deletions evm_loader/program/src/evm/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use solana_program::{
#[maybe_async(?Send)]
pub trait Database: LogCollector {
fn is_synced_state(&self) -> bool;
fn is_on_emulator(&self) -> bool;
fn program_id(&self) -> &Pubkey;
fn operator(&self) -> Pubkey;
fn chain_id_to_token(&self, chain_id: u64) -> Pubkey;
Expand Down
14 changes: 9 additions & 5 deletions evm_loader/program/src/evm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ pub struct Context {
pub contract_chain_id: u64,
pub value: U256,
pub code_address: Option<Address>,
pub interrupt_solana_call: bool,
pub got_solana_call: bool,
}

#[repr(C)]
Expand Down Expand Up @@ -279,7 +279,7 @@ impl<B: Database, T: EventListener> Machine<B, T> {
contract_chain_id: backend.contract_chain_id(target).await.unwrap_or(chain_id),
value: trx.value(),
code_address: Some(target),
interrupt_solana_call: true,
got_solana_call: false,
},
gas_price: trx.gas_price(),
gas_limit: trx.gas_limit(),
Expand Down Expand Up @@ -332,7 +332,7 @@ impl<B: Database, T: EventListener> Machine<B, T> {
contract_chain_id: chain_id,
value: trx.value(),
code_address: None,
interrupt_solana_call: true,
got_solana_call: false,
},
gas_price: trx.gas_price(),
gas_limit: trx.gas_limit(),
Expand All @@ -356,8 +356,9 @@ impl<B: Database, T: EventListener> Machine<B, T> {
&mut self,
step_limit: u64,
backend: &mut B,
) -> Result<(ExitStatus, u64, Option<T>)> {
) -> Result<(ExitStatus, u64, Option<u64>, Option<T>)> {
let mut step = 0_u64;
let mut step_call_solana: Option<u64> = None;

begin_vm!(
self,
Expand Down Expand Up @@ -401,6 +402,9 @@ impl<B: Database, T: EventListener> Machine<B, T> {
}
};

if step_call_solana.is_none() && self.context.got_solana_call {
step_call_solana = Some(step);
}
match opcode_result {
Action::Continue => self.pc += 1,
Action::Jump(target) => self.pc = target,
Expand All @@ -414,7 +418,7 @@ impl<B: Database, T: EventListener> Machine<B, T> {
}
};

Ok((status, step, self.tracer.take()))
Ok((status, step, step_call_solana, self.tracer.take()))
}

fn fork(
Expand Down
6 changes: 3 additions & 3 deletions evm_loader/program/src/evm/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,7 @@ impl<B: Database, T: EventListener> Machine<B, T> {
contract_chain_id: chain_id,
value,
code_address: None,
interrupt_solana_call: true,
got_solana_call: false,
};

begin_vm!(self, backend, context, chain_id, init_code);
Expand Down Expand Up @@ -1166,7 +1166,7 @@ impl<B: Database, T: EventListener> Machine<B, T> {
contract_chain_id: backend.contract_chain_id(address).await.unwrap_or(chain_id),
value,
code_address: Some(address),
interrupt_solana_call: true,
got_solana_call: false,
};

begin_vm!(self, backend, context, chain_id, call_data);
Expand Down Expand Up @@ -1307,7 +1307,7 @@ impl<B: Database, T: EventListener> Machine<B, T> {
contract_chain_id: backend.contract_chain_id(address).await.unwrap_or(chain_id),
value: U256::ZERO,
code_address: Some(address),
interrupt_solana_call: true,
got_solana_call: false,
};

begin_vm!(self, backend, context, chain_id, call_data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,10 +317,19 @@ async fn execute_external_instruction<State: Database>(
#[cfg(not(target_os = "solana"))]
log::info!("instruction: {:?}", instruction);

if !state.is_synced_state() && context.interrupt_solana_call {
context.interrupt_solana_call = false;
if !state.is_synced_state() && !context.got_solana_call {
context.got_solana_call = true;
return Err(Error::InterruptedCall);
}

/*
if !context.got_solana_call {
context.got_solana_call = true;
if !state.is_synced_state() /*|| !state.is_on_emulator()*/ {
return Err(Error::InterruptedCall);
}
}
*/
let called_program = instruction.program_id;
state.set_return_data(&[]);

Expand Down
3 changes: 3 additions & 0 deletions evm_loader/program/src/executor/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ impl<'a, B: AccountStorage> Database for ExecutorState<'a, B> {
fn is_synced_state(&self) -> bool {
false
}
fn is_on_emulator(&self) -> bool {
self.backend.is_on_emulator()
}
fn program_id(&self) -> &Pubkey {
self.backend.program_id()
}
Expand Down
3 changes: 3 additions & 0 deletions evm_loader/program/src/executor/synced_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ impl<'a, B: SyncedAccountStorage> Database for SyncedExecutorState<'a, B> {
fn is_synced_state(&self) -> bool {
true
}
fn is_on_emulator(&self) -> bool {
self.backend.is_on_emulator()
}
fn program_id(&self) -> &Pubkey {
self.backend.program_id()
}
Expand Down
4 changes: 2 additions & 2 deletions evm_loader/program/src/instruction/transaction_execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn execute(
let mut backend = ExecutorState::new(&mut account_storage, &mut backend_data);

let mut evm = Machine::new(&trx, origin, &mut backend, None::<NoopEventListener>)?;
let (result, steps_executed, _) = evm.execute(u64::MAX, &mut backend)?;
let (result, steps_executed, _, _) = evm.execute(u64::MAX, &mut backend)?;

(result, steps_executed)
};
Expand Down Expand Up @@ -89,7 +89,7 @@ pub fn execute_with_solana_call(
let mut backend = SyncedExecutorState::new(&mut account_storage);

let mut evm = Machine::new(&trx, origin, &mut backend, None::<NoopEventListener>)?;
let (result, steps_executed, _) = evm.execute(u64::MAX, &mut backend)?;
let (result, steps_executed, _, _) = evm.execute(u64::MAX, &mut backend)?;

(result, steps_executed)
};
Expand Down
4 changes: 2 additions & 2 deletions evm_loader/program/src/instruction/transaction_step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub fn do_continue<'a>(

let mut steps_executed = 0;
if backend.exit_status().is_none() {
let (exit_status, steps_returned, _) = evm.execute(step_count, &mut backend)?;
let (exit_status, steps_returned, _, _) = evm.execute(step_count, &mut backend)?;
if exit_status != ExitStatus::StepLimit {
backend.set_exit_status(exit_status)
}
Expand Down Expand Up @@ -261,7 +261,7 @@ fn finalize_interrupted(
&mut backend,
None::<NoopEventListener>,
)?;
let (result, steps_executed, _) = evm.execute(u64::MAX, &mut backend)?;
let (result, steps_executed, _, _) = evm.execute(u64::MAX, &mut backend)?;
(result, steps_executed)
};
log_data(&[
Expand Down

0 comments on commit a292047

Please sign in to comment.