From 94329d936bada68e5f3a8c601d839f9395ae172c Mon Sep 17 00:00:00 2001 From: enitrat Date: Fri, 4 Oct 2024 11:38:45 +0200 Subject: [PATCH] refactor: eth_send_raw_transaction --- crates/contracts/src/account_contract.cairo | 13 +- .../contracts/src/kakarot_core/eth_rpc.cairo | 16 +-- .../src/eth_transaction/transaction.cairo | 114 +++++++----------- 3 files changed, 59 insertions(+), 84 deletions(-) diff --git a/crates/contracts/src/account_contract.cairo b/crates/contracts/src/account_contract.cairo index 9391ac4db..5de99dd12 100644 --- a/crates/contracts/src/account_contract.cairo +++ b/crates/contracts/src/account_contract.cairo @@ -68,7 +68,7 @@ pub mod AccountContract { use crate::storage::StorageBytecode; use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait}; use super::OutsideExecution; - use utils::eth_transaction::transaction::TransactionUnsignedTrait; + use utils::eth_transaction::transaction::TransactionTrait; use utils::serialization::{deserialize_signature, deserialize_bytes, serialize_bytes}; use utils::traits::DefaultSignature; @@ -249,18 +249,13 @@ pub mod AccountContract { let mut encoded_tx_data = deserialize_bytes((*outside_execution.calls[0]).calldata) .expect('conversion to Span failed') .span(); - let unsigned_transaction = TransactionUnsignedTrait::decode_enveloped( - ref encoded_tx_data - ) - .expect('EOA: could not decode tx'); + let unsigned_transaction_hash = TransactionTrait::compute_hash(encoded_tx_data); let address = self.Account_evm_address.read(); - verify_eth_signature(unsigned_transaction.hash, signature, address); + verify_eth_signature(unsigned_transaction_hash, signature, address); - //TODO: refactor this to call eth_send_raw_unsigned_tx. Only the transactions bytes are - //passed. let (success, return_data, gas_used) = kakarot - .eth_send_transaction(unsigned_transaction.transaction); + .eth_send_raw_unsigned_tx(encoded_tx_data); let return_data = serialize_bytes(return_data).span(); // See Argent account diff --git a/crates/contracts/src/kakarot_core/eth_rpc.cairo b/crates/contracts/src/kakarot_core/eth_rpc.cairo index 8e98b20e4..62ea780dd 100644 --- a/crates/contracts/src/kakarot_core/eth_rpc.cairo +++ b/crates/contracts/src/kakarot_core/eth_rpc.cairo @@ -10,7 +10,7 @@ use evm::model::{TransactionResult, Address}; use evm::{EVMTrait}; use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait}; use utils::constants::POW_2_53; -use utils::eth_transaction::transaction::Transaction; +use utils::eth_transaction::transaction::{Transaction, TransactionTrait}; #[starknet::interface] pub trait IEthRPC { @@ -175,6 +175,14 @@ pub impl EthRPC< fn eth_send_transaction( ref self: TContractState, mut tx: Transaction ) -> (bool, Span, u64) { + panic!("unimplemented") + } + + fn eth_send_raw_unsigned_tx( + ref self: TContractState, mut tx_data: Span + ) -> (bool, Span, u64) { + let tx = TransactionTrait::decode_enveloped(ref tx_data).expect('EOA: could not decode tx'); + let mut kakarot_state = KakarotState::get_state(); let intrinsic_gas = validate_eth_tx(@kakarot_state, tx); @@ -189,12 +197,6 @@ pub impl EthRPC< starknet_backend::commit(ref state).expect('Committing state failed'); (success, return_data, gas_used) } - - fn eth_send_raw_unsigned_tx( - ref self: TContractState, tx_data: Span - ) -> (bool, Span, u64) { - panic!("unimplemented") - } } trait IEthRPCInternal { diff --git a/crates/utils/src/eth_transaction/transaction.cairo b/crates/utils/src/eth_transaction/transaction.cairo index 9e1d57f90..959ab463b 100644 --- a/crates/utils/src/eth_transaction/transaction.cairo +++ b/crates/utils/src/eth_transaction/transaction.cairo @@ -173,19 +173,8 @@ pub impl _Transasction of TransactionTrait { Transaction::Eip1559(tx) => tx.input, } } -} - -#[derive(Copy, Drop, Debug, PartialEq)] -pub struct TransactionUnsigned { - /// Transaction hash - pub hash: u256, - /// Raw transaction info - pub transaction: Transaction, -} -#[generate_trait] -pub impl _TransactionUnsigned of TransactionUnsignedTrait { /// Decodes the "raw" format of transaction (similar to `eth_sendRawTransaction`). /// /// This should be used for any method that accepts a raw transaction. @@ -201,9 +190,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { /// /// Both for legacy and EIP-2718 transactions, an error will be returned if there is an excess /// of bytes in input data. - fn decode_enveloped( - ref tx_data: Span, - ) -> Result { + fn decode_enveloped(ref tx_data: Span,) -> Result { if tx_data.is_empty() { return Result::Err(EthTransactionError::RLPError(RLPError::InputTooShort)); } @@ -233,9 +220,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { /// chainId, 0, 0] /// Note: this function assumes that tx_type has been checked to make sure it is a legacy /// transaction - fn decode_legacy_tx( - ref encoded_tx_data: Span - ) -> Result { + fn decode_legacy_tx(ref encoded_tx_data: Span) -> Result { let rlp_decoded_data = RLPTrait::decode(encoded_tx_data); let mut rlp_decoded_data = rlp_decoded_data.map_err()?; @@ -256,11 +241,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { } }; - let tx_hash = Self::compute_hash(encoded_tx_data); - - Result::Ok( - TransactionUnsigned { transaction: Transaction::Legacy(legacy_tx), hash: tx_hash, } - ) + Result::Ok(Transaction::Legacy(legacy_tx)) } /// Decodes an enveloped EIP-2718 typed transaction. @@ -275,7 +256,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { /// CAUTION: this expects that `data` is `tx-type || rlp(tx-data)` fn decode_enveloped_typed_transaction( ref encoded_tx_data: Span - ) -> Result { + ) -> Result { // keep this around so we can use it to calculate the hash let original_data = encoded_tx_data; @@ -316,8 +297,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { } }; - let tx_hash = Self::compute_hash(original_data); - Result::Ok(TransactionUnsigned { transaction, hash: tx_hash }) + Result::Ok(transaction) } /// Returns the hash of the unsigned transaction @@ -355,7 +335,7 @@ mod tests { legacy_rlp_encoded_tx, legacy_rlp_encoded_deploy_tx, eip_2930_encoded_tx, eip_1559_encoded_tx }; - use super::{TransactionTrait, TransactionUnsignedTrait}; + use super::{TransactionTrait}; #[test] @@ -368,18 +348,18 @@ mod tests { // message_hash: 0xcf71743e6e25fef715398915997f782b95554c8bbfb7b3f7701e007332ed31b4 // chain id used: 'KKRT' let mut encoded_tx_data = legacy_rlp_encoded_tx(); - let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); - assert_eq!(decoded.transaction.nonce(), 0); - assert_eq!(decoded.transaction.max_fee_per_gas(), 0x3b9aca00); - assert_eq!(decoded.transaction.gas_limit(), 0x1e8480); + let transaction = TransactionTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(transaction.nonce(), 0); + assert_eq!(transaction.max_fee_per_gas(), 0x3b9aca00); + assert_eq!(transaction.gas_limit(), 0x1e8480); assert_eq!( - decoded.transaction.kind(), + transaction.kind(), TxKind::Call(0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap()) ); - assert_eq!(decoded.transaction.value(), 0x016345785d8a0000); - assert_eq!(decoded.transaction.input(), [0xab, 0xcd, 0xef].span()); - assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); - assert_eq!(decoded.transaction.transaction_type(), TxType::Legacy); + assert_eq!(transaction.value(), 0x016345785d8a0000); + assert_eq!(transaction.input(), [0xab, 0xcd, 0xef].span()); + assert_eq!(transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(transaction.transaction_type(), TxType::Legacy); } #[test] @@ -389,18 +369,18 @@ mod tests { // expected rlp decoding: // ["0x","0x0a","0x061a80","0x","0x0186a0","0x600160010a5060006000f3","0x4b4b5254","0x","0x"] let mut encoded_tx_data = legacy_rlp_encoded_deploy_tx(); - let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); - assert_eq!(decoded.transaction.nonce(), 0); - assert_eq!(decoded.transaction.max_fee_per_gas(), 0x0a); - assert_eq!(decoded.transaction.gas_limit(), 0x061a80); - assert_eq!(decoded.transaction.kind(), TxKind::Create); - assert_eq!(decoded.transaction.value(), 0x0186a0); + let transaction = TransactionTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(transaction.nonce(), 0); + assert_eq!(transaction.max_fee_per_gas(), 0x0a); + assert_eq!(transaction.gas_limit(), 0x061a80); + assert_eq!(transaction.kind(), TxKind::Create); + assert_eq!(transaction.value(), 0x0186a0); assert_eq!( - decoded.transaction.input(), + transaction.input(), [0x60, 0x01, 0x60, 0x01, 0x0a, 0x50, 0x60, 0x00, 0x60, 0x00, 0xf3].span() ); - assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); - assert_eq!(decoded.transaction.transaction_type(), TxType::Legacy); + assert_eq!(transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(transaction.transaction_type(), TxType::Legacy); } #[test] @@ -416,18 +396,18 @@ mod tests { // chain id used: 'KKRT' let mut encoded_tx_data = eip_2930_encoded_tx(); - let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); - assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); - assert_eq!(decoded.transaction.nonce(), 0); - assert_eq!(decoded.transaction.max_fee_per_gas(), 0x3b9aca00); - assert_eq!(decoded.transaction.gas_limit(), 0x1e8480); + let transaction = TransactionTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(transaction.nonce(), 0); + assert_eq!(transaction.max_fee_per_gas(), 0x3b9aca00); + assert_eq!(transaction.gas_limit(), 0x1e8480); assert_eq!( - decoded.transaction.kind(), + transaction.kind(), TxKind::Call(0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap()) ); - assert_eq!(decoded.transaction.value(), 0x016345785d8a0000); - assert_eq!(decoded.transaction.input(), [0xab, 0xcd, 0xef].span()); - assert_eq!(decoded.transaction.transaction_type(), TxType::Eip2930); + assert_eq!(transaction.value(), 0x016345785d8a0000); + assert_eq!(transaction.input(), [0xab, 0xcd, 0xef].span()); + assert_eq!(transaction.transaction_type(), TxType::Eip2930); } #[test] @@ -443,17 +423,17 @@ mod tests { // chain id used: 'KKRT' let mut encoded_tx_data = eip_1559_encoded_tx(); - let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); - assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); - assert_eq!(decoded.transaction.nonce(), 0); - assert_eq!(decoded.transaction.max_fee_per_gas(), 0x3b9aca00); - assert_eq!(decoded.transaction.gas_limit(), 0x1e8480); + let transaction = TransactionTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(transaction.nonce(), 0); + assert_eq!(transaction.max_fee_per_gas(), 0x3b9aca00); + assert_eq!(transaction.gas_limit(), 0x1e8480); assert_eq!( - decoded.transaction.kind(), + transaction.kind(), TxKind::Call(0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap()) ); - assert_eq!(decoded.transaction.value(), 0x016345785d8a0000); - assert_eq!(decoded.transaction.input(), [0xab, 0xcd, 0xef].span()); + assert_eq!(transaction.value(), 0x016345785d8a0000); + assert_eq!(transaction.input(), [0xab, 0xcd, 0xef].span()); let expected_access_list = [ AccessListItem { ethereum_address: 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap(), @@ -463,16 +443,14 @@ mod tests { ].span() } ].span(); - assert_eq!( - decoded.transaction.access_list().expect('access_list is none'), expected_access_list - ); - assert_eq!(decoded.transaction.transaction_type(), TxType::Eip1559); + assert_eq!(transaction.access_list().expect('access_list is none'), expected_access_list); + assert_eq!(transaction.transaction_type(), TxType::Eip1559); } #[test] fn test_is_legacy_tx_eip_155_tx() { let encoded_tx_data = legacy_rlp_encoded_tx(); - let result = TransactionUnsignedTrait::is_legacy_tx(encoded_tx_data); + let result = TransactionTrait::is_legacy_tx(encoded_tx_data); assert(result, 'is_legacy_tx expected true'); } @@ -480,7 +458,7 @@ mod tests { #[test] fn test_is_legacy_tx_eip_1559_tx() { let encoded_tx_data = eip_1559_encoded_tx(); - let result = TransactionUnsignedTrait::is_legacy_tx(encoded_tx_data); + let result = TransactionTrait::is_legacy_tx(encoded_tx_data); assert(!result, 'is_legacy_tx expected false'); } @@ -488,7 +466,7 @@ mod tests { #[test] fn test_is_legacy_tx_eip_2930_tx() { let encoded_tx_data = eip_2930_encoded_tx(); - let result = TransactionUnsignedTrait::is_legacy_tx(encoded_tx_data); + let result = TransactionTrait::is_legacy_tx(encoded_tx_data); assert(!result, 'is_legacy_tx expected false'); }