Skip to content

Commit a06d156

Browse files
Merge branch 'starkware-libs:main' into main
2 parents 061ef9d + 1ac0693 commit a06d156

File tree

211 files changed

+106435
-10125
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

211 files changed

+106435
-10125
lines changed

Cargo.lock

Lines changed: 9 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/papyrus/default_config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@
159159
"pointer_target": "chain_id",
160160
"privacy": "Public"
161161
},
162+
"context.constant_l2_gas_price": {
163+
"description": "If true, sets STRK gas price to its minimum price from the versioned constants.",
164+
"privacy": "Public",
165+
"value": false
166+
},
162167
"context.l1_da_mode": {
163168
"description": "The data availability mode, true: Blob, false: Calldata.",
164169
"privacy": "Public",

crates/apollo_batcher/src/batcher.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ use crate::metrics::{
6767
LAST_SYNCED_BLOCK,
6868
REJECTED_TRANSACTIONS,
6969
REVERTED_BLOCKS,
70+
REVERTED_TRANSACTIONS,
7071
STORAGE_HEIGHT,
7172
SYNCED_TRANSACTIONS,
7273
};
@@ -572,6 +573,15 @@ impl Batcher {
572573
let n_rejected_txs =
573574
u64::try_from(block_execution_artifacts.execution_data.rejected_tx_hashes.len())
574575
.expect("Number of rejected transactions should fit in u64");
576+
let n_reverted_count = u64::try_from(
577+
block_execution_artifacts
578+
.execution_data
579+
.execution_infos
580+
.values()
581+
.filter(|info| info.revert_error.is_some())
582+
.count(),
583+
)
584+
.expect("Number of reverted transactions should fit in u64");
575585
self.commit_proposal_and_block(
576586
height,
577587
state_diff.clone(),
@@ -585,6 +595,7 @@ impl Batcher {
585595
LAST_BATCHED_BLOCK.set_lossy(height.0);
586596
BATCHED_TRANSACTIONS.increment(n_txs);
587597
REJECTED_TRANSACTIONS.increment(n_rejected_txs);
598+
REVERTED_TRANSACTIONS.increment(n_reverted_count);
588599

589600
Ok(DecisionReachedResponse {
590601
state_diff,

crates/apollo_batcher/src/batcher_test.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ use crate::metrics::{
6464
PROPOSAL_SUCCEEDED,
6565
REJECTED_TRANSACTIONS,
6666
REVERTED_BLOCKS,
67+
REVERTED_TRANSACTIONS,
6768
STORAGE_HEIGHT,
6869
SYNCED_TRANSACTIONS,
6970
};
@@ -525,10 +526,10 @@ async fn send_content_to_unknown_proposal(#[case] content: SendProposalContent)
525526
}
526527

527528
#[rstest]
528-
#[case::send_txs(SendProposalContent::Txs(test_txs(0..1)), ProposalStatus::InvalidProposal)]
529+
#[case::send_txs(SendProposalContent::Txs(test_txs(0..1)), ProposalStatus::InvalidProposal("Block is full".to_string()))]
529530
#[case::send_finish(
530531
SendProposalContent::Finish(DUMMY_FINAL_N_EXECUTED_TXS),
531-
ProposalStatus::InvalidProposal
532+
ProposalStatus::InvalidProposal("Block is full".to_string())
532533
)]
533534
#[case::send_abort(SendProposalContent::Abort, ProposalStatus::Aborted)]
534535
#[tokio::test]
@@ -1046,6 +1047,17 @@ async fn decision_reached() {
10461047
REJECTED_TRANSACTIONS.parse_numeric_metric::<usize>(&metrics),
10471048
Some(expected_artifacts.execution_data.rejected_tx_hashes.len())
10481049
);
1050+
assert_eq!(
1051+
REVERTED_TRANSACTIONS.parse_numeric_metric::<usize>(&metrics),
1052+
Some(
1053+
expected_artifacts
1054+
.execution_data
1055+
.execution_infos
1056+
.values()
1057+
.filter(|info| info.revert_error.is_some())
1058+
.count(),
1059+
)
1060+
);
10491061
}
10501062

10511063
#[rstest]

crates/apollo_batcher/src/block_builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ impl BlockBuilder {
365365
Err(e @ TransactionProviderError::L1HandlerTransactionValidationFailed { .. })
366366
if self.execution_params.is_validator =>
367367
{
368+
warn!("Failed to validate L1 Handler transaction: {:?}", e);
368369
return Err(BlockBuilderError::FailOnError(L1HandlerTransactionValidationFailed(
369370
e,
370371
)));

crates/apollo_batcher/src/metrics.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ define_metrics!(
1717
// Transactions
1818
MetricCounter { BATCHED_TRANSACTIONS, "batcher_batched_transactions", "Counter of batched transactions across all forks", init = 0 },
1919
MetricCounter { REJECTED_TRANSACTIONS, "batcher_rejected_transactions", "Counter of rejected transactions", init = 0 },
20+
MetricCounter { REVERTED_TRANSACTIONS, "batcher_reverted_transactions", "Counter of reverted transactions across all forks", init = 0 },
2021
MetricCounter { SYNCED_TRANSACTIONS, "batcher_synced_transactions", "Counter of synced transactions", init = 0 },
2122

2223
MetricCounter { FULL_BLOCKS, "batcher_full_blocks", "Counter of blocks closed on full capacity", init = 0 },
@@ -39,6 +40,7 @@ pub fn register_metrics(storage_height: BlockNumber) {
3940

4041
BATCHED_TRANSACTIONS.register();
4142
REJECTED_TRANSACTIONS.register();
43+
REVERTED_TRANSACTIONS.register();
4244
SYNCED_TRANSACTIONS.register();
4345

4446
FULL_BLOCKS.register();

crates/apollo_batcher/src/pre_confirmed_block_writer.rs

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ use indexmap::map::Entry;
1313
use indexmap::IndexMap;
1414
#[cfg(test)]
1515
use mockall::automock;
16+
use reqwest::StatusCode;
1617
use serde::{Deserialize, Serialize};
1718
use starknet_api::block::BlockNumber;
1819
use starknet_api::consensus_transaction::InternalConsensusTransaction;
1920
use starknet_api::transaction::TransactionHash;
2021
use thiserror::Error;
21-
use tracing::info;
22+
use tracing::{error, info};
2223

2324
use crate::cende_client_types::{
2425
CendeBlockMetadata,
@@ -146,7 +147,7 @@ impl PreconfirmedBlockWriterTrait for PreconfirmedBlockWriter {
146147
// We initially mark that we have pending changes so that the client will write to the
147148
// Cende recorder that a new proposal round has started.
148149
let mut pending_changes = true;
149-
let mut write_iteration: u64 = 0;
150+
let mut next_write_iteration = 0;
150151

151152
loop {
152153
tokio::select! {
@@ -156,15 +157,22 @@ impl PreconfirmedBlockWriterTrait for PreconfirmedBlockWriter {
156157
// TODO(noamsp): Extract to a function.
157158
let pre_confirmed_block = self.create_pre_confirmed_block(
158159
&transactions_map,
159-
write_iteration,
160+
next_write_iteration,
160161
);
161162
pending_tasks.push(self.cende_client.write_pre_confirmed_block(pre_confirmed_block));
162-
write_iteration += 1;
163+
next_write_iteration += 1;
163164
pending_changes = false;
164165
}
165166
}
166-
// TODO(noamsp): Handle height/round mismatch by immediately exiting the loop; All the other writes will be rejected as well.
167-
Some(_) = pending_tasks.next() => {}
167+
168+
Some(result) = pending_tasks.next() => {
169+
if let Err(error) = result {
170+
if is_round_mismatch_error(&error, next_write_iteration) {
171+
pending_tasks.clear();
172+
return Err(error.into());
173+
}
174+
}
175+
}
168176
msg = self.pre_confirmed_tx_receiver.recv() => {
169177
match msg {
170178
Some((tx, tx_receipt, tx_state_diff)) => {
@@ -205,19 +213,53 @@ impl PreconfirmedBlockWriterTrait for PreconfirmedBlockWriter {
205213

206214
if pending_changes {
207215
let pre_confirmed_block =
208-
self.create_pre_confirmed_block(&transactions_map, write_iteration);
216+
self.create_pre_confirmed_block(&transactions_map, next_write_iteration);
209217
self.cende_client.write_pre_confirmed_block(pre_confirmed_block).await?
210218
}
211219

212220
// Wait for all pending tasks to complete gracefully.
213-
// TODO(noamsp): Add error handling and timeout.
214-
while pending_tasks.next().await.is_some() {}
221+
// TODO(noamsp): Add timeout.
222+
while let Some(result) = pending_tasks.next().await {
223+
if let Err(error) = result {
224+
if is_round_mismatch_error(&error, next_write_iteration) {
225+
pending_tasks.clear();
226+
return Err(error.into());
227+
}
228+
}
229+
}
215230
info!("Pre confirmed block writer finished");
216231

217232
Ok(())
218233
}
219234
}
220235

236+
fn is_round_mismatch_error(
237+
error: &PreconfirmedCendeClientError,
238+
next_write_iteration: u64,
239+
) -> bool {
240+
let PreconfirmedCendeClientError::CendeRecorderError {
241+
block_number,
242+
round,
243+
write_iteration,
244+
status_code,
245+
} = error
246+
else {
247+
return false;
248+
};
249+
250+
// A bad request status indicates a round or write iteration mismatch. The latest request can
251+
// receive a bad request status only if it is due to a round mismatch.
252+
if *status_code == StatusCode::BAD_REQUEST && *write_iteration == next_write_iteration - 1 {
253+
error!(
254+
"A higher round was detected for block_number: {}. rejected round: {}. Stopping \
255+
pre-confirmed block writer.",
256+
block_number, round,
257+
);
258+
return true;
259+
}
260+
false
261+
}
262+
221263
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Copy)]
222264
pub struct PreconfirmedBlockWriterConfig {
223265
pub channel_buffer_capacity: usize,

crates/apollo_batcher/src/pre_confirmed_cende_client.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use apollo_batcher_types::batcher_types::Round;
44
use apollo_config::dumping::{ser_param, SerializeConfig};
55
use apollo_config::{ParamPath, ParamPrivacyInput, SerializedParam};
66
use async_trait::async_trait;
7-
use reqwest::Client;
7+
use reqwest::{Client, StatusCode};
88
use serde::{Deserialize, Serialize};
99
use starknet_api::block::BlockNumber;
1010
use thiserror::Error;
@@ -15,12 +15,19 @@ use crate::cende_client_types::CendePreconfirmedBlock;
1515
use crate::metrics::PRECONFIRMED_BLOCK_WRITTEN;
1616

1717
#[derive(Debug, Error)]
18-
// TODO(noamsp): add block number/round mismatch and handle it in the client implementation.
1918
pub enum PreconfirmedCendeClientError {
2019
#[error(transparent)]
2120
RequestError(#[from] reqwest::Error),
22-
#[error("CendeRecorder returned an error: {0}")]
23-
CendeRecorderError(String),
21+
#[error(
22+
"Cende recorder returned an error. block_number: {block_number}, round: {round}, \
23+
write_iteration: {write_iteration}, status_code: {status_code}."
24+
)]
25+
CendeRecorderError {
26+
block_number: BlockNumber,
27+
round: Round,
28+
write_iteration: u64,
29+
status_code: StatusCode,
30+
},
2431
}
2532

2633
pub type PreconfirmedCendeClientResult<T> = Result<T, PreconfirmedCendeClientError>;
@@ -101,13 +108,15 @@ impl PreconfirmedCendeClientTrait for PreconfirmedCendeClient {
101108
let block_number = pre_confirmed_block.block_number;
102109
let round = pre_confirmed_block.round;
103110
let write_iteration = pre_confirmed_block.write_iteration;
111+
let number_of_txs = pre_confirmed_block.pre_confirmed_block.transactions.len();
104112

105113
let request_builder =
106114
self.client.post(self.write_pre_confirmed_block_url.clone()).json(&pre_confirmed_block);
107115

108116
trace!(
109117
"Sending write_pre_confirmed_block request to Cende recorder. \
110-
block_number={block_number}, round={round}, write_iteration={write_iteration}",
118+
block_number={block_number}, round={round}, write_iteration={write_iteration}. The \
119+
block contains {number_of_txs} transactions.",
111120
);
112121

113122
let response = request_builder.send().await?;
@@ -121,12 +130,17 @@ impl PreconfirmedCendeClientTrait for PreconfirmedCendeClient {
121130
PRECONFIRMED_BLOCK_WRITTEN.increment(1);
122131
Ok(())
123132
} else {
124-
let error_msg = format!(
133+
warn!(
125134
"write_pre_confirmed_block request failed. block_number={block_number}, \
126135
round={round}, write_iteration={write_iteration}, status={response_status}",
127136
);
128-
warn!("{error_msg}");
129-
Err(PreconfirmedCendeClientError::CendeRecorderError(error_msg))
137+
138+
return Err(PreconfirmedCendeClientError::CendeRecorderError {
139+
block_number,
140+
round,
141+
write_iteration,
142+
status_code: response_status,
143+
});
130144
}
131145
}
132146
}

0 commit comments

Comments
 (0)