Skip to content

Commit

Permalink
add test
Browse files Browse the repository at this point in the history
  • Loading branch information
greged93 committed Sep 28, 2023
1 parent c5341ea commit 2d1f614
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 5 deletions.
77 changes: 77 additions & 0 deletions crates/ef-testing/src/sequencer/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,80 @@ impl InitializeEvmState for KakarotSequencer {
Ok(())
}
}

#[cfg(test)]
mod tests {
use crate::sequencer::{
constants::{
tests::{PRIVATE_KEY, PUBLIC_KEY, SELECTOR, TEST_CONTRACT_ADDRESS},
CHAIN_ID,
},
utils::to_broadcasted_starknet_transaction,
};

use super::*;
use blockifier::state::state_api::StateReader;
use bytes::BytesMut;
use reth_primitives::{sign_message, AccessList, Signature, TransactionSigned, TxEip1559};
use revm_primitives::B256;
use sequencer::{
execution::Execution, state::State as SequencerState, transaction::StarknetTransaction,
};
use starknet::core::types::BroadcastedTransaction;

#[test]
fn test_execute_contract_address() {
// Given
let sequencer = KakarotSequencer::new(SequencerState::default());
let mut sequencer = sequencer.initialize().unwrap();

let transaction = TransactionSigned {
hash: B256::default(),
signature: Signature::default(),
transaction: reth_primitives::Transaction::Eip1559(TxEip1559 {
chain_id: *CHAIN_ID,
nonce: 0,
gas_limit: 0,
max_fee_per_gas: 0,
max_priority_fee_per_gas: 0,
to: reth_primitives::TransactionKind::Call(*TEST_CONTRACT_ADDRESS),
value: 0,
access_list: AccessList::default(),
input: SELECTOR.clone(),
}),
};
let signature =
sign_message(*PRIVATE_KEY, transaction.transaction.signature_hash()).unwrap();
let mut output = BytesMut::new();
transaction.encode_with_signature(&signature, &mut output, false);
let transaction = BroadcastedTransaction::Invoke(
to_broadcasted_starknet_transaction(&sequencer, &output.to_vec().into()).unwrap(),
);
let transaction = StarknetTransaction::new(transaction).try_into().unwrap();

// When
let bytecode = Bytes::from(vec![96, 1, 96, 0, 85]); // PUSH 01 PUSH 00 SSTORE
let nonce = U256::from(0);
sequencer
.initialize_contract(&TEST_CONTRACT_ADDRESS, &bytecode, nonce, vec![])
.unwrap();
sequencer
.initialize_contract(&PUBLIC_KEY, &Bytes::default(), U256::from(0), vec![])
.unwrap();
sequencer.0.execute(transaction).unwrap();

// Then
let contract_starknet_address = sequencer
.compute_starknet_address(&TEST_CONTRACT_ADDRESS)
.try_into()
.unwrap();
let storage = (&mut sequencer.0.state)
.get_storage_at(
contract_starknet_address,
get_storage_var_address("storage_", &[StarkFelt::from(0u8), StarkFelt::from(0u8)])
.unwrap(),
)
.unwrap();
assert_eq!(storage, StarkFelt::from(1u8));
}
}
53 changes: 52 additions & 1 deletion crates/ef-testing/src/sequencer/utils.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
use blockifier::abi::abi_utils::get_storage_var_address as blockifier_get_storage_var_address;
use reth_primitives::Bytes;
use reth_primitives::{Bytes, TransactionSigned};
use reth_rlp::Decodable;
use revm_primitives::U256;
use starknet::{
core::types::{BroadcastedInvokeTransaction, FieldElement},
macros::selector,
};
use starknet_api::{
core::{ClassHash, ContractAddress},
hash::StarkFelt,
state::StorageKey,
};

use super::{constants::KAKAROT_ADDRESS, KakarotSequencer};

pub(crate) fn get_storage_var_address(
storage_var: &str,
keys: &[StarkFelt],
Expand Down Expand Up @@ -39,3 +46,47 @@ pub(crate) fn contract_address_to_starkfelt(contract_address: &ContractAddress)
pub(crate) fn class_hash_to_starkfelt(class_hash: &ClassHash) -> StarkFelt {
class_hash.0
}

pub fn bytes_to_felt_vec(bytes: &Bytes) -> Vec<FieldElement> {
bytes.to_vec().into_iter().map(FieldElement::from).collect()
}

#[allow(dead_code)]
pub(crate) fn to_broadcasted_starknet_transaction(
sequencer: &KakarotSequencer,
bytes: &Bytes,
) -> Result<BroadcastedInvokeTransaction, eyre::Error> {
let transaction = TransactionSigned::decode(&mut bytes.as_ref())?;

let evm_address = transaction
.recover_signer()
.ok_or_else(|| eyre::eyre!("Missing signer in signed transaction"))?;

let nonce = FieldElement::from(transaction.nonce());
let starknet_address = sequencer.compute_starknet_address(&evm_address);

let mut calldata = bytes_to_felt_vec(bytes);

let mut execute_calldata: Vec<FieldElement> = vec![
FieldElement::ONE, // call array length
contract_address_to_starkfelt(&KAKAROT_ADDRESS).into(), // contract address
selector!("eth_send_transaction"), // selector
FieldElement::ZERO, // data offset
FieldElement::from(calldata.len()), // data length
FieldElement::from(calldata.len()), // calldata length
];
execute_calldata.append(&mut calldata);

let signature = vec![];

let request = BroadcastedInvokeTransaction {
max_fee: FieldElement::from(0u8),
signature,
nonce,
sender_address: starknet_address.into(),
calldata: execute_calldata,
is_query: false,
};

Ok(request)
}
11 changes: 7 additions & 4 deletions crates/sequencer/src/sequencer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct Sequencer<S>
where
for<'a> &'a mut S: State + StateReader,
{
pub context: BlockContext,
pub block_context: BlockContext,
pub state: S,
}

Expand All @@ -32,8 +32,11 @@ where
for<'a> &'a mut S: State + StateReader,
{
/// Creates a new Sequencer instance.
pub fn new(context: BlockContext, state: S) -> Self {
Self { context, state }
pub fn new(block_context: BlockContext, state: S) -> Self {
Self {
block_context,
state,
}
}
}

Expand All @@ -44,7 +47,7 @@ where
fn execute(&mut self, transaction: Transaction) -> Result<(), TransactionExecutionError> {
let mut cached_state = CachedState::new(&mut self.state);
let charge_fee = false;
let res = transaction.execute(&mut cached_state, &self.context, charge_fee);
let res = transaction.execute(&mut cached_state, &self.block_context, charge_fee);

match res {
Err(err) => {
Expand Down

0 comments on commit 2d1f614

Please sign in to comment.