v0.3.14-pre.004
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/unit_tests/grpc_stream.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum FixtureMode {
|
||||
@@ -13,6 +13,7 @@ enum FixtureMode {
|
||||
Idle,
|
||||
ReconnectReplay,
|
||||
ReplayGap,
|
||||
ReplayAcceptedWithoutBoundary,
|
||||
ReconnectExhausted,
|
||||
}
|
||||
|
||||
@@ -153,6 +154,22 @@ impl yellowstone_grpc_proto::geyser::geyser_server::Geyser for FixtureGeyser {
|
||||
}
|
||||
}
|
||||
},
|
||||
FixtureMode::ReplayAcceptedWithoutBoundary => {
|
||||
if subscribe_call == 1 {
|
||||
assert_eq!(initial.from_slot, std::option::Option::None);
|
||||
let _ = outbound_tx.send(std::result::Result::Ok(slot_update(800))).await;
|
||||
} else {
|
||||
assert_eq!(subscribe_call, 2);
|
||||
assert_eq!(initial.from_slot, std::option::Option::Some(800));
|
||||
if outbound_tx.send(std::result::Result::Ok(slot_update(805))).await.is_err() {
|
||||
return;
|
||||
}
|
||||
let half_close = inbound.message().await;
|
||||
if matches!(half_close, std::result::Result::Ok(std::option::Option::None)) {
|
||||
half_close_seen.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
},
|
||||
FixtureMode::ReconnectExhausted => {
|
||||
assert_eq!(subscribe_call, 1);
|
||||
let _ = outbound_tx.send(std::result::Result::Ok(slot_update(700))).await;
|
||||
@@ -191,7 +208,7 @@ impl yellowstone_grpc_proto::geyser::geyser_server::Geyser for FixtureGeyser {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let first_available = match self.mode {
|
||||
FixtureMode::ReconnectReplay | FixtureMode::ReconnectExhausted => std::option::Option::Some(400),
|
||||
FixtureMode::ReconnectReplay | FixtureMode::ReconnectExhausted | FixtureMode::ReplayAcceptedWithoutBoundary => std::option::Option::Some(400),
|
||||
FixtureMode::ReplayGap => std::option::Option::Some(505),
|
||||
_ => return std::result::Result::Err(tonic::Status::unimplemented("replay info is outside this fixture mode")),
|
||||
};
|
||||
@@ -595,6 +612,8 @@ async fn yellowstone_reconnect_replays_from_last_observed_slot_and_counts_duplic
|
||||
assert_eq!(snapshot.state(), crate::YellowstoneGrpcSubscribeState::Active);
|
||||
assert_eq!(snapshot.reconnect_count(), 1);
|
||||
assert_eq!(snapshot.replay_attempt_count(), 1);
|
||||
assert_eq!(snapshot.replay_delivery_count(), 1);
|
||||
assert_eq!(snapshot.replay_coverage_unproven_count(), 1);
|
||||
assert_eq!(snapshot.continuity_gap_count(), 0);
|
||||
assert_eq!(snapshot.duplicate_update_count(), 1);
|
||||
assert_eq!(snapshot.last_requested_from_slot(), std::option::Option::Some(500));
|
||||
@@ -627,6 +646,8 @@ async fn yellowstone_replay_info_proves_and_clamps_retention_gap_without_lossles
|
||||
let snapshot = session.snapshot();
|
||||
assert_eq!(snapshot.reconnect_count(), 1);
|
||||
assert_eq!(snapshot.replay_attempt_count(), 1);
|
||||
assert_eq!(snapshot.replay_delivery_count(), 1);
|
||||
assert_eq!(snapshot.replay_coverage_unproven_count(), 1);
|
||||
assert_eq!(snapshot.continuity_gap_count(), 1);
|
||||
assert_eq!(snapshot.duplicate_update_count(), 0);
|
||||
assert_eq!(snapshot.last_requested_from_slot(), std::option::Option::Some(505));
|
||||
@@ -635,6 +656,42 @@ async fn yellowstone_replay_info_proves_and_clamps_retention_gap_without_lossles
|
||||
server.stop().await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn v0_3_14_pre_004_replay_acceptance_without_boundary_delivery_never_claims_coverage() {
|
||||
let server = FixtureServer::start(FixtureMode::ReplayAcceptedWithoutBoundary).await;
|
||||
let defaults = crate::YellowstoneGrpcSessionSettings::default();
|
||||
let settings = fixture_settings_with_reconnect(
|
||||
server.endpoint_url.as_str(),
|
||||
8,
|
||||
8,
|
||||
defaults.max_inbound_message_size_bytes(),
|
||||
defaults.max_outbound_message_size_bytes(),
|
||||
crate::YellowstoneGrpcReconnectSettings::new(3, std::time::Duration::from_millis(5), std::time::Duration::from_millis(20)),
|
||||
);
|
||||
let channel = crate::YellowstoneGrpcChannel::connect(&settings).await.expect("fixture channel must connect");
|
||||
let mut session = channel.open_standard_subscribe(initial_request()).await.expect("fixture Subscribe stream must open");
|
||||
let first = session.next_update().await.expect("first slot must decode").expect("first slot must be present");
|
||||
match first {
|
||||
crate::YellowstoneSubscribeUpdate::Slot(value) => assert_eq!(value.slot(), 800),
|
||||
_ => panic!("fixture must return first Slot"),
|
||||
}
|
||||
let resumed = session.next_update().await.expect("post-reconnect slot must decode").expect("post-reconnect slot must be present");
|
||||
match resumed {
|
||||
crate::YellowstoneSubscribeUpdate::Slot(value) => assert_eq!(value.slot(), 805),
|
||||
_ => panic!("fixture must return post-reconnect Slot"),
|
||||
}
|
||||
let snapshot = session.snapshot();
|
||||
assert_eq!(snapshot.reconnect_count(), 1);
|
||||
assert_eq!(snapshot.replay_attempt_count(), 1);
|
||||
assert_eq!(snapshot.replay_delivery_count(), 0);
|
||||
assert_eq!(snapshot.replay_coverage_unproven_count(), 1);
|
||||
assert_eq!(snapshot.continuity_gap_count(), 0);
|
||||
assert_eq!(snapshot.last_requested_from_slot(), std::option::Option::Some(800));
|
||||
assert_eq!(snapshot.last_observed_slot(), std::option::Option::Some(805));
|
||||
session.close().await.expect("coverage-unproven fixture must close cleanly");
|
||||
server.stop().await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn yellowstone_reconnect_budget_exhaustion_is_terminal_and_safe() {
|
||||
let server = FixtureServer::start(FixtureMode::ReconnectExhausted).await;
|
||||
@@ -656,6 +713,8 @@ async fn yellowstone_reconnect_budget_exhaustion_is_terminal_and_safe() {
|
||||
assert_eq!(snapshot.state(), crate::YellowstoneGrpcSubscribeState::Failed);
|
||||
assert_eq!(snapshot.reconnect_count(), 0);
|
||||
assert_eq!(snapshot.replay_attempt_count(), 2);
|
||||
assert_eq!(snapshot.replay_delivery_count(), 0);
|
||||
assert_eq!(snapshot.replay_coverage_unproven_count(), 0);
|
||||
assert_eq!(snapshot.terminal_error_code(), std::option::Option::Some(crate::ERROR_CODE_GRPC_CHANNEL_FAILED));
|
||||
let rendered = format!("{error:?} {session:?}");
|
||||
assert!(!rendered.contains("GRPC-RECONNECT-SECRET-CANARY"));
|
||||
|
||||
Reference in New Issue
Block a user