Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/os_v0_13_3' into gm/log2_hint
Browse files Browse the repository at this point in the history
  • Loading branch information
ftheirs committed Dec 31, 2024
2 parents 11862fd + 497feca commit b957c01
Show file tree
Hide file tree
Showing 32 changed files with 392 additions and 285 deletions.
17 changes: 3 additions & 14 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: "Install cairo-lang"
run: |
# We need to pin the version of sympy, 1.13.0 is incompatible with cairo-lang
pip install cairo-lang==0.13.2 "sympy<1.13.0"
pip install cairo-lang==0.13.3 "sympy<1.13.0"
- name: "Prepare test environment"
run: |
mkdir -p build
Expand All @@ -53,7 +53,7 @@ jobs:
- name: "Install cairo-lang"
run: |
# We need to pin the version of sympy, 1.13.0 is incompatible with cairo-lang
pip install cairo-lang==0.13.2 "sympy<1.13.0"
pip install cairo-lang==0.13.3 "sympy<1.13.0"
- name: "Prepare test environment"
run: |
bash ./setup-scripts/reset-tests.sh
Expand All @@ -78,21 +78,10 @@ jobs:
- name: "Install cairo-lang"
run: |
# We need to pin the version of sympy, 1.13.0 is incompatible with cairo-lang
pip install cairo-lang==0.13.2 "sympy<1.13.0"
pip install cairo-lang==0.13.3 "sympy<1.13.0"
- name: "Prepare test environment"
run: |
mkdir -p build
cairo-compile cairo-lang/src/starkware/starknet/core/os/os.cairo --output build/os_latest.json --cairo_path cairo-lang/src
- run: cargo install cargo-udeps --locked
- run: cargo udeps --all-targets

orphans:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: rustup show
- run: rustup component add rustfmt
- uses: Swatinem/rust-cache@v2
- run: git submodule update --init
- run: ./scripts/check-orphans.sh

12 changes: 11 additions & 1 deletion .github/workflows/prove_blocks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
- name: Setup the tests
run: |
source venv/bin/activate
pip install cairo-lang==0.13.2 "sympy<1.13.0"
pip install cairo-lang==0.13.3 "sympy<1.13.0"
bash setup-scripts/setup-tests.sh
- name: Prove Blocks
Expand All @@ -57,3 +57,13 @@ jobs:
PATHFINDER_RPC_URL: ${{ secrets.PATHFINDER_RPC_URL }}
run: |
cargo test --release --package prove_block --test hash_tests -- test_recompute_class_hash test_class_proof_verification_ok test_class_proof_verification_non_inclusion --show-output --ignored
- name: Hint tool Orphans
env:
PATHFINDER_RPC_URL: ${{ secrets.PATHFINDER_RPC_URL }}
run: |
RESULT=$(cargo run --release -p hint_tool -- --subset orphaned --in-file build/os_latest.json | grep -oP '\d+$')
if [ "$RESULT" -gt 1 ]; then
echo "Error: Only breakpoint hint is allowed to be orphaned."
exit 1
fi
2 changes: 1 addition & 1 deletion cairo-lang
Submodule cairo-lang updated 39 files
+2 −2 README.md
+2 −0 src/starkware/cairo/common/BUILD
+36 −0 src/starkware/cairo/common/copy_indices.cairo
+28 −0 src/starkware/cairo/common/log2_ceil.cairo
+1 −0 src/starkware/cairo/lang/BUILD
+1 −1 src/starkware/cairo/lang/VERSION
+1 −1 src/starkware/cairo/lang/ide/vscode-cairo/package.json
+6 −3 src/starkware/starknet/business_logic/execution/execute_entry_point.py
+1 −0 src/starkware/starknet/business_logic/fact_state/BUILD
+112 −8 src/starkware/starknet/business_logic/fact_state/state.py
+3 −3 src/starkware/starknet/business_logic/state/state_api_objects.py
+9 −6 src/starkware/starknet/business_logic/transaction/deprecated_objects.py
+6 −2 src/starkware/starknet/core/aggregator/BUILD
+169 −125 src/starkware/starknet/core/aggregator/aggregator_test.py
+159 −37 src/starkware/starknet/core/aggregator/output_parser.py
+2 −2 src/starkware/starknet/core/aggregator/program_hash.json
+6 −4 src/starkware/starknet/core/aggregator/utils.py
+2 −2 src/starkware/starknet/core/os/BUILD
+26 −0 src/starkware/starknet/core/os/data_availability/BUILD
+432 −0 src/starkware/starknet/core/os/data_availability/compression.cairo
+288 −0 src/starkware/starknet/core/os/data_availability/compression.py
+42 −12 src/starkware/starknet/core/os/output.cairo
+1 −1 src/starkware/starknet/core/os/program_hash.json
+54 −28 src/starkware/starknet/core/os/state/output.cairo
+1 −1 src/starkware/starknet/definitions/BUILD
+6 −1 src/starkware/starknet/definitions/chain_ids.py
+2 −0 src/starkware/starknet/definitions/constants.py
+1 −0 src/starkware/starknet/definitions/error_codes.py
+6 −7 src/starkware/starknet/definitions/fields.py
+37 −59 src/starkware/starknet/definitions/general_config.py
+4 −5 src/starkware/starknet/definitions/general_config.yml
+11 −0 src/starkware/starknet/definitions/overridable_versioned_constants.py
+1 −1 src/starkware/starknet/definitions/versioned_constants.json
+20 −0 src/starkware/starknet/solidity/IStarknetMessaging.sol
+2 −1 src/starkware/starknet/solidity/Starknet.sol
+1 −1 src/starkware/starknet/solidity/StarknetGovernance.sol
+23 −11 src/starkware/starknet/solidity/StarknetMessaging.sol
+1 −1 src/starkware/starknet/solidity/StarknetOperator.sol
+8 −2 src/starkware/starknet/solidity/StarknetState.sol
Binary file removed crates/bin/prove_block/reference-pies/173404.zip
Binary file not shown.
Binary file not shown.
Binary file added crates/bin/prove_block/reference-pies/341101.zip
Binary file not shown.
Binary file added crates/bin/prove_block/reference-pies/355710.zip
Binary file not shown.
Binary file added crates/bin/prove_block/reference-pies/355783.zip
Binary file not shown.
Binary file added crates/bin/prove_block/reference-pies/355802.zip
Binary file not shown.
13 changes: 10 additions & 3 deletions crates/bin/prove_block/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ pub async fn prove_block(
// This is a workaorund to catch the case where the block number is less than the buffer and still preserve the check
// The OS will also handle the case where the block number is less than the buffer.
let older_block_number =
if block_number <= STORED_BLOCK_HASH_BUFFER { 1 } else { block_number - STORED_BLOCK_HASH_BUFFER };
if block_number <= STORED_BLOCK_HASH_BUFFER { 0 } else { block_number - STORED_BLOCK_HASH_BUFFER };

let older_block =
match rpc_client.starknet_rpc().get_block_with_tx_hashes(BlockId::Number(older_block_number)).await? {
Expand Down Expand Up @@ -309,8 +309,15 @@ pub async fn prove_block(
let updated_root = block_hash_storage_proof.class_commitment.unwrap_or(Felt::ZERO);
let previous_root = previous_block_hash_storage_proof.class_commitment.unwrap_or(Felt::ZERO);

let previous_contract_trie_root = previous_block_hash_storage_proof.contract_proof[0].hash::<PedersenHash>();
let current_contract_trie_root = block_hash_storage_proof.contract_proof[0].hash::<PedersenHash>();
// On devnet and until block 10, the storage_root_idx might be None and that means that contract_proof is empty
let previous_contract_trie_root = match previous_block_hash_storage_proof.contract_proof.first() {
Some(proof) => proof.hash::<PedersenHash>(),
None => Felt252::ZERO,
};
let current_contract_trie_root = match block_hash_storage_proof.contract_proof.first() {
Some(proof) => proof.hash::<PedersenHash>(),
None => Felt252::ZERO,
};

let previous_contract_proofs: Vec<_> =
previous_storage_proofs.values().map(|proof| proof.contract_proof.clone()).collect();
Expand Down
9 changes: 6 additions & 3 deletions crates/bin/prove_block/src/reexecute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use blockifier::transaction::objects::TransactionExecutionInfo;
use blockifier::transaction::transaction_execution::Transaction;
use blockifier::transaction::transactions::ExecutableTransaction;
use cairo_vm::Felt252;
use rpc_client::pathfinder::proofs::{PathfinderProof, TrieNode};
use rpc_client::pathfinder::proofs::{ContractData, PathfinderProof, TrieNode};
use rpc_client::RpcClient;
use starknet::core::types::{BlockId, StarknetError};
use starknet::providers::{Provider as _, ProviderError};
Expand Down Expand Up @@ -163,8 +163,11 @@ pub(crate) fn format_commitment_facts<H: HashFunctionType>(
impl PerContractStorage for ProverPerContractStorage {
async fn compute_commitment(&mut self) -> Result<CommitmentInfo, CommitmentInfoError> {
// TODO: error code
let contract_data =
self.storage_proof.contract_data.as_ref().expect("storage proof should have a contract_data field");
let contract_data = match self.storage_proof.contract_data.as_ref() {
None => &ContractData::default(),
Some(data) => data,
};

let updated_root = contract_data.root;

let commitment_facts = format_commitment_facts::<PedersenHash>(&contract_data.storage_proofs);
Expand Down
38 changes: 36 additions & 2 deletions crates/bin/prove_block/src/rpc_utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};

use blockifier::transaction::objects::TransactionExecutionInfo;
use cairo_vm::Felt252;
Expand All @@ -12,7 +12,7 @@ use starknet::core::types::BlockWithTxs;
use starknet_api::core::{ContractAddress, PatriciaKey};
use starknet_api::state::StorageKey;
use starknet_api::{contract_address, felt, patricia_key};
use starknet_os::config::DEFAULT_STORAGE_TREE_HEIGHT;
use starknet_os::config::{DEFAULT_STORAGE_TREE_HEIGHT, STORED_BLOCK_HASH_BUFFER};
use starknet_os::starkware_utils::commitment_tree::base_types::Height;
use starknet_types_core::felt::Felt;

Expand Down Expand Up @@ -111,6 +111,36 @@ fn verify_storage_proof(contract_data: &ContractData, keys: &[Felt]) -> Vec<Felt
additional_keys
}

/// Inserts additional keys for retrieving storage proof from the block hash contract (address 0x1).
/// Certain contracts necessitate extra nodes from the contract 0x1. However, since Blockifier does not provide this information,
/// it is necessary to add some extra keys to ensure the inclusion of the required nodes.
/// This approach serves as a workaround. The ideal solutions would be to either retrieve the full tree or obtain information about the necessary nodes.
/// The first approach would introduce significant overhead for most blocks, and the second solution is currently not feasible at the moment.
fn insert_extra_storage_reads_keys(
old_block_number: Felt252,
keys: &mut HashMap<ContractAddress, HashSet<StorageKey>>,
) {
// A list of the contracts that accessed to the storage from 0x1 using `get_block_hash_syscall`
let special_addresses: Vec<ContractAddress> = vec![
contract_address!("0x01246c3031c5d0d1cf60a9370aac03a4717538f659e4a2bfb0f692e970e0c4b5"),
contract_address!("0x00656ca4889a405ec5222e4b0997e5a043902a98cb1f85a039f76f50c000479d"),
contract_address!("0x022207b425a6c0239bbf5d58fbf0272fbb059ee4bb89f48255321d6e7c1606ef"),
// Ekubo:core contract address. Source code is not available but `key_not_in_preimage` error is triggered every time it's called
contract_address!("0x5dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b"),
];

if special_addresses.iter().any(|address| keys.contains_key(address)) {
let extra_storage_reads = 200 * STORED_BLOCK_HASH_BUFFER;
if old_block_number >= Felt252::from(extra_storage_reads) {
for i in 1..=extra_storage_reads {
keys.entry(contract_address!("0x1"))
.or_default()
.insert((old_block_number - i).try_into().expect("Felt to StorageKey conversion failed"));
}
}
}
}

pub(crate) async fn get_storage_proofs(
client: &RpcClient,
block_number: u64,
Expand All @@ -121,6 +151,8 @@ pub(crate) async fn get_storage_proofs(
let mut keys = get_all_accessed_keys(tx_execution_infos);
// We need to fetch the storage proof for the block hash contract
keys.entry(contract_address!("0x1")).or_default().insert(old_block_number.try_into().unwrap());
// Include extra keys for contracts that trigger get_block_hash_syscall
insert_extra_storage_reads_keys(old_block_number, &mut keys);
keys
};

Expand All @@ -132,6 +164,7 @@ pub(crate) async fn get_storage_proofs(
let contract_address_felt = *contract_address.key();
let storage_proof =
get_storage_proof_for_contract(client, contract_address, storage_keys.into_iter(), block_number).await?;

storage_proofs.insert(contract_address_felt, storage_proof);
}

Expand Down Expand Up @@ -215,6 +248,7 @@ pub(crate) fn get_starknet_version(block_with_txs: &BlockWithTxs) -> blockifier:
"0.13.1.1" => blockifier::versioned_constants::StarknetVersion::V0_13_1_1,
"0.13.2" => blockifier::versioned_constants::StarknetVersion::V0_13_2,
"0.13.2.1" => blockifier::versioned_constants::StarknetVersion::Latest,
"0.13.3" => blockifier::versioned_constants::StarknetVersion::Latest,
other => {
unimplemented!("Unsupported Starknet version: {}", other)
}
Expand Down
24 changes: 22 additions & 2 deletions crates/bin/prove_block/tests/prove_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ const DEFAULT_COMPILED_OS: &[u8] = include_bytes!("../../../../build/os_latest.j
#[case::inconsistent_cairo0_class_hash_1(204936)]
#[case::no_possible_convertion_1(155007)]
#[case::no_possible_convertion_2(155029)]
#[case::reference_pie_with_full_output_enabled(173404)]
#[case::inconsistent_cairo0_class_hash_2(159674)]
#[case::inconsistent_cairo0_class_hash_3(164180)]
#[case::key_not_in_proof_0(155087)]
Expand All @@ -72,6 +71,23 @@ const DEFAULT_COMPILED_OS: &[u8] = include_bytes!("../../../../build/os_latest.j
#[case::memory_invalid_signature(216914)]
#[case::diff_assert_values(218624)]
#[case::could_nt_compute_operand_op1(204337)]
// The following ten tests were added due key not found in preimage (verify_game contract function related)
#[case::key_not_found_in_preimage_0(237025)]
#[case::key_not_found_in_preimage_1(237030)]
#[case::key_not_found_in_preimage_2(237037)]
#[case::key_not_found_in_preimage_3(237042)]
#[case::key_not_found_in_preimage_4(237044)]
#[case::key_not_found_in_preimage_5(237053)]
#[case::key_not_found_in_preimage_6(237083)]
#[case::key_not_found_in_preimage_7(237086)]
#[case::key_not_found_in_preimage_8(235385)]
#[case::key_not_found_in_preimage_9(235620)]
// Reference pies for v0.13.3
#[case::reference_pie_with_full_output_enabled_00(341097)]
#[case::reference_pie_with_full_output_enabled_01(341101)]
#[case::reference_pie_with_full_output_enabled_02(355710)]
#[case::reference_pie_with_full_output_enabled_03(355783)]
#[case::reference_pie_with_full_output_enabled_04(355802)]
#[ignore = "Requires a running Pathfinder node"]
#[tokio::test(flavor = "multi_thread")]
async fn test_prove_selected_blocks(#[case] block_number: u64) {
Expand All @@ -98,7 +114,11 @@ async fn test_prove_selected_blocks(#[case] block_number: u64) {

fn get_reference_pie_bytes(block_number: u64) -> Option<Vec<u8>> {
match block_number {
173404 => Some(include_bytes!("../reference-pies/173404.zip").to_vec()),
341097 => Some(include_bytes!("../reference-pies/341097.zip").to_vec()),
341101 => Some(include_bytes!("../reference-pies/341101.zip").to_vec()),
355710 => Some(include_bytes!("../reference-pies/355710.zip").to_vec()),
355783 => Some(include_bytes!("../reference-pies/355783.zip").to_vec()),
355802 => Some(include_bytes!("../reference-pies/355802.zip").to_vec()),
_ => None,
}
}
4 changes: 2 additions & 2 deletions crates/rpc-client/src/pathfinder/proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl TrieNode {
}
}

#[derive(Debug, Clone, Deserialize)]
#[derive(Debug, Clone, Deserialize, Default)]
pub struct ContractData {
/// Root of the Contract state tree
pub root: Felt,
Expand Down Expand Up @@ -75,7 +75,7 @@ impl ContractData {

#[derive(Debug, Clone, Deserialize)]
pub struct PathfinderProof {
pub state_commitment: Felt,
pub state_commitment: Option<Felt>,
pub class_commitment: Option<Felt>,
pub contract_proof: Vec<TrieNode>,
pub contract_data: Option<ContractData>,
Expand Down
26 changes: 11 additions & 15 deletions crates/starknet-os/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ pub const fn default_layout() -> LayoutName {
LayoutName::all_cairo
}

// https://github.com/starkware-libs/blockifier/blob/8da582b285bfbc7d4c21178609bbd43f80a69240/crates/native_blockifier/src/py_block_executor.rs#L44
const MAX_STEPS_PER_TX: u32 = 4_000_000;
// The following values were taken from general_config.yml from cairo-lang
const VALIDATE_MAX_N_STEPS_OVERRIDE: u32 = 1000000;

const DEFAULT_CONFIG_PATH: &str = "../../cairo-lang/src/starkware/starknet/definitions/general_config.yml";
pub const STORED_BLOCK_HASH_BUFFER: u64 = 10;
Expand All @@ -32,9 +32,9 @@ pub const COMPILED_CLASS_HASH_COMMITMENT_TREE_HEIGHT: usize = 251;
pub const CONTRACT_STATES_COMMITMENT_TREE_HEIGHT: usize = 251;
pub const DEFAULT_INNER_TREE_HEIGHT: u64 = 64;
// TODO: update with relevant address
pub const DEFAULT_FEE_TOKEN_ADDR: &str = "482bc27fc5627bf974a72b65c43aa8a0464a70aab91ad8379b56a4f17a84c3";
pub const DEFAULT_DEPRECATED_FEE_TOKEN_ADDR: &str = "482bc27fc5627bf974a72b65c43aa8a0464a70aab91ad8379b56a4f17a84c3";
pub const SEQUENCER_ADDR_0_13_2: &str = "0x795488c127693ffb36733cc054f9e2be39241a794a4877dc8fc1dbe52750488";
pub const DEFAULT_FEE_TOKEN_ADDR: &str = "7ce4aa542d72a82662cda96b147da9b041ecf8c61f67ef657f3bbb852fc698f";
pub const DEFAULT_DEPRECATED_FEE_TOKEN_ADDR: &str = "5195ba458d98a8d5a390afa87e199566e473d1124c07a3c57bf19813255ac41";
pub const SEQUENCER_ADDR_0_13_3: &str = "0x31c641e041f8d25997985b0efe68d0c5ce89d418ca9a127ae043aebed6851c5";
pub const CONTRACT_ADDRESS_BITS: usize = 251;
pub const CONTRACT_CLASS_LEAF_VERSION: &[u8] = "CONTRACT_CLASS_LEAF_V0".as_bytes();

Expand Down Expand Up @@ -67,8 +67,7 @@ const fn default_use_kzg_da() -> bool {
pub struct StarknetGeneralConfig {
pub starknet_os_config: StarknetOsConfig,
pub gas_price_bounds: GasPriceBounds,
pub invoke_tx_max_n_steps: u32,
pub validate_max_n_steps: u32,
pub validate_max_n_steps_override: u32,
pub default_eth_price_in_fri: u128,
pub sequencer_address: ContractAddress,
pub enforce_l1_handler_fee: bool,
Expand All @@ -92,10 +91,9 @@ impl Default for StarknetGeneralConfig {
min_wei_l1_data_gas_price: 100000,
min_wei_l1_gas_price: 10000000000,
},
invoke_tx_max_n_steps: MAX_STEPS_PER_TX,
validate_max_n_steps: MAX_STEPS_PER_TX,
validate_max_n_steps_override: VALIDATE_MAX_N_STEPS_OVERRIDE,
default_eth_price_in_fri: 1_000_000_000_000_000_000_000,
sequencer_address: contract_address!(SEQUENCER_ADDR_0_13_2),
sequencer_address: contract_address!(SEQUENCER_ADDR_0_13_3),
enforce_l1_handler_fee: true,
use_kzg_da: false,
}
Expand All @@ -114,8 +112,7 @@ impl StarknetGeneralConfig {

pub fn empty_block_context(&self) -> BlockContext {
let mut versioned_constants = VersionedConstants::default();
versioned_constants.invoke_tx_max_n_steps = self.invoke_tx_max_n_steps;
versioned_constants.validate_max_n_steps = self.validate_max_n_steps;

versioned_constants.max_recursion_depth = 50;

let block_info = BlockInfo {
Expand Down Expand Up @@ -171,15 +168,14 @@ mod tests {

#[test]
fn parse_starknet_config() {
let expected_seq_addr = contract_address!(SEQUENCER_ADDR_0_13_2);
let expected_seq_addr = contract_address!(SEQUENCER_ADDR_0_13_3);

let conf = StarknetGeneralConfig::from_default_file().expect("Failed to load default config file");

assert!(conf.enforce_l1_handler_fee);

assert_eq!(1000000, conf.invoke_tx_max_n_steps);
assert_eq!(1000000000000000000000, conf.default_eth_price_in_fri);
assert_eq!(1000000, conf.validate_max_n_steps);
assert_eq!(1000000, conf.validate_max_n_steps_override);

assert_eq!(expected_seq_addr, conf.sequencer_address);
}
Expand Down
Loading

0 comments on commit b957c01

Please sign in to comment.