Skip to content
This repository has been archived by the owner on Jan 9, 2025. It is now read-only.

Commit

Permalink
Use evm address as key in state
Browse files Browse the repository at this point in the history
  • Loading branch information
ClementWalter committed Nov 22, 2023
1 parent 64ac288 commit c3d8a97
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 43 deletions.
34 changes: 20 additions & 14 deletions src/data_availability/starknet.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.bool import FALSE
from starkware.cairo.common.cairo_builtins import HashBuiltin
from starkware.cairo.common.dict_access import DictAccess
from starkware.cairo.common.hash import hash2
from starkware.cairo.common.uint256 import Uint256
from starkware.starknet.common.storage import normalize_address
from starkware.starknet.common.syscalls import (
emit_event,
get_contract_address,
Expand Down Expand Up @@ -73,6 +71,25 @@ namespace Starknet {
evm_to_starknet_address.write(evm_address, starknet_address);
return (account_address=starknet_address);
}

// @notice Return the bytecode of a given account
// @dev Return empty if the account is not deployed
// @param evm_address The address of the account
// @return bytecode_len The len of the bytecode
// @return bytecode The bytecode
func get_bytecode{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
evm_address: felt
) -> (bytecode_len: felt, bytecode: felt*) {
let (starknet_address) = evm_to_starknet_address.read(evm_address);

if (starknet_address == 0) {
let (bytecode: felt*) = alloc();
return (0, bytecode);
}

let (bytecode_len, bytecode) = IAccount.bytecode(starknet_address);
return (bytecode_len, bytecode);
}
}

namespace Internals {
Expand All @@ -88,7 +105,7 @@ namespace Internals {
return ();
}

let starknet_address = accounts_start.key;
let (starknet_address) = Account.compute_starknet_address(accounts_start.key);
let account = cast(accounts_start.new_value, Account.Summary*);
_commit_account(account, starknet_address);

Expand Down Expand Up @@ -216,15 +233,4 @@ namespace Internals {

return _save_storage(starknet_address, storage_start + DictAccess.SIZE, storage_end);
}

// @notice Compute the storage address of the given key when the storage var interface is
// storage_(key: Uint256)
// @dev Just the generated addr method when compiling the contract_account
func _storage_addr{pedersen_ptr: HashBuiltin*, range_check_ptr}(key: Uint256*) -> (res: felt) {
let res = 1510236440068827666686527023008568026372765124888307403567795291192307314167;
let (res) = hash2{hash_ptr=pedersen_ptr}(res, cast(key, felt*)[0]);
let (res) = hash2{hash_ptr=pedersen_ptr}(res, cast(key, felt*)[1]);
let (res) = normalize_address(addr=res);
return (res=res);
}
}
2 changes: 1 addition & 1 deletion src/kakarot/evm.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ namespace EVM {
let (state, success) = State.add_transfer(state, transfer);

// Check collision
let account = Account.fetch_or_create(address);
let (state, account) = State.get_account(state, address);
let code_or_nonce = Account.has_code_or_nonce(account);
let is_collision = code_or_nonce * is_deploy_tx;
// Nonce is set to 1 in case of deploy_tx
Expand Down
7 changes: 4 additions & 3 deletions src/kakarot/instructions/system_operations.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -766,17 +766,16 @@ namespace CreateHelper {
self=ctx.memory, element_len=size.low, element=bytecode, offset=offset.low
);

// Get new account address
// Get target account
let (state, evm_contract_address) = get_evm_address(
ctx.state, ctx.call_context.address, popped_len, popped, size.low, bytecode
);
let (starknet_contract_address) = Account.compute_starknet_address(evm_contract_address);
tempvar address = new model.Address(starknet_contract_address, evm_contract_address);

// Create Account with empty bytecode
let account = Account.fetch_or_create(address);
let (state, account) = State.get_account(state, address);
let is_collision = Account.has_code_or_nonce(account);
let account = Account.set_nonce(account, 1);

// Update calling context before creating sub context
let ctx = ExecutionContext.update_memory(ctx, memory);
Expand All @@ -790,6 +789,8 @@ namespace CreateHelper {

// Create sub context with copied state
let state = State.copy(ctx.state);
let (state, account) = State.get_account(state, address);
let account = Account.set_nonce(account, 1);
let state = State.set_account(state, address, account);
let (calldata: felt*) = alloc();
tempvar call_context: model.CallContext* = new model.CallContext(
Expand Down
6 changes: 3 additions & 3 deletions src/kakarot/library.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ namespace Kakarot {

let is_regular_tx = is_not_zero(to);
let is_deploy_tx = 1 - is_regular_tx;
let account = Account.fetch_or_create(address);
let (bytecode_len, bytecode) = Starknet.get_bytecode(address.evm);

let summary = EVM.execute(
address,
is_deploy_tx,
origin_address,
account.code_len,
account.code,
bytecode_len,
bytecode,
data_len,
data,
value,
Expand Down
14 changes: 6 additions & 8 deletions src/kakarot/state.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ namespace State {
) -> (model.State*, model.Account*) {
alloc_locals;
let accounts = self.accounts;
let (pointer) = dict_read{dict_ptr=accounts}(key=address.starknet);
let (pointer) = dict_read{dict_ptr=accounts}(key=address.evm);

// Return from local storage if found
if (pointer != 0) {
Expand All @@ -120,7 +120,7 @@ namespace State {
// Otherwise read values from contract storage
local accounts: DictAccess* = accounts;
let account = Account.fetch_or_create(address);
dict_write{dict_ptr=accounts}(key=address.starknet, new_value=cast(account, felt));
dict_write{dict_ptr=accounts}(key=address.evm, new_value=cast(account, felt));
tempvar state = new model.State(
accounts_start=self.accounts_start,
accounts=accounts,
Expand All @@ -141,7 +141,7 @@ namespace State {
self: model.State*, address: model.Address*, account: model.Account*
) -> model.State* {
let accounts = self.accounts;
dict_write{dict_ptr=accounts}(key=address.starknet, new_value=cast(account, felt));
dict_write{dict_ptr=accounts}(key=address.evm, new_value=cast(account, felt));
return new model.State(
accounts_start=self.accounts_start,
accounts=accounts,
Expand Down Expand Up @@ -231,10 +231,8 @@ namespace State {
let recipient = Account.set_balance(recipient, &recipient_balance_new);

let accounts = self.accounts;
dict_write{dict_ptr=accounts}(key=transfer.sender.starknet, new_value=cast(sender, felt));
dict_write{dict_ptr=accounts}(
key=transfer.recipient.starknet, new_value=cast(recipient, felt)
);
dict_write{dict_ptr=accounts}(key=transfer.sender.evm, new_value=cast(sender, felt));
dict_write{dict_ptr=accounts}(key=transfer.recipient.evm, new_value=cast(recipient, felt));
assert self.transfers[self.transfers_len] = transfer;

tempvar state = new model.State(
Expand All @@ -256,7 +254,7 @@ namespace State {
self: model.State*, address: model.Address*
) -> (state: model.State*, balance: Uint256) {
let accounts = self.accounts;
let (pointer) = dict_read{dict_ptr=accounts}(key=address.starknet);
let (pointer) = dict_read{dict_ptr=accounts}(key=address.evm);
tempvar self = new model.State(
accounts_start=self.accounts_start,
accounts=accounts,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ from starkware.starknet.common.syscalls import get_contract_address
from openzeppelin.token.erc20.library import ERC20

// Local dependencies
from data_availability.starknet import Starknet
from kakarot.account import Account
from kakarot.constants import Constants
from kakarot.storages import (
Expand Down Expand Up @@ -123,7 +124,7 @@ func test__exec_extcodesize__should_handle_address_with_no_code{

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (local starknet_contract_address) = Account.deploy(
let (local starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, evm_contract_address
);
let address = Helpers.to_uint256(evm_contract_address);
Expand Down Expand Up @@ -159,7 +160,7 @@ func test__exec_extcodecopy__should_handle_address_with_code{

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (local starknet_contract_address) = Account.deploy(
let (local starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, evm_contract_address
);
IContractAccount.write_bytecode(starknet_contract_address, bytecode_len, bytecode);
Expand Down Expand Up @@ -211,7 +212,7 @@ func test__exec_extcodecopy__should_handle_address_with_no_code{

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (local starknet_contract_address) = Account.deploy(
let (local starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, evm_contract_address
);
let evm_contract_address_uint256 = Helpers.to_uint256(evm_contract_address);
Expand Down Expand Up @@ -387,7 +388,7 @@ func test__exec_extcodehash__should_handle_address_with_code{

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (local starknet_contract_address) = Account.deploy(
let (local starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, evm_contract_address
);
IContractAccount.write_bytecode(starknet_contract_address, bytecode_len, bytecode);
Expand Down
21 changes: 11 additions & 10 deletions tests/src/kakarot/instructions/test_system_operations.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ from starkware.starknet.common.syscalls import deploy, get_contract_address
from openzeppelin.token.erc20.library import ERC20

// Local dependencies
from data_availability.starknet import Starknet
from kakarot.constants import Constants
from kakarot.storages import (
native_token_address,
Expand Down Expand Up @@ -170,11 +171,11 @@ func test__exec_call__should_return_a_new_context_based_on_calling_ctx_stack{

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (caller_evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (caller_starknet_contract_address) = Account.deploy(
let (caller_starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, caller_evm_contract_address
);
let (callee_evm_contract_address) = CreateHelper.get_create_address(1, 0);
let (callee_starknet_contract_address) = Account.deploy(
let (callee_starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, callee_evm_contract_address
);

Expand Down Expand Up @@ -258,14 +259,14 @@ func test__exec_call__should_transfer_value{

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (caller_evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (caller_starknet_contract_address) = Account.deploy(
let (caller_starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, caller_evm_contract_address
);
tempvar caller_address = new model.Address(
caller_starknet_contract_address, caller_evm_contract_address
);
let (callee_evm_contract_address) = CreateHelper.get_create_address(1, 0);
let (callee_starknet_contract_address) = Account.deploy(
let (callee_starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, callee_evm_contract_address
);
tempvar callee_address = new model.Address(
Expand Down Expand Up @@ -327,11 +328,11 @@ func test__exec_callcode__should_return_a_new_context_based_on_calling_ctx_stack

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (caller_evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (caller_starknet_contract_address) = Account.deploy(
let (caller_starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, caller_evm_contract_address
);
let (callee_evm_contract_address) = CreateHelper.get_create_address(1, 0);
let (_) = Account.deploy(contract_account_class_hash_, callee_evm_contract_address);
let (_) = Starknet.deploy(contract_account_class_hash_, callee_evm_contract_address);

// Fill the stack with input data
let stack: model.Stack* = Stack.init();
Expand Down Expand Up @@ -407,14 +408,14 @@ func test__exec_callcode__should_transfer_value{

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (caller_evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (caller_starknet_contract_address) = Account.deploy(
let (caller_starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, caller_evm_contract_address
);
tempvar caller_address = new model.Address(
caller_starknet_contract_address, caller_evm_contract_address
);
let (callee_evm_contract_address) = CreateHelper.get_create_address(1, 0);
let (callee_starknet_contract_address) = Account.deploy(
let (callee_starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, callee_evm_contract_address
);
tempvar callee_address = new model.Address(
Expand Down Expand Up @@ -476,7 +477,7 @@ func test__exec_staticcall__should_return_a_new_context_based_on_calling_ctx_sta

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (local starknet_contract_address) = Account.deploy(
let (local starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, evm_contract_address
);

Expand Down Expand Up @@ -550,7 +551,7 @@ func test__exec_delegatecall__should_return_a_new_context_based_on_calling_ctx_s

let (contract_account_class_hash_) = contract_account_class_hash.read();
let (evm_contract_address) = CreateHelper.get_create_address(0, 0);
let (local starknet_contract_address) = Account.deploy(
let (local starknet_contract_address) = Starknet.deploy(
contract_account_class_hash_, evm_contract_address
);

Expand Down

0 comments on commit c3d8a97

Please sign in to comment.