v0.3.14-pre.004
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
|
||||
// version: 30
|
||||
// version: 31
|
||||
|
||||
use sha2::Digest; // rust-rules: trait-import
|
||||
|
||||
@@ -3635,6 +3635,8 @@ struct RawTransactionIngestProcessingFrontierReporter {
|
||||
source_state: std::option::Option<crate::RawTransactionIngestSourceState>,
|
||||
source_reconnect_total: u64,
|
||||
source_replay_attempt_total: u64,
|
||||
source_replay_delivery_total: u64,
|
||||
source_replay_coverage_unproven_total: u64,
|
||||
source_continuity_gap_total: u64,
|
||||
source_overflow_total: u64,
|
||||
websocket_incident_anchor: std::option::Option<crate::RawTransactionIngestWebSocketIncidentAnchor>,
|
||||
@@ -3648,6 +3650,8 @@ impl RawTransactionIngestProcessingFrontierReporter {
|
||||
source_state: std::option::Option::None,
|
||||
source_reconnect_total: 0,
|
||||
source_replay_attempt_total: 0,
|
||||
source_replay_delivery_total: 0,
|
||||
source_replay_coverage_unproven_total: 0,
|
||||
source_continuity_gap_total: 0,
|
||||
source_overflow_total: 0,
|
||||
websocket_incident_anchor: std::option::Option::None,
|
||||
@@ -3689,6 +3693,8 @@ impl RawTransactionIngestProcessingFrontierReporter {
|
||||
map_yellowstone_source_state(snapshot.state()),
|
||||
snapshot.reconnect_count(),
|
||||
snapshot.replay_attempt_count(),
|
||||
snapshot.replay_delivery_count(),
|
||||
snapshot.replay_coverage_unproven_count(),
|
||||
snapshot.continuity_gap_count(),
|
||||
);
|
||||
}
|
||||
@@ -3777,23 +3783,33 @@ impl RawTransactionIngestProcessingFrontierReporter {
|
||||
state: crate::RawTransactionIngestSourceState,
|
||||
reconnect_total: u64,
|
||||
replay_attempt_total: u64,
|
||||
replay_delivery_total: u64,
|
||||
replay_coverage_unproven_total: u64,
|
||||
continuity_gap_total: u64,
|
||||
) -> ksp_core_lib::Result<()> {
|
||||
if reconnect_total < self.source_reconnect_total
|
||||
|| replay_attempt_total < self.source_replay_attempt_total
|
||||
|| replay_delivery_total < self.source_replay_delivery_total
|
||||
|| replay_coverage_unproven_total < self.source_replay_coverage_unproven_total
|
||||
|| continuity_gap_total < self.source_continuity_gap_total
|
||||
{
|
||||
return std::result::Result::Err(crate::runtime_error("source.continuity_counter_regression"));
|
||||
}
|
||||
let gap_increased = continuity_gap_total > self.source_continuity_gap_total;
|
||||
let replay_coverage_unproven_increased = replay_coverage_unproven_total > self.source_replay_coverage_unproven_total;
|
||||
self.source_state = std::option::Option::Some(state);
|
||||
self.source_reconnect_total = reconnect_total;
|
||||
self.source_replay_attempt_total = replay_attempt_total;
|
||||
self.source_replay_delivery_total = replay_delivery_total;
|
||||
self.source_replay_coverage_unproven_total = replay_coverage_unproven_total;
|
||||
self.source_continuity_gap_total = continuity_gap_total;
|
||||
self.publish();
|
||||
if gap_increased {
|
||||
return std::result::Result::Err(crate::runtime_error("source.continuity_gap_proven"));
|
||||
}
|
||||
if replay_coverage_unproven_increased {
|
||||
return std::result::Result::Err(crate::runtime_error("source.replay_coverage_unproven"));
|
||||
}
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
|
||||
// version: 27
|
||||
// version: 28
|
||||
|
||||
//! External public, security, redaction and release-boundary hardening canaries through `v0.3.14-pre.003`.
|
||||
//! External public, security, redaction and release-boundary hardening canaries through `v0.3.14-pre.004`.
|
||||
|
||||
fn network(value: &'static str) -> std::option::Option<ksp_store_lib::RawNetworkId> {
|
||||
let result = ksp_store_lib::RawNetworkId::new(value);
|
||||
@@ -1024,3 +1024,33 @@ fn v0_3_14_pre_003_websocket_continuity_observation_reuses_transport_snapshot_so
|
||||
assert!(!worker.contains("set_from_slot("));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn v0_3_14_pre_004_yellowstone_replay_evidence_is_transport_owned_and_fail_closed_without_coverage_proof() {
|
||||
let worker = include_str!("../src/runtime_resources.rs");
|
||||
let transport = include_str!("../../ksp-onchain-transport-lib/src/grpc_stream.rs");
|
||||
for required in [
|
||||
"snapshot.replay_delivery_count()",
|
||||
"snapshot.replay_coverage_unproven_count()",
|
||||
"source_replay_delivery_total",
|
||||
"source_replay_coverage_unproven_total",
|
||||
"source.replay_coverage_unproven",
|
||||
] {
|
||||
assert!(worker.contains(required), "required pre.004 Worker replay-evidence guard missing: {required}");
|
||||
}
|
||||
for required in [
|
||||
"replay_delivery_count",
|
||||
"replay_coverage_unproven_count",
|
||||
"pending_replay_from_slot",
|
||||
"tracker.begin_replay(effective_from_slot)",
|
||||
"first_available > requested",
|
||||
] {
|
||||
assert!(transport.contains(required), "required pre.004 Transport replay-evidence guard missing: {required}");
|
||||
}
|
||||
for forbidden in ["subscribe_replay_info(", "set_from_slot(", "YellowstoneReplayInfo", "last_requested_from_slot()"] {
|
||||
assert!(!worker.contains(forbidden), "pre.004 Worker took replay ownership: {forbidden}");
|
||||
}
|
||||
assert!(!transport.contains("replay_covered_count"));
|
||||
assert!(!transport.contains("replay_coverage_proven_count"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/tests/release_completeness.rs
|
||||
// version: 22
|
||||
// version: 23
|
||||
|
||||
//! Release-completeness canaries through the `v0.3.14-pre.003` WebSocket continuity-observation tranche.
|
||||
//! Release-completeness canaries through the `v0.3.14-pre.004` Yellowstone native replay-evidence tranche.
|
||||
|
||||
#[test]
|
||||
fn pre_010_production_module_inventory_is_exact() -> std::io::Result<()> {
|
||||
@@ -248,3 +248,18 @@ fn v0_3_13_pre_012_cross_layer_completeness_security_inventory_is_exact() {
|
||||
assert!(public_api.contains("v0_3_13_pre_012_completeness_closure_adds_no_public_implementation_surface"));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn v0_3_14_pre_004_native_replay_evidence_canaries_are_present_without_public_replay_ownership() {
|
||||
let hardening = include_str!("hardening.rs");
|
||||
let resources = include_str!("../src/runtime_resources.rs");
|
||||
let resource_tests = include_str!("../unit_tests/runtime_resources.rs");
|
||||
let root = include_str!("../src/lib.rs");
|
||||
assert!(hardening.contains("v0_3_14_pre_004_yellowstone_replay_evidence_is_transport_owned_and_fail_closed_without_coverage_proof"));
|
||||
assert!(resource_tests.contains("v0_3_14_pre_004_replay_delivery_is_not_coverage_and_unproven_coverage_fails_closed"));
|
||||
assert!(resources.contains("source.replay_coverage_unproven"));
|
||||
assert!(!root.contains("ReplayInfo"));
|
||||
assert!(!root.contains("from_slot"));
|
||||
assert!(!root.contains("set_from_slot"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
|
||||
// version: 24
|
||||
// version: 25
|
||||
|
||||
fn grpc_endpoint(cluster: &str) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings> {
|
||||
return grpc_endpoint_with_identity(cluster, "yellowstone-fixture", "fixture-provider");
|
||||
@@ -2659,7 +2659,7 @@ fn pre_008_reconnect_replay_and_proven_gap_are_distinct_monotone_and_frontier_pr
|
||||
let (sender, receiver) = tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty());
|
||||
let mut reporter = super::RawTransactionIngestProcessingFrontierReporter::new(sender);
|
||||
assert!(reporter.observe_pending(42).is_ok());
|
||||
assert!(reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Reconnecting, 0, 1, 0).is_ok());
|
||||
assert!(reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Reconnecting, 0, 1, 0, 0, 0).is_ok());
|
||||
let replaying = *receiver.borrow();
|
||||
assert_eq!(replaying.hydration_pending(), 1);
|
||||
assert_eq!(replaying.oldest_pending_slot(), std::option::Option::Some(42));
|
||||
@@ -2667,8 +2667,8 @@ fn pre_008_reconnect_replay_and_proven_gap_are_distinct_monotone_and_frontier_pr
|
||||
assert_eq!(replaying.source_reconnect_total(), 0);
|
||||
assert_eq!(replaying.source_replay_attempt_total(), 1);
|
||||
assert_eq!(replaying.source_continuity_gap_total(), 0);
|
||||
assert!(reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Active, 1, 1, 0).is_ok());
|
||||
let gap = reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Reconnecting, 1, 2, 1);
|
||||
assert!(reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Active, 1, 1, 1, 0, 0).is_ok());
|
||||
let gap = reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Reconnecting, 1, 2, 1, 0, 1);
|
||||
assert!(gap.is_err());
|
||||
let gap = match gap {
|
||||
std::result::Result::Ok(()) => return,
|
||||
@@ -2684,7 +2684,37 @@ fn pre_008_reconnect_replay_and_proven_gap_are_distinct_monotone_and_frontier_pr
|
||||
assert_eq!(proven.source_reconnect_total(), 1);
|
||||
assert_eq!(proven.source_replay_attempt_total(), 2);
|
||||
assert_eq!(proven.source_continuity_gap_total(), 1);
|
||||
let regression = reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Active, 0, 2, 1);
|
||||
let regression = reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Active, 0, 2, 1, 0, 1);
|
||||
assert!(regression.is_err());
|
||||
let regression = match regression {
|
||||
std::result::Result::Ok(()) => return,
|
||||
std::result::Result::Err(value) => value,
|
||||
};
|
||||
assert!(regression.context().iter().any(|context| {
|
||||
return context.value() == "source.continuity_counter_regression";
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn v0_3_14_pre_004_replay_delivery_is_not_coverage_and_unproven_coverage_fails_closed() {
|
||||
let (sender, receiver) = tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty());
|
||||
let mut reporter = super::RawTransactionIngestProcessingFrontierReporter::new(sender);
|
||||
assert!(reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Active, 1, 1, 0, 0, 0).is_ok());
|
||||
let attempted = *receiver.borrow();
|
||||
assert_eq!(attempted.source_reconnect_total(), 1);
|
||||
assert_eq!(attempted.source_replay_attempt_total(), 1);
|
||||
assert_eq!(attempted.source_continuity_gap_total(), 0);
|
||||
let unproven = reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Active, 1, 1, 1, 1, 0);
|
||||
assert!(unproven.is_err());
|
||||
let unproven = match unproven {
|
||||
std::result::Result::Ok(()) => return,
|
||||
std::result::Result::Err(value) => value,
|
||||
};
|
||||
assert!(unproven.context().iter().any(|context| {
|
||||
return context.value() == "source.replay_coverage_unproven";
|
||||
}));
|
||||
let regression = reporter.observe_source_continuity(crate::RawTransactionIngestSourceState::Active, 1, 1, 0, 1, 0);
|
||||
assert!(regression.is_err());
|
||||
let regression = match regression {
|
||||
std::result::Result::Ok(()) => return,
|
||||
|
||||
Reference in New Issue
Block a user