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

Commit

Permalink
Add account_type and set nonce to 1 for EOA
Browse files Browse the repository at this point in the history
  • Loading branch information
ClementWalter committed Oct 25, 2023
1 parent c3bdda6 commit edacead
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 19 deletions.
41 changes: 26 additions & 15 deletions src/kakarot/account.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ namespace Account {
) {
alloc_locals;

let (registered_starknet_account) = get_registered_starknet_address(self.address);
let starknet_account_exists = is_not_zero(registered_starknet_account);
let starknet_account_exists = is_registered(self.address);

// Case new Account
if (starknet_account_exists == 0) {
Expand Down Expand Up @@ -150,10 +149,8 @@ namespace Account {
return ();
}

// Case EOA
// TODO: use supports interface instead of the bytecode_len proxy
let (bytecode_len) = IAccount.bytecode_len(contract_address=starknet_address);
if (bytecode_len == 0) {
let (account_type) = IAccount.account_type(contract_address=starknet_address);
if (account_type == 'EOA') {
return ();
}

Expand All @@ -173,8 +170,7 @@ namespace Account {
address: model.Address*
) -> model.Account* {
alloc_locals;
let (local registered_starknet_account) = get_registered_starknet_address(address.evm);
let starknet_account_exists = is_not_zero(registered_starknet_account);
let starknet_account_exists = is_registered(address.evm);

// Case touching a non deployed account
if (starknet_account_exists == 0) {
Expand All @@ -183,17 +179,21 @@ namespace Account {
return account;
}

// Case EOA
// TODO: use supports interface instead of the bytecode_len proxy
let (bytecode_len, bytecode) = IAccount.bytecode(contract_address=address.starknet);
if (bytecode_len == 0) {
let (account_type) = IAccount.account_type(contract_address=address.starknet);

if (account_type == 'EOA') {
let (bytecode: felt*) = alloc();
let account = Account.init(
address=address.evm, code_len=bytecode_len, code=bytecode, nonce=0
// There is no way to access the nonce of an EOA currently
// But putting 1 shouldn't have any impact and is safer than 0
// since has_code_or_nonce is used in some places to trigger collision
address=address.evm, code_len=0, code=bytecode, nonce=1
);
return account;
}

// Case CA
let (bytecode_len, bytecode) = IAccount.bytecode(contract_address=address.starknet);
let (nonce) = IContractAccount.get_nonce(contract_address=address.starknet);
let account = Account.init(
address=address.evm, code_len=bytecode_len, code=bytecode, nonce=nonce
Expand Down Expand Up @@ -234,8 +234,7 @@ namespace Account {
}

// Case reading from Starknet storage
let (local registered_starknet_account) = get_registered_starknet_address(address.evm);
let starknet_account_exists = is_not_zero(registered_starknet_account);
let starknet_account_exists = is_registered(address.evm);
if (starknet_account_exists != 0) {
let (value) = IContractAccount.storage(
contract_address=address.starknet, storage_addr=storage_addr
Expand Down Expand Up @@ -427,6 +426,18 @@ namespace Account {
}
return FALSE;
}

// @notice Tell if an account is already registered
// @param address the address (EVM) as felt
// @return true if the account is already registered
func is_registered{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
address: felt
) -> felt {
alloc_locals;
let (local registered_starknet_account) = get_registered_starknet_address(address);
let starknet_account_exists = is_not_zero(registered_starknet_account);
return starknet_account_exists;
}
}

namespace Internals {
Expand Down
8 changes: 8 additions & 0 deletions src/kakarot/accounts/contract/contract_account.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,11 @@ func get_nonce{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
func set_nonce{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(nonce: felt) {
return ContractAccount.set_nonce(nonce);
}

// @notice Returns the account type
@view
func account_type{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (
type: felt
) {
return ('CA',);
}
8 changes: 8 additions & 0 deletions src/kakarot/accounts/eoa/externally_owned_account.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,11 @@ func bytecode_len{
}() -> (len: felt) {
return (len=0);
}

// @notice Returns the account type
@view
func account_type{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (
type: felt
) {
return ('EOA',);
}
3 changes: 3 additions & 0 deletions src/kakarot/interfaces/interfaces.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ namespace IAccount {

func bytecode() -> (bytecode_len: felt, bytecode: felt*) {
}

func account_type() -> (type: felt) {
}
}

@contract_interface
Expand Down
8 changes: 5 additions & 3 deletions src/kakarot/library.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,11 @@ namespace Kakarot {
let (state, success) = State.add_transfer(state, transfer);

// Check collision
let (state, account) = State.get_account(state, address);
let has_code_or_nonce = Account.has_code_or_nonce(account);
let is_collision = has_code_or_nonce * is_deploy_tx;
let is_registered = Account.is_registered(address.evm);
let is_collision = is_registered * is_deploy_tx;

// Nonce is set to 1 in case of deploy_tx
let account = Account.fetch_or_create(address);
let nonce = account.nonce * (1 - is_deploy_tx) + is_deploy_tx;
let account = Account.set_nonce(account, nonce);
let state = State.set_account(state, address, account);
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/ef_tests/test_ef_blockchain_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ async def test_case(
starknet_address = get_starknet_address(int(transaction["sender"], 16))

await kakarot.eth_send_transaction(
to=int(transaction["to"], 16),
to=int(transaction["to"] or "0", 16),
gas_limit=int(transaction["gasLimit"], 16),
gas_price=int(transaction["gasPrice"], 16),
value=int(transaction["value"], 16),
Expand Down

0 comments on commit edacead

Please sign in to comment.