Skip to content

Commit

Permalink
Merge branch 'main' into feat/kakarot_core_update
Browse files Browse the repository at this point in the history
  • Loading branch information
Eikix authored Oct 11, 2023
2 parents 251f759 + c4060fb commit f2ddcc2
Show file tree
Hide file tree
Showing 15 changed files with 427 additions and 108 deletions.
1 change: 1 addition & 0 deletions crates/eoa/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ version = "0.1.0"

[dependencies]
starknet.workspace = true
evm = { path = "../evm" }
70 changes: 60 additions & 10 deletions crates/eoa/src/externally_owned_account.cairo
Original file line number Diff line number Diff line change
@@ -1,29 +1,79 @@
// Migrate https://github.com/kkrt-labs/kakarot/blob/7ec7a96074394ddb592a2b6fbea279c6c5cb25a6/src/kakarot/accounts/eoa/externally_owned_account.cairo#L4
use starknet::{ContractAddress, EthAddress,};
use starknet::account::{Call, AccountContract};

#[starknet::interface]
trait IExternallyOwnedAccount<TContractState> {
fn bytecode(self: @TContractState) -> Span<u8>;
fn bytecode_len(self: @TContractState) -> u32;
fn kakarot_core_address(self: @TContractState) -> ContractAddress;
fn evm_address(self: @TContractState) -> EthAddress;
}

#[starknet::contract]
mod ExternallyOwnedAccount {
use starknet::ContractAddress;
use starknet::{ContractAddress, EthAddress, VALIDATED, get_caller_address};
use starknet::account::{Call, AccountContract};

#[storage]
struct Storage {
starknet_address: ContractAddress
evm_address: EthAddress,
kakarot_core_address: ContractAddress,
}

#[constructor]
fn constructor(
ref self: ContractState, kakarot_address: ContractAddress, evm_address: EthAddress
) {
self.kakarot_core_address.write(kakarot_address);
self.evm_address.write(evm_address);
}

#[external(v0)]
impl ExternallyOwnedAccount of super::IExternallyOwnedAccount<ContractState> {
/// Returns an empty span, required for the EXTCODE opcode
fn bytecode(self: @ContractState) -> Span<u8> {
return ArrayTrait::<u8>::new().span();
fn kakarot_core_address(self: @ContractState) -> ContractAddress {
self.kakarot_core_address.read()
}
/// Return 0 bytecode_len, required for the EXTCODE opcode
fn bytecode_len(self: @ContractState) -> u32 {
return 0;
fn evm_address(self: @ContractState) -> EthAddress {
self.evm_address.read()
}
}

#[external(v0)]
impl AccountContractImpl of AccountContract<ContractState> {
fn __validate__(ref self: ContractState, calls: Array<Call>) -> felt252 {
assert(get_caller_address().is_zero(), 'Caller not zero');
// TODO
// Steps:
// Receive a payload formed as:
// Starknet Transaction Signature field: r, s, v (EVM Signature fields)
// Calldata field: an RLP-encoded EVM transaction, without r, s, v

// Step 1:
// Hash RLP-encoded EVM transaction
// Step 2:
// Verify EVM signature using get_tx_info().signature field against the keccak hash of the EVM tx
// Step 3:
// If valid signature, decode the RLP-encoded payload
// Step 4:
// Return ok

VALIDATED
}

/// Validate Declare is not used for Kakarot
fn __validate_declare__(self: @ContractState, class_hash: felt252) -> felt252 {
panic_with_felt252('Cannot Declare EOA')
}


fn __execute__(ref self: ContractState, calls: Array<Call>) -> Array<Span<felt252>> {
// TODO

// Step 1:
// Decode RLP-encoded transaction
// Step 2:
// Call KakarotCore.send_eth_transaction with correct params

array![]
}
}
}
Expand Down
21 changes: 13 additions & 8 deletions crates/eoa/src/tests/test_externally_owned_account.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ mod test_external_owned_account {
IExternallyOwnedAccountDispatcherTrait
};
use starknet::class_hash::Felt252TryIntoClassHash;
use starknet::{deploy_syscall, ContractAddress, get_contract_address, contract_address_const};
use starknet::{
deploy_syscall, ContractAddress, get_contract_address, contract_address_const, EthAddress
};
use starknet::testing::{set_caller_address, set_contract_address};
use evm::tests::test_utils::{kakarot_address, eoa_address};

fn deploy_eoa() -> IExternallyOwnedAccountDispatcher {
let mut calldata = ArrayTrait::new();
let calldata: Span<felt252> = array![kakarot_address().into(), eoa_address().into()].span();

let (contract_address, _) = deploy_syscall(
ExternallyOwnedAccount::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false
ExternallyOwnedAccount::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata, true
)
.unwrap();

Expand All @@ -21,21 +24,23 @@ mod test_external_owned_account {

#[test]
#[available_gas(2000000000)]
fn test_bytecode() {
let owner = contract_address_const::<1>();
fn test_kakarot_address() {
let expected_address = kakarot_address();

let eoa_contract = deploy_eoa();

assert(eoa_contract.bytecode() == Default::default().span(), 'wrong bytecode');
assert(eoa_contract.kakarot_core_address() == expected_address, 'wrong kakarot_address');
}

#[test]
#[available_gas(2000000000)]
fn test_bytecode_len() {
fn test_evm_address() {
let owner = contract_address_const::<1>();

let expected_address: EthAddress = eoa_address();

let eoa_contract = deploy_eoa();

assert(eoa_contract.bytecode_len() == 0, 'wrong bytecode');
assert(eoa_contract.evm_address() == expected_address, 'wrong evm_address');
}
}
5 changes: 5 additions & 0 deletions crates/evm/src/context.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ impl ExecutionContextImpl of ExecutionContextTrait {
true
}

#[inline(always)]
fn status(self: @ExecutionContext) -> Status {
*self.status
}

#[inline(always)]
fn call_ctx(self: @ExecutionContext) -> CallContext {
(*self.call_ctx).unbox()
Expand Down
33 changes: 23 additions & 10 deletions crates/evm/src/interpreter.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// System imports.

/// Internal imports.
use evm::context::{CallContextTrait,};
use evm::context::{CallContextTrait, Status};
use evm::errors::{EVMError, PC_OUT_OF_BOUNDS};
use evm::instructions::{
duplication_operations, environmental_information, ExchangeOperationsTrait, logging_operations,
Expand All @@ -11,6 +11,7 @@ use evm::instructions::{
MemoryOperationTrait
};
use evm::machine::{Machine, MachineCurrentContextTrait};
use evm::storage_journal::JournalTrait;
use utils::{helpers::u256_to_bytes_array};

#[derive(Drop, Copy)]
Expand All @@ -23,6 +24,7 @@ trait EVMInterpreterTrait {
fn run(ref self: EVMInterpreter, ref machine: Machine);
/// Decodes the opcode at `pc` and executes the associated function.
fn decode_and_execute(ref self: EVMInterpreter, ref machine: Machine) -> Result<(), EVMError>;
fn handle_revert(ref self: EVMInterpreter, ref machine: Machine);
}


Expand All @@ -38,21 +40,25 @@ impl EVMInterpreterImpl of EVMInterpreterTrait {

match result {
Result::Ok(_) => {
// Check if the execution is complete.
if !(machine.stopped()) {
// Execute the next opcode.
self.run(ref machine);
}
if machine.reverted() { // TODO: Revert logic
}
if machine.stopped() { // TODO: stopped logic
match machine.status() {
Status::Active => {
// execute the next opcode
self.run(ref machine);
},
Status::Stopped => {
machine.storage_journal.finalize_local();
if machine.is_root() {
machine.storage_journal.finalize_global();
}
},
Status::Reverted => { self.handle_revert(ref machine); }
}
},
Result::Err(error) => {
// If an error occurred, revert execution machine.
// Currently, revert reason is a Span<u8>.
machine.revert(u256_to_bytes_array(error.into()).span());
// TODO: Revert logic
self.handle_revert(ref machine);
}
}
}
Expand Down Expand Up @@ -649,4 +655,11 @@ impl EVMInterpreterImpl of EVMInterpreterTrait {
// Unknown opcode
return Result::Err(EVMError::UnknownOpcode(opcode));
}

/// Handles the revert of an execution context.
/// Clears all pending journal entries, not finalizing the pending state changes applied inside this context.
fn handle_revert(ref self: EVMInterpreter, ref machine: Machine) {
machine.storage_journal.clear_local();
//TODO add the rest of the revert handling.
}
}
9 changes: 9 additions & 0 deletions crates/evm/src/machine.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ impl MachineCurrentContextImpl of MachineCurrentContextTrait {
stopped
}

#[inline(always)]
fn status(ref self: Machine) -> Status {
let current_execution_ctx = self.current_ctx.unbox();
let status = current_execution_ctx.status();

self.current_ctx = BoxTrait::new(current_execution_ctx);
status
}


#[inline(always)]
fn call_ctx(ref self: Machine) -> CallContext {
Expand Down
5 changes: 5 additions & 0 deletions crates/evm/src/storage_journal.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,9 @@ impl JournalImpl of JournalTrait {
};
self.global_keys = Default::default();
}

fn clear_local(ref self: Journal) {
self.local_keys = Default::default();
self.local_changes = Default::default();
}
}
11 changes: 11 additions & 0 deletions crates/evm/src/tests/test_utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ fn callvalue() -> u256 {
123456789
}


fn deploy_fee() -> u128 {
0x10
}
Expand All @@ -50,6 +51,16 @@ fn chain_id() -> u128 {
'CHAIN_ID'.try_into().unwrap()
}

fn kakarot_address() -> ContractAddress {
let test_kakarot_address: ContractAddress = contract_address_const::<0x777>();
test_kakarot_address
}

fn eoa_address() -> EthAddress {
let evm_address: EthAddress = 0xe0a.try_into().unwrap();
evm_address
}

fn setup_call_context() -> CallContext {
let bytecode: Span<u8> = array![1, 2, 3].span();
let calldata: Span<u8> = array![4, 5, 6].span();
Expand Down
1 change: 1 addition & 0 deletions crates/utils/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

mod helpers;
mod constants;
mod num;
mod math;
mod eth_transaction;
mod rlp;
Expand Down
Loading

0 comments on commit f2ddcc2

Please sign in to comment.