From 24f6dbc601d6e1ca59bb1d6384da80cd3734a4dd Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 21 Aug 2024 10:27:49 +0200 Subject: [PATCH 01/19] feat: eth_send_raw_transaction --- src/kakarot/accounts/library.cairo | 79 +---- src/kakarot/eth_rpc.cairo | 93 +++++- src/kakarot/interfaces/interfaces.cairo | 5 + src/kakarot/interpreter.cairo | 2 +- src/kakarot/kakarot.cairo | 1 + src/kakarot/library.cairo | 2 +- src/kakarot/model.cairo | 2 +- src/utils/eth_transaction.cairo | 13 +- tests/fixtures/EVM.cairo | 6 - .../kakarot/accounts/test_account_contract.py | 299 +----------------- tests/src/kakarot/test_kakarot.cairo | 22 +- tests/src/kakarot/test_kakarot.py | 185 ++++++++++- 12 files changed, 326 insertions(+), 383 deletions(-) diff --git a/src/kakarot/accounts/library.cairo b/src/kakarot/accounts/library.cairo index 53955c5f4..8af00add8 100644 --- a/src/kakarot/accounts/library.cairo +++ b/src/kakarot/accounts/library.cairo @@ -5,11 +5,10 @@ from starkware.cairo.common.alloc import alloc from starkware.cairo.common.bool import FALSE, TRUE from starkware.cairo.common.dict_access import DictAccess from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin -from starkware.cairo.common.math import split_int, split_felt +from starkware.cairo.common.math import split_int from starkware.cairo.common.memcpy import memcpy -from starkware.cairo.common.uint256 import Uint256, uint256_not, uint256_le +from starkware.cairo.common.uint256 import Uint256 from starkware.cairo.common.math_cmp import is_nn, is_le_felt -from starkware.cairo.common.math import assert_le_felt from starkware.starknet.common.syscalls import ( StorageRead, StorageWrite, @@ -29,7 +28,6 @@ from kakarot.accounts.model import CallArray from kakarot.errors import Errors from kakarot.constants import Constants from utils.eth_transaction import EthTransaction -from utils.uint256 import uint256_add from utils.bytes import bytes_to_bytes8_little_endian from utils.signature import Signature from utils.utils import Helpers @@ -205,9 +203,7 @@ namespace AccountContract { helpers_class=helpers_class, ); - let tx = EthTransaction.decode(tx_data_len, tx_data); - - // Whitelisting pre-eip155 or validate chain_id for post eip155 + // Whitelisting pre-eip155 if (pre_eip155_tx != FALSE) { let (is_authorized) = Account_authorized_message_hashes.read(msg_hash); with_attr error_message("Unauthorized pre-eip155 transaction") { @@ -217,9 +213,6 @@ namespace AccountContract { tempvar pedersen_ptr = pedersen_ptr; tempvar range_check_ptr = range_check_ptr; } else { - with_attr error_message("Invalid chain id") { - assert tx.chain_id = chain_id; - } tempvar syscall_ptr = syscall_ptr; tempvar pedersen_ptr = pedersen_ptr; tempvar range_check_ptr = range_check_ptr; @@ -228,71 +221,9 @@ namespace AccountContract { let pedersen_ptr = cast([ap - 2], HashBuiltin*); let range_check_ptr = [ap - 1]; - // Validate nonce - let (account_nonce) = Account_nonce.read(); - with_attr error_message("Invalid nonce") { - assert tx.signer_nonce = account_nonce; - } - - // Validate gas and value - let (kakarot_address) = Ownable_owner.read(); - let (native_token_address) = IKakarot.get_native_token(kakarot_address); - let (contract_address) = get_contract_address(); - let (balance) = IERC20.balanceOf(native_token_address, contract_address); - - with_attr error_message("Gas limit too high") { - assert_le_felt(tx.gas_limit, 2 ** 64 - 1); - } - - with_attr error_message("Max fee per gas too high") { - assert [range_check_ptr] = tx.max_fee_per_gas; - let range_check_ptr = range_check_ptr + 1; - } - - let max_gas_fee = tx.gas_limit * tx.max_fee_per_gas; - let (max_fee_high, max_fee_low) = split_felt(max_gas_fee); - let (tx_cost, carry) = uint256_add(tx.amount, Uint256(low=max_fee_low, high=max_fee_high)); - assert carry = 0; - let (is_balance_enough) = uint256_le(tx_cost, balance); - with_attr error_message("Not enough ETH to pay msg.value + max gas fees") { - assert is_balance_enough = TRUE; - } - - let (block_gas_limit) = IKakarot.get_block_gas_limit(kakarot_address); - let tx_gas_fits_in_block = is_nn(block_gas_limit - tx.gas_limit); - with_attr error_message("Transaction gas_limit > Block gas_limit") { - assert tx_gas_fits_in_block = TRUE; - } - - let (block_base_fee) = IKakarot.get_base_fee(kakarot_address); - let enough_fee = is_nn(tx.max_fee_per_gas - block_base_fee); - with_attr error_message("Max fee per gas too low") { - assert enough_fee = TRUE; - } - - with_attr error_message("Max priority fee greater than max fee per gas") { - assert_le_felt(tx.max_priority_fee_per_gas, tx.max_fee_per_gas); - } - - let possible_priority_fee = tx.max_fee_per_gas - block_base_fee; - let priority_fee_is_max_priority_fee = is_nn( - possible_priority_fee - tx.max_priority_fee_per_gas - ); - let priority_fee_per_gas = priority_fee_is_max_priority_fee * tx.max_priority_fee_per_gas + - (1 - priority_fee_is_max_priority_fee) * possible_priority_fee; - let effective_gas_price = priority_fee_per_gas + block_base_fee; - // Send tx to Kakarot - let (return_data_len, return_data, success, gas_used) = IKakarot.eth_send_transaction( - contract_address=kakarot_address, - to=tx.destination, - gas_limit=tx.gas_limit, - gas_price=effective_gas_price, - value=tx.amount, - data_len=tx.payload_len, - data=tx.payload, - access_list_len=tx.access_list_len, - access_list=tx.access_list, + let (return_data_len, return_data, success, gas_used) = IKakarot.eth_send_raw_transaction( + contract_address=kakarot_address, tx_data_len=tx_data_len, tx_data=tx_data ); // See Argent account diff --git a/src/kakarot/eth_rpc.cairo b/src/kakarot/eth_rpc.cairo index b982e194a..c30c5e8f6 100644 --- a/src/kakarot/eth_rpc.cairo +++ b/src/kakarot/eth_rpc.cairo @@ -1,9 +1,12 @@ %lang starknet +from openzeppelin.access.ownable.library import Ownable_owner +from starkware.cairo.common.bool import FALSE, TRUE from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin -from starkware.cairo.common.math_cmp import is_not_zero +from starkware.cairo.common.math import assert_le_felt, assert_nn, split_felt +from starkware.cairo.common.math_cmp import is_not_zero, is_nn from starkware.cairo.common.registers import get_fp_and_pc -from starkware.cairo.common.uint256 import Uint256 +from starkware.cairo.common.uint256 import Uint256, uint256_add, uint256_le from starkware.starknet.common.syscalls import get_caller_address, get_tx_info from backend.starknet import Starknet @@ -12,6 +15,7 @@ from kakarot.interfaces.interfaces import IAccount, IERC20 from kakarot.library import Kakarot from kakarot.model import model from kakarot.storages import Kakarot_native_token_address +from utils.eth_transaction import EthTransaction from utils.maths import unsigned_div_rem from utils.utils import Helpers @@ -180,7 +184,6 @@ func eth_estimate_gas{ // @return return_data An array of returned felts // @return success An boolean, TRUE if the transaction succeeded, FALSE otherwise // @return gas_used The amount of gas used by the transaction -@external func eth_send_transaction{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin* }( @@ -221,3 +224,87 @@ func eth_send_transaction{ return result; } + +@external +func eth_send_raw_transaction{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin* +}(tx_data_len: felt, tx_data: felt*) -> ( + return_data_len: felt, return_data: felt*, success: felt, gas_used: felt +) { + let tx = EthTransaction.decode(tx_data_len, tx_data); + + // Whitelisting pre-eip155 or validate chain_id for post eip155 + let (chain_id) = Kakarot.eth_chain_id(); + tempvar is_tx_post_eip155 = is_not_zero(tx.chain_id.is_some); + if (tx.chain_id.is_some != FALSE) { + with_attr error_message("Invalid chain id") { + assert tx.chain_id.value = chain_id; + } + } + + // Get the caller address + let (caller_address) = get_caller_address(); + + // Validate nonce + let (account_nonce) = IAccount.get_nonce(contract_address=caller_address); + with_attr error_message("Invalid nonce") { + assert tx.signer_nonce = account_nonce; + } + + // Validate gas + with_attr error_message("Gas limit too high") { + assert_le_felt(tx.gas_limit, 2 ** 64 - 1); + } + + with_attr error_message("Max fee per gas too high") { + assert [range_check_ptr] = tx.max_fee_per_gas; + let range_check_ptr = range_check_ptr + 1; + } + + let (block_gas_limit) = Kakarot.get_block_gas_limit(); + with_attr error_message("Transaction gas_limit > Block gas_limit") { + assert_nn(block_gas_limit - tx.gas_limit); + } + + let (block_base_fee) = Kakarot.get_base_fee(); + with_attr error_message("Max fee per gas too low") { + assert_nn(tx.max_fee_per_gas - block_base_fee); + } + + with_attr error_message("Max priority fee greater than max fee per gas") { + assert_le_felt(tx.max_priority_fee_per_gas, tx.max_fee_per_gas); + } + + let (native_token_address) = Kakarot_native_token_address.read(); + let (balance) = IERC20.balanceOf(native_token_address, caller_address); + let max_gas_fee = tx.gas_limit * tx.max_fee_per_gas; + let (max_fee_high, max_fee_low) = split_felt(max_gas_fee); + let (tx_cost, carry) = uint256_add(tx.amount, Uint256(low=max_fee_low, high=max_fee_high)); + assert carry = 0; + let (is_balance_enough) = uint256_le(tx_cost, balance); + with_attr error_message("Not enough ETH to pay msg.value + max gas fees") { + assert is_balance_enough = TRUE; + } + + let possible_priority_fee = tx.max_fee_per_gas - block_base_fee; + let priority_fee_is_max_priority_fee = is_nn( + possible_priority_fee - tx.max_priority_fee_per_gas + ); + let priority_fee_per_gas = priority_fee_is_max_priority_fee * tx.max_priority_fee_per_gas + ( + 1 - priority_fee_is_max_priority_fee + ) * possible_priority_fee; + let effective_gas_price = priority_fee_per_gas + block_base_fee; + + let (return_data_len, return_data, success, gas_used) = eth_send_transaction( + to=tx.destination, + gas_limit=tx.gas_limit, + gas_price=effective_gas_price, + value=tx.amount, + data_len=tx.payload_len, + data=tx.payload, + access_list_len=tx.access_list_len, + access_list=tx.access_list, + ); + + return (return_data_len, return_data, success, gas_used); +} diff --git a/src/kakarot/interfaces/interfaces.cairo b/src/kakarot/interfaces/interfaces.cairo index 3ba5e2f6f..17a468a3b 100644 --- a/src/kakarot/interfaces/interfaces.cairo +++ b/src/kakarot/interfaces/interfaces.cairo @@ -189,6 +189,11 @@ namespace IKakarot { func eth_chain_id() -> (chain_id: felt) { } + + func eth_send_raw_transaction(tx_data_len: felt, tx_data: felt*) -> ( + return_data_len: felt, return_data: felt*, success: felt, gas_used: felt + ) { + } } @contract_interface diff --git a/src/kakarot/interpreter.cairo b/src/kakarot/interpreter.cairo index fa77b6c93..0439d0ce8 100644 --- a/src/kakarot/interpreter.cairo +++ b/src/kakarot/interpreter.cairo @@ -897,7 +897,7 @@ namespace Interpreter { // Charge the gas fee to the user without setting up a transfer. // Transfers with the exact amounts will be performed post-execution. - // Note: balance > effective_fee was verified in AccountContract.execute_from_outside() + // Note: balance > effective_fee was verified in eth_send_raw_transaction() let max_fee = gas_limit * env.gas_price; let (fee_high, fee_low) = split_felt(max_fee); let max_fee_u256 = Uint256(low=fee_low, high=fee_high); diff --git a/src/kakarot/kakarot.cairo b/src/kakarot/kakarot.cairo index 1496e7350..c5e22496a 100644 --- a/src/kakarot/kakarot.cairo +++ b/src/kakarot/kakarot.cairo @@ -25,6 +25,7 @@ from kakarot.eth_rpc import ( eth_call, eth_estimate_gas, eth_send_transaction, + eth_send_raw_transaction, ) // Constructor diff --git a/src/kakarot/library.cairo b/src/kakarot/library.cairo index 833f077a0..07d8c68fd 100644 --- a/src/kakarot/library.cairo +++ b/src/kakarot/library.cairo @@ -218,7 +218,7 @@ namespace Kakarot { block_gas_limit: felt ) { let (block_gas_limit) = Kakarot_block_gas_limit.read(); - return (block_gas_limit,); + return (block_gas_limit=block_gas_limit); } // @notice Deploy a new externally owned account. diff --git a/src/kakarot/model.cairo b/src/kakarot/model.cairo index 308b5f730..cb4ed97b1 100644 --- a/src/kakarot/model.cairo +++ b/src/kakarot/model.cairo @@ -217,6 +217,6 @@ namespace model { payload: felt*, access_list_len: felt, access_list: felt*, - chain_id: felt, + chain_id: Option, } } diff --git a/src/utils/eth_transaction.cairo b/src/utils/eth_transaction.cairo index e2989d4c3..5c1f9b780 100644 --- a/src/utils/eth_transaction.cairo +++ b/src/utils/eth_transaction.cairo @@ -57,14 +57,21 @@ namespace EthTransaction { // pre eip-155 txs have 6 fields, post eip-155 txs have 9 fields if (items_len == 6) { + tempvar is_some = 0; tempvar chain_id = 0; } else { assert items_len = 9; assert items[6].is_list = FALSE; assert items[7].is_list = FALSE; assert items[8].is_list = FALSE; + tempvar is_some = 1; let chain_id = Helpers.bytes_to_felt(items[6].data_len, items[6].data); + tempvar chain_id = chain_id; + + tempvar is_some = 1; + tempvar chain_id = chain_id; } + let is_some = [ap - 2]; let chain_id = [ap - 1]; tempvar tx = new model.EthTransaction( @@ -78,7 +85,7 @@ namespace EthTransaction { payload=payload, access_list_len=0, access_list=cast(0, felt*), - chain_id=chain_id, + chain_id=model.Option(is_some=is_some, value=chain_id), ); return tx; } @@ -135,7 +142,7 @@ namespace EthTransaction { payload=payload, access_list_len=access_list_len, access_list=access_list, - chain_id=chain_id, + chain_id=model.Option(is_some=1, value=chain_id), ); return tx; } @@ -193,7 +200,7 @@ namespace EthTransaction { payload=payload, access_list_len=access_list_len, access_list=access_list, - chain_id=chain_id, + chain_id=model.Option(is_some=1, value=chain_id), ); return tx; } diff --git a/tests/fixtures/EVM.cairo b/tests/fixtures/EVM.cairo index 9ecc6926f..6788bce4c 100644 --- a/tests/fixtures/EVM.cairo +++ b/tests/fixtures/EVM.cairo @@ -28,12 +28,6 @@ from kakarot.storages import ( Kakarot_block_gas_limit, Kakarot_evm_to_starknet_address, ) -from kakarot.kakarot import ( - constructor, - get_account_contract_class_hash, - get_cairo1_helpers_class_hash, - get_native_token, -) from backend.starknet import Starknet, Internals as StarknetInternals from utils.dict import dict_keys, dict_values from utils.utils import Helpers diff --git a/tests/src/kakarot/accounts/test_account_contract.py b/tests/src/kakarot/accounts/test_account_contract.py index 3208f5355..fd87db39b 100644 --- a/tests/src/kakarot/accounts/test_account_contract.py +++ b/tests/src/kakarot/accounts/test_account_contract.py @@ -6,7 +6,7 @@ import rlp from eth_account.account import Account from eth_utils import keccak -from hypothesis import assume, given, settings +from hypothesis import given, settings from hypothesis.strategies import binary, composite, integers, lists, permutations from starkware.cairo.lang.cairo_constants import DEFAULT_PRIME from starkware.starknet.public.abi import ( @@ -15,7 +15,7 @@ ) from kakarot_scripts.constants import ARACHNID_PROXY_DEPLOYER, ARACHNID_PROXY_SIGNED_TX -from tests.utils.constants import CHAIN_ID, TRANSACTION_GAS_LIMIT, TRANSACTIONS +from tests.utils.constants import CHAIN_ID, TRANSACTIONS from tests.utils.errors import cairo_error from tests.utils.helpers import generate_random_private_key, rlp_encode_signed_data from tests.utils.hints import patch_hint @@ -382,272 +382,11 @@ def test_should_raise_invalid_signature_for_invalid_chain_id_when_tx_type0_not_p chain_id=CHAIN_ID + 1, ) - def test_should_raise_invalid_chain_id_tx_type_different_from_0( - self, cairo_run - ): - transaction = { - "type": 2, - "gas": 100_000, - "maxFeePerGas": 2_000_000_000, - "maxPriorityFeePerGas": 2_000_000_000, - "data": "0x616263646566", - "nonce": 34, - "to": "", - "value": 0x00, - "accessList": [], - "chainId": CHAIN_ID, - } - tx_data = list(rlp_encode_signed_data(transaction)) - private_key = generate_random_private_key() - address = int(private_key.public_key.to_checksum_address(), 16) - signed = Account.sign_transaction(transaction, private_key) - signature = [*int_to_uint256(signed.r), *int_to_uint256(signed.s), signed.v] - - with ( - SyscallHandler.patch("Account_evm_address", address), - cairo_error(message="Invalid chain id"), - ): - cairo_run( - "test__execute_from_outside", - tx_data=tx_data, - signature=signature, - chain_id=CHAIN_ID + 1, - ) - - @SyscallHandler.patch("Account_nonce", 1) - @pytest.mark.parametrize("transaction", TRANSACTIONS) - def test_should_raise_invalid_nonce(self, cairo_run, transaction): - # explicitly set the nonce in transaction to be different from the patch - transaction = {**transaction, "nonce": 0} - private_key = generate_random_private_key() - address = int(private_key.public_key.to_checksum_address(), 16) - signed = Account.sign_transaction(transaction, private_key) - signature = [*int_to_uint256(signed.r), *int_to_uint256(signed.s), signed.v] - tx_data = list(rlp_encode_signed_data(transaction)) - - with ( - SyscallHandler.patch("Account_evm_address", address), - cairo_error(message="Invalid nonce"), - ): - cairo_run( - "test__execute_from_outside", - tx_data=tx_data, - signature=signature, - chain_id=transaction.get("chainId") or CHAIN_ID, - ) - - @SyscallHandler.patch("IKakarot.get_native_token", lambda addr, data: [0xDEAD]) - @SyscallHandler.patch("IERC20.balanceOf", lambda addr, data: [0, 0]) - @pytest.mark.parametrize("transaction", TRANSACTIONS) - def test_raise_not_enough_ETH_balance(self, cairo_run, transaction): - private_key = generate_random_private_key() - address = int(private_key.public_key.to_checksum_address(), 16) - signed = Account.sign_transaction(transaction, private_key) - signature = [*int_to_uint256(signed.r), *int_to_uint256(signed.s), signed.v] - tx_data = list(rlp_encode_signed_data(transaction)) - - with ( - SyscallHandler.patch("Account_evm_address", address), - SyscallHandler.patch("Account_nonce", transaction.get("nonce", 0)), - cairo_error(message="Not enough ETH to pay msg.value + max gas fees"), - ): - cairo_run( - "test__execute_from_outside", - tx_data=tx_data, - signature=signature, - chain_id=transaction.get("chainId") or CHAIN_ID, - ) - - @SyscallHandler.patch("IKakarot.get_native_token", lambda addr, data: [0xDEAD]) - @SyscallHandler.patch( - "IERC20.balanceOf", lambda addr, data: int_to_uint256(10**128) - ) - @SyscallHandler.patch("IKakarot.get_block_gas_limit", lambda addr, data: [0]) - @pytest.mark.parametrize("transaction", TRANSACTIONS) - def test_raise_transaction_gas_limit_too_high(self, cairo_run, transaction): - private_key = generate_random_private_key() - address = int(private_key.public_key.to_checksum_address(), 16) - signed = Account.sign_transaction(transaction, private_key) - signature = [*int_to_uint256(signed.r), *int_to_uint256(signed.s), signed.v] - tx_data = list(rlp_encode_signed_data(transaction)) - - with ( - SyscallHandler.patch("Account_evm_address", address), - SyscallHandler.patch("Account_nonce", transaction.get("nonce", 0)), - cairo_error(message="Transaction gas_limit > Block gas_limit"), - ): - cairo_run( - "test__execute_from_outside", - tx_data=tx_data, - signature=signature, - chain_id=transaction.get("chainId") or CHAIN_ID, - ) - - @SyscallHandler.patch("IKakarot.get_native_token", lambda addr, data: [0xDEAD]) - @SyscallHandler.patch( - "IERC20.balanceOf", lambda addr, data: int_to_uint256(10**128) - ) - @SyscallHandler.patch( - "IKakarot.get_block_gas_limit", lambda addr, data: [TRANSACTION_GAS_LIMIT] - ) - @SyscallHandler.patch( - "IKakarot.get_base_fee", lambda addr, data: [TRANSACTION_GAS_LIMIT * 10**10] - ) - @pytest.mark.parametrize("transaction", TRANSACTIONS) - def test_raise_max_fee_per_gas_too_low(self, cairo_run, transaction): - private_key = generate_random_private_key() - address = int(private_key.public_key.to_checksum_address(), 16) - signed = Account.sign_transaction(transaction, private_key) - signature = [*int_to_uint256(signed.r), *int_to_uint256(signed.s), signed.v] - tx_data = list(rlp_encode_signed_data(transaction)) - - with ( - SyscallHandler.patch("Account_evm_address", address), - SyscallHandler.patch("Account_nonce", transaction.get("nonce", 0)), - cairo_error(message="Max fee per gas too low"), - ): - cairo_run( - "test__execute_from_outside", - tx_data=tx_data, - signature=signature, - chain_id=transaction.get("chainId") or CHAIN_ID, - ) - - @SyscallHandler.patch("IKakarot.get_native_token", lambda addr, data: [0xDEAD]) - @SyscallHandler.patch( - "IERC20.balanceOf", lambda addr, data: int_to_uint256(10**128) - ) - @given(gas_limit=integers(min_value=2**64, max_value=DEFAULT_PRIME - 1)) - def test_raise_gas_limit_too_high(self, cairo_run, gas_limit): - transaction = { - "type": 2, - "gas": gas_limit, - "maxFeePerGas": 2_000_000_000, - "maxPriorityFeePerGas": 3_000_000_000, - "data": "0x616263646566", - "nonce": 34, - "to": "0x09616C3d61b3331fc4109a9E41a8BDB7d9776609", - "value": 0x5AF3107A4000, - "accessList": [], - "chainId": CHAIN_ID, - } - tx_data = list(rlp_encode_signed_data(transaction)) - private_key = generate_random_private_key() - address = int(private_key.public_key.to_checksum_address(), 16) - signed = Account.sign_transaction(transaction, private_key) - signature = [*int_to_uint256(signed.r), *int_to_uint256(signed.s), signed.v] - - with ( - SyscallHandler.patch("Account_evm_address", address), - SyscallHandler.patch("Account_nonce", transaction["nonce"]), - cairo_error(message="Gas limit too high"), - ): - cairo_run( - "test__execute_from_outside", - tx_data=tx_data, - signature=signature, - chain_id=transaction["chainId"], - ) - - @SyscallHandler.patch("IKakarot.get_native_token", lambda addr, data: [0xDEAD]) - @SyscallHandler.patch( - "IERC20.balanceOf", lambda addr, data: int_to_uint256(10**128) - ) - @SyscallHandler.patch( - "IKakarot.get_block_gas_limit", lambda addr, data: [TRANSACTION_GAS_LIMIT] - ) - @given(maxFeePerGas=integers(min_value=2**128, max_value=DEFAULT_PRIME - 1)) - def test_raise_max_fee_per_gas_too_high(self, cairo_run, maxFeePerGas): - transaction = { - "type": 2, - "gas": 100_000, - "maxFeePerGas": maxFeePerGas, - "maxPriorityFeePerGas": 3_000_000_000, - "data": "0x616263646566", - "nonce": 34, - "to": "0x09616C3d61b3331fc4109a9E41a8BDB7d9776609", - "value": 0x5AF3107A4000, - "accessList": [], - "chainId": CHAIN_ID, - } - tx_data = list(rlp_encode_signed_data(transaction)) - private_key = generate_random_private_key() - address = int(private_key.public_key.to_checksum_address(), 16) - signed = Account.sign_transaction(transaction, private_key) - signature = [*int_to_uint256(signed.r), *int_to_uint256(signed.s), signed.v] - - with ( - SyscallHandler.patch("Account_evm_address", address), - SyscallHandler.patch("Account_nonce", transaction["nonce"]), - cairo_error(message="Max fee per gas too high"), - ): - cairo_run( - "test__execute_from_outside", - tx_data=tx_data, - signature=signature, - chain_id=transaction["chainId"], - ) - - @composite - def max_priority_fee_too_high(draw): - maxFeePerGas = draw(integers(min_value=0, max_value=2**128 - 1)) - maxPriorityFeePerGas = draw(integers(min_value=0, max_value=2**128 - 1)) - assume(maxFeePerGas < maxPriorityFeePerGas) - return (maxFeePerGas, maxPriorityFeePerGas) - - @SyscallHandler.patch("IKakarot.get_native_token", lambda addr, data: [0xDEAD]) + @SyscallHandler.patch("IKakarot.get_native_token", lambda _, __: [0xDEAD]) + @SyscallHandler.patch("IERC20.balanceOf", lambda _, __: int_to_uint256(10**128)) @SyscallHandler.patch( - "IERC20.balanceOf", lambda addr, data: int_to_uint256(10**128) - ) - @SyscallHandler.patch( - "IKakarot.get_block_gas_limit", lambda addr, data: [TRANSACTION_GAS_LIMIT] - ) - @SyscallHandler.patch("IKakarot.get_base_fee", lambda addr, data: [0]) - @given(max_priority_fee_too_high()) - def test_raise_max_priority_fee_too_high( - self, cairo_run, max_priority_fee_too_high - ): - transaction = { - "type": 2, - "gas": 100_000, - "maxFeePerGas": max_priority_fee_too_high[0], - "maxPriorityFeePerGas": max_priority_fee_too_high[1], - "data": "0x616263646566", - "nonce": 34, - "to": "0x09616C3d61b3331fc4109a9E41a8BDB7d9776609", - "value": 0x5AF3107A4000, - "accessList": [], - "chainId": CHAIN_ID, - } - tx_data = list(rlp_encode_signed_data(transaction)) - private_key = generate_random_private_key() - address = int(private_key.public_key.to_checksum_address(), 16) - signed = Account.sign_transaction(transaction, private_key) - signature = [*int_to_uint256(signed.r), *int_to_uint256(signed.s), signed.v] - - with ( - SyscallHandler.patch("Account_evm_address", address), - SyscallHandler.patch("Account_nonce", transaction["nonce"]), - cairo_error(message="Max priority fee greater than max fee per gas"), - ): - cairo_run( - "test__execute_from_outside", - tx_data=tx_data, - signature=signature, - chain_id=transaction["chainId"], - ) - - @SyscallHandler.patch("IKakarot.get_native_token", lambda addr, data: [0xDEAD]) - @SyscallHandler.patch( - "IERC20.balanceOf", lambda addr, data: int_to_uint256(10**128) - ) - @SyscallHandler.patch( - "IKakarot.get_block_gas_limit", lambda addr, data: [TRANSACTION_GAS_LIMIT] - ) - @SyscallHandler.patch("IKakarot.get_base_fee", lambda addr, data: [0]) - @SyscallHandler.patch( - "IKakarot.eth_send_transaction", - lambda addr, data: [1, 0x68656C6C6F, 1, 1], # hello + "IKakarot.eth_send_raw_transaction", + lambda _, __: [1, 0x68656C6C6F, 1, 1], # hello ) def test_pass_authorized_pre_eip155_transaction(self, cairo_run): rlp_decoded = rlp.decode(ARACHNID_PROXY_SIGNED_TX) @@ -688,17 +427,10 @@ def test_pass_authorized_pre_eip155_transaction(self, cairo_run): assert output_len == 1 assert output[0] == 0x68656C6C6F - @SyscallHandler.patch("IKakarot.get_native_token", lambda addr, data: [0xDEAD]) - @SyscallHandler.patch( - "IERC20.balanceOf", lambda addr, data: int_to_uint256(10**128) - ) - @SyscallHandler.patch( - "IKakarot.get_block_gas_limit", lambda addr, data: [TRANSACTION_GAS_LIMIT] - ) - @SyscallHandler.patch("IKakarot.get_base_fee", lambda addr, data: [0]) + @SyscallHandler.patch("IERC20.balanceOf", lambda _, __: int_to_uint256(10**128)) @SyscallHandler.patch( - "IKakarot.eth_send_transaction", - lambda addr, data: [1, 0x68656C6C6F, 1, 1], # hello + "IKakarot.eth_send_raw_transaction", + lambda _, __: [1, 0x68656C6C6F, 1, 1], # hello ) @pytest.mark.parametrize("transaction", TRANSACTIONS) def test_pass_all_transactions_types(self, cairo_run, seed, transaction): @@ -732,17 +464,10 @@ def test_pass_all_transactions_types(self, cairo_run, seed, transaction): assert output_len == 1 assert output[0] == 0x68656C6C6F - @SyscallHandler.patch("IKakarot.get_native_token", lambda addr, data: [0xDEAD]) - @SyscallHandler.patch( - "IERC20.balanceOf", lambda addr, data: int_to_uint256(10**128) - ) - @SyscallHandler.patch( - "IKakarot.get_block_gas_limit", lambda addr, data: [TRANSACTION_GAS_LIMIT] - ) - @SyscallHandler.patch("IKakarot.get_base_fee", lambda addr, data: [0]) + @SyscallHandler.patch("IERC20.balanceOf", lambda _, __: int_to_uint256(10**128)) @SyscallHandler.patch( - "IKakarot.eth_send_transaction", - lambda addr, data: [1, 0x68656C6C6F, 1, 1], # hello + "IKakarot.eth_send_raw_transaction", + lambda _, __: [1, 0x68656C6C6F, 1, 1], # hello ) def test_should_pass_all_data_len(self, cairo_run, bytecode): transaction = { diff --git a/tests/src/kakarot/test_kakarot.cairo b/tests/src/kakarot/test_kakarot.cairo index 9a5fad07d..9edc18957 100644 --- a/tests/src/kakarot/test_kakarot.cairo +++ b/tests/src/kakarot/test_kakarot.cairo @@ -6,6 +6,7 @@ from starkware.cairo.common.uint256 import Uint256 from kakarot.library import Kakarot from kakarot.kakarot import ( + eth_send_raw_transaction, register_account, set_native_token, set_base_fee, @@ -24,8 +25,6 @@ from kakarot.account import Account func eth_call{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin* }() -> (model.EVM*, model.State*, felt, felt) { - // Given - tempvar origin; tempvar to: model.Option; tempvar gas_limit; @@ -40,7 +39,6 @@ func eth_call{ %{ from tests.utils.uint256 import int_to_uint256 - ids.origin = program_input.get("origin", 0) ids.to.is_some = int(bool(program_input.get("to") is not None)) ids.to.value = program_input.get("to") or 0 @@ -70,6 +68,24 @@ func eth_call{ return (evm, state, gas_used, required_gas); } +func test__eth_send_raw_transaction{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin* +}() -> (felt, felt*, felt, felt) { + tempvar tx_data_len: felt; + let (tx_data) = alloc(); + + %{ + segments.write_arg(ids.tx_data, program_input["tx_data"]) + ids.tx_data_len = len(program_input["tx_data"]) + %} + + let (return_data_len, return_data, success, gas_used) = eth_send_raw_transaction( + tx_data_len=tx_data_len, tx_data=tx_data + ); + + return (return_data_len, return_data, success, gas_used); +} + func compute_starknet_address{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( ) -> felt { tempvar evm_address; diff --git a/tests/src/kakarot/test_kakarot.py b/tests/src/kakarot/test_kakarot.py index 4c47d22c4..a802c32c9 100644 --- a/tests/src/kakarot/test_kakarot.py +++ b/tests/src/kakarot/test_kakarot.py @@ -6,17 +6,18 @@ from eth_abi import decode, encode from eth_utils import keccak from eth_utils.address import to_checksum_address -from hypothesis import given -from hypothesis.strategies import integers +from hypothesis import assume, given +from hypothesis.strategies import composite, integers +from starkware.cairo.lang.cairo_constants import DEFAULT_PRIME from starkware.starknet.public.abi import get_storage_var_address from web3._utils.abi import map_abi_data from web3._utils.normalizers import BASE_RETURN_NORMALIZERS from web3.exceptions import NoABIFunctionsFound from kakarot_scripts.ef_tests.fetch import EF_TESTS_PARSED_DIR -from tests.utils.constants import TRANSACTION_GAS_LIMIT +from tests.utils.constants import CHAIN_ID, TRANSACTION_GAS_LIMIT, TRANSACTIONS from tests.utils.errors import cairo_error -from tests.utils.helpers import felt_to_signed_int +from tests.utils.helpers import felt_to_signed_int, rlp_encode_signed_data from tests.utils.syscall_handler import SyscallHandler, parse_state CONTRACT_ADDRESS = 1234 @@ -414,6 +415,182 @@ def test_should_return_chain_id_modulo_53(self, cairo_run, chain_id): res = cairo_run("test__eth_chain_id") assert res == chain_id % 2**53 + class TestEthSendRawTransactionEntrypoint: + def test_should_raise_invalid_chain_id_tx_type_different_from_0( + self, cairo_run + ): + transaction = { + "type": 2, + "gas": 100_000, + "maxFeePerGas": 2_000_000_000, + "maxPriorityFeePerGas": 2_000_000_000, + "data": "0x616263646566", + "nonce": 34, + "to": "", + "value": 0x00, + "accessList": [], + "chainId": 9999, + } + tx_data = list(rlp_encode_signed_data(transaction)) + + with cairo_error(message="Invalid chain id"): + cairo_run( + "test__eth_send_raw_transaction", + tx_data_len=len(tx_data), + tx_data=tx_data, + ) + + @SyscallHandler.patch("IAccount.get_nonce", lambda addr, data: [1]) + @pytest.mark.parametrize("tx", TRANSACTIONS) + def test_should_raise_invalid_nonce(self, cairo_run, tx): + # explicitly set the nonce in transaction to be different from the patch + tx = {**tx, "nonce": 0} + tx_data = list(rlp_encode_signed_data(tx)) + with cairo_error(message="Invalid nonce"): + cairo_run( + "test__eth_send_raw_transaction", + tx_data_len=len(tx_data), + tx_data=tx_data, + ) + + @given(gas_limit=integers(min_value=2**64, max_value=DEFAULT_PRIME - 1)) + def test_raise_gas_limit_too_high(self, cairo_run, gas_limit): + tx = { + "type": 2, + "gas": gas_limit, + "maxFeePerGas": 2_000_000_000, + "maxPriorityFeePerGas": 3_000_000_000, + "data": "0x616263646566", + "nonce": 34, + "to": "0x09616C3d61b3331fc4109a9E41a8BDB7d9776609", + "value": 0x5AF3107A4000, + "accessList": [], + "chainId": CHAIN_ID, + } + tx_data = list(rlp_encode_signed_data(tx)) + + with ( + SyscallHandler.patch("IAccount.get_nonce", lambda _, __: [tx["nonce"]]), + cairo_error(message="Gas limit too high"), + ): + cairo_run( + "test__eth_send_raw_transaction", + tx_data_len=len(tx_data), + tx_data=tx_data, + ) + + @SyscallHandler.patch("Kakarot_block_gas_limit", 0) + @given(maxFeePerGas=integers(min_value=2**128, max_value=DEFAULT_PRIME - 1)) + def test_raise_max_fee_per_gas_too_high(self, cairo_run, maxFeePerGas): + tx = { + "type": 2, + "gas": 100_000, + "maxFeePerGas": maxFeePerGas, + "maxPriorityFeePerGas": 3_000_000_000, + "data": "0x616263646566", + "nonce": 34, + "to": "0x09616C3d61b3331fc4109a9E41a8BDB7d9776609", + "value": 0x5AF3107A4000, + "accessList": [], + "chainId": CHAIN_ID, + } + tx_data = list(rlp_encode_signed_data(tx)) + + with ( + SyscallHandler.patch("IAccount.get_nonce", lambda _, __: [tx["nonce"]]), + cairo_error(message="Max fee per gas too high"), + ): + cairo_run( + "test__eth_send_raw_transaction", + tx_data_len=len(tx_data), + tx_data=tx_data, + ) + + @SyscallHandler.patch("Kakarot_block_gas_limit", 0) + @pytest.mark.parametrize("tx", TRANSACTIONS) + def test_raise_transaction_gas_limit_too_high(self, cairo_run, tx): + tx_data = list(rlp_encode_signed_data(tx)) + + with ( + SyscallHandler.patch("IAccount.get_nonce", lambda _, __: [tx["nonce"]]), + cairo_error(message="Transaction gas_limit > Block gas_limit"), + ): + cairo_run( + "test__eth_send_raw_transaction", + tx_data_len=len(tx_data), + tx_data=tx_data, + ) + + @SyscallHandler.patch("Kakarot_block_gas_limit", TRANSACTION_GAS_LIMIT) + @SyscallHandler.patch("Kakarot_base_fee", TRANSACTION_GAS_LIMIT * 10**10) + @pytest.mark.parametrize("tx", TRANSACTIONS) + def test_raise_max_fee_per_gas_too_low(self, cairo_run, tx): + tx_data = list(rlp_encode_signed_data(tx)) + + with ( + SyscallHandler.patch("IAccount.get_nonce", lambda _, __: [tx["nonce"]]), + cairo_error(message="Max fee per gas too low"), + ): + cairo_run( + "test__eth_send_raw_transaction", + tx_data_len=len(tx_data), + tx_data=tx_data, + ) + + @composite + def max_priority_fee_too_high(draw): + maxFeePerGas = draw(integers(min_value=0, max_value=2**128 - 1)) + maxPriorityFeePerGas = draw(integers(min_value=0, max_value=2**128 - 1)) + assume(maxFeePerGas < maxPriorityFeePerGas) + return (maxFeePerGas, maxPriorityFeePerGas) + + @SyscallHandler.patch("Kakarot_block_gas_limit", TRANSACTION_GAS_LIMIT) + @SyscallHandler.patch("Kakarot_base_fee", 0) + @given(max_priority_fee_too_high()) + def test_raise_max_priority_fee_too_high( + self, cairo_run, max_priority_fee_too_high + ): + tx = { + "type": 2, + "gas": 100_000, + "maxFeePerGas": max_priority_fee_too_high[0], + "maxPriorityFeePerGas": max_priority_fee_too_high[1], + "data": "0x616263646566", + "nonce": 34, + "to": "0x09616C3d61b3331fc4109a9E41a8BDB7d9776609", + "value": 0x5AF3107A4000, + "accessList": [], + "chainId": CHAIN_ID, + } + tx_data = list(rlp_encode_signed_data(tx)) + + with ( + SyscallHandler.patch("IAccount.get_nonce", lambda _, __: [tx["nonce"]]), + cairo_error(message="Max priority fee greater than max fee per gas"), + ): + cairo_run( + "test__eth_send_raw_transaction", + tx_data_len=len(tx_data), + tx_data=tx_data, + ) + + @SyscallHandler.patch("IERC20.balanceOf", lambda _, __: [0, 0]) + @SyscallHandler.patch("Kakarot_block_gas_limit", TRANSACTION_GAS_LIMIT) + @SyscallHandler.patch("Kakarot_base_fee", 0) + @pytest.mark.parametrize("tx", TRANSACTIONS) + def test_raise_not_enough_ETH_balance(self, cairo_run, tx): + tx_data = list(rlp_encode_signed_data(tx)) + + with ( + SyscallHandler.patch("IAccount.get_nonce", lambda _, __: [tx["nonce"]]), + cairo_error(message="Not enough ETH to pay msg.value + max gas fees"), + ): + cairo_run( + "test__eth_send_raw_transaction", + tx_data_len=len(tx_data), + tx_data=tx_data, + ) + class TestLoopProfiling: @pytest.mark.slow @pytest.mark.NoCI From 53ba3b149089bcdc157858c3129c075de4a2dd71 Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 22 Aug 2024 11:41:47 +0200 Subject: [PATCH 02/19] remove unnecessary tempvar --- src/kakarot/eth_rpc.cairo | 3 +-- src/utils/eth_transaction.cairo | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/kakarot/eth_rpc.cairo b/src/kakarot/eth_rpc.cairo index c30c5e8f6..39cd3b90c 100644 --- a/src/kakarot/eth_rpc.cairo +++ b/src/kakarot/eth_rpc.cairo @@ -233,9 +233,8 @@ func eth_send_raw_transaction{ ) { let tx = EthTransaction.decode(tx_data_len, tx_data); - // Whitelisting pre-eip155 or validate chain_id for post eip155 + // Validate chain_id for post eip155 let (chain_id) = Kakarot.eth_chain_id(); - tempvar is_tx_post_eip155 = is_not_zero(tx.chain_id.is_some); if (tx.chain_id.is_some != FALSE) { with_attr error_message("Invalid chain id") { assert tx.chain_id.value = chain_id; diff --git a/src/utils/eth_transaction.cairo b/src/utils/eth_transaction.cairo index 5c1f9b780..13473cd97 100644 --- a/src/utils/eth_transaction.cairo +++ b/src/utils/eth_transaction.cairo @@ -64,7 +64,6 @@ namespace EthTransaction { assert items[6].is_list = FALSE; assert items[7].is_list = FALSE; assert items[8].is_list = FALSE; - tempvar is_some = 1; let chain_id = Helpers.bytes_to_felt(items[6].data_len, items[6].data); tempvar chain_id = chain_id; From c964fe092a9234f2bd99b020989aee273719d894 Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 22 Aug 2024 11:53:20 +0200 Subject: [PATCH 03/19] refactor: avoid manual rebinding --- src/kakarot/accounts/library.cairo | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/kakarot/accounts/library.cairo b/src/kakarot/accounts/library.cairo index 8af00add8..df1b675f1 100644 --- a/src/kakarot/accounts/library.cairo +++ b/src/kakarot/accounts/library.cairo @@ -204,22 +204,12 @@ namespace AccountContract { ); // Whitelisting pre-eip155 + let (is_authorized) = Account_authorized_message_hashes.read(msg_hash); if (pre_eip155_tx != FALSE) { - let (is_authorized) = Account_authorized_message_hashes.read(msg_hash); with_attr error_message("Unauthorized pre-eip155 transaction") { assert is_authorized = TRUE; } - tempvar syscall_ptr = syscall_ptr; - tempvar pedersen_ptr = pedersen_ptr; - tempvar range_check_ptr = range_check_ptr; - } else { - tempvar syscall_ptr = syscall_ptr; - tempvar pedersen_ptr = pedersen_ptr; - tempvar range_check_ptr = range_check_ptr; } - let syscall_ptr = cast([ap - 3], felt*); - let pedersen_ptr = cast([ap - 2], HashBuiltin*); - let range_check_ptr = [ap - 1]; // Send tx to Kakarot let (return_data_len, return_data, success, gas_used) = IKakarot.eth_send_raw_transaction( From b286ef1258d9a5405f42090d3ffc77d710fa0253 Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 22 Aug 2024 11:58:55 +0200 Subject: [PATCH 04/19] test: chain_id is now model.Option --- tests/src/utils/test_eth_transaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/utils/test_eth_transaction.py b/tests/src/utils/test_eth_transaction.py index fb80a8901..073dd14c6 100644 --- a/tests/src/utils/test_eth_transaction.py +++ b/tests/src/utils/test_eth_transaction.py @@ -49,7 +49,7 @@ async def test_should_decode_all_transactions_types( assert expected_to == decoded_tx["destination"] assert transaction["value"] == int(decoded_tx["amount"], 16) # pre-eip155 txs have an internal chain_id set to 0 in the decoded tx - assert transaction.get("chainId", 0) == decoded_tx["chain_id"] + assert transaction.get("chainId", 0) == decoded_tx["chain_id"]["value"] assert expected_data == decoded_tx["payload"] assert expected_access_list == decoded_tx["access_list"] From daadeb96cc03f1af64b89f11799fdfb050ecc61a Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 22 Aug 2024 12:34:01 +0200 Subject: [PATCH 05/19] test: undo wrong import deletion --- tests/fixtures/EVM.cairo | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/fixtures/EVM.cairo b/tests/fixtures/EVM.cairo index 6788bce4c..9ecc6926f 100644 --- a/tests/fixtures/EVM.cairo +++ b/tests/fixtures/EVM.cairo @@ -28,6 +28,12 @@ from kakarot.storages import ( Kakarot_block_gas_limit, Kakarot_evm_to_starknet_address, ) +from kakarot.kakarot import ( + constructor, + get_account_contract_class_hash, + get_cairo1_helpers_class_hash, + get_native_token, +) from backend.starknet import Starknet, Internals as StarknetInternals from utils.dict import dict_keys, dict_values from utils.utils import Helpers From 3bae8a292fa9427e931a1bdb1cc4f990f1a53b0e Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 09:43:34 +0200 Subject: [PATCH 06/19] refactor: renaming eth_send_raw_unsigned_tx --- src/kakarot/accounts/library.cairo | 2 +- src/kakarot/eth_rpc.cairo | 11 ++++++++++- src/kakarot/interfaces/interfaces.cairo | 2 +- src/kakarot/interpreter.cairo | 2 +- src/kakarot/kakarot.cairo | 2 +- .../kakarot/accounts/test_account_contract.py | 6 +++--- tests/src/kakarot/test_kakarot.cairo | 6 +++--- tests/src/kakarot/test_kakarot.py | 16 ++++++++-------- 8 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/kakarot/accounts/library.cairo b/src/kakarot/accounts/library.cairo index df1b675f1..a58cd19d1 100644 --- a/src/kakarot/accounts/library.cairo +++ b/src/kakarot/accounts/library.cairo @@ -212,7 +212,7 @@ namespace AccountContract { } // Send tx to Kakarot - let (return_data_len, return_data, success, gas_used) = IKakarot.eth_send_raw_transaction( + let (return_data_len, return_data, success, gas_used) = IKakarot.eth_send_raw_unsigned_tx( contract_address=kakarot_address, tx_data_len=tx_data_len, tx_data=tx_data ); diff --git a/src/kakarot/eth_rpc.cairo b/src/kakarot/eth_rpc.cairo index 39cd3b90c..9a257a7c2 100644 --- a/src/kakarot/eth_rpc.cairo +++ b/src/kakarot/eth_rpc.cairo @@ -225,8 +225,17 @@ func eth_send_transaction{ return result; } +// @notice The eth_send_raw_unsigned_tx. Modified version of eth_sendRawTransaction function described in the spec. +// See https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendrawtransaction +// @dev This function takes the transaction data unsigned. Signature validation should be done before calling this function. +// @param tx_data_len The length of the unsigned transaction data +// @param tx_data The unsigned transaction data +// @return return_data_len The length of the return_data +// @return return_data An array of returned felts +// @return success An boolean, TRUE if the transaction succeeded, FALSE otherwise +// @return gas_used The amount of gas used by the transaction @external -func eth_send_raw_transaction{ +func eth_send_raw_unsigned_tx{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin* }(tx_data_len: felt, tx_data: felt*) -> ( return_data_len: felt, return_data: felt*, success: felt, gas_used: felt diff --git a/src/kakarot/interfaces/interfaces.cairo b/src/kakarot/interfaces/interfaces.cairo index 17a468a3b..e0c19abf0 100644 --- a/src/kakarot/interfaces/interfaces.cairo +++ b/src/kakarot/interfaces/interfaces.cairo @@ -190,7 +190,7 @@ namespace IKakarot { func eth_chain_id() -> (chain_id: felt) { } - func eth_send_raw_transaction(tx_data_len: felt, tx_data: felt*) -> ( + func eth_send_raw_unsigned_tx(tx_data_len: felt, tx_data: felt*) -> ( return_data_len: felt, return_data: felt*, success: felt, gas_used: felt ) { } diff --git a/src/kakarot/interpreter.cairo b/src/kakarot/interpreter.cairo index 0439d0ce8..a51dd805c 100644 --- a/src/kakarot/interpreter.cairo +++ b/src/kakarot/interpreter.cairo @@ -897,7 +897,7 @@ namespace Interpreter { // Charge the gas fee to the user without setting up a transfer. // Transfers with the exact amounts will be performed post-execution. - // Note: balance > effective_fee was verified in eth_send_raw_transaction() + // Note: balance > effective_fee was verified in eth_send_raw_unsigned_tx() let max_fee = gas_limit * env.gas_price; let (fee_high, fee_low) = split_felt(max_fee); let max_fee_u256 = Uint256(low=fee_low, high=fee_high); diff --git a/src/kakarot/kakarot.cairo b/src/kakarot/kakarot.cairo index c5e22496a..6d73141fd 100644 --- a/src/kakarot/kakarot.cairo +++ b/src/kakarot/kakarot.cairo @@ -25,7 +25,7 @@ from kakarot.eth_rpc import ( eth_call, eth_estimate_gas, eth_send_transaction, - eth_send_raw_transaction, + eth_send_raw_unsigned_tx, ) // Constructor diff --git a/tests/src/kakarot/accounts/test_account_contract.py b/tests/src/kakarot/accounts/test_account_contract.py index fd87db39b..d6e776596 100644 --- a/tests/src/kakarot/accounts/test_account_contract.py +++ b/tests/src/kakarot/accounts/test_account_contract.py @@ -385,7 +385,7 @@ def test_should_raise_invalid_signature_for_invalid_chain_id_when_tx_type0_not_p @SyscallHandler.patch("IKakarot.get_native_token", lambda _, __: [0xDEAD]) @SyscallHandler.patch("IERC20.balanceOf", lambda _, __: int_to_uint256(10**128)) @SyscallHandler.patch( - "IKakarot.eth_send_raw_transaction", + "IKakarot.eth_send_raw_unsigned_tx", lambda _, __: [1, 0x68656C6C6F, 1, 1], # hello ) def test_pass_authorized_pre_eip155_transaction(self, cairo_run): @@ -429,7 +429,7 @@ def test_pass_authorized_pre_eip155_transaction(self, cairo_run): @SyscallHandler.patch("IERC20.balanceOf", lambda _, __: int_to_uint256(10**128)) @SyscallHandler.patch( - "IKakarot.eth_send_raw_transaction", + "IKakarot.eth_send_raw_unsigned_tx", lambda _, __: [1, 0x68656C6C6F, 1, 1], # hello ) @pytest.mark.parametrize("transaction", TRANSACTIONS) @@ -466,7 +466,7 @@ def test_pass_all_transactions_types(self, cairo_run, seed, transaction): @SyscallHandler.patch("IERC20.balanceOf", lambda _, __: int_to_uint256(10**128)) @SyscallHandler.patch( - "IKakarot.eth_send_raw_transaction", + "IKakarot.eth_send_raw_unsigned_tx", lambda _, __: [1, 0x68656C6C6F, 1, 1], # hello ) def test_should_pass_all_data_len(self, cairo_run, bytecode): diff --git a/tests/src/kakarot/test_kakarot.cairo b/tests/src/kakarot/test_kakarot.cairo index 9edc18957..a97d08208 100644 --- a/tests/src/kakarot/test_kakarot.cairo +++ b/tests/src/kakarot/test_kakarot.cairo @@ -6,7 +6,7 @@ from starkware.cairo.common.uint256 import Uint256 from kakarot.library import Kakarot from kakarot.kakarot import ( - eth_send_raw_transaction, + eth_send_raw_unsigned_tx, register_account, set_native_token, set_base_fee, @@ -68,7 +68,7 @@ func eth_call{ return (evm, state, gas_used, required_gas); } -func test__eth_send_raw_transaction{ +func test__eth_send_raw_unsigned_tx{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin* }() -> (felt, felt*, felt, felt) { tempvar tx_data_len: felt; @@ -79,7 +79,7 @@ func test__eth_send_raw_transaction{ ids.tx_data_len = len(program_input["tx_data"]) %} - let (return_data_len, return_data, success, gas_used) = eth_send_raw_transaction( + let (return_data_len, return_data, success, gas_used) = eth_send_raw_unsigned_tx( tx_data_len=tx_data_len, tx_data=tx_data ); diff --git a/tests/src/kakarot/test_kakarot.py b/tests/src/kakarot/test_kakarot.py index a802c32c9..48afdd2ca 100644 --- a/tests/src/kakarot/test_kakarot.py +++ b/tests/src/kakarot/test_kakarot.py @@ -435,7 +435,7 @@ def test_should_raise_invalid_chain_id_tx_type_different_from_0( with cairo_error(message="Invalid chain id"): cairo_run( - "test__eth_send_raw_transaction", + "test__eth_send_raw_unsigned_tx", tx_data_len=len(tx_data), tx_data=tx_data, ) @@ -448,7 +448,7 @@ def test_should_raise_invalid_nonce(self, cairo_run, tx): tx_data = list(rlp_encode_signed_data(tx)) with cairo_error(message="Invalid nonce"): cairo_run( - "test__eth_send_raw_transaction", + "test__eth_send_raw_unsigned_tx", tx_data_len=len(tx_data), tx_data=tx_data, ) @@ -474,7 +474,7 @@ def test_raise_gas_limit_too_high(self, cairo_run, gas_limit): cairo_error(message="Gas limit too high"), ): cairo_run( - "test__eth_send_raw_transaction", + "test__eth_send_raw_unsigned_tx", tx_data_len=len(tx_data), tx_data=tx_data, ) @@ -501,7 +501,7 @@ def test_raise_max_fee_per_gas_too_high(self, cairo_run, maxFeePerGas): cairo_error(message="Max fee per gas too high"), ): cairo_run( - "test__eth_send_raw_transaction", + "test__eth_send_raw_unsigned_tx", tx_data_len=len(tx_data), tx_data=tx_data, ) @@ -516,7 +516,7 @@ def test_raise_transaction_gas_limit_too_high(self, cairo_run, tx): cairo_error(message="Transaction gas_limit > Block gas_limit"), ): cairo_run( - "test__eth_send_raw_transaction", + "test__eth_send_raw_unsigned_tx", tx_data_len=len(tx_data), tx_data=tx_data, ) @@ -532,7 +532,7 @@ def test_raise_max_fee_per_gas_too_low(self, cairo_run, tx): cairo_error(message="Max fee per gas too low"), ): cairo_run( - "test__eth_send_raw_transaction", + "test__eth_send_raw_unsigned_tx", tx_data_len=len(tx_data), tx_data=tx_data, ) @@ -569,7 +569,7 @@ def test_raise_max_priority_fee_too_high( cairo_error(message="Max priority fee greater than max fee per gas"), ): cairo_run( - "test__eth_send_raw_transaction", + "test__eth_send_raw_unsigned_tx", tx_data_len=len(tx_data), tx_data=tx_data, ) @@ -586,7 +586,7 @@ def test_raise_not_enough_ETH_balance(self, cairo_run, tx): cairo_error(message="Not enough ETH to pay msg.value + max gas fees"), ): cairo_run( - "test__eth_send_raw_transaction", + "test__eth_send_raw_unsigned_tx", tx_data_len=len(tx_data), tx_data=tx_data, ) From 32871ec71cea129055c573515cc87c80cc537c2f Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 09:45:38 +0200 Subject: [PATCH 07/19] refactor: max_priority_fee_per_gas range checked --- src/kakarot/eth_rpc.cairo | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/kakarot/eth_rpc.cairo b/src/kakarot/eth_rpc.cairo index 9a257a7c2..110a67a9e 100644 --- a/src/kakarot/eth_rpc.cairo +++ b/src/kakarot/eth_rpc.cairo @@ -3,7 +3,7 @@ from openzeppelin.access.ownable.library import Ownable_owner from starkware.cairo.common.bool import FALSE, TRUE from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin -from starkware.cairo.common.math import assert_le_felt, assert_nn, split_felt +from starkware.cairo.common.math import assert_le_felt, assert_le, assert_nn, split_felt from starkware.cairo.common.math_cmp import is_not_zero, is_nn from starkware.cairo.common.registers import get_fp_and_pc from starkware.cairo.common.uint256 import Uint256, uint256_add, uint256_le @@ -280,7 +280,9 @@ func eth_send_raw_unsigned_tx{ } with_attr error_message("Max priority fee greater than max fee per gas") { - assert_le_felt(tx.max_priority_fee_per_gas, tx.max_fee_per_gas); + assert [range_check_ptr] = tx.max_priority_fee_per_gas; + let range_check_ptr = range_check_ptr + 1; + assert_le(tx.max_priority_fee_per_gas, tx.max_fee_per_gas); } let (native_token_address) = Kakarot_native_token_address.read(); From 2e1569da75f5562e39247e38bd44e8f417c62f29 Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 09:52:26 +0200 Subject: [PATCH 08/19] fix: remove unnecessary tempvar --- src/utils/eth_transaction.cairo | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/eth_transaction.cairo b/src/utils/eth_transaction.cairo index 13473cd97..a272b1688 100644 --- a/src/utils/eth_transaction.cairo +++ b/src/utils/eth_transaction.cairo @@ -65,7 +65,6 @@ namespace EthTransaction { assert items[7].is_list = FALSE; assert items[8].is_list = FALSE; let chain_id = Helpers.bytes_to_felt(items[6].data_len, items[6].data); - tempvar chain_id = chain_id; tempvar is_some = 1; tempvar chain_id = chain_id; From c31fea06ffa015b36d15a557542a2697d2e5ad37 Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 09:51:51 +0200 Subject: [PATCH 09/19] refactor: use eth_get_balance --- src/kakarot/eth_rpc.cairo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kakarot/eth_rpc.cairo b/src/kakarot/eth_rpc.cairo index 110a67a9e..aa5b82ebc 100644 --- a/src/kakarot/eth_rpc.cairo +++ b/src/kakarot/eth_rpc.cairo @@ -240,6 +240,7 @@ func eth_send_raw_unsigned_tx{ }(tx_data_len: felt, tx_data: felt*) -> ( return_data_len: felt, return_data: felt*, success: felt, gas_used: felt ) { + alloc_locals; let tx = EthTransaction.decode(tx_data_len, tx_data); // Validate chain_id for post eip155 @@ -285,8 +286,7 @@ func eth_send_raw_unsigned_tx{ assert_le(tx.max_priority_fee_per_gas, tx.max_fee_per_gas); } - let (native_token_address) = Kakarot_native_token_address.read(); - let (balance) = IERC20.balanceOf(native_token_address, caller_address); + let (balance) = eth_get_balance(caller_address); let max_gas_fee = tx.gas_limit * tx.max_fee_per_gas; let (max_fee_high, max_fee_low) = split_felt(max_gas_fee); let (tx_cost, carry) = uint256_add(tx.amount, Uint256(low=max_fee_low, high=max_fee_high)); From 29f104e3c900bca5d84c104db071daec9fb68916 Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 10:39:55 +0200 Subject: [PATCH 10/19] test: remove patch storage var for 0 --- tests/src/kakarot/test_kakarot.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/src/kakarot/test_kakarot.py b/tests/src/kakarot/test_kakarot.py index 48afdd2ca..299a2e153 100644 --- a/tests/src/kakarot/test_kakarot.py +++ b/tests/src/kakarot/test_kakarot.py @@ -479,7 +479,6 @@ def test_raise_gas_limit_too_high(self, cairo_run, gas_limit): tx_data=tx_data, ) - @SyscallHandler.patch("Kakarot_block_gas_limit", 0) @given(maxFeePerGas=integers(min_value=2**128, max_value=DEFAULT_PRIME - 1)) def test_raise_max_fee_per_gas_too_high(self, cairo_run, maxFeePerGas): tx = { @@ -506,7 +505,6 @@ def test_raise_max_fee_per_gas_too_high(self, cairo_run, maxFeePerGas): tx_data=tx_data, ) - @SyscallHandler.patch("Kakarot_block_gas_limit", 0) @pytest.mark.parametrize("tx", TRANSACTIONS) def test_raise_transaction_gas_limit_too_high(self, cairo_run, tx): tx_data = list(rlp_encode_signed_data(tx)) @@ -545,7 +543,6 @@ def max_priority_fee_too_high(draw): return (maxFeePerGas, maxPriorityFeePerGas) @SyscallHandler.patch("Kakarot_block_gas_limit", TRANSACTION_GAS_LIMIT) - @SyscallHandler.patch("Kakarot_base_fee", 0) @given(max_priority_fee_too_high()) def test_raise_max_priority_fee_too_high( self, cairo_run, max_priority_fee_too_high @@ -576,7 +573,6 @@ def test_raise_max_priority_fee_too_high( @SyscallHandler.patch("IERC20.balanceOf", lambda _, __: [0, 0]) @SyscallHandler.patch("Kakarot_block_gas_limit", TRANSACTION_GAS_LIMIT) - @SyscallHandler.patch("Kakarot_base_fee", 0) @pytest.mark.parametrize("tx", TRANSACTIONS) def test_raise_not_enough_ETH_balance(self, cairo_run, tx): tx_data = list(rlp_encode_signed_data(tx)) From 2d530255f56108b4355a1d4d88cd6116df5994a6 Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 10:42:08 +0200 Subject: [PATCH 11/19] test: refactor max_priority_fee_too_high --- tests/src/kakarot/test_kakarot.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/src/kakarot/test_kakarot.py b/tests/src/kakarot/test_kakarot.py index 299a2e153..8d97902e5 100644 --- a/tests/src/kakarot/test_kakarot.py +++ b/tests/src/kakarot/test_kakarot.py @@ -537,10 +537,11 @@ def test_raise_max_fee_per_gas_too_low(self, cairo_run, tx): @composite def max_priority_fee_too_high(draw): - maxFeePerGas = draw(integers(min_value=0, max_value=2**128 - 1)) - maxPriorityFeePerGas = draw(integers(min_value=0, max_value=2**128 - 1)) - assume(maxFeePerGas < maxPriorityFeePerGas) - return (maxFeePerGas, maxPriorityFeePerGas) + max_fee_per_gas = draw(integers(min_value=0, max_value=2**128 - 1)) + max_priority_fee_per_gas = draw( + integers(min_value=max_fee_per_gas + 1, max_value=2**128 - 1) + ) + return (max_fee_per_gas, max_priority_fee_per_gas) @SyscallHandler.patch("Kakarot_block_gas_limit", TRANSACTION_GAS_LIMIT) @given(max_priority_fee_too_high()) From 92fe475d61977afffd5dc86d6d1f797f3804fb61 Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 10:56:29 +0200 Subject: [PATCH 12/19] test: modify serdy for chain_id --- tests/src/utils/test_eth_transaction.py | 2 +- tests/utils/serde.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/src/utils/test_eth_transaction.py b/tests/src/utils/test_eth_transaction.py index 073dd14c6..fb80a8901 100644 --- a/tests/src/utils/test_eth_transaction.py +++ b/tests/src/utils/test_eth_transaction.py @@ -49,7 +49,7 @@ async def test_should_decode_all_transactions_types( assert expected_to == decoded_tx["destination"] assert transaction["value"] == int(decoded_tx["amount"], 16) # pre-eip155 txs have an internal chain_id set to 0 in the decoded tx - assert transaction.get("chainId", 0) == decoded_tx["chain_id"]["value"] + assert transaction.get("chainId", 0) == decoded_tx["chain_id"] assert expected_data == decoded_tx["payload"] assert expected_access_list == decoded_tx["access_list"] diff --git a/tests/utils/serde.py b/tests/utils/serde.py index b8460c8e7..8766cba32 100644 --- a/tests/utils/serde.py +++ b/tests/utils/serde.py @@ -164,7 +164,9 @@ def serialize_eth_transaction(self, ptr): if raw["access_list"] is not None else [] ), - "chain_id": raw["chain_id"], + "chain_id": ( + raw["chain_id"]["value"] if raw["chain_id"]["is_some"] == 1 else 0 + ), } def serialize_message(self, ptr): From 23cac178e5e0da84eff91b6b51e956b3278c70a7 Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 10:59:18 +0200 Subject: [PATCH 13/19] test: remove unused import --- tests/src/kakarot/test_kakarot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/kakarot/test_kakarot.py b/tests/src/kakarot/test_kakarot.py index 8d97902e5..a6bdd1601 100644 --- a/tests/src/kakarot/test_kakarot.py +++ b/tests/src/kakarot/test_kakarot.py @@ -6,7 +6,7 @@ from eth_abi import decode, encode from eth_utils import keccak from eth_utils.address import to_checksum_address -from hypothesis import assume, given +from hypothesis import given from hypothesis.strategies import composite, integers from starkware.cairo.lang.cairo_constants import DEFAULT_PRIME from starkware.starknet.public.abi import get_storage_var_address From e10762f964eb9b81e1a642577926143e75391f73 Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 11:00:44 +0200 Subject: [PATCH 14/19] refactor: use assert_le tx.gas_limit --- src/kakarot/eth_rpc.cairo | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/kakarot/eth_rpc.cairo b/src/kakarot/eth_rpc.cairo index aa5b82ebc..02e5d3ae1 100644 --- a/src/kakarot/eth_rpc.cairo +++ b/src/kakarot/eth_rpc.cairo @@ -3,7 +3,7 @@ from openzeppelin.access.ownable.library import Ownable_owner from starkware.cairo.common.bool import FALSE, TRUE from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin -from starkware.cairo.common.math import assert_le_felt, assert_le, assert_nn, split_felt +from starkware.cairo.common.math import assert_le, assert_nn, split_felt from starkware.cairo.common.math_cmp import is_not_zero, is_nn from starkware.cairo.common.registers import get_fp_and_pc from starkware.cairo.common.uint256 import Uint256, uint256_add, uint256_le @@ -262,7 +262,9 @@ func eth_send_raw_unsigned_tx{ // Validate gas with_attr error_message("Gas limit too high") { - assert_le_felt(tx.gas_limit, 2 ** 64 - 1); + assert [range_check_ptr] = tx.gas_limit; + let range_check_ptr = range_check_ptr + 1; + assert_le(tx.gas_limit, 2 ** 64 - 1); } with_attr error_message("Max fee per gas too high") { From d5cf416e0205d32d5ce8134d56391e5716558584 Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 11:25:13 +0200 Subject: [PATCH 15/19] fix: use evm_address for eth_get_balance --- src/kakarot/eth_rpc.cairo | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kakarot/eth_rpc.cairo b/src/kakarot/eth_rpc.cairo index 02e5d3ae1..9f54a1b01 100644 --- a/src/kakarot/eth_rpc.cairo +++ b/src/kakarot/eth_rpc.cairo @@ -288,7 +288,8 @@ func eth_send_raw_unsigned_tx{ assert_le(tx.max_priority_fee_per_gas, tx.max_fee_per_gas); } - let (balance) = eth_get_balance(caller_address); + let (evm_address) = IAccount.get_evm_address(caller_address); + let (balance) = eth_get_balance(evm_address); let max_gas_fee = tx.gas_limit * tx.max_fee_per_gas; let (max_fee_high, max_fee_low) = split_felt(max_gas_fee); let (tx_cost, carry) = uint256_add(tx.amount, Uint256(low=max_fee_low, high=max_fee_high)); From 3fe24758576c42ee63b7f463b702b5462b81c5fe Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 12:28:50 +0200 Subject: [PATCH 16/19] test: patch get_evm_address --- tests/src/kakarot/test_kakarot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/src/kakarot/test_kakarot.py b/tests/src/kakarot/test_kakarot.py index a6bdd1601..41e349c31 100644 --- a/tests/src/kakarot/test_kakarot.py +++ b/tests/src/kakarot/test_kakarot.py @@ -574,6 +574,7 @@ def test_raise_max_priority_fee_too_high( @SyscallHandler.patch("IERC20.balanceOf", lambda _, __: [0, 0]) @SyscallHandler.patch("Kakarot_block_gas_limit", TRANSACTION_GAS_LIMIT) + @SyscallHandler.patch("IAccount.get_evm_address", lambda _, __: [0xABDE1]) @pytest.mark.parametrize("tx", TRANSACTIONS) def test_raise_not_enough_ETH_balance(self, cairo_run, tx): tx_data = list(rlp_encode_signed_data(tx)) From 1dfb9c4cb7b942833e1006c4753f0e470ae3fff9 Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 13:14:13 +0200 Subject: [PATCH 17/19] test: fix composite max_priority_fee_too_high --- tests/src/kakarot/test_kakarot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/kakarot/test_kakarot.py b/tests/src/kakarot/test_kakarot.py index 41e349c31..fe01e6aec 100644 --- a/tests/src/kakarot/test_kakarot.py +++ b/tests/src/kakarot/test_kakarot.py @@ -537,9 +537,9 @@ def test_raise_max_fee_per_gas_too_low(self, cairo_run, tx): @composite def max_priority_fee_too_high(draw): - max_fee_per_gas = draw(integers(min_value=0, max_value=2**128 - 1)) + max_fee_per_gas = draw(integers(min_value=0, max_value=2**128 - 2)) max_priority_fee_per_gas = draw( - integers(min_value=max_fee_per_gas + 1, max_value=2**128 - 1) + integers(min_value=max_fee_per_gas + 1, max_value=DEFAULT_PRIME - 1) ) return (max_fee_per_gas, max_priority_fee_per_gas) From 6682009a3945e4d3e4ce41a21aad877fb6cbc98a Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 26 Aug 2024 18:01:09 +0200 Subject: [PATCH 18/19] test: refactor chain_id serde --- tests/src/utils/test_eth_transaction.py | 2 +- tests/utils/serde.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/utils/test_eth_transaction.py b/tests/src/utils/test_eth_transaction.py index fb80a8901..67baa9819 100644 --- a/tests/src/utils/test_eth_transaction.py +++ b/tests/src/utils/test_eth_transaction.py @@ -49,7 +49,7 @@ async def test_should_decode_all_transactions_types( assert expected_to == decoded_tx["destination"] assert transaction["value"] == int(decoded_tx["amount"], 16) # pre-eip155 txs have an internal chain_id set to 0 in the decoded tx - assert transaction.get("chainId", 0) == decoded_tx["chain_id"] + assert transaction.get("chainId", None) == decoded_tx["chain_id"] assert expected_data == decoded_tx["payload"] assert expected_access_list == decoded_tx["access_list"] diff --git a/tests/utils/serde.py b/tests/utils/serde.py index 8766cba32..4d6208fef 100644 --- a/tests/utils/serde.py +++ b/tests/utils/serde.py @@ -165,7 +165,7 @@ def serialize_eth_transaction(self, ptr): else [] ), "chain_id": ( - raw["chain_id"]["value"] if raw["chain_id"]["is_some"] == 1 else 0 + raw["chain_id"]["value"] if raw["chain_id"]["is_some"] == 1 else None ), } From a0bbc62366310c2c5a0618b5d9aa8f3223be07ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Walter?= Date: Tue, 27 Aug 2024 09:55:55 +0200 Subject: [PATCH 19/19] Update tests/src/utils/test_eth_transaction.py --- tests/src/utils/test_eth_transaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/utils/test_eth_transaction.py b/tests/src/utils/test_eth_transaction.py index 67baa9819..1e6569bf7 100644 --- a/tests/src/utils/test_eth_transaction.py +++ b/tests/src/utils/test_eth_transaction.py @@ -49,7 +49,7 @@ async def test_should_decode_all_transactions_types( assert expected_to == decoded_tx["destination"] assert transaction["value"] == int(decoded_tx["amount"], 16) # pre-eip155 txs have an internal chain_id set to 0 in the decoded tx - assert transaction.get("chainId", None) == decoded_tx["chain_id"] + assert transaction.get("chainId") == decoded_tx["chain_id"] assert expected_data == decoded_tx["payload"] assert expected_access_list == decoded_tx["access_list"]