Skip to content

Commit

Permalink
feat: send transaction (#560)
Browse files Browse the repository at this point in the history
* implement eth_send_transaction

* test eth_send_transaction

* lint

* update comments

* fix comments

* init

* fix: greg's bug

* Update crates/contracts/src/tests/test_kakarot_core.cairo

---------

Co-authored-by: enitrat <[email protected]>
Co-authored-by: Mathieu <[email protected]>
  • Loading branch information
3 people committed Nov 21, 2023
1 parent 9c481e6 commit ad9ff2f
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 11 deletions.
6 changes: 3 additions & 3 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@ lint:
- [email protected]
- [email protected]
- [email protected]
- [email protected].37
- [email protected].40
- git-diff-check
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected].5
- [email protected].6
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- trufflehog@3.62.1
- trufflehog@3.63.0
- [email protected]
actions:
disabled:
Expand Down
4 changes: 2 additions & 2 deletions crates/contracts/src/kakarot_core/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ trait IKakarotCore<TContractState> {
/// Executes an EVM transaction and possibly modifies the state
fn eth_send_transaction(
ref self: TContractState,
to: EthAddress,
to: Option<EthAddress>,
gas_limit: u128,
gas_price: u128,
value: u256,
Expand Down Expand Up @@ -177,7 +177,7 @@ trait IExtendedKakarotCore<TContractState> {
/// Executes an EVM transaction and possibly modifies the state
fn eth_send_transaction(
ref self: TContractState,
to: EthAddress,
to: Option<EthAddress>,
gas_limit: u128,
gas_price: u128,
value: u256,
Expand Down
35 changes: 32 additions & 3 deletions crates/contracts/src/kakarot_core/kakarot.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod KakarotCore {
use contracts::components::ownable::{ownable_component};
use contracts::components::upgradeable::{IUpgradeable, upgradeable_component};
use contracts::contract_account::{IContractAccountDispatcher, IContractAccountDispatcherTrait};
use contracts::eoa::{IExternallyOwnedAccountDispatcher, IExternallyOwnedAccountDispatcherTrait};
use contracts::kakarot_core::interface::IKakarotCore;
use contracts::kakarot_core::interface;
use core::starknet::SyscallResultTrait;
Expand All @@ -30,8 +31,10 @@ mod KakarotCore {
use evm::model::contract_account::{ContractAccountTrait};
use evm::model::eoa::{EOATrait};
use evm::model::{ExecutionResult, Address, AddressTrait};
use evm::state::StateTrait;
use starknet::{
EthAddress, ContractAddress, ClassHash, get_tx_info, get_contract_address, deploy_syscall
EthAddress, ContractAddress, ClassHash, get_tx_info, get_contract_address, deploy_syscall,
get_caller_address
};
use super::{INVOKE_ETH_CALL_FORBIDDEN};
use super::{StoredAccountType};
Expand Down Expand Up @@ -263,13 +266,39 @@ mod KakarotCore {

fn eth_send_transaction(
ref self: ContractState,
to: EthAddress,
to: Option<EthAddress>,
gas_limit: u128,
gas_price: u128,
value: u256,
data: Span<u8>
) -> Span<u8> {
array![].span()
let starknet_caller_address = get_caller_address();
let account = IExternallyOwnedAccountDispatcher {
contract_address: starknet_caller_address
};
let from = Address { evm: account.evm_address(), starknet: starknet_caller_address };

// Invariant:
// We want to make sure the caller is part of the Kakarot address_registry
// and is an EOA. Contracts are added to the registry ONLY if there are
// part of the Kakarot system and thus deployed by the main Kakarot contract
// itself.
let (caller_account_type, caller_starknet_address) = self
.address_registry(from.evm)
.expect('Fetching EOA failed');
assert(caller_account_type == AccountType::EOA, 'Caller is not an EOA');

let mut result = self.handle_call(:from, :to, :gas_limit, :gas_price, :value, :data);
match result {
Result::Ok(result) => {
let mut state = result.state;
state.commit_state();
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()),
}
}

fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {
Expand Down
45 changes: 42 additions & 3 deletions crates/contracts/src/tests/test_kakarot_core.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use contracts::contract_account::ContractAccount::TEST_CLASS_HASH as ContractAcc
use contracts::contract_account::{IContractAccountDispatcher, IContractAccountDispatcherTrait};
use contracts::eoa::ExternallyOwnedAccount;
use contracts::kakarot_core::interface::IExtendedKakarotCoreDispatcherTrait;
use contracts::kakarot_core::interface::IKakarotCore;
use contracts::kakarot_core::kakarot::StoredAccountType;
use contracts::kakarot_core::{
interface::IExtendedKakarotCoreDispatcherImpl, KakarotCore, KakarotCore::{KakarotCoreInternal},
Expand Down Expand Up @@ -254,7 +255,7 @@ fn test_kakarot_contract_account_false_positive_jumpdest() {

#[test]
#[available_gas(2000000000000)]
fn test_eth_call() {
fn test_eth_send_transaction() {
// Given
let (native_token, kakarot_core) = contract_utils::setup_contracts_for_testing();

Expand All @@ -270,16 +271,54 @@ fn test_eth_call() {
let gas_limit = test_utils::gas_limit();
let gas_price = test_utils::gas_price();
let value = 0;
// selector: function inc()
let data = array![0x37, 0x13, 0x03, 0xc0].span();

// When
testing::set_contract_address(eoa);
let return_data = kakarot_core.eth_send_transaction(:to, :gas_limit, :gas_price, :value, :data);

// Then
// selector: function get()
let data = array![0x6d, 0x4c, 0xe6, 0x3c].span();

// When
let return_data = kakarot_core
.eth_call(from: evm_address, :to, :gas_limit, :gas_price, :value, :data);

// Then
assert(return_data == u256_to_bytes_array(1).span(), 'wrong result');
}

#[test]
#[available_gas(2000000000000)]
fn test_eth_call() {
// Given
let (native_token, kakarot_core) = contract_utils::setup_contracts_for_testing();

let evm_address = test_utils::evm_address();
let eoa = kakarot_core.deploy_eoa(evm_address);

let account = ContractAccountTrait::deploy(
test_utils::other_evm_address(), counter_evm_bytecode()
)
.unwrap();
let counter = IContractAccountDispatcher { contract_address: account.starknet };
counter.set_storage_at(0, 1);

let to = Option::Some(test_utils::other_evm_address());
let gas_limit = test_utils::gas_limit();
let gas_price = test_utils::gas_price();
let value = 0;
// selector: function get()
let data = array![0x6d, 0x4c, 0xe6, 0x3c].span();

// When
let return_data = kakarot_core
.eth_call(from: evm_address, :to, :gas_limit, :gas_price, :value, :data);

// Then
assert(return_data == u256_to_bytes_array(0).span(), 'wrong result');
assert(return_data == u256_to_bytes_array(1).span(), 'wrong result');
}


Expand All @@ -288,6 +327,7 @@ fn test_eth_call() {
fn test_handle_call() {
// Given
let (native_token, kakarot_core) = contract_utils::setup_contracts_for_testing();
let mut kakarot_core = KakarotCore::unsafe_new_contract_state();

let evm_address = test_utils::evm_address();
let eoa = kakarot_core.deploy_eoa(evm_address);
Expand All @@ -304,7 +344,6 @@ fn test_handle_call() {
let data = array![0x6d, 0x4c, 0xe6, 0x3c].span();

// When

let mut kakarot_core = KakarotCore::unsafe_new_contract_state();
let result = kakarot_core
.handle_call(
Expand Down

0 comments on commit ad9ff2f

Please sign in to comment.