Skip to content
This repository has been archived by the owner on Aug 2, 2024. It is now read-only.

Commit

Permalink
dev: check that class exist before using it in BuildGenesisConfig (#1389
Browse files Browse the repository at this point in the history
)

Co-authored-by: Timothée Delabrouille <34384633+tdelabro@users.noreply.github.com>
  • Loading branch information
kfastov and tdelabro authored Feb 12, 2024
1 parent a3101a4 commit c7c70de
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- refacto: remove abusive `TryInto` impl
- dev: optimize tx trace creation
- dev: make Madara std compatible
- dev: check that class exist before using it in BuildGenesisConfig
- CI: fix taplo version
- chore: add cache usage for `getEvents` and `getTransactionReceipt`
- fix: cairo1 contracts should be identified by their sierra class hash
Expand Down
16 changes: 14 additions & 2 deletions crates/pallets/starknet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ use transaction_validation::TxPriorityInfo;

use crate::alloc::string::ToString;
use crate::execution_config::RuntimeExecutionConfigBuilder;
use crate::types::{CasmClassHash, SierraClassHash, StorageSlot};
use crate::types::{CasmClassHash, SierraClassHash, SierraOrCasmClassHash, StorageSlot};

pub(crate) const LOG_TARGET: &str = "runtime::starknet";

Expand Down Expand Up @@ -265,7 +265,8 @@ pub mod pallet {
#[pallet::storage]
#[pallet::unbounded]
#[pallet::getter(fn contract_class_by_class_hash)]
pub(super) type ContractClasses<T: Config> = StorageMap<_, Identity, CasmClassHash, ContractClass, OptionQuery>;
pub(super) type ContractClasses<T: Config> =
StorageMap<_, Identity, SierraOrCasmClassHash, ContractClass, OptionQuery>;

/// Mapping from Starknet Sierra class hash to Casm compiled contract class.
/// Safe to use `Identity` as the key is already a hash.
Expand Down Expand Up @@ -375,10 +376,21 @@ pub mod pallet {
}

for (sierra_class_hash, casm_class_hash) in self.sierra_to_casm_class_hash.iter() {
assert!(
ContractClasses::<T>::contains_key(sierra_class_hash),
"Sierra class hash {} does not exist in contract_classes",
sierra_class_hash,
);
CompiledClassHashes::<T>::insert(sierra_class_hash, CompiledClassHash(casm_class_hash.0));
}

for (address, class_hash) in self.contracts.iter() {
assert!(
ContractClasses::<T>::contains_key(class_hash),
"Class hash {} does not exist in contract_classes",
class_hash,
);

ContractClassHashes::<T>::insert(address, class_hash);
}

Expand Down
49 changes: 49 additions & 0 deletions crates/pallets/starknet/src/tests/build_genesis_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use sp_runtime::BuildStorage;
use starknet_api::api_core::{ClassHash, ContractAddress};

use super::mock::default_mock;
use super::utils::get_contract_class;
use crate::GenesisConfig;

#[test]
fn works_when_sierra_clash_hash_in_mapping_is_known() {
let mut t = frame_system::GenesisConfig::<default_mock::MockRuntime>::default().build_storage().unwrap();
let genesis: GenesisConfig<default_mock::MockRuntime> = GenesisConfig {
sierra_to_casm_class_hash: vec![(ClassHash(1u8.into()), ClassHash(42u8.into()))],
contract_classes: vec![(ClassHash(1u8.into()), get_contract_class("ERC20.json", 0))],
..Default::default()
};
genesis.assimilate_storage(&mut t).unwrap();
}

#[test]
#[should_panic(expected = "does not exist in contract_classes")]
fn fails_when_only_casm_clash_hash_in_mapping_is_known() {
let mut t = frame_system::GenesisConfig::<default_mock::MockRuntime>::default().build_storage().unwrap();
let genesis: GenesisConfig<default_mock::MockRuntime> = GenesisConfig {
sierra_to_casm_class_hash: vec![(ClassHash(1u8.into()), ClassHash(42u8.into()))],
contract_classes: vec![(ClassHash(42u8.into()), get_contract_class("ERC20.json", 0))],
..Default::default()
};
genesis.assimilate_storage(&mut t).unwrap();
}

#[test]
#[should_panic(expected = "does not exist in contract_classes")]
fn fail_with_unknown_class_hash_in_sierra_mappings() {
let mut t = frame_system::GenesisConfig::<default_mock::MockRuntime>::default().build_storage().unwrap();
let genesis: GenesisConfig<default_mock::MockRuntime> = GenesisConfig {
sierra_to_casm_class_hash: vec![(ClassHash(1u8.into()), ClassHash(42u8.into()))],
..Default::default()
};
genesis.assimilate_storage(&mut t).unwrap();
}

#[test]
#[should_panic(expected = "does not exist in contract_classes")]
fn fail_with_unknown_class_hash_in_contracts() {
let mut t = frame_system::GenesisConfig::<default_mock::MockRuntime>::default().build_storage().unwrap();
let genesis: GenesisConfig<default_mock::MockRuntime> =
GenesisConfig { contracts: vec![(ContractAddress(1u8.into()), ClassHash(42u8.into()))], ..Default::default() };
genesis.assimilate_storage(&mut t).unwrap();
}
1 change: 1 addition & 0 deletions crates/pallets/starknet/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::tests::utils::sign_message_hash;
use crate::{Config, Nonces};

mod account_helper;
mod build_genesis_config;
mod call_contract;
mod declare_tx;
mod deploy_account_tx;
Expand Down
1 change: 1 addition & 0 deletions crates/pallets/starknet/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub type StorageSlot = (StorageKey, Felt252Wrapper);

pub type CasmClassHash = ClassHash;
pub type SierraClassHash = ClassHash;
pub type SierraOrCasmClassHash = ClassHash;

/// Declare Transaction Output
#[derive(Clone, Debug, PartialEq, Eq, parity_scale_codec::Encode, parity_scale_codec::Decode, scale_info::TypeInfo)]
Expand Down

0 comments on commit c7c70de

Please sign in to comment.