diff --git a/CHANGELOG.md b/CHANGELOG.md index 4706444748..8ec3409b42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ git # Madara Changelog ## Next release +- fux(getStorageAt): #28 - fix(genesis): #107 - fix(class): #32 #33 #34 - fix(class): #116 diff --git a/crates/client/deoxys/src/commitments/events.rs b/crates/client/deoxys/src/commitments/events.rs index 5c205f84e3..2be64c12a4 100644 --- a/crates/client/deoxys/src/commitments/events.rs +++ b/crates/client/deoxys/src/commitments/events.rs @@ -67,8 +67,6 @@ where let mut bonsai_storage = BonsaiStorage::<_, _, Pedersen>::new(bonsai_db, config).expect("Failed to create bonsai storage"); - let root_hash = bonsai_storage.root_hash().expect("Failed to get root hash"); - println!("Root hash: {}", root_hash); let mut id_builder = BasicIdBuilder::new(); let zero = id_builder.new_id(); @@ -86,7 +84,6 @@ where let root_hash = bonsai_storage.root_hash().expect("Failed to get root hash"); bonsai_storage.revert_to(zero).unwrap(); - println!("Root hash 2: {:?}", Felt252Wrapper::from(root_hash)); Ok(Felt252Wrapper::from(root_hash)) } else { diff --git a/crates/node/src/chain_spec.rs b/crates/node/src/chain_spec.rs index 00c23ff0ad..392ed1639a 100644 --- a/crates/node/src/chain_spec.rs +++ b/crates/node/src/chain_spec.rs @@ -133,14 +133,16 @@ pub fn deoxys_config(sealing: SealingMode, chain_id: &str) -> Result Result { log::info!("🧪 Fetching genesis block"); let runtime = Runtime::new().unwrap(); - let genesis_block = runtime.block_on(async { - SequencerGatewayProvider::starknet_alpha_mainnet() - .get_block(BlockId::Number(0)) + let provider = SequencerGatewayProvider::starknet_alpha_mainnet(); + let diff = runtime.block_on(async { + provider + .get_state_update(BlockId::Number(0)) .await - .map_err(|e| format!("failed to get block: {e}")) + .map(|state_update| state_update.state_diff) + .map_err(|e| format!("Failed to get state update {e}")) })?; - Ok(GenesisData::from(genesis_block)) + Ok(GenesisData::from(diff)) } /// Configure initial storage state for FRAME modules. diff --git a/crates/pallets/starknet/src/genesis_loader.rs b/crates/pallets/starknet/src/genesis_loader.rs index cd0f100ef6..c8587f6cbb 100644 --- a/crates/pallets/starknet/src/genesis_loader.rs +++ b/crates/pallets/starknet/src/genesis_loader.rs @@ -3,6 +3,9 @@ use std::vec::Vec; use blockifier::execution::contract_class::ContractClass as StarknetContractClass; use mp_felt::Felt252Wrapper; pub use mp_genesis_config::{GenesisData, GenesisLoader, HexFelt, PredeployedAccount}; +use starknet_api::api_core::{ContractAddress, PatriciaKey}; +use starknet_api::hash::StarkFelt; +use starknet_api::state::StorageKey; use crate::GenesisConfig; @@ -28,9 +31,23 @@ impl From for GenesisConfig { (sierra_hash, casm_hash) }) .collect::>(); + let storage = data + .storage + .clone() + .into_iter() + .map(|((contract_address, key), value)| { + ( + ( + ContractAddress(PatriciaKey(StarkFelt(contract_address.0.to_bytes_be()))), + StorageKey(PatriciaKey(StarkFelt(key.0.to_bytes_be()))), + ), + StarkFelt(value.0.to_bytes_be()), + ) + }) + .collect(); let fee_token_address = Felt252Wrapper(data.fee_token_address.0).into(); - GenesisConfig { contracts, sierra_to_casm_class_hash, fee_token_address, ..Default::default() } + GenesisConfig { contracts, sierra_to_casm_class_hash, storage, fee_token_address, ..Default::default() } } } @@ -60,8 +77,6 @@ pub fn read_contract_class_from_json(json_str: &str, version: u8) -> StarknetCon #[cfg(test)] mod tests { - use starknet_crypto::FieldElement; - use super::*; #[test] diff --git a/crates/pallets/starknet/src/lib.rs b/crates/pallets/starknet/src/lib.rs index da5cdda0a9..cee85dd93e 100644 --- a/crates/pallets/starknet/src/lib.rs +++ b/crates/pallets/starknet/src/lib.rs @@ -436,6 +436,7 @@ pub mod pallet { /// a test environment or in the case of a migration of an existing chain state. pub contracts: Vec<(ContractAddress, SierraClassHash)>, pub sierra_to_casm_class_hash: Vec<(SierraClassHash, CasmClassHash)>, + pub storage: Vec<(ContractStorageKey, StarkFelt)>, /// The address of the fee token. /// Must be set to the address of the fee token ERC20 contract. pub fee_token_address: ContractAddress, @@ -448,6 +449,7 @@ pub mod pallet { Self { contracts: vec![], sierra_to_casm_class_hash: vec![], + storage: vec![], fee_token_address: ContractAddress::default(), _phantom: PhantomData, } @@ -470,6 +472,11 @@ pub mod pallet { CompiledClassHashes::::insert(class_hash, CompiledClassHash(compiled_class_hash.0)) }); + log::info!("Saving Genesis storage diffs"); + self.storage + .iter() + .for_each(|(contract_storage_key, value)| StorageView::::insert(contract_storage_key, value)); + LastKnownEthBlock::::set(None); // Set the fee token address from the genesis config. FeeTokenAddress::::set(self.fee_token_address); diff --git a/crates/primitives/genesis-config/src/lib.rs b/crates/primitives/genesis-config/src/lib.rs index d6230cebd6..640338b865 100644 --- a/crates/primitives/genesis-config/src/lib.rs +++ b/crates/primitives/genesis-config/src/lib.rs @@ -60,48 +60,60 @@ pub type StorageValue = HexFelt; pub struct GenesisData { pub contracts: Vec<(ContractAddress, ClassHash)>, pub sierra_class_hash_to_casm_class_hash: Vec<(ClassHash, ClassHash)>, + pub storage: Vec<(ContractStorageKey, StorageValue)>, pub fee_token_address: ContractAddress, } #[cfg(feature = "std")] pub mod convert { - use starknet_providers::sequencer::models::{Block as BlockProvider, TransactionType}; + use starknet_providers::sequencer::models::state_update::{StateDiff, StorageDiff}; use super::*; - impl From for GenesisData { - fn from(genesis_block: BlockProvider) -> Self { + impl From for GenesisData { + fn from(genesis_diff: StateDiff) -> Self { Self { - contracts: convert_contract(&genesis_block), - sierra_class_hash_to_casm_class_hash: convert_sierra_class_hash(&genesis_block), + contracts: convert_contract(&genesis_diff), + sierra_class_hash_to_casm_class_hash: convert_sierra_class_hash(&genesis_diff), + storage: convert_storage(&genesis_diff), fee_token_address: *ETH_TOKEN_ADDR, } } } - fn convert_contract(genesis_block: &BlockProvider) -> Vec<(ContractAddress, ClassHash)> { - genesis_block - .transactions + fn convert_contract(genesis_diff: &StateDiff) -> Vec<(ContractAddress, ClassHash)> { + genesis_diff + .deployed_contracts .iter() - .filter_map(|transaction| if let TransactionType::Deploy(tx) = transaction { Some(tx) } else { None }) - .map(|transaction| (HexFelt(transaction.contract_address), HexFelt(transaction.class_hash))) + .map(|contract| (HexFelt(contract.address), HexFelt(contract.class_hash))) .collect() } - fn convert_sierra_class_hash(genesis_block: &BlockProvider) -> Vec<(ClassHash, ClassHash)> { - genesis_block - .transactions + fn convert_sierra_class_hash(genesis_diff: &StateDiff) -> Vec<(ClassHash, ClassHash)> { + genesis_diff + .declared_classes .iter() - .filter_map(|transaction| if let TransactionType::Declare(tx) = transaction { Some(tx) } else { None }) - .filter_map(|transaction| { - if let Some(compiled_class_hash) = transaction.compiled_class_hash { - Some((HexFelt(transaction.class_hash), HexFelt(compiled_class_hash))) - } else { - None - } - }) + .map(|contract| (HexFelt(contract.class_hash), HexFelt(contract.compiled_class_hash))) .collect() } + + #[rustfmt::skip] + fn convert_storage(genesis_diff: &StateDiff) -> Vec<(ContractStorageKey, StorageValue)> { + genesis_diff.storage_diffs.iter().fold(vec![], |mut acc, diff| { + acc.extend( + diff.1 + .into_iter() + .map(|StorageDiff { key, value }| ( + ( + HexFelt(diff.0.clone()), + HexFelt(key.clone()) + ), + HexFelt(value.clone())) + ) + ); + acc + }) + } } #[derive(Constructor, Clone)]