Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: architecture refactor #604

Merged
merged 10 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
scarb nightly-2023-11-25
scarb 2.4.0-rc6
4 changes: 2 additions & 2 deletions Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ members = ["crates/*"]
[workspace.package]
description = "Kakarot is an (zk)-Ethereum Virtual Machine implementation written in Cairo."
documentation = "https://www.kakarot.org/"
cairo-version = "2.3.1"
cairo-version = "2.4.0"
version = "0.1.0"
readme = "README.md"
repository = "https://github.com/kkrt-labs/kakarot-ssj/"
license-file = "LICENSE"

[workspace.dependencies]
starknet = "2.3.1"
starknet = "2.4.0-rc6"

[workspace.tool.fmt]
sort-module-level-items = true
4 changes: 2 additions & 2 deletions crates/contracts/src/eoa.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,12 @@ mod ExternallyOwnedAccount {
contract_address: self.kakarot_core_address()
};

let result = kakarot_core_dispatcher
let (_, return_data) = kakarot_core_dispatcher
.eth_send_transaction(
Option::Some(destination), gas_limit, gas_price, amount, calldata
);

array![result.to_felt252_array().span()]
array![return_data.to_felt252_array().span()]
}
}

Expand Down
8 changes: 4 additions & 4 deletions crates/contracts/src/kakarot_core/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ trait IKakarotCore<TContractState> {
gas_price: u128,
value: u256,
calldata: Span<u8>
) -> Span<u8>;
) -> (bool, Span<u8>);

/// Transaction entrypoint into the EVM
/// Executes an EVM transaction and possibly modifies the state
Expand All @@ -81,7 +81,7 @@ trait IKakarotCore<TContractState> {
gas_price: u128,
value: u256,
calldata: Span<u8>
) -> Span<u8>;
) -> (bool, Span<u8>);

/// Upgrade the KakarotCore smart contract
/// Using replace_class_syscall
Expand Down Expand Up @@ -171,7 +171,7 @@ trait IExtendedKakarotCore<TContractState> {
gas_price: u128,
value: u256,
calldata: Span<u8>
) -> Span<u8>;
) -> (bool, Span<u8>);

/// Transaction entrypoint into the EVM
/// Executes an EVM transaction and possibly modifies the state
Expand All @@ -182,7 +182,7 @@ trait IExtendedKakarotCore<TContractState> {
gas_price: u128,
value: u256,
calldata: Span<u8>
) -> Span<u8>;
) -> (bool, Span<u8>);

/// Upgrade the KakarotCore smart contract
/// Using replace_class_syscall
Expand Down
91 changes: 49 additions & 42 deletions crates/contracts/src/kakarot_core/kakarot.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@ mod KakarotCore {
use core::traits::TryInto;
use core::zeroable::Zeroable;

use evm::context::Status;
use evm::errors::{EVMError, EVMErrorTrait, CALLING_FROM_CA, CALLING_FROM_UNDEPLOYED_ACCOUNT};
use evm::execution::execute;
use evm::machine::{Machine, MachineTrait};
use evm::interpreter::{EVMTrait};
use evm::model::account::{Account, AccountType, AccountTrait};
use evm::model::contract_account::{ContractAccountTrait};
use evm::model::eoa::{EOATrait};
use evm::model::{ExecutionResult, Address, AddressTrait};
use evm::model::{ExecutionSummary, Address, AddressTrait};
use evm::model::{Message, Environment};
use evm::state::{State, StateTrait};
use starknet::{
EthAddress, ContractAddress, ClassHash, get_tx_info, get_contract_address, deploy_syscall,
Expand Down Expand Up @@ -253,20 +252,16 @@ mod KakarotCore {
gas_price: u128,
value: u256,
calldata: Span<u8>
) -> Span<u8> {
) -> (bool, Span<u8>) {
if !self.is_view() {
panic_with_felt252('fn must be called, not invoked');
};

let origin = Address { evm: origin, starknet: self.compute_starknet_address(origin) };

let result = self.handle_call(:origin, :to, :gas_limit, :gas_price, :value, :calldata);
match result {
Result::Ok(result) => result.return_data,
// TODO: Return the error message as Bytes in the response
// Eliminate all paths of possible panic in logic with relations to the EVM itself.
Result::Err(err) => panic_with_felt252(err.to_string()),
}
let ExecutionSummary{state: _, return_data, address: _, success } = self
.process_transaction(:origin, :to, :gas_limit, :gas_price, :value, :calldata);
(success, return_data)
}

fn eth_send_transaction(
Expand All @@ -276,7 +271,7 @@ mod KakarotCore {
gas_price: u128,
value: u256,
calldata: Span<u8>
) -> Span<u8> {
) -> (bool, Span<u8>) {
let starknet_caller_address = get_caller_address();
let account = IExternallyOwnedAccountDispatcher {
contract_address: starknet_caller_address
Expand All @@ -294,21 +289,10 @@ mod KakarotCore {
.expect('Fetching EOA failed');
assert(caller_account_type == AccountType::EOA, 'Caller is not an EOA');

let mut maybe_exec_result = self
.handle_call(:origin, :to, :gas_limit, :gas_price, :value, :calldata);
match maybe_exec_result {
Result::Ok(mut result) => {
result.state.commit_state().expect('Committing state failed');
if to.is_none() {
// Overwrite return_data with deployed address
return result.address.evm.to_bytes().span();
}
result.return_data
},
// TODO: Return the error message as Bytes in the response
// Eliminate all paths of possible panic in logic with relations to the EVM itself.
Result::Err(err) => panic_with_felt252(err.to_string()),
}
let ExecutionSummary{mut state, return_data, address: _, success } = self
.process_transaction(:origin, :to, :gas_limit, :gas_price, :value, :calldata);
state.commit_state().expect('Committing state failed');
Eikix marked this conversation as resolved.
Show resolved Hide resolved
(success, return_data)
}

fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {
Expand Down Expand Up @@ -373,42 +357,65 @@ mod KakarotCore {
}


fn handle_call(
fn process_transaction(
self: @ContractState,
origin: Address,
to: Option<EthAddress>,
gas_limit: u128,
gas_price: u128,
value: u256,
calldata: Span<u8>
) -> Result<ExecutionResult, EVMError> {
let (to, is_deploy_tx) = match to {
) -> ExecutionSummary {
let block_info = starknet::get_block_info().unbox();
let eoa = IExternallyOwnedAccountDispatcher {
Eikix marked this conversation as resolved.
Show resolved Hide resolved
contract_address: block_info.sequencer_address
};
let coinbase = eoa.evm_address();
let mut env = Environment {
origin: origin.evm,
gas_price,
chain_id: self.chain_id.read(),
prevrandao: 0,
block_number: block_info.block_number,
coinbase,
timestamp: block_info.block_timestamp,
state: Default::default(),
};

let (to, is_deploy_tx, code, calldata) = match to {
Option::Some(to) => {
let target_starknet_address = self.compute_starknet_address(to);
let to = Address { evm: to, starknet: target_starknet_address };
(to, false)
let code = env.state.get_account(to.evm).code;
(to, false, code, calldata)
},
Option::None => {
// Deploy tx case.
let mut origin_nonce: u64 = get_tx_info().unbox().nonce.try_into().unwrap();
let to_evm_address = compute_contract_address(origin.evm, origin_nonce);
let to_starknet_address = self.compute_starknet_address(to_evm_address);
let to = Address { evm: to_evm_address, starknet: to_starknet_address };
(to, true)
let code = calldata;
let calldata = Default::default().span();
(to, true, code, calldata)
},
};

let execution_result = execute(
:origin,
let code = env.state.get_account(to.evm).code;

let message = Message {
caller: origin,
target: to,
:calldata,
:value,
:gas_price,
:gas_limit,
gas_limit,
data: calldata,
code,
value,
depth: 0,
read_only: false,
:is_deploy_tx,
);
Result::Ok(execution_result)
should_transfer_value: true,
};

EVMTrait::process_message_call(message, env, is_deploy_tx)
}
}
}
17 changes: 2 additions & 15 deletions crates/contracts/src/tests/test_eoa.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ mod test_external_owned_account {


#[test]
#[available_gas(2000000000)]
fn test_kakarot_address() {
let (_, kakarot) = setup_contracts_for_testing();
let kakarot_address = kakarot.contract_address;
Expand All @@ -53,7 +52,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
fn test_evm_address() {
let expected_address: EthAddress = eoa_address();
setup_contracts_for_testing();
Expand All @@ -64,7 +62,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
fn test_eoa_upgrade() {
setup_contracts_for_testing();
let eoa_contract = deploy_eoa(eoa_address());
Expand All @@ -85,7 +82,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
#[should_panic(expected: ('Caller not self', 'ENTRYPOINT_FAILED'))]
fn test_eoa_upgrade_from_noncontractaddress() {
setup_contracts_for_testing();
Expand All @@ -98,7 +94,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
fn test___execute__() {
let (_, kakarot_core) = setup_contracts_for_testing();

Expand All @@ -117,7 +112,7 @@ mod test_external_owned_account {
let data_get_tx = array![0x6d, 0x4c, 0xe6, 0x3c].span();

// check counter value is 0 before doing inc
let return_data = kakarot_core
let (_, return_data) = kakarot_core
.eth_call(
origin: evm_address,
to: Option::Some(other_evm_address()),
Expand All @@ -141,7 +136,7 @@ mod test_external_owned_account {
eoa_contract.__execute__(array![call]);

// check counter value has increased
let return_data = kakarot_core
let (_, return_data) = kakarot_core
.eth_call(
origin: evm_address,
to: Option::Some(other_evm_address()),
Expand All @@ -155,7 +150,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
#[should_panic(expected: ('calls length is not 1', 'ENTRYPOINT_FAILED'))]
fn test___execute___should_fail_with_zero_calls() {
setup_contracts_for_testing();
Expand All @@ -169,7 +163,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
#[should_panic(expected: ('Caller not 0', 'ENTRYPOINT_FAILED'))]
fn test___validate__fail__caller_not_0() {
let (_, kakarot_core) = setup_contracts_for_testing();
Expand All @@ -184,7 +177,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
#[should_panic(expected: ('call len is not 1', 'ENTRYPOINT_FAILED'))]
fn test___validate__fail__call_data_len_not_1() {
let (_, kakarot_core) = setup_contracts_for_testing();
Expand All @@ -199,7 +191,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
#[should_panic(expected: ('to is not kakarot core', 'ENTRYPOINT_FAILED'))]
fn test___validate__fail__to_address_not_kakarot_core() {
let (_, kakarot_core) = setup_contracts_for_testing();
Expand All @@ -219,7 +210,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
#[should_panic(
expected: ("Validate: selector must be eth_send_transaction", 'ENTRYPOINT_FAILED')
)]
Expand All @@ -239,7 +229,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
fn test___validate__legacy_transaction() {
let (_, kakarot_core) = setup_contracts_for_testing();
let evm_address: EthAddress = 0x6Bd85F39321B00c6d603474C5B2fddEB9c92A466_u256.into();
Expand Down Expand Up @@ -269,7 +258,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
fn test___validate__eip_2930_transaction() {
let (_, kakarot_core) = setup_contracts_for_testing();
let evm_address: EthAddress = 0x6Bd85F39321B00c6d603474C5B2fddEB9c92A466_u256.into();
Expand Down Expand Up @@ -300,7 +288,6 @@ mod test_external_owned_account {
}

#[test]
#[available_gas(2000000000)]
fn test___validate__eip_1559_transaction() {
let (_, kakarot_core) = setup_contracts_for_testing();
let evm_address: EthAddress = 0x6Bd85F39321B00c6d603474C5B2fddEB9c92A466_u256.into();
Expand Down
Loading
Loading