Skip to content

Commit

Permalink
feat: only sender account is an EOA in tests (#659)
Browse files Browse the repository at this point in the history
* feat: only sender account is an EOA in tests

* satisfy clippy

* happy trunk

* Ignore validation failure due to EOA with code
  • Loading branch information
enitrat authored Feb 16, 2024
1 parent e7d0f3e commit 4e35d11
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 12 deletions.
1 change: 1 addition & 0 deletions crates/ef-testing/src/evm_sequencer/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub mod kkrt_account {
_code: &Bytes,
_nonce: U256,
_evm_storage: &[(U256, U256)],
_is_eoa: bool,
) -> Result<Self, StarknetApiError> {
Ok(Self {
evm_address: StarkFelt::default(),
Expand Down
6 changes: 3 additions & 3 deletions crates/ef-testing/src/evm_sequencer/account/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ impl KakarotAccount {
code: &Bytes,
nonce: U256,
evm_storage: &[(U256, U256)],
is_eoa: bool,
) -> Result<Self, StarknetApiError> {
let nonce = StarkFelt::from(TryInto::<u128>::try_into(nonce).map_err(|err| {
StarknetApiError::OutOfRange {
Expand All @@ -30,9 +31,8 @@ impl KakarotAccount {
];

// Initialize the implementation and nonce based on account type.
// The account is an EOA if it has no bytecode and no storage (or all storage is zero).
let has_code_or_storage = !code.is_empty() || evm_storage.iter().any(|x| x.1 != U256::ZERO);
let account_type = if !has_code_or_storage {
// In tests, only the sender is an EOA.
let account_type = if is_eoa {
AccountType::EOA
} else {
storage.append(&mut vec![starknet_storage!("nonce", nonce)]);
Expand Down
6 changes: 3 additions & 3 deletions crates/ef-testing/src/evm_sequencer/account/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ impl KakarotAccount {
code: &Bytes,
nonce: U256,
evm_storage: &[(U256, U256)],
is_eoa: bool,
) -> Result<Self, StarknetApiError> {
let nonce = StarkFelt::from(TryInto::<u128>::try_into(nonce).map_err(|err| {
StarknetApiError::OutOfRange {
Expand All @@ -36,9 +37,8 @@ impl KakarotAccount {
let mut storage = vec![starknet_storage!("evm_address", evm_address)];

// Initialize the implementation and nonce based on account type.
// The account is an EOA if it has no bytecode and no storage (or all storage is zero).
let has_code_or_storage = !code.is_empty() || evm_storage.iter().any(|x| x.1 != U256::ZERO);
let account_type = if !has_code_or_storage {
// In tests, only the sender is an EOA.
let account_type = if is_eoa {
AccountType::EOA
} else {
storage.push(starknet_storage!("contract_account_nonce", nonce));
Expand Down
5 changes: 3 additions & 2 deletions crates/ef-testing/src/evm_sequencer/evm_state/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,9 @@ mod tests {
let nonce = U256::from(0);

// When
let contract = KakarotAccount::new(&TEST_CONTRACT_ADDRESS, &bytecode, nonce, &[]).unwrap();
let eoa = KakarotAccount::new(&PUBLIC_KEY, &Bytes::default(), nonce, &[]).unwrap();
let contract =
KakarotAccount::new(&TEST_CONTRACT_ADDRESS, &bytecode, nonce, &[], false).unwrap();
let eoa = KakarotAccount::new(&PUBLIC_KEY, &Bytes::default(), nonce, &[], true).unwrap();
sequencer.setup_account(contract).unwrap();
sequencer.setup_account(eoa).unwrap();
sequencer.execute_transaction(transaction).unwrap();
Expand Down
9 changes: 5 additions & 4 deletions crates/ef-testing/src/evm_sequencer/evm_state/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ impl Evm for KakarotSequencer {
/// Sets up the evm state (coinbase, block number, etc.)
fn setup_state(&mut self, _base_fee: U256) -> StateResult<()> {
let coinbase_address = *self.address();
let coinbase = KakarotAccount::new(&coinbase_address, &Bytes::default(), U256::ZERO, &[])?;
let coinbase =
KakarotAccount::new(&coinbase_address, &Bytes::default(), U256::ZERO, &[], true)?;
self.setup_account(coinbase)?;
self.fund(&coinbase_address, U256::ZERO)?;

Expand Down Expand Up @@ -383,7 +384,7 @@ mod tests {

// When
let account =
KakarotAccount::new(&TEST_CONTRACT_ADDRESS, &bytecode, U256::ZERO, &[]).unwrap();
KakarotAccount::new(&TEST_CONTRACT_ADDRESS, &bytecode, U256::ZERO, &[], false).unwrap();
sequencer.setup_account(account).unwrap();

// Then
Expand Down Expand Up @@ -437,8 +438,8 @@ mod tests {
]); // PUSH 01 PUSH 00 SSTORE
let nonce = U256::from(0);
let contract_account =
KakarotAccount::new(&TEST_CONTRACT_ADDRESS, &bytecode, nonce, &[]).unwrap();
let eoa = KakarotAccount::new(&PUBLIC_KEY, &Bytes::default(), nonce, &[]).unwrap();
KakarotAccount::new(&TEST_CONTRACT_ADDRESS, &bytecode, nonce, &[], false).unwrap();
let eoa = KakarotAccount::new(&PUBLIC_KEY, &Bytes::default(), nonce, &[], true).unwrap();
sequencer.setup_account(contract_account).unwrap();
sequencer.setup_account(eoa).unwrap();
sequencer.execute_transaction(transaction).unwrap();
Expand Down
6 changes: 6 additions & 0 deletions crates/ef-testing/src/models/case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,18 @@ impl BlockchainTestCase {
}

fn handle_pre_state(&self, sequencer: &mut KakarotSequencer) -> Result<(), RunnerError> {
let wallet = LocalWallet::from_bytes(&self.secret_key.0)
.map_err(|err| RunnerError::Other(vec![err.to_string()].into()))?;
let sender_address = wallet.address().to_fixed_bytes();

for (address, account) in self.pre.iter() {
let is_eoa = address.0 == sender_address;
let kakarot_account = KakarotAccount::new(
address,
&account.code,
account.nonce,
&account.storage.clone().into_iter().collect::<Vec<_>>()[..],
is_eoa,
)?;
sequencer.setup_account(kakarot_account)?;
sequencer.fund(address, account.balance)?;
Expand Down
5 changes: 5 additions & 0 deletions crates/ef-testing/src/models/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ pub(crate) fn log_execution_result(
TransactionExecutionResult::Err(TransactionExecutionError::ValidateTransactionError(
EntryPointExecutionError::VirtualMachineExecutionErrorWithTrace { trace, .. },
)) => {
// There are specific test cases where validation failed because the sender account has code.
// They're caught by EOA validation, and rejected with this specific error message.
if trace.contains("EOAs cannot have code") {
return;
}
let re = regex::Regex::new(
r#"Error in the called contract \((0x[0-9a-zA-Z]+)\)[\s\S]*?EntryPointSelector\(StarkFelt\("(0x[0-9a-zA-Z]+)"\)\)"#,
).unwrap();
Expand Down

0 comments on commit 4e35d11

Please sign in to comment.