1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use num_bigint::BigUint;
use serde::{Deserialize, Serialize};

use super::block::GlobalRootHex;
use crate::contract_address::ContractAddress;
use crate::felt::{BlockHash, ClassHash, Felt, Nonce};
use crate::patricia_key::PatriciaKey;

pub type CompiledClassHashHex = Felt;
pub type Balance = BigUint;

#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub enum StateUpdateResult {
    StateUpdate(StateUpdate),
    PendingStateUpdate(PendingStateUpdate),
}

impl StateUpdateResult {
    pub fn get_state_diff(&self) -> ThinStateDiff {
        match self {
            StateUpdateResult::StateUpdate(s) => s.state_diff.clone(),
            StateUpdateResult::PendingStateUpdate(s) => s.state_diff.clone(),
        }
    }
}

#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct StateUpdate {
    pub block_hash: BlockHash,
    pub new_root: GlobalRootHex,
    pub old_root: GlobalRootHex,
    pub state_diff: ThinStateDiff,
}

#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct PendingStateUpdate {
    pub old_root: GlobalRootHex,
    pub state_diff: ThinStateDiff,
}

#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct ThinStateDiff {
    pub deployed_contracts: Vec<DeployedContract>,
    pub storage_diffs: Vec<StorageDiff>,
    pub declared_classes: Vec<ClassHashes>,
    pub deprecated_declared_classes: Vec<ClassHash>,
    pub nonces: Vec<ContractNonce>,
    pub replaced_classes: Vec<ReplacedClasses>,
}

/// A deployed contract in Starknet.
#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct DeployedContract {
    pub address: ContractAddress,
    pub class_hash: ClassHash,
}

/// Storage differences in Starknet.
// Invariant: Storage keys are strictly increasing. In particular, no key appears twice.
#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct StorageDiff {
    pub address: ContractAddress,
    pub storage_entries: Vec<StorageEntry>,
}

/// A storage entry in a contract.
#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct StorageEntry {
    pub key: PatriciaKey,
    pub value: Felt,
}

#[derive(Debug, Clone, Default, Eq, PartialEq, Deserialize, Serialize)]
pub struct ClassHashes {
    pub class_hash: ClassHash,
    pub compiled_class_hash: CompiledClassHashHex,
}

#[derive(Debug, Clone, Default, Eq, PartialEq, Deserialize, Serialize)]
pub struct ReplacedClasses {
    pub contract_address: ContractAddress,
    pub class_hash: ClassHash,
}

/// The nonce of a Starknet contract.
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct ContractNonce {
    pub contract_address: ContractAddress,
    pub nonce: Nonce,
}