Skip to content

Commit 2071c1a

Browse files
apollo_consensus_orchestrator: Replace skip_write_height config with checking
if the blob is already in cende
1 parent c993d41 commit 2071c1a

File tree

9 files changed

+275
-95
lines changed

9 files changed

+275
-95
lines changed

crates/apollo_consensus_orchestrator/src/cende/cende_test.rs

Lines changed: 173 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,19 @@ use metrics_exporter_prometheus::PrometheusBuilder;
55
use reqwest::StatusCode;
66
use rstest::rstest;
77
use starknet_api::block::{BlockInfo, BlockNumber};
8+
use url::Url;
89

910
use super::{CendeAmbassador, RECORDER_WRITE_BLOB_PATH};
10-
use crate::cende::{BlobParameters, CendeConfig, CendeContext};
11+
use crate::cende::{
12+
BlobParameters,
13+
CendeConfig,
14+
CendeContext,
15+
GetLatestBlobResponse,
16+
RECORDER_GET_LATEST_BLOB_PATH,
17+
};
1118
use crate::metrics::{
1219
register_metrics,
13-
CendeWriteFailureReason,
20+
CendeWritePrevHeightFailureReason,
1421
CENDE_LAST_PREPARED_BLOB_BLOCK_NUMBER,
1522
CENDE_WRITE_BLOB_FAILURE,
1623
CENDE_WRITE_BLOB_SUCCESS,
@@ -32,6 +39,7 @@ struct ExpectedMetrics {
3239
failure_block_height_mismatch: usize,
3340
failure_recorder_error: usize,
3441
failure_skip_write_height: usize,
42+
failure_communication_error: usize,
3543
}
3644

3745
impl ExpectedMetrics {
@@ -51,39 +59,82 @@ impl ExpectedMetrics {
5159
Self { failure_recorder_error: 1, ..Default::default() }
5260
}
5361

62+
fn skip_write_height() -> Self {
63+
Self { failure_skip_write_height: 1, ..Default::default() }
64+
}
65+
66+
fn communication_error() -> Self {
67+
Self { failure_communication_error: 1, ..Default::default() }
68+
}
69+
5470
fn verify_metrics(&self, metrics: &str) {
5571
CENDE_WRITE_BLOB_FAILURE.assert_eq(
5672
metrics,
5773
self.failure_skip_write_height,
58-
&[(LABEL_CENDE_FAILURE_REASON, CendeWriteFailureReason::SkipWriteHeight.into())],
74+
&[(
75+
LABEL_CENDE_FAILURE_REASON,
76+
CendeWritePrevHeightFailureReason::SkipWriteHeight.into(),
77+
)],
5978
);
6079
CENDE_WRITE_BLOB_FAILURE.assert_eq(
6180
metrics,
6281
self.failure_no_prev_blob,
63-
&[(LABEL_CENDE_FAILURE_REASON, CendeWriteFailureReason::BlobNotAvailable.into())],
82+
&[(
83+
LABEL_CENDE_FAILURE_REASON,
84+
CendeWritePrevHeightFailureReason::BlobNotAvailable.into(),
85+
)],
6486
);
6587
CENDE_WRITE_BLOB_FAILURE.assert_eq(
6688
metrics,
6789
self.failure_block_height_mismatch,
68-
&[(LABEL_CENDE_FAILURE_REASON, CendeWriteFailureReason::HeightMismatch.into())],
90+
&[(
91+
LABEL_CENDE_FAILURE_REASON,
92+
CendeWritePrevHeightFailureReason::HeightMismatch.into(),
93+
)],
6994
);
7095
CENDE_WRITE_BLOB_FAILURE.assert_eq(
7196
metrics,
7297
self.failure_recorder_error,
73-
&[(LABEL_CENDE_FAILURE_REASON, CendeWriteFailureReason::CendeRecorderError.into())],
98+
&[(
99+
LABEL_CENDE_FAILURE_REASON,
100+
CendeWritePrevHeightFailureReason::CendeRecorderError.into(),
101+
)],
102+
);
103+
CENDE_WRITE_BLOB_FAILURE.assert_eq(
104+
metrics,
105+
self.failure_communication_error,
106+
&[(
107+
LABEL_CENDE_FAILURE_REASON,
108+
CendeWritePrevHeightFailureReason::CommunicationError.into(),
109+
)],
74110
);
75111
CENDE_WRITE_BLOB_SUCCESS.assert_eq(metrics, self.success);
76112
}
77113
}
78114

79115
#[rstest]
80-
#[case::success(200, Some(9), 1, true, ExpectedMetrics::success())]
81-
#[case::no_prev_block(200, None, 0, false, ExpectedMetrics::no_prev_blob())]
82-
#[case::prev_block_height_mismatch(200, Some(7), 0, false, ExpectedMetrics::height_mismatch())]
83-
#[case::recorder_return_fatal_error(400, Some(9), 1, false, ExpectedMetrics::recorder_error())]
116+
#[case::success(200, HEIGHT_TO_WRITE, Some(9), 1, true, ExpectedMetrics::success())]
117+
#[case::height_zero(200, BlockNumber(0), None, 0, true, ExpectedMetrics::skip_write_height())]
118+
#[case::prev_block_height_mismatch(
119+
200,
120+
HEIGHT_TO_WRITE,
121+
Some(7),
122+
0,
123+
false,
124+
ExpectedMetrics::height_mismatch()
125+
)]
126+
#[case::recorder_return_fatal_error(
127+
400,
128+
HEIGHT_TO_WRITE,
129+
Some(9),
130+
1,
131+
false,
132+
ExpectedMetrics::recorder_error()
133+
)]
84134
#[tokio::test]
85135
async fn write_prev_height_blob(
86136
#[case] mock_status_code: usize,
137+
#[case] current_height: BlockNumber,
87138
#[case] prev_block: Option<u64>,
88139
#[case] expected_calls: usize,
89140
#[case] expected_result: bool,
@@ -111,7 +162,7 @@ async fn write_prev_height_blob(
111162
.unwrap();
112163
}
113164

114-
let receiver = cende_ambassador.write_prev_height_blob(HEIGHT_TO_WRITE);
165+
let receiver = cende_ambassador.write_prev_height_blob(current_height);
115166

116167
assert_eq!(receiver.await.unwrap(), expected_result);
117168
mock.expect(expected_calls).assert();
@@ -181,29 +232,127 @@ async fn prepare_blob_for_next_height() {
181232
}
182233

183234
#[tokio::test]
184-
async fn no_write_at_skipped_height() {
235+
async fn write_prev_height_blob_no_prev_blob_and_cende_communication_error() {
236+
const CURRENT_HEIGHT: BlockNumber = BlockNumber(10);
237+
185238
let recorder = PrometheusBuilder::new().build_recorder();
186239
let _recorder_guard = metrics::set_default_local_recorder(&recorder);
187240
register_metrics();
188241

189-
const SKIP_WRITE_HEIGHT: BlockNumber = HEIGHT_TO_WRITE;
190242
let cende_ambassador = CendeAmbassador::new(
191-
CendeConfig { skip_write_height: Some(SKIP_WRITE_HEIGHT), ..Default::default() },
243+
CendeConfig {
244+
// We do not create a mock server and we send a bogus URL. This should cause
245+
// request_builder.send to return an Err.
246+
recorder_url: Url::parse("https://bogus.url").unwrap(),
247+
..Default::default()
248+
},
192249
Arc::new(MockClassManagerClient::new()),
193250
);
194251

195-
// Returns false since the blob is missing and the height is different than skip_write_height.
196-
assert!(
197-
!cende_ambassador.write_prev_height_blob(HEIGHT_TO_WRITE.unchecked_next()).await.unwrap()
252+
let receiver = cende_ambassador.write_prev_height_blob(CURRENT_HEIGHT);
253+
254+
assert!(!receiver.await.unwrap());
255+
256+
ExpectedMetrics::communication_error().verify_metrics(&recorder.handle().render());
257+
}
258+
259+
#[tokio::test]
260+
async fn write_prev_height_blob_no_prev_blob_and_cende_recorder_error() {
261+
const CURRENT_HEIGHT: BlockNumber = BlockNumber(10);
262+
263+
let recorder = PrometheusBuilder::new().build_recorder();
264+
let _recorder_guard = metrics::set_default_local_recorder(&recorder);
265+
register_metrics();
266+
267+
let mut server = mockito::Server::new_async().await;
268+
let url = server.url();
269+
270+
let get_latest_blob_mock = server
271+
.mock("GET", RECORDER_GET_LATEST_BLOB_PATH)
272+
// Return a non retryable error.
273+
.with_status(StatusCode::METHOD_NOT_ALLOWED.as_u16().into())
274+
.create();
275+
276+
let cende_ambassador = CendeAmbassador::new(
277+
CendeConfig { recorder_url: url.parse().unwrap(), ..Default::default() },
278+
Arc::new(MockClassManagerClient::new()),
198279
);
199280

200-
assert!(cende_ambassador.write_prev_height_blob(HEIGHT_TO_WRITE).await.unwrap());
281+
let receiver = cende_ambassador.write_prev_height_blob(CURRENT_HEIGHT);
282+
283+
assert!(!receiver.await.unwrap());
284+
get_latest_blob_mock.expect(1).assert();
285+
286+
ExpectedMetrics::recorder_error().verify_metrics(&recorder.handle().render());
287+
}
288+
289+
#[tokio::test]
290+
async fn write_prev_height_blob_no_prev_blob_and_not_written_to_cende() {
291+
const CURRENT_HEIGHT: BlockNumber = BlockNumber(10);
292+
293+
let recorder = PrometheusBuilder::new().build_recorder();
294+
let _recorder_guard = metrics::set_default_local_recorder(&recorder);
295+
register_metrics();
201296

202-
// Verify metrics.
203-
let expected_metrics = ExpectedMetrics {
204-
failure_no_prev_blob: 1,
205-
failure_skip_write_height: 1,
206-
..Default::default()
297+
let mut server = mockito::Server::new_async().await;
298+
let url = server.url();
299+
300+
let latest_blob_response = GetLatestBlobResponse {
301+
// The latest blob is at height 2 below current, so we don't have the previous blob.
302+
height: CURRENT_HEIGHT.prev().unwrap().prev().unwrap(),
303+
proposal_commitment: "Unused".to_string(),
207304
};
208-
expected_metrics.verify_metrics(&recorder.handle().render());
305+
306+
let get_latest_blob_mock = server
307+
.mock("GET", RECORDER_GET_LATEST_BLOB_PATH)
308+
.with_body(serde_json::to_string(&latest_blob_response).unwrap())
309+
.create();
310+
311+
let cende_ambassador = CendeAmbassador::new(
312+
CendeConfig { recorder_url: url.parse().unwrap(), ..Default::default() },
313+
Arc::new(MockClassManagerClient::new()),
314+
);
315+
316+
let receiver = cende_ambassador.write_prev_height_blob(CURRENT_HEIGHT);
317+
318+
assert!(!receiver.await.unwrap());
319+
get_latest_blob_mock.expect(1).assert();
320+
321+
ExpectedMetrics::no_prev_blob().verify_metrics(&recorder.handle().render());
322+
}
323+
324+
#[tokio::test]
325+
async fn write_prev_height_blob_no_prev_blob_but_it_was_written_to_cende() {
326+
const CURRENT_HEIGHT: BlockNumber = BlockNumber(10);
327+
328+
let recorder = PrometheusBuilder::new().build_recorder();
329+
let _recorder_guard = metrics::set_default_local_recorder(&recorder);
330+
register_metrics();
331+
332+
let mut server = mockito::Server::new_async().await;
333+
let url = server.url();
334+
335+
let latest_blob_response = GetLatestBlobResponse {
336+
// The latest blob is at height 1 below current, so we don't have to write the previous
337+
// blob.
338+
height: CURRENT_HEIGHT.prev().unwrap(),
339+
proposal_commitment: "Unused".to_string(),
340+
};
341+
342+
let get_latest_blob_mock = server
343+
.mock("GET", RECORDER_GET_LATEST_BLOB_PATH)
344+
.with_body(serde_json::to_string(&latest_blob_response).unwrap())
345+
.create();
346+
347+
let cende_ambassador = CendeAmbassador::new(
348+
CendeConfig { recorder_url: url.parse().unwrap(), ..Default::default() },
349+
Arc::new(MockClassManagerClient::new()),
350+
);
351+
352+
let receiver = cende_ambassador.write_prev_height_blob(CURRENT_HEIGHT);
353+
354+
assert!(receiver.await.unwrap());
355+
get_latest_blob_mock.expect(1).assert();
356+
357+
ExpectedMetrics::skip_write_height().verify_metrics(&recorder.handle().render());
209358
}

0 commit comments

Comments
 (0)