Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"account_deployment_data": [],
"proof_facts": [
"0x5649525455414c5f534e4f53",
"0x4",
"0x130206a40921880628605041292e995870334451179c63090221210893986a2",
"0x3",
"0x2",
"0x1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
],
"proof_facts": [
"0x5649525455414c5f534e4f53",
"0x4",
"0x130206a40921880628605041292e995870334451179c63090221210893986a2",
"0x3",
"0x2",
"0x1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"account_deployment_data": [],
"proof_facts": [
"0x5649525455414c5f534e4f53",
"0x4",
"0x130206a40921880628605041292e995870334451179c63090221210893986a2",
"0x3",
"0x2",
"0x1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"type": "INVOKE_FUNCTION",
"proof_facts": [
"0x5649525455414c5f534e4f53",
"0x4",
"0x130206a40921880628605041292e995870334451179c63090221210893986a2",
"0x3",
"0x2",
"0x1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ const RESERVED_CONTRACT_ADDRESS = 0x3;
// The block number -> block hash mapping is written for the current block number minus this number.
const STORED_BLOCK_HASH_BUFFER = 10;

// Allowed virtual OS program hashes for client-side proving.
const ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_0 = (
0x0130206a40921880628605041292e995870334451179c63090221210893986a2
);
const ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_LEN = 1;

// Gas constants.

const STEP_GAS_COST = 100;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ const RESERVED_CONTRACT_ADDRESS = {RESERVED_CONTRACT_ADDRESS};
// The block number -> block hash mapping is written for the current block number minus this number.
const STORED_BLOCK_HASH_BUFFER = {STORED_BLOCK_HASH_BUFFER};

// Allowed virtual OS program hashes for client-side proving.
{ALLOWED_VIRTUAL_OS_PROGRAM_HASHES}

// Gas constants.

const STEP_GAS_COST = {STEP_GAS_COST};
Expand Down
79 changes: 53 additions & 26 deletions crates/apollo_starknet_os_program/src/constants_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use apollo_infra_utils::compile_time_cargo_manifest_dir;
use blockifier::blockifier_versioned_constants::{OsConstants, VersionedConstants};
use blockifier::execution::syscalls::vm_syscall_utils::SyscallSelector;
use expect_test::expect_file;
use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector};
use starknet_api::core::{ContractAddress, EntryPointSelector};
use starknet_api::versioned_constants_logic::VersionedConstantsTrait;
use starknet_types_core::felt::Felt;

Expand All @@ -29,32 +29,49 @@ fn base_only_syscall_cost(selector: SyscallSelector, os_constants: &OsConstants)
fn quote_string(s: &str) -> String {
format!("'{s}'")
}

/// Create constants from a list of class hashes. Example:
/// Create Rust `const` definitions from a list of hashes (rendered as `Felt`s).
///
/// Example:
/// ```
/// let hashes = [ClassHash(1), ClassHash(2)];
///
/// let s = format_hash_consts("X", &hashes, |h| &h.0);
///
/// let expected = "\
/// const X_0 = 0x0000000000000000000000000000000000000000000000000000000000000001;\n
/// const X_1 = 0x0000000000000000000000000000000000000000000000000000000000000002;\n
/// const X_LEN = 2;";
///
/// assert_eq!(s, expected);
/// ```
/// let expected = #"
/// X_0 = 0x1;
/// X_1 = 0x2;
/// X_LEN = 2;
/// "#;
/// assert_eq!(stringify_class_hash_list("X", &[ClassHash(1), ClassHash(2)]), expected);
///
/// Conceptual output (simplified for readability):
/// ```text
/// const X_0 = 0x1;
/// const X_1 = 0x2;
/// const X_LEN = 2;
/// ```
fn stringify_class_hash_list(name: &str, class_hashes: &[ClassHash]) -> String {
class_hashes
fn format_hash_consts<T, F>(name: &str, hash_list: &[T], to_felt: F) -> String
where
F: Fn(&T) -> &Felt,
{
hash_list
.iter()
.enumerate()
.map(|(i, class_hash)| {
// If the line ends up longer than 100 chars, wrap the value in parenthesis, so the
// formatter can split the lines.
let line = format!("const {name}_{i} = {:#066x};", class_hash.0);
if line.len() > 100 {
format!("const {name}_{i} = ({:#066x});", class_hash.0)
.map(|(i, hash)| {
let felt = to_felt(hash);

// If the line ends up longer than 100 chars, wrap the value in parentheses so the
// formatter can split the line.
let const_def = format!("const {name}_{i} = {:#066x};", felt);
if const_def.len() > 100 {
format!("const {name}_{i} = ({:#066x});", felt)
} else {
line
const_def
}
})
.chain(std::iter::once(format!("const {name}_LEN = {};", class_hashes.len())))
.collect::<Vec<String>>()
.chain(std::iter::once(format!("const {name}_LEN = {};", hash_list.len())))
.collect::<Vec<_>>()
.join("\n")
}

Expand Down Expand Up @@ -96,6 +113,11 @@ fn generate_constants_file() -> String {
RESERVED_CONTRACT_ADDRESS = contract_address_to_hex(
&os_constants.os_contract_addresses.reserved_contract_address()
),
ALLOWED_VIRTUAL_OS_PROGRAM_HASHES = format_hash_consts(
"ALLOWED_VIRTUAL_OS_PROGRAM_HASHES",
&os_constants.allowed_virtual_os_program_hashes,
|felt| felt
),
// Base costs.
STEP_GAS_COST = os_constants.gas_costs.base.step_gas_cost,
MEMORY_HOLE_GAS_COST = os_constants.gas_costs.base.memory_hole_gas_cost,
Expand Down Expand Up @@ -190,18 +212,23 @@ fn generate_constants_file() -> String {
VALIDATE_TIMESTAMP_ROUNDING =
os_constants.validate_rounding_consts.validate_timestamp_rounding,
// Backward compatibility accounts.
V1_BOUND_ACCOUNTS_CAIRO0 = stringify_class_hash_list(
V1_BOUND_ACCOUNTS_CAIRO0 = format_hash_consts(
"V1_BOUND_ACCOUNTS_CAIRO0",
&os_constants.v1_bound_accounts_cairo0
&os_constants.v1_bound_accounts_cairo0,
|class_hash| &class_hash.0
),
V1_BOUND_ACCOUNTS_CAIRO1 = stringify_class_hash_list(
V1_BOUND_ACCOUNTS_CAIRO1 = format_hash_consts(
"V1_BOUND_ACCOUNTS_CAIRO1",
&os_constants.v1_bound_accounts_cairo1
&os_constants.v1_bound_accounts_cairo1,
|class_hash| &class_hash.0
),
V1_BOUND_ACCOUNTS_MAX_TIP =
format!("{:#?}", Felt::from(os_constants.v1_bound_accounts_max_tip)),
DATA_GAS_ACCOUNTS =
stringify_class_hash_list("DATA_GAS_ACCOUNTS", &os_constants.data_gas_accounts),
DATA_GAS_ACCOUNTS = format_hash_consts(
"DATA_GAS_ACCOUNTS",
&os_constants.data_gas_accounts,
|class_hash| &class_hash.0
),
);

// Format and return.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "100.0.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 0,
"bitwise": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "100.0.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 0,
"bitwise": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "100.0.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 0,
"bitwise": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "100.0.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 0,
"bitwise": 594,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "100.0.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 0,
"bitwise": 594,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "100.0.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 0,
"bitwise": 594,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "1.7.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 230,
"bitwise": 583,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "1.7.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 230,
"bitwise": 583,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "1.7.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 230,
"bitwise": 583,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "1.7.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 230,
"bitwise": 583,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"max_recursion_depth": 50,
"min_sierra_version_for_sierra_gas": "1.7.0",
"os_constants": {
"allowed_virtual_os_program_hashes": [],
"builtin_gas_costs": {
"add_mod": 230,
"bitwise": 583,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
"max_recursion_depth": 50,
"segment_arena_cells": false,
"os_constants": {
"allowed_virtual_os_program_hashes": [
"0x130206a40921880628605041292e995870334451179c63090221210893986a2"
],
"constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194",
"default_entry_point_selector": "0x0",
"entry_point_initial_budget": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
~ /enable_casm_hash_migration: false
+ /os_constants/allowed_virtual_os_program_hashes/0: "0x130206a40921880628605041292e995870334451179c63090221210893986a2"
11 changes: 11 additions & 0 deletions crates/blockifier/src/blockifier_versioned_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector};
use starknet_api::define_versioned_constants;
use starknet_api::executable_transaction::TransactionType;
use starknet_api::execution_resources::{GasAmount, GasVector};
use starknet_api::hash::StarkHash;
use starknet_api::transaction::fields::{hex_to_tip, GasVectorComputationMode, Tip};
use starknet_api::versioned_constants_logic::VersionedConstantsTrait;
use strum::IntoEnumIterator;
Expand Down Expand Up @@ -97,6 +98,9 @@ pub struct RawVersionedConstants {
#[derive(Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct RawOsConstants {
// Allowed virtual OS program hashes for client-side proving.
pub allowed_virtual_os_program_hashes: Vec<StarkHash>,

// Selectors.
pub constructor_entry_point_selector: EntryPointSelector,
pub default_entry_point_selector: EntryPointSelector,
Expand Down Expand Up @@ -240,6 +244,7 @@ pub struct VersionedConstants {
pub max_recursion_depth: usize,
pub validate_max_n_steps: u32,
pub min_sierra_version_for_sierra_gas: SierraVersion,

// BACKWARD COMPATIBILITY: If true, the segment_arena builtin instance counter will be
// multiplied by 3. This offsets a bug in the old vm where the counter counted the number of
// cells used by instances of the builtin, instead of the number of instances.
Expand Down Expand Up @@ -1097,6 +1102,9 @@ impl GasCosts {
pub struct OsConstants {
pub gas_costs: GasCosts,

// Allowed virtual OS program hashes for client-side proving.
pub allowed_virtual_os_program_hashes: Vec<StarkHash>,

// Selectors.
pub constructor_entry_point_selector: EntryPointSelector,
pub default_entry_point_selector: EntryPointSelector,
Expand Down Expand Up @@ -1177,6 +1185,9 @@ impl OsConstants {

Self {
gas_costs,
allowed_virtual_os_program_hashes: raw_constants
.allowed_virtual_os_program_hashes
.clone(),
constructor_entry_point_selector: raw_constants.constructor_entry_point_selector,
default_entry_point_selector: raw_constants.default_entry_point_selector,
execute_entry_point_selector: raw_constants.execute_entry_point_selector,
Expand Down
19 changes: 15 additions & 4 deletions crates/blockifier/src/transaction/account_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use starknet_api::transaction::{constants, TransactionHash, TransactionVersion};
use starknet_types_core::felt::Felt;

use super::errors::ResourceBoundsError;
use crate::blockifier_versioned_constants::OsConstants;
use crate::context::{BlockContext, GasCounter, TransactionContext};
use crate::execution::call_info::CallInfo;
use crate::execution::common_hints::ExecutionMode;
Expand Down Expand Up @@ -246,15 +247,25 @@ impl AccountTransaction {
}
}

fn validate_proof_facts(&self) -> TransactionPreValidationResult<()> {
fn validate_proof_facts(
&self,
os_constants: &OsConstants,
) -> TransactionPreValidationResult<()> {
if let Transaction::Invoke(tx) = &self.tx {
if tx.tx.version() == TransactionVersion::THREE {
let proof_facts_variant = ProofFactsVariant::try_from(&tx.tx.proof_facts())
.map_err(|e| TransactionPreValidationError::InvalidProofFacts(e.to_string()))?;
match proof_facts_variant {
ProofFactsVariant::Empty => {}
ProofFactsVariant::Snos(_snos_proof_facts) => {
// TODO(Meshi/ AvivG): add proof facts validations.
ProofFactsVariant::Snos(snos_proof_facts) => {
// Validates the proof facts program hash.
let allowed = &os_constants.allowed_virtual_os_program_hashes;
if !allowed.contains(&snos_proof_facts.program_hash) {
return Err(TransactionPreValidationError::InvalidProofFacts(format!(
"Virtual OS program hash {} is not allowed",
snos_proof_facts.program_hash
)));
}
}
}
}
Expand All @@ -278,7 +289,7 @@ impl AccountTransaction {
verify_can_pay_committed_bounds(state, tx_context).map_err(Box::new)?;
}

self.validate_proof_facts()?;
self.validate_proof_facts(&tx_context.block_context.versioned_constants.os_constants)?;

Ok(())
}
Expand Down
Loading
Loading