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
41 changes: 22 additions & 19 deletions crates/apollo_batcher/src/batcher_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ const PROPOSAL_ID: ProposalId = ProposalId(0);
const BUILD_BLOCK_FAIL_ON_ERROR: BlockBuilderError =
BlockBuilderError::FailOnError(FailOnErrorCause::BlockFull);

fn proposal_commitment() -> ProposalCommitment {
BlockExecutionArtifacts::create_for_testing().commitment()
async fn proposal_commitment() -> ProposalCommitment {
BlockExecutionArtifacts::create_for_testing().await.commitment()
}

fn propose_block_input(proposal_id: ProposalId) -> ProposeBlockInput {
Expand Down Expand Up @@ -420,12 +420,12 @@ async fn ignore_l1_handler_provider_not_ready(#[case] proposer: bool) {
mock_create_builder_for_propose_block(
&mut deps.block_builder_factory,
vec![],
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);
} else {
mock_create_builder_for_validate_block(
&mut deps.block_builder_factory,
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);
}
deps.l1_provider_client.expect_start_block().returning(|_, _| {
Expand Down Expand Up @@ -459,7 +459,7 @@ async fn consecutive_heights_success() {
mock_create_builder_for_propose_block(
&mut block_builder_factory,
vec![],
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);
}

Expand Down Expand Up @@ -497,7 +497,7 @@ async fn validate_block_full_flow() {
let recorder = PrometheusBuilder::new().build_recorder();
let _recorder_guard = metrics::set_default_local_recorder(&recorder);
let mut batcher = create_batcher_with_active_validate_block(Ok(
BlockExecutionArtifacts::create_for_testing(),
BlockExecutionArtifacts::create_for_testing().await,
))
.await;
let metrics = recorder.handle().render();
Expand All @@ -518,7 +518,9 @@ async fn validate_block_full_flow() {
};
assert_eq!(
batcher.send_proposal_content(finish_proposal).await.unwrap(),
SendProposalContentResponse { response: ProposalStatus::Finished(proposal_commitment()) }
SendProposalContentResponse {
response: ProposalStatus::Finished(proposal_commitment().await)
}
);
let metrics = recorder.handle().render();
assert_proposal_metrics(&metrics, 1, 1, 0, 0);
Expand Down Expand Up @@ -582,7 +584,7 @@ async fn send_proposal_content_after_finish_or_abort(
#[case] content: SendProposalContent,
) {
let mut batcher = create_batcher_with_active_validate_block(Ok(
BlockExecutionArtifacts::create_for_testing(),
BlockExecutionArtifacts::create_for_testing().await,
))
.await;

Expand Down Expand Up @@ -636,7 +638,7 @@ async fn propose_block_full_flow() {
mock_create_builder_for_propose_block(
&mut block_builder_factory,
expected_streamed_txs.clone(),
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);

let mut l1_provider_client = MockL1ProviderClient::new();
Expand Down Expand Up @@ -674,8 +676,9 @@ async fn propose_block_full_flow() {
commitment,
GetProposalContentResponse {
content: GetProposalContent::Finished {
id: proposal_commitment(),
id: proposal_commitment().await,
final_n_executed_txs: BlockExecutionArtifacts::create_for_testing()
.await
.final_n_executed_txs
}
}
Expand Down Expand Up @@ -703,7 +706,7 @@ async fn multiple_proposals_with_l1_every_n_proposals() {
mock_create_builder_for_propose_block(
&mut block_builder_factory,
expected_streamed_txs.clone(),
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);
}

Expand Down Expand Up @@ -796,11 +799,11 @@ async fn consecutive_proposal_generation_success() {
mock_create_builder_for_propose_block(
&mut block_builder_factory,
vec![],
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);
mock_create_builder_for_validate_block(
&mut block_builder_factory,
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);
}
let mut l1_provider_client = MockL1ProviderClient::new();
Expand Down Expand Up @@ -842,7 +845,7 @@ async fn concurrent_proposals_generation_fail() {
for _ in 0..2 {
mock_create_builder_for_validate_block(
&mut block_builder_factory,
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);
}
let mut batcher = start_batcher_with_active_validate(block_builder_factory).await;
Expand Down Expand Up @@ -874,7 +877,7 @@ async fn proposal_startup_failure_allows_new_proposals() {
let mut block_builder_factory = MockBlockBuilderFactoryTrait::new();
mock_create_builder_for_validate_block(
&mut block_builder_factory,
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);
let mut l1_provider_client = MockL1ProviderClient::new();
l1_provider_client.expect_start_block().returning(|_, _| Ok(()));
Expand Down Expand Up @@ -1069,7 +1072,7 @@ async fn decision_reached() {
let recorder = PrometheusBuilder::new().build_recorder();
let _recorder_guard = metrics::set_default_local_recorder(&recorder);
let mut mock_dependencies = MockDependencies::default();
let expected_artifacts = BlockExecutionArtifacts::create_for_testing();
let expected_artifacts = BlockExecutionArtifacts::create_for_testing().await;

mock_dependencies
.mempool_client
Expand Down Expand Up @@ -1110,7 +1113,7 @@ async fn decision_reached() {
mock_create_builder_for_propose_block(
&mut mock_dependencies.block_builder_factory,
vec![],
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);

let decision_reached_response =
Expand Down Expand Up @@ -1169,7 +1172,7 @@ async fn test_execution_info_order_is_kept() {
mock_dependencies.l1_provider_client.expect_commit_block().returning(|_, _, _| Ok(()));
mock_dependencies.storage_writer.expect_commit_proposal().returning(|_, _, _| Ok(()));

let block_builder_result = BlockExecutionArtifacts::create_for_testing();
let block_builder_result = BlockExecutionArtifacts::create_for_testing().await;
// Check that the execution_infos were initiated properly for this test.
let execution_infos = block_builder_result
.execution_data
Expand Down Expand Up @@ -1259,7 +1262,7 @@ async fn decision_reached_return_success_when_l1_commit_block_fails(
mock_create_builder_for_propose_block(
&mut mock_dependencies.block_builder_factory,
vec![],
Ok(BlockExecutionArtifacts::create_for_testing()),
Ok(BlockExecutionArtifacts::create_for_testing().await),
);

let result = batcher_propose_and_commit_block(mock_dependencies).await;
Expand Down
133 changes: 74 additions & 59 deletions crates/apollo_batcher/src/block_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ use starknet_api::block_hash::block_hash_calculator::{
PartialBlockHashComponents,
TransactionHashingData,
};
use starknet_api::block_hash::state_diff_hash::calculate_state_diff_hash;
use starknet_api::consensus_transaction::InternalConsensusTransaction;
use starknet_api::core::{ContractAddress, Nonce, SequencerContractAddress};
use starknet_api::data_availability::L1DataAvailabilityMode;
Expand Down Expand Up @@ -124,10 +123,59 @@ pub struct BlockExecutionArtifacts {
// The number of transactions executed by the proposer out of the transactions that were sent.
// This value includes rejected transactions.
pub final_n_executed_txs: usize,
pub block_info: BlockInfo,
partial_block_hash_components: PartialBlockHashComponents,
}

impl BlockExecutionArtifacts {
pub async fn new(
BlockExecutionSummary {
state_diff: commitment_state_diff,
compressed_state_diff,
bouncer_weights,
casm_hash_computation_data_sierra_gas,
casm_hash_computation_data_proving_gas,
compiled_class_hashes_for_migration,
block_info,
}: BlockExecutionSummary,
execution_data: BlockTransactionExecutionData,
final_n_executed_txs: usize,
) -> Self {
let l1_da_mode = L1DataAvailabilityMode::from_use_kzg_da(block_info.use_kzg_da);
let starknet_version = block_info.starknet_version;
let transactions_data =
prepare_txs_hashing_data(&execution_data.execution_infos_and_signatures);
let header_commitments = calculate_block_commitments(
&transactions_data,
commitment_state_diff_as_thin_state_diff(&commitment_state_diff),
l1_da_mode,
&starknet_version,
)
.await;
let partial_block_hash_components = PartialBlockHashComponents {
header_commitments,
block_number: block_info.block_number,
l1_gas_price: block_info.gas_prices.l1_gas_price_per_token(),
l1_data_gas_price: block_info.gas_prices.l1_data_gas_price_per_token(),
l2_gas_price: block_info.gas_prices.l2_gas_price_per_token(),
sequencer: SequencerContractAddress(block_info.sequencer_address),
timestamp: block_info.block_timestamp,
starknet_version,
};
let l2_gas_used = execution_data.l2_gas_used();
Self {
execution_data,
commitment_state_diff,
compressed_state_diff,
bouncer_weights,
l2_gas_used,
casm_hash_computation_data_sierra_gas,
casm_hash_computation_data_proving_gas,
compiled_class_hashes_for_migration,
final_n_executed_txs,
partial_block_hash_components,
}
}

pub fn address_to_nonce(&self) -> HashMap<ContractAddress, Nonce> {
HashMap::from_iter(
self.commitment_state_diff
Expand All @@ -142,49 +190,21 @@ impl BlockExecutionArtifacts {
}

pub fn thin_state_diff(&self) -> ThinStateDiff {
// TODO(Ayelet): Remove the clones.
let commitment_state_diff = self.commitment_state_diff.clone();
ThinStateDiff {
deployed_contracts: commitment_state_diff.address_to_class_hash,
storage_diffs: commitment_state_diff.storage_updates,
class_hash_to_compiled_class_hash: commitment_state_diff
.class_hash_to_compiled_class_hash,
nonces: commitment_state_diff.address_to_nonce,
// TODO(AlonH): Remove this when the structure of storage diffs changes.
deprecated_declared_classes: Vec::new(),
}
commitment_state_diff_as_thin_state_diff(&self.commitment_state_diff)
}

pub fn commitment(&self) -> ProposalCommitment {
ProposalCommitment {
state_diff_commitment: calculate_state_diff_hash(&self.thin_state_diff()),
state_diff_commitment: self
.partial_block_hash_components
.header_commitments
.state_diff_commitment,
}
}

// TODO(Nimrod): Consider caching this method.
/// Returns the [PartialBlockHashComponents] based on the execution artifacts.
pub async fn partial_block_hash_components(&self) -> PartialBlockHashComponents {
let l1_da_mode = L1DataAvailabilityMode::from_use_kzg_da(self.block_info.use_kzg_da);
let starknet_version = self.block_info.starknet_version;
let transactions_data =
prepare_txs_hashing_data(&self.execution_data.execution_infos_and_signatures);
let header_commitments = calculate_block_commitments(
&transactions_data,
self.thin_state_diff(),
l1_da_mode,
&starknet_version,
)
.await;
PartialBlockHashComponents {
header_commitments,
block_number: self.block_info.block_number,
l1_gas_price: self.block_info.gas_prices.l1_gas_price_per_token(),
l1_data_gas_price: self.block_info.gas_prices.l1_data_gas_price_per_token(),
l2_gas_price: self.block_info.gas_prices.l2_gas_price_per_token(),
sequencer: SequencerContractAddress(self.block_info.sequencer_address),
timestamp: self.block_info.block_timestamp,
starknet_version,
}
self.partial_block_hash_components.clone()
}
}

Expand All @@ -204,6 +224,22 @@ fn prepare_txs_hashing_data(
.collect()
}

fn commitment_state_diff_as_thin_state_diff(
commitment_state_diff: &CommitmentStateDiff,
) -> ThinStateDiff {
// TODO(Ayelet): Remove the clones.
ThinStateDiff {
deployed_contracts: commitment_state_diff.address_to_class_hash.clone(),
storage_diffs: commitment_state_diff.storage_updates.clone(),
class_hash_to_compiled_class_hash: commitment_state_diff
.class_hash_to_compiled_class_hash
.clone(),
nonces: commitment_state_diff.address_to_nonce.clone(),
// TODO(AlonH): Remove this when the structure of storage diffs changes.
deprecated_declared_classes: Vec::new(),
}
}

/// The BlockBuilderTrait is responsible for building a new block from transactions provided by the
/// tx_provider. The block building will stop at time deadline.
/// The transactions that were added to the block will be streamed to the output_content_sender.
Expand Down Expand Up @@ -406,16 +442,6 @@ impl BlockBuilder {
.await
.expect("Failed to spawn blocking executor task.")?;

let BlockExecutionSummary {
state_diff,
compressed_state_diff,
bouncer_weights,
casm_hash_computation_data_sierra_gas,
casm_hash_computation_data_proving_gas,
compiled_class_hashes_for_migration,
block_info,
} = block_summary;

let mut execution_data = std::mem::take(&mut self.execution_data);
if let Some(final_n_executed_txs) = final_n_executed_txs {
// Remove the transactions that were executed, but eventually not included in the block.
Expand All @@ -425,19 +451,8 @@ impl BlockBuilder {
self.block_txs[final_n_executed_txs..].iter().map(|tx| tx.tx_hash()).collect();
execution_data.remove_last_txs(&remove_tx_hashes);
}
let l2_gas_used = execution_data.l2_gas_used();
Ok(BlockExecutionArtifacts {
execution_data,
commitment_state_diff: state_diff,
compressed_state_diff,
bouncer_weights,
l2_gas_used,
casm_hash_computation_data_sierra_gas,
casm_hash_computation_data_proving_gas,
final_n_executed_txs: final_n_executed_txs_nonopt,
compiled_class_hashes_for_migration,
block_info,
})
Ok(BlockExecutionArtifacts::new(block_summary, execution_data, final_n_executed_txs_nonopt)
.await)
}

/// Returns the number of transactions that are currently being executed by the executor.
Expand Down
Loading
Loading