Skip to content

Commit 73f5b9d

Browse files
starknet_os_runner: fetch base block data
1 parent abcff6b commit 73f5b9d

File tree

9 files changed

+107
-47
lines changed

9 files changed

+107
-47
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/blockifier_reexecution/src/state_reader/rpc_state_reader.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ impl Default for RetryConfig {
9999

100100
#[derive(Clone)]
101101
pub struct RpcStateReader {
102-
pub(crate) rpc_state_reader: GatewayRpcStateReader,
102+
pub rpc_state_reader: GatewayRpcStateReader,
103103
pub(crate) retry_config: RetryConfig,
104-
pub(crate) chain_id: ChainId,
104+
pub chain_id: ChainId,
105105
#[allow(dead_code)]
106106
pub(crate) contract_class_mapping_dumper: Arc<Mutex<Option<StarknetContractClassMapping>>>,
107107
}

crates/starknet_api/src/block_hash/block_hash_calculator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ pub async fn calculate_block_commitments(
312312
// transaction_count (64 bits) | event_count (64 bits) | state_diff_length (64 bits)
313313
// | L1 data availability mode: 0 for calldata, 1 for blob (1 bit) | 0 ...
314314
// ].
315-
pub(crate) fn concat_counts(
315+
pub fn concat_counts(
316316
transaction_count: usize,
317317
event_count: usize,
318318
state_diff_length: usize,

crates/starknet_os_runner/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ description = "Runs transactions through the Starknet OS and returns Cairo PIE a
1010
cairo_native = ["blockifier/cairo_native"]
1111

1212
[dependencies]
13+
apollo_gateway.workspace = true
1314
async-trait.workspace = true
1415
blockifier.workspace = true
1516
blockifier_reexecution.workspace = true

crates/starknet_os_runner/src/errors.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ pub enum VirtualBlockExecutorError {
1010
#[error(transparent)]
1111
// Boxed to reduce the size of Result on the stack (ReexecutionError is >128 bytes).
1212
ReexecutionError(#[from] Box<ReexecutionError>),
13-
1413
#[error("Transaction execution failed: {0}")]
1514
TransactionExecutionError(String),
16-
1715
#[error("Block state unavailable after execution")]
1816
StateUnavailable,
1917
}

crates/starknet_os_runner/src/runner.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,16 @@ pub struct VirtualOsBlockInput {
3333
pub tx_execution_infos: Vec<CentralTransactionExecutionInfo>,
3434
pub block_info: BlockInfo,
3535
pub initial_reads: StateMaps,
36+
pub base_block_hash: BlockHash,
37+
pub base_block_header_commitments: BlockHeaderCommitments,
3638
pub prev_base_block_hash: BlockHash,
3739
pub compiled_classes: BTreeMap<CompiledClassHash, CasmContractClass>,
3840
}
3941

4042
impl From<VirtualOsBlockInput> for StarknetOsInput {
4143
fn from(virtual_os_block_input: VirtualOsBlockInput) -> Self {
4244
let os_block_input = OsBlockInput {
43-
block_hash_commitments: BlockHeaderCommitments::default(),
45+
block_hash_commitments: virtual_os_block_input.base_block_header_commitments,
4446
contract_state_commitment_info: virtual_os_block_input.contract_state_commitment_info,
4547
address_to_storage_commitment_info: virtual_os_block_input
4648
.address_to_storage_commitment_info,
@@ -64,7 +66,7 @@ impl From<VirtualOsBlockInput> for StarknetOsInput {
6466
block_info: virtual_os_block_input.block_info,
6567
initial_reads: virtual_os_block_input.initial_reads,
6668
declared_class_hash_to_component_hashes: HashMap::new(),
67-
new_block_hash: BlockHash::default(),
69+
new_block_hash: virtual_os_block_input.base_block_hash,
6870
old_block_number_and_hash: None,
6971
class_hashes_to_migrate: Vec::new(),
7072
};
@@ -114,7 +116,7 @@ where
114116
)?;
115117

116118
// Extract chain info from block context.
117-
let chain_info = execution_data.block_context.chain_info();
119+
let chain_info = execution_data.base_block_info.block_context.chain_info();
118120
let os_chain_info = OsChainInfo {
119121
chain_id: chain_info.chain_id.clone(),
120122
strk_fee_token_address: chain_info.fee_token_addresses.strk_fee_token_address,
@@ -148,9 +150,13 @@ where
148150
.classes_trie_commitment_info,
149151
transactions: txs,
150152
tx_execution_infos,
151-
block_info: execution_data.block_context.block_info().clone(),
153+
block_info: execution_data.base_block_info.block_context.block_info().clone(),
152154
initial_reads: execution_data.initial_reads,
153-
prev_base_block_hash: execution_data.prev_base_block_hash,
155+
base_block_hash: execution_data.base_block_info.base_block_hash,
156+
base_block_header_commitments: execution_data
157+
.base_block_info
158+
.base_block_header_commitments,
159+
prev_base_block_hash: execution_data.base_block_info.prev_base_block_hash,
154160
compiled_classes: classes.compiled_classes,
155161
};
156162

crates/starknet_os_runner/src/storage_proofs_test.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ use blockifier::context::BlockContext;
44
use blockifier::state::cached_state::StateMaps;
55
use rstest::rstest;
66
use starknet_api::block::{BlockHash, BlockNumber};
7+
use starknet_api::block_hash::block_hash_calculator::BlockHeaderCommitments;
78
use starknet_api::core::ContractAddress;
89
use starknet_api::state::StorageKey;
910
use starknet_rust::providers::Provider;
1011
use starknet_types_core::felt::Felt;
1112

1213
use crate::storage_proofs::{RpcStorageProofsProvider, StorageProofProvider};
1314
use crate::test_utils::{rpc_provider, STRK_TOKEN_ADDRESS};
14-
use crate::virtual_block_executor::VirtualBlockExecutionData;
15+
use crate::virtual_block_executor::{BaseBlockInfo, VirtualBlockExecutionData};
1516

1617
/// Fixture: Creates initial reads with the STRK contract and storage slot 0.
1718
#[rstest::fixture]
@@ -44,10 +45,14 @@ fn test_get_storage_proofs_from_rpc(
4445

4546
let execution_data = VirtualBlockExecutionData {
4647
execution_outputs: vec![],
47-
block_context: BlockContext::create_for_account_testing(),
48+
base_block_info: BaseBlockInfo {
49+
block_context: BlockContext::create_for_account_testing(),
50+
base_block_hash: BlockHash::default(),
51+
prev_base_block_hash: BlockHash::default(),
52+
base_block_header_commitments: BlockHeaderCommitments::default(),
53+
},
4854
initial_reads: state_maps,
4955
executed_class_hashes: HashSet::new(),
50-
prev_base_block_hash: BlockHash::default(),
5156
};
5257

5358
let result = runtime.block_on(async {

crates/starknet_os_runner/src/virtual_block_executor.rs

Lines changed: 82 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
use std::collections::HashSet;
22

3+
use apollo_gateway::rpc_objects::BlockHeader;
34
use blockifier::blockifier::config::TransactionExecutorConfig;
45
use blockifier::blockifier::transaction_executor::{
56
TransactionExecutionOutput,
67
TransactionExecutor,
78
};
9+
use blockifier::blockifier_versioned_constants::VersionedConstants;
10+
use blockifier::bouncer::BouncerConfig;
811
use blockifier::context::BlockContext;
912
use blockifier::state::cached_state::{CachedState, StateMaps};
1013
use blockifier::state::contract_class_manager::ContractClassManager;
@@ -14,29 +17,88 @@ use blockifier::state::state_reader_and_contract_manager::{
1417
};
1518
use blockifier::transaction::account_transaction::ExecutionFlags;
1619
use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction;
17-
use blockifier_reexecution::state_reader::reexecution_state_reader::ReexecutionStateReader;
1820
use blockifier_reexecution::state_reader::rpc_state_reader::RpcStateReader;
19-
use starknet_api::block::{BlockHash, BlockNumber};
21+
use blockifier_reexecution::utils::get_chain_info;
22+
use starknet_api::block::{BlockHash, BlockInfo, BlockNumber};
23+
use starknet_api::block_hash::block_hash_calculator::{concat_counts, BlockHeaderCommitments};
2024
use starknet_api::core::{ChainId, ClassHash};
2125
use starknet_api::transaction::fields::Fee;
2226
use starknet_api::transaction::{InvokeTransaction, Transaction, TransactionHash};
27+
use starknet_api::versioned_constants_logic::VersionedConstantsTrait;
2328

2429
use crate::errors::VirtualBlockExecutorError;
2530

2631
/// Captures execution data for a virtual block (multiple transactions).
2732
///
2833
/// This struct contains all the execution data needed for proof generation.
34+
pub struct BaseBlockInfo {
35+
pub(crate) block_context: BlockContext,
36+
/// The block hash of the base block,
37+
/// in which the virtual block is executed.
38+
pub(crate) base_block_hash: BlockHash,
39+
/// The commitment used for computing the block hash of the base block.
40+
pub(crate) base_block_header_commitments: BlockHeaderCommitments,
41+
/// The block hash of the previous base block.
42+
/// Used to compute the base block hash in the os.
43+
pub(crate) prev_base_block_hash: BlockHash,
44+
}
45+
46+
impl TryFrom<(BlockHeader, ChainId)> for BaseBlockInfo {
47+
type Error = VirtualBlockExecutorError;
48+
49+
fn try_from((header, chain_id): (BlockHeader, ChainId)) -> Result<Self, Self::Error> {
50+
let base_block_hash = header.block_hash;
51+
let prev_base_block_hash = header.parent_hash;
52+
let base_block_header_commitments = BlockHeaderCommitments {
53+
transaction_commitment: header.transaction_commitment,
54+
event_commitment: header.event_commitment,
55+
receipt_commitment: header.receipt_commitment,
56+
state_diff_commitment: header.state_diff_commitment,
57+
concatenated_counts: concat_counts(
58+
header.transaction_count,
59+
header.event_count,
60+
header.state_diff_length,
61+
header.l1_da_mode,
62+
),
63+
};
64+
65+
let block_info: BlockInfo = header.try_into().map_err(|e| {
66+
VirtualBlockExecutorError::TransactionExecutionError(format!(
67+
"Failed to convert block header to block info: {e}"
68+
))
69+
})?;
70+
let chain_info = get_chain_info(&chain_id);
71+
let versioned_constants =
72+
VersionedConstants::get(&block_info.starknet_version).map_err(|e| {
73+
VirtualBlockExecutorError::TransactionExecutionError(format!(
74+
"Failed to get versioned constants: {e}"
75+
))
76+
})?;
77+
let block_context = BlockContext::new(
78+
block_info,
79+
chain_info,
80+
versioned_constants.clone(),
81+
BouncerConfig::default(),
82+
);
83+
84+
Ok(BaseBlockInfo {
85+
block_context,
86+
base_block_hash,
87+
base_block_header_commitments,
88+
prev_base_block_hash,
89+
})
90+
}
91+
}
92+
2993
pub struct VirtualBlockExecutionData {
3094
/// Execution outputs for all transactions in the virtual block.
3195
pub execution_outputs: Vec<TransactionExecutionOutput>,
32-
/// The block context in which the transactions were executed.
33-
pub block_context: BlockContext,
3496
/// The initial state reads (accessed state) during execution.
3597
pub initial_reads: StateMaps,
3698
/// The class hashes of all contracts executed in the virtual block.
3799
pub executed_class_hashes: HashSet<ClassHash>,
38-
/// The block hash of the state at the start of the virtual block.
39-
pub prev_base_block_hash: BlockHash,
100+
/// The base block info for the virtual block.
101+
pub base_block_info: BaseBlockInfo,
40102
}
41103

42104
/// Executes a virtual block of transactions.
@@ -85,9 +147,8 @@ pub trait VirtualBlockExecutor {
85147
txs: Vec<(InvokeTransaction, TransactionHash)>,
86148
) -> Result<VirtualBlockExecutionData, VirtualBlockExecutorError> {
87149
let blockifier_txs = self.convert_invoke_txs(txs)?;
88-
let block_context = self.block_context(block_number)?;
150+
let base_block_info = self.base_block_info(block_number)?;
89151
let state_reader = self.state_reader(block_number)?;
90-
let prev_base_block_hash = self.prev_base_block_hash(block_number)?;
91152

92153
// Create state reader with contract manager.
93154
let state_reader_and_contract_manager =
@@ -98,7 +159,7 @@ pub trait VirtualBlockExecutor {
98159
// Create executor WITHOUT preprocessing (no pre_process_block call).
99160
let mut transaction_executor = TransactionExecutor::new(
100161
block_state,
101-
block_context.clone(),
162+
base_block_info.block_context.clone(),
102163
TransactionExecutorConfig::default(),
103164
);
104165

@@ -131,10 +192,9 @@ pub trait VirtualBlockExecutor {
131192

132193
Ok(VirtualBlockExecutionData {
133194
execution_outputs,
134-
block_context,
195+
base_block_info,
135196
initial_reads,
136197
executed_class_hashes,
137-
prev_base_block_hash,
138198
})
139199
}
140200

@@ -169,17 +229,12 @@ pub trait VirtualBlockExecutor {
169229
})
170230
.collect()
171231
}
172-
/// Returns the block context for the given block number.
173-
fn block_context(
174-
&self,
175-
block_number: BlockNumber,
176-
) -> Result<BlockContext, VirtualBlockExecutorError>;
177232

178-
/// Returns the block hash of the state at the start of the virtual block.
179-
fn prev_base_block_hash(
233+
/// Returns the base block info for the given block number.
234+
fn base_block_info(
180235
&self,
181236
block_number: BlockNumber,
182-
) -> Result<BlockHash, VirtualBlockExecutorError>;
237+
) -> Result<BaseBlockInfo, VirtualBlockExecutorError>;
183238

184239
/// Returns a state reader that implements `FetchCompiledClasses` for the given block number.
185240
/// Must be `Send + Sync + 'static` to be used in the transaction executor.
@@ -194,6 +249,7 @@ pub trait VirtualBlockExecutor {
194249

195250
#[allow(dead_code)]
196251
pub(crate) struct RpcVirtualBlockExecutor {
252+
/// The state reader for the virtual block executor.
197253
pub rpc_state_reader: RpcStateReader,
198254
/// Whether transaction validation is enabled during execution.
199255
pub validate_txs: bool,
@@ -219,22 +275,15 @@ impl RpcVirtualBlockExecutor {
219275
/// without block preprocessing. Validation and fee charging are always skipped,
220276
/// making it suitable for simulation and OS input generation.
221277
impl VirtualBlockExecutor for RpcVirtualBlockExecutor {
222-
fn block_context(
278+
fn base_block_info(
223279
&self,
224280
_block_number: BlockNumber,
225-
) -> Result<BlockContext, VirtualBlockExecutorError> {
226-
self.rpc_state_reader
227-
.get_block_context()
228-
.map_err(|e| VirtualBlockExecutorError::ReexecutionError(Box::new(e)))
229-
}
230-
231-
fn prev_base_block_hash(
232-
&self,
233-
block_number: BlockNumber,
234-
) -> Result<BlockHash, VirtualBlockExecutorError> {
235-
self.rpc_state_reader
236-
.get_old_block_hash(block_number)
237-
.map_err(|e| VirtualBlockExecutorError::ReexecutionError(Box::new(e)))
281+
) -> Result<BaseBlockInfo, VirtualBlockExecutorError> {
282+
let block_header = self
283+
.rpc_state_reader
284+
.get_block_header()
285+
.map_err(|e| VirtualBlockExecutorError::ReexecutionError(Box::new(e)))?;
286+
BaseBlockInfo::try_from((block_header, self.rpc_state_reader.chain_id.clone()))
238287
}
239288

240289
fn state_reader(

crates/starknet_os_runner/src/virtual_block_executor_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ fn test_execute_constructed_balance_of_transaction(
124124

125125
// Verify block context was captured.
126126
assert_eq!(
127-
result.block_context.block_info().block_number,
127+
result.base_block_info.block_context.block_info().block_number,
128128
BlockNumber(TEST_BLOCK_NUMBER),
129129
"Block context should have the correct block number"
130130
);

0 commit comments

Comments
 (0)