Skip to content

Commit

Permalink
feat: add support for system contract 0x2
Browse files Browse the repository at this point in the history
  • Loading branch information
CHr15F0x committed Jan 8, 2025
1 parent c2d7a93 commit 5256180
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 29 deletions.
13 changes: 12 additions & 1 deletion crates/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ impl ContractAddress {
/// It is used by starknet to store values for smart contracts to access
/// using syscalls. For example the block hash.
pub const ONE: ContractAddress = contract_address!("0x1");
/// The contract at 0x2 was introduced in Starknet version 0.13.4. It is
/// used for stateful compression:
/// - storage key 0 points to the global counter, which is the base for
/// index values in the next block,
/// - other storage k-v pairs store the mapping of key to index,
/// - the global counter starts at value 0x80 in the first block from
/// 0.13.4,
/// - keys of value lower than 0x80 are not indexed.
pub const TWO: ContractAddress = contract_address!("0x2");
/// Useful for iteration over the system contracts
pub const SYSTEM: [ContractAddress; 2] = [ContractAddress::ONE, ContractAddress::TWO];
}

// Bytecode and entry point list of a class
Expand Down Expand Up @@ -595,7 +606,7 @@ impl ContractAddress {
}

pub fn is_system_contract(&self) -> bool {
*self == ContractAddress::ONE
(*self == ContractAddress::ONE) || (*self == ContractAddress::TWO)
}
}

Expand Down
20 changes: 11 additions & 9 deletions crates/gateway-types/src/reply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2056,17 +2056,19 @@ impl From<StateUpdate> for pathfinder_common::StateUpdate {
// This must occur before we map the contract updates, since we want to first
// remove the system contract updates.
//
// Currently this is only the contract at address 0x1.
// Currently there are two such contracts, at addresses 0x1 and 0x2.
//
// As of starknet v0.12.0 these are embedded in this way, but in the future will
// As of starknet v0.13.4 these are embedded in this way, but in the future will
// be a separate property in the state diff.
if let Some((address, storage_updates)) = gateway
.state_diff
.storage_diffs
.remove_entry(&ContractAddress::ONE)
{
for state_update::StorageDiff { key, value } in storage_updates {
state_update = state_update.with_system_storage_update(address, key, value);
for system_contract in ContractAddress::SYSTEM.iter() {
if let Some((address, storage_updates)) = gateway
.state_diff
.storage_diffs
.remove_entry(system_contract)
{
for state_update::StorageDiff { key, value } in storage_updates {
state_update = state_update.with_system_storage_update(address, key, value);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/merkle-tree/src/contract_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ pub fn update_contract_state(
};

let class_hash = if contract_address.is_system_contract() {
// This is a special system contract at address 0x1, which doesn't have a class
// hash.
// This is a special system contract at address 0x1 or 0x2, which doesn't have a
// class hash.
ClassHash::ZERO
} else if let Some(class_hash) = new_class_hash {
class_hash
Expand Down
4 changes: 2 additions & 2 deletions crates/p2p/src/client/peer_agnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ impl BlockClient for Client {
}
}
let address = ContractAddress(address.0);
if address == ContractAddress::ONE {
if address.is_system_contract() {
let storage = &mut state_diff
.system_contract_updates
.entry(address)
Expand Down Expand Up @@ -1046,7 +1046,7 @@ mod state_diff_stream {

progress.checked_sub_assign(values.len())?;

if address == ContractAddress::ONE {
if address.is_system_contract() {
let storage = &mut state_diff
.system_contract_updates
.entry(address)
Expand Down
14 changes: 13 additions & 1 deletion crates/p2p/src/client/peer_agnostic/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use pathfinder_common::{
TransactionHash,
TransactionIndex,
};
use rand::seq::SliceRandom;
use tagged::Tagged;
use tagged_debug_derive::TaggedDebug;
use tokio::sync::Mutex;
Expand Down Expand Up @@ -249,6 +250,7 @@ pub fn state_diff(tag: i32) -> StateUpdateData {
Some(x) => ([].into(), [(SierraHash(Faker.fake()), x)].into()),
None => ([ClassHash(Faker.fake())].into(), [].into()),
};

let (contract_updates, system_contract_updates) = if Faker.fake() {
(
[(
Expand All @@ -263,8 +265,18 @@ pub fn state_diff(tag: i32) -> StateUpdateData {
[].into(),
)
} else {
([].into(), [(ContractAddress::ONE, Faker.fake())].into())
(
[].into(),
[(
*ContractAddress::SYSTEM
.choose(&mut rand::thread_rng())
.unwrap(),
Faker.fake(),
)]
.into(),
)
};

Tagged::get(format!("state diff {tag}"), || StateUpdateData {
contract_updates,
system_contract_updates,
Expand Down
9 changes: 5 additions & 4 deletions crates/pathfinder/src/p2p_network/sync_handlers/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ mod prop {
}

proptest! {
#![proptest_config(ProptestConfig::with_cases(25))]
#![proptest_config(ProptestConfig::with_cases(1))]
#[test]
fn get_state_diffs((num_blocks, seed, start_block, limit, step, direction) in strategy::composite()) {
// Fake storage with a given number of blocks
Expand Down Expand Up @@ -274,18 +274,19 @@ mod prop {
// Check the rest
responses.into_iter().for_each(|response| match response {
StateDiffsResponse::ContractDiff(ContractDiff { address, nonce, class_hash, values, domain: _ }) => {
if address.0 == Felt::from_u64(1) {
let contract_address = ContractAddress(address.0);
if contract_address.is_system_contract() {
actual_system_contract_updates.push(
(
ContractAddress(address.0),
contract_address,
SystemContractUpdate {
storage: values.into_iter().map(
|ContractStoredValue { key, value }| (StorageAddress(key), StorageValue(value))).collect()}
));
} else {
actual_contract_updates.push(
(
ContractAddress(address.0),
contract_address,
ContractUpdate {
storage: values.into_iter().map(|ContractStoredValue { key, value }|
(StorageAddress(key), StorageValue(value))).collect(),
Expand Down
24 changes: 20 additions & 4 deletions crates/storage/src/connection/state_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ impl Transaction<'_> {
.transpose()
.context("Iterating over storage query rows")?
{
state_update = if address == ContractAddress::ONE {
state_update = if address.is_system_contract() {
state_update.with_system_storage_update(address, key, value)
} else {
state_update.with_storage_update(address, key, value)
Expand Down Expand Up @@ -1214,8 +1214,13 @@ mod tests {
)
.with_system_storage_update(
ContractAddress::ONE,
storage_address_bytes!(b"key"),
storage_value_bytes!(b"value"),
storage_address_bytes!(b"key 1"),
storage_value_bytes!(b"value 1"),
)
.with_system_storage_update(
ContractAddress::TWO,
storage_address_bytes!(b"key 2"),
storage_value_bytes!(b"value 2"),
)
.with_deployed_contract(
contract_address_bytes!(b"contract addr 2"),
Expand Down Expand Up @@ -1308,7 +1313,18 @@ mod tests {
ContractAddress::ONE,
ReverseContractUpdate::Updated(ContractUpdate {
storage: HashMap::from([(
storage_address_bytes!(b"key"),
storage_address_bytes!(b"key 1"),
StorageValue::ZERO
)]),
nonce: None,
class: None
})
),
(
ContractAddress::TWO,
ReverseContractUpdate::Updated(ContractUpdate {
storage: HashMap::from([(
storage_address_bytes!(b"key 2"),
StorageValue::ZERO
)]),
nonce: None,
Expand Down
20 changes: 14 additions & 6 deletions crates/storage/src/fake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,12 +411,20 @@ pub mod generate {
declared_cairo_classes,
declared_sierra_classes,
system_contract_updates: if occurrence.system_storage.contains(&1) {
Some((
ContractAddress::ONE,
SystemContractUpdate {
storage: fake_non_empty_with_rng(rng),
},
))
[
(
ContractAddress::ONE,
SystemContractUpdate {
storage: fake_non_empty_with_rng(rng),
},
),
(
ContractAddress::TWO,
SystemContractUpdate {
storage: fake_non_empty_with_rng(rng),
},
),
]
.into_iter()
.collect()
} else {
Expand Down

0 comments on commit 5256180

Please sign in to comment.