Skip to content

Commit

Permalink
build(blockifier_reexecution): add serialization for reexecution data
Browse files Browse the repository at this point in the history
  • Loading branch information
aner-starkware committed Nov 4, 2024
1 parent 0b906af commit 3ee1065
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 23 deletions.
2 changes: 1 addition & 1 deletion crates/blockifier_reexecution/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ license.workspace = true
blockifier_regression_https_testing = []

[dependencies]
blockifier.workspace = true
blockifier = { workspace = true, features = ["transaction_serde"] }
cairo-lang-starknet-classes.workspace = true
cairo-lang-utils.workspace = true
cairo-vm.workspace = true
Expand Down
86 changes: 64 additions & 22 deletions crates/blockifier_reexecution/src/state_reader/test_state_reader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::fs;
use std::sync::{Arc, Mutex};

use blockifier::blockifier::block::BlockInfo;
Expand All @@ -12,6 +13,7 @@ use blockifier::state::errors::StateError;
use blockifier::state::state_api::{StateReader, StateResult};
use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction;
use blockifier::versioned_constants::VersionedConstants;
use serde::{Deserialize, Serialize};
use serde_json::{json, to_value};
use starknet_api::block::{BlockNumber, StarknetVersion};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
Expand All @@ -36,20 +38,64 @@ use crate::state_reader::utils::{
disjoint_hashmap_union,
get_chain_info,
get_rpc_state_reader_config,
ReexecutionStateMaps,
};

pub type ReexecutionResult<T> = Result<T, ReexecutionError>;

pub type StarknetContractClassMapping = HashMap<ClassHash, StarknetContractClass>;

pub struct OfflineReexecutionData {
state_maps: StateMaps,
contract_class_mapping: StarknetContractClassMapping,
offline_state_reader_prev_block: OfflineStateReader,
block_context_next_block: BlockContext,
transactions_next_block: Vec<BlockifierTransaction>,
state_diff_next_block: CommitmentStateDiff,
}

#[derive(Serialize, Deserialize)]
pub struct SerializableOfflineReexecutionData {
state_maps: ReexecutionStateMaps,
contract_class_mapping: StarknetContractClassMapping,
block_info_next_block: BlockInfo,
starknet_version: StarknetVersion,
transactions_next_block: Vec<(Transaction, TransactionHash)>,
state_diff_next_block: CommitmentStateDiff,
}

impl SerializableOfflineReexecutionData {
pub fn write_to_file(&self, file_path: &str, file_name: &str) -> ReexecutionResult<()> {
fs::create_dir_all(file_path)
.unwrap_or_else(|_| panic!("Failed to create directory {file_path}."));
let full_file_path = file_path.to_owned() + "/" + file_name;
fs::write(full_file_path.clone(), serde_json::to_string_pretty(&self)?)
.unwrap_or_else(|_| panic!("Failed to write to file {full_file_path}."));
Ok(())
}
}

impl From<SerializableOfflineReexecutionData> for OfflineReexecutionData {
fn from(value: SerializableOfflineReexecutionData) -> Self {
let offline_state_reader_prev_block = OfflineStateReader {
state_maps: value.state_maps.try_into().expect("Failed to deserialize state maps."),
contract_class_mapping: value.contract_class_mapping,
};
let transactions_next_block = offline_state_reader_prev_block
.api_txs_to_blockifier_txs(value.transactions_next_block)
.expect("Failed to convert starknet-api transactions to blockifier transactions.");
Self {
offline_state_reader_prev_block,
block_context_next_block: BlockContext::new(
value.block_info_next_block,
get_chain_info(),
VersionedConstants::get(&value.starknet_version).unwrap().clone(),
BouncerConfig::max(),
),
transactions_next_block,
state_diff_next_block: value.state_diff_next_block,
}
}
}

pub struct TestStateReader {
rpc_state_reader: RpcStateReader,
#[allow(dead_code)]
Expand Down Expand Up @@ -295,7 +341,7 @@ impl ConsecutiveTestStateReaders {
dump_mode: bool,
) -> Self {
let config = config.unwrap_or(get_rpc_state_reader_config());
ConsecutiveTestStateReaders {
Self {
last_block_state_reader: TestStateReader::new(
&config,
last_constructed_block_number,
Expand Down Expand Up @@ -383,6 +429,18 @@ impl StateReader for OfflineStateReader {
}
}

impl ReexecutionStateReader for OfflineStateReader {
fn get_contract_class(&self, class_hash: &ClassHash) -> StateResult<StarknetContractClass> {
Ok(self
.contract_class_mapping
.get(class_hash)
.ok_or(StateError::StateReadError(format!(
"Missing contract class at class hash: {class_hash}"
)))?
.clone())
}
}

impl OfflineStateReader {
pub fn get_transaction_executor(
self,
Expand All @@ -397,18 +455,6 @@ impl OfflineStateReader {
}
}

impl ReexecutionStateReader for OfflineStateReader {
fn get_contract_class(&self, class_hash: &ClassHash) -> StateResult<StarknetContractClass> {
Ok(self
.contract_class_mapping
.get(class_hash)
.ok_or(StateError::StateReadError(format!(
"Missing contract class at class hash: {class_hash}"
)))?
.clone())
}
}

pub struct OfflineConsecutiveStateReaders {
pub offline_state_reader_prev_block: OfflineStateReader,
pub block_context_next_block: BlockContext,
Expand All @@ -420,18 +466,14 @@ impl OfflineConsecutiveStateReaders {
// TODO(Aner): create directly from json.
pub fn new(
OfflineReexecutionData {
state_maps,
contract_class_mapping,
offline_state_reader_prev_block,
block_context_next_block,
transactions_next_block,
state_diff_next_block,
}: OfflineReexecutionData,
) -> Self {
OfflineConsecutiveStateReaders {
offline_state_reader_prev_block: OfflineStateReader {
state_maps,
contract_class_mapping,
},
Self {
offline_state_reader_prev_block,
block_context_next_block,
transactions_next_block,
state_diff_next_block,
Expand Down

0 comments on commit 3ee1065

Please sign in to comment.