Skip to content

Commit

Permalink
feat: add eth_chain_id entrypoint (#932)
Browse files Browse the repository at this point in the history
* rebase: rebase feat/add_eth_chain_id with main

* add: implement eth_chain_id

* fix: refactor code to call eth_chain_id properly

* fix: scarb fmt

* dev: add unit test eth_chain_id

* dev: add tests to test more cases of eth_chain_id
  • Loading branch information
bitfalt committed Sep 18, 2024
1 parent a3e5da8 commit 6334f29
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 18 deletions.
7 changes: 3 additions & 4 deletions crates/contracts/src/account_contract.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,8 @@ pub mod AccountContract {
use core::starknet::{
EthAddress, ClassHash, get_caller_address, get_tx_info, get_block_timestamp
};
use core::traits::TryInto;
use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait};
use super::OutsideExecution;
use utils::constants::{POW_2_32};
use utils::eth_transaction::transaction::TransactionUnsignedTrait;
use utils::serialization::{deserialize_signature, deserialize_bytes, serialize_bytes};
use utils::traits::DefaultSignature;
Expand Down Expand Up @@ -241,7 +239,9 @@ pub mod AccountContract {
// EOA Validation
assert(self.Account_bytecode_len.read().is_zero(), 'EOA: cannot have code');

let chain_id: u64 = tx_info.chain_id.try_into().unwrap() % POW_2_32.try_into().unwrap();
let kakarot = IEthRPCDispatcher { contract_address: self.ownable.owner() };

let chain_id: u64 = kakarot.eth_chain_id();
assert(signature.len() == 5, 'EOA: Invalid signature length');
let signature = deserialize_signature(signature, chain_id)
.expect('EOA: invalid signature');
Expand All @@ -257,7 +257,6 @@ pub mod AccountContract {
let address = self.Account_evm_address.read();
verify_eth_signature(unsigned_transaction.hash, signature, address);

let kakarot = IEthRPCDispatcher { contract_address: self.ownable.owner() };
//TODO: refactor this to call eth_send_raw_unsigned_tx. Only the transactions bytes are
//passed.
let (success, return_data, gas_used) = kakarot
Expand Down
57 changes: 56 additions & 1 deletion crates/contracts/src/kakarot_core/eth_rpc.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use evm::backend::starknet_backend;
use evm::backend::validation::validate_eth_tx;
use evm::model::{TransactionResult, Address};
use evm::{EVMTrait};
use utils::constants::POW_2_53;
use utils::eth_transaction::transaction::{TransactionTrait, Transaction};

#[starknet::interface]
Expand Down Expand Up @@ -130,7 +131,9 @@ pub impl EthRPC<
}

fn eth_chain_id(self: @TContractState) -> u64 {
panic!("unimplemented")
let tx_info = get_tx_info().unbox();
let tx_chain_id: u64 = tx_info.chain_id.try_into().unwrap();
tx_chain_id % POW_2_53.try_into().unwrap()
}

fn eth_call(
Expand Down Expand Up @@ -210,3 +213,55 @@ fn is_view(self: @KakarotCore::ContractState) -> bool {
}
true
}

#[cfg(test)]
mod tests {
use contracts::kakarot_core::KakarotCore;
use contracts::kakarot_core::eth_rpc::IEthRPC;
use snforge_std::{start_cheat_chain_id_global, stop_cheat_chain_id_global};
use utils::constants::POW_2_53;

fn set_up() -> KakarotCore::ContractState {
// Define the kakarot state to access contract functions
let kakarot_state = KakarotCore::unsafe_new_contract_state();

kakarot_state
}

fn tear_down() {
stop_cheat_chain_id_global();
}


#[test]
fn test_eth_chain_id_returns_input_when_less_than_pow_2_53() {
let kakarot_state = KakarotCore::unsafe_new_contract_state();
// Convert POW_2_53 - 1 to u64 since POW_2_53 is defined as u128
let chain_id: u64 = (POW_2_53 - 1).try_into().unwrap();
start_cheat_chain_id_global(chain_id.into());
assert_eq!(
kakarot_state.eth_chain_id(),
chain_id,
"Should return original chain ID when below 2^53"
);
tear_down();
}

#[test]
fn test_eth_chain_id_returns_modulo_when_greater_than_or_equal_to_pow_2_53() {
// Test with a value equal to 2^53
let kakarot_state = set_up();
let chain_id: u64 = POW_2_53.try_into().unwrap();
start_cheat_chain_id_global(chain_id.into());
assert_eq!(kakarot_state.eth_chain_id(), 0, "Should return 0 when chain ID is 2^53");

// Test with a value greater than 2^53
let chain_id: u64 = (POW_2_53 + 53).try_into().unwrap();
start_cheat_chain_id_global(chain_id.into());
assert_eq!(
kakarot_state.eth_chain_id(), 53, "Should return correct value after modulo operation"
);
tear_down();
}
}

14 changes: 8 additions & 6 deletions crates/evm/src/backend/starknet_backend.cairo
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use contracts::account_contract::{IAccountDispatcher, IAccountDispatcherTrait};
use contracts::kakarot_core::eth_rpc::IEthRPC;
use contracts::kakarot_core::{KakarotCore, KakarotCore::KakarotCoreImpl};
use core::num::traits::zero::Zero;
use core::ops::SnapshotDeref;
use core::starknet::storage::StoragePointerReadAccess;
use core::starknet::syscalls::{deploy_syscall};
use core::starknet::syscalls::{emit_event_syscall};
use core::starknet::{EthAddress, get_tx_info, get_block_info, SyscallResultTrait};
use core::starknet::{EthAddress, get_block_info, SyscallResultTrait};
use evm::errors::{ensure, EVMError, EOA_EXISTS};
use evm::model::{Address, AddressTrait, Environment, Account, AccountTrait};
use evm::model::{Transfer};
Expand Down Expand Up @@ -71,21 +72,22 @@ pub fn get_bytecode(evm_address: EthAddress) -> Span<u8> {

/// Populate an Environment with Starknet syscalls.
pub fn get_env(origin: EthAddress, gas_price: u128) -> Environment {
let kakarot_state = KakarotCore::unsafe_new_contract_state().snapshot_deref();
let kakarot_state = KakarotCore::unsafe_new_contract_state();
let kakarot_storage = kakarot_state.snapshot_deref();
let block_info = get_block_info().unbox();

// tx.gas_price and env.gas_price have the same values here
// - this is not always true in EVM transactions
Environment {
origin: origin,
gas_price,
chain_id: get_tx_info().unbox().chain_id.try_into().unwrap(),
prevrandao: kakarot_state.Kakarot_prev_randao.read(),
chain_id: kakarot_state.eth_chain_id(),
prevrandao: kakarot_storage.Kakarot_prev_randao.read(),
block_number: block_info.block_number,
block_gas_limit: constants::BLOCK_GAS_LIMIT,
block_timestamp: block_info.block_timestamp,
coinbase: kakarot_state.Kakarot_coinbase.read(),
base_fee: kakarot_state.Kakarot_base_fee.read(),
coinbase: kakarot_storage.Kakarot_coinbase.read(),
base_fee: kakarot_storage.Kakarot_base_fee.read(),
state: Default::default(),
}
}
Expand Down
10 changes: 3 additions & 7 deletions crates/evm/src/backend/validation.cairo
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use contracts::account_contract::{IAccountDispatcher, IAccountDispatcherTrait};
use contracts::kakarot_core::KakarotCore;
use contracts::kakarot_core::eth_rpc::IEthRPC;
use core::ops::SnapshotDeref;
use core::starknet::storage::{StoragePointerReadAccess};
use core::starknet::{get_caller_address, get_tx_info};
use core::starknet::{get_caller_address};
use evm::gas;
use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait};
use starknet::storage::StorageTrait;
Expand All @@ -24,12 +25,7 @@ pub fn validate_eth_tx(kakarot_state: @KakarotCore::ContractState, tx: Transacti

// Validate chain_id for post eip155
let tx_chain_id = tx.chain_id();
let kakarot_chain_id: u64 = get_tx_info()
.chain_id
.try_into()
.unwrap() % POW_2_32
.try_into()
.unwrap();
let kakarot_chain_id: u64 = kakarot_state.eth_chain_id();
if (tx_chain_id.is_some()) {
assert(tx_chain_id.unwrap() == kakarot_chain_id, 'Invalid chain id');
}
Expand Down
1 change: 1 addition & 0 deletions crates/utils/src/constants.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ pub const POW_2_24: u128 = 0x1000000;
pub const POW_2_32: u128 = 0x100000000;
pub const POW_2_40: u128 = 0x10000000000;
pub const POW_2_48: u128 = 0x1000000000000;
pub const POW_2_53: u128 = 0x20000000000000;
pub const POW_2_56: u128 = 0x100000000000000;
pub const POW_2_64: u128 = 0x10000000000000000;
pub const POW_2_72: u128 = 0x1000000000000000000;
Expand Down

0 comments on commit 6334f29

Please sign in to comment.