177 lines
7.3 KiB
Rust
177 lines
7.3 KiB
Rust
// file: kb-pipeline-demo-scenarios/src/metadata_solana_program_validation.rs
|
|
// version: 2
|
|
|
|
//! Conservative Solana Program Metadata validation status and evidence contracts.
|
|
|
|
/// Maximum evidence entries accepted by one operation validation row.
|
|
pub const MAX_SOLANA_PROGRAM_METADATA_VALIDATION_EVIDENCE: usize = 16;
|
|
|
|
/// Exact network validation status.
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum SolanaProgramMetadataValidationStatus {
|
|
/// No network execution was attempted.
|
|
NotRun,
|
|
/// Exact transaction simulated successfully.
|
|
Simulated,
|
|
/// Transaction submitted but not yet confirmed.
|
|
Submitted,
|
|
/// Transaction confirmed and postconditions validated.
|
|
Confirmed,
|
|
/// Required network capability was unavailable.
|
|
Unavailable,
|
|
/// Validation failed with retained diagnostics.
|
|
Failed,
|
|
}
|
|
|
|
/// One bounded evidence record.
|
|
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct SolanaProgramMetadataValidationEvidence {
|
|
/// Stable evidence kind.
|
|
pub kind: std::string::String,
|
|
/// Non-secret evidence value.
|
|
pub value: std::string::String,
|
|
}
|
|
|
|
/// One operation row in the closed Devnet validation matrix.
|
|
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct SolanaProgramMetadataValidationOperation {
|
|
/// Stable operation code.
|
|
pub operation_code: std::string::String,
|
|
/// Scenario step that exercises the operation.
|
|
pub scenario_step_id: std::string::String,
|
|
/// Exact current validation status.
|
|
pub status: crate::SolanaProgramMetadataValidationStatus,
|
|
/// Whether a destructive approval is required.
|
|
pub requires_explicit_approval: bool,
|
|
/// Evidence required for confirmed status.
|
|
pub required_evidence: std::vec::Vec<std::string::String>,
|
|
/// Bounded observed evidence.
|
|
#[serde(default)]
|
|
pub evidence: std::vec::Vec<crate::SolanaProgramMetadataValidationEvidence>,
|
|
}
|
|
|
|
/// Closed validation matrix for all nine stable operations.
|
|
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct SolanaProgramMetadataValidationMatrix {
|
|
/// Matrix schema version.
|
|
pub matrix_version: u32,
|
|
/// Exact owning prerelease.
|
|
pub milestone: std::string::String,
|
|
/// Ordered stable operations.
|
|
pub operations: std::vec::Vec<crate::SolanaProgramMetadataValidationOperation>,
|
|
}
|
|
|
|
/// Loads and validates the canonical Solana Program Metadata Devnet matrix.
|
|
pub fn load_solana_program_metadata_validation_matrix()
|
|
-> kb_core::Result<crate::SolanaProgramMetadataValidationMatrix> {
|
|
let parsed = match serde_json::from_str::<crate::SolanaProgramMetadataValidationMatrix>(
|
|
include_str!(
|
|
"../../test-fixtures/contract-matrices/SOLANA_PROGRAM_METADATA_DEVNET_VALIDATION_MATRIX.json"
|
|
),
|
|
) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => {
|
|
return std::result::Result::Err(kb_core::Error::new(
|
|
"solana_program_metadata_validation_matrix_invalid_json",
|
|
format!("Solana Program Metadata validation matrix is invalid: {error}"),
|
|
));
|
|
},
|
|
};
|
|
if let std::result::Result::Err(error) =
|
|
validate_solana_program_metadata_validation_matrix(&parsed)
|
|
{
|
|
return std::result::Result::Err(error);
|
|
}
|
|
return std::result::Result::Ok(parsed);
|
|
}
|
|
|
|
/// Validates exact inventory, order and conservative evidence claims.
|
|
pub fn validate_solana_program_metadata_validation_matrix(
|
|
matrix: &crate::SolanaProgramMetadataValidationMatrix,
|
|
) -> kb_core::Result<()> {
|
|
if matrix.matrix_version != 1 || matrix.milestone != "0.4.8-pre.009" {
|
|
return std::result::Result::Err(kb_core::Error::new(
|
|
"solana_program_metadata_validation_matrix_contract_mismatch",
|
|
"Solana Program Metadata validation matrix must use version 1 for 0.4.8-pre.009",
|
|
));
|
|
}
|
|
let compiled_steps = crate::solana_program_metadata_devnet_scenarios()
|
|
.into_iter()
|
|
.flat_map(|scenario| return scenario.steps)
|
|
.collect::<std::vec::Vec<_>>();
|
|
let expected = compiled_steps
|
|
.iter()
|
|
.map(|step| return step.operation_code.as_str())
|
|
.collect::<std::vec::Vec<_>>();
|
|
let actual = matrix
|
|
.operations
|
|
.iter()
|
|
.map(|operation| return operation.operation_code.as_str())
|
|
.collect::<std::vec::Vec<_>>();
|
|
if actual != expected {
|
|
return std::result::Result::Err(kb_core::Error::new(
|
|
"solana_program_metadata_validation_matrix_inventory_mismatch",
|
|
"Solana Program Metadata validation matrix differs from the compiled journey order",
|
|
));
|
|
}
|
|
for (operation, step) in matrix.operations.iter().zip(compiled_steps.iter()) {
|
|
if operation.scenario_step_id != step.id
|
|
|| operation.requires_explicit_approval != step.requires_explicit_approval
|
|
|| operation.required_evidence != step.required_evidence
|
|
|| operation.evidence.len() > crate::MAX_SOLANA_PROGRAM_METADATA_VALIDATION_EVIDENCE
|
|
{
|
|
return std::result::Result::Err(kb_core::Error::new(
|
|
"solana_program_metadata_validation_matrix_row_invalid",
|
|
"Solana Program Metadata validation row differs from the compiled scenario contract",
|
|
));
|
|
}
|
|
if matches!(
|
|
operation.status,
|
|
crate::SolanaProgramMetadataValidationStatus::NotRun
|
|
| crate::SolanaProgramMetadataValidationStatus::Unavailable
|
|
) && !operation.evidence.is_empty()
|
|
{
|
|
return std::result::Result::Err(kb_core::Error::new(
|
|
"solana_program_metadata_validation_unobserved_with_evidence",
|
|
"not-run or unavailable validation rows must not contain observed evidence",
|
|
));
|
|
}
|
|
if operation.status == crate::SolanaProgramMetadataValidationStatus::Confirmed {
|
|
let observed = operation
|
|
.evidence
|
|
.iter()
|
|
.map(|evidence| return evidence.kind.as_str())
|
|
.collect::<std::collections::BTreeSet<_>>();
|
|
if !operation
|
|
.required_evidence
|
|
.iter()
|
|
.all(|kind| return observed.contains(kind.as_str()))
|
|
{
|
|
return std::result::Result::Err(kb_core::Error::new(
|
|
"solana_program_metadata_validation_confirmed_without_evidence",
|
|
"confirmed validation row lacks required evidence",
|
|
));
|
|
}
|
|
}
|
|
}
|
|
return std::result::Result::Ok(());
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
#[test]
|
|
fn canonical_matrix_matches_the_compiled_two_journey_inventory() {
|
|
let matrix = match crate::load_solana_program_metadata_validation_matrix() {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => panic!("matrix load failed: {error}"),
|
|
};
|
|
assert_eq!(matrix.operations.len(), 9);
|
|
assert!(matrix.operations.iter().all(|operation| return operation.status
|
|
== crate::SolanaProgramMetadataValidationStatus::NotRun));
|
|
}
|
|
}
|