Skip to content

Commit b3070eb

Browse files
committed
Add get_by_slot_successful_fetch
1 parent e8d1725 commit b3070eb

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

crates/charon/src/eth2wrap/valcache.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,86 @@ mod tests {
380380
}
381381
}
382382

383+
#[tokio::test]
384+
async fn get_by_slot_successful_fetch() {
385+
// Create two validator pubkeys
386+
let pubkeys = vec![test_pubkey(0), test_pubkey(1)];
387+
388+
// Set up mock server with different responses based on slot
389+
let mock_server = MockServer::start().await;
390+
391+
endpoint_success(
392+
"1",
393+
vec![
394+
test_validator_datum(0, &pubkeys[0], ValidatorStatus::PendingQueued),
395+
test_validator_datum(1, &pubkeys[1], ValidatorStatus::ActiveOngoing),
396+
],
397+
)
398+
.mount(&mock_server)
399+
.await;
400+
401+
endpoint_success(
402+
"2",
403+
vec![
404+
test_validator_datum(0, &pubkeys[0], ValidatorStatus::ActiveOngoing),
405+
test_validator_datum(1, &pubkeys[1], ValidatorStatus::ActiveOngoing),
406+
],
407+
)
408+
.mount(&mock_server)
409+
.await;
410+
411+
endpoint_success(
412+
"11",
413+
vec![
414+
test_validator_datum(0, &pubkeys[0], ValidatorStatus::PendingQueued),
415+
test_validator_datum(1, &pubkeys[1], ValidatorStatus::PendingQueued),
416+
],
417+
)
418+
.mount(&mock_server)
419+
.await;
420+
421+
endpoint_not_found("3").mount(&mock_server).await;
422+
endpoint_not_found("head").mount(&mock_server).await;
423+
424+
let eth2_cl = EthBeaconNodeApiClient::with_base_url(mock_server.uri())
425+
.expect("Failed to create client");
426+
427+
let cache = ValidatorCache::new(eth2_cl, pubkeys.clone());
428+
429+
// Test slot 1: 1 active validator (index 1), 2 complete, refreshed_by_slot=true
430+
let (active, complete, refreshed_by_slot) = cache
431+
.get_by_slot(1)
432+
.await
433+
.expect("`get_by_slot(1)` succeeds");
434+
assert_eq!(active.len(), 1);
435+
assert_eq!(active.get(&1), Some(&pubkeys[1]));
436+
assert_eq!(complete.len(), 2);
437+
assert!(refreshed_by_slot);
438+
439+
// Test slot 2: 2 active validators, 2 complete, refreshed_by_slot=true
440+
let (active, complete, refreshed_by_slot) = cache
441+
.get_by_slot(2)
442+
.await
443+
.expect("`get_by_slot(2)` succeeds");
444+
assert_eq!(active.len(), 2);
445+
assert_eq!(complete.len(), 2);
446+
assert!(refreshed_by_slot);
447+
448+
// Test slot 11: 0 active validators, 2 complete, refreshed_by_slot=true
449+
let (active, complete, refreshed_by_slot) = cache
450+
.get_by_slot(11)
451+
.await
452+
.expect("`get_by_slot(11)` succeeds");
453+
assert!(active.is_empty());
454+
assert_eq!(complete.len(), 2);
455+
assert!(refreshed_by_slot);
456+
457+
// Test slot 3: error (both slot and head fallback fail),
458+
// refreshed_by_slot=false
459+
let result = cache.get_by_slot(3).await;
460+
assert!(result.is_err());
461+
}
462+
383463
fn test_pubkey(seed: u8) -> PubKey {
384464
let mut bytes = [0u8; 48];
385465
bytes[0] = seed;
@@ -410,6 +490,29 @@ mod tests {
410490
}
411491
}
412492

493+
fn endpoint_success(
494+
state_id: impl AsRef<str>,
495+
validators: Vec<GetStateValidatorsResponseResponseDatum>,
496+
) -> Mock {
497+
Mock::given(method("POST"))
498+
.and(path_regex(format!(
499+
"/eth/v1/beacon/states/{}/validators",
500+
state_id.as_ref()
501+
)))
502+
.respond_with(
503+
ResponseTemplate::new(200).set_body_json(success_response_body(validators)),
504+
)
505+
}
506+
507+
fn endpoint_not_found(state_id: impl AsRef<str>) -> Mock {
508+
Mock::given(method("POST"))
509+
.and(path_regex(format!(
510+
"/eth/v1/beacon/states/{}/validators",
511+
state_id.as_ref()
512+
)))
513+
.respond_with(ResponseTemplate::new(404).set_body_json(not_found_response_body()))
514+
}
515+
413516
fn success_response_body(
414517
validators: Vec<GetStateValidatorsResponseResponseDatum>,
415518
) -> GetStateValidatorsResponseResponse {

0 commit comments

Comments
 (0)