use num_bigint::BigUint;
use serde::Serialize;
use starknet_types_core::felt::Felt;
use super::block::BlockRoot;
use crate::contract_address::ContractAddress;
use crate::felt::{BlockHash, ClassHash, CompiledClassHash, Nonce};
use crate::patricia_key::PatriciaKey;
pub type Balance = BigUint;
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "testing", derive(serde::Deserialize), serde(deny_unknown_fields))]
pub enum StateUpdateResult {
StateUpdate(StateUpdate),
PreConfirmedStateUpdate(PreConfirmedStateUpdate),
}
impl StateUpdateResult {
pub fn get_state_diff(&self) -> &ThinStateDiff {
match self {
StateUpdateResult::StateUpdate(s) => &s.state_diff,
StateUpdateResult::PreConfirmedStateUpdate(s) => &s.state_diff,
}
}
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "testing", derive(serde::Deserialize), serde(deny_unknown_fields))]
pub struct StateUpdate {
pub block_hash: BlockHash,
pub new_root: BlockRoot,
pub old_root: BlockRoot,
pub state_diff: ThinStateDiff,
}
impl StateUpdate {
pub fn new(block_hash: Felt, state_diff: ThinStateDiff) -> Self {
Self { block_hash, new_root: Felt::default(), old_root: Felt::default(), state_diff }
}
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "testing", derive(serde::Deserialize), serde(deny_unknown_fields))]
pub struct PreConfirmedStateUpdate {
pub old_root: Option<BlockRoot>,
pub state_diff: ThinStateDiff,
}
#[derive(Debug, Default, Clone, Serialize)]
#[cfg_attr(
feature = "testing",
derive(serde::Deserialize, Eq, PartialEq),
serde(deny_unknown_fields)
)]
pub struct ThinStateDiff {
pub deployed_contracts: Vec<DeployedContract>,
pub storage_diffs: Vec<StorageDiff>,
pub declared_classes: Vec<ClassHashPair>,
pub deprecated_declared_classes: Vec<ClassHash>,
pub nonces: Vec<ContractNonce>,
pub replaced_classes: Vec<ReplacedClasses>,
#[serde(skip_serializing_if = "Option::is_none")]
pub migrated_compiled_classes: Option<Vec<ClassHashPair>>,
}
impl ThinStateDiff {
pub fn len(&self) -> usize {
let mut result = 0usize;
result += self.deployed_contracts.len();
result += self.declared_classes.len();
result += self.deprecated_declared_classes.len();
result += self.nonces.len();
for diff in &self.storage_diffs {
result += diff.storage_entries.len();
}
result
}
pub fn is_empty(&self) -> bool {
self.deployed_contracts.is_empty()
&& self.declared_classes.is_empty()
&& self.deprecated_declared_classes.is_empty()
&& self.nonces.is_empty()
&& self.storage_diffs.iter().all(|s| s.storage_entries.is_empty())
}
pub fn filter_by_address(&self, contract_addresses: Vec<ContractAddress>) -> Self {
let mut result = self.clone();
result.deployed_contracts.retain(|c| contract_addresses.contains(&c.address));
result.storage_diffs.retain(|s| contract_addresses.contains(&s.address));
result.nonces.retain(|n| contract_addresses.contains(&n.contract_address));
result.replaced_classes.retain(|r| contract_addresses.contains(&r.contract_address));
result
}
}
#[derive(Debug, Default, Clone, Serialize)]
#[cfg_attr(
feature = "testing",
derive(serde::Deserialize, Eq, PartialEq),
serde(deny_unknown_fields)
)]
pub struct DeployedContract {
pub address: ContractAddress,
pub class_hash: ClassHash,
}
#[derive(Debug, Default, Clone, Serialize)]
#[cfg_attr(
feature = "testing",
derive(serde::Deserialize, Eq, PartialEq),
serde(deny_unknown_fields)
)]
pub struct StorageDiff {
pub address: ContractAddress,
pub storage_entries: Vec<StorageEntry>,
}
#[derive(Debug, Default, Clone, Serialize)]
#[cfg_attr(
feature = "testing",
derive(serde::Deserialize, Eq, PartialEq),
serde(deny_unknown_fields)
)]
pub struct StorageEntry {
pub key: PatriciaKey,
pub value: Felt,
}
#[derive(Debug, Clone, Default, Serialize)]
#[cfg_attr(feature = "testing", derive(PartialEq, Eq, serde::Deserialize))]
pub struct ClassHashPair {
pub class_hash: ClassHash,
pub compiled_class_hash: CompiledClassHash,
}
#[derive(Debug, Clone, Default, Serialize)]
#[cfg_attr(feature = "testing", derive(Eq, PartialEq, serde::Deserialize))]
pub struct ReplacedClasses {
pub contract_address: ContractAddress,
pub class_hash: ClassHash,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(
feature = "testing",
derive(serde::Deserialize, Eq, PartialEq),
serde(deny_unknown_fields)
)]
pub struct ContractNonce {
pub contract_address: ContractAddress,
pub nonce: Nonce,
}