v0.1.0-pre.061

This commit is contained in:
2026-07-28 18:41:30 +02:00
parent c7bad46f50
commit f40fb78817
527 changed files with 4598 additions and 4114 deletions

View File

@@ -1,5 +1,5 @@
// file: kb-pipeline-demo-scenarios/src/lib.rs
// version: 2
// version: 3
#![forbid(unsafe_code)]
#![deny(unreachable_pub)]
@@ -12,9 +12,9 @@ mod environment;
mod solana_ata_execution;
mod solana_execution;
mod solana_memo_execution;
mod solana_token2022_devnet_execution;
mod solana_token2022_devnet_scenarios;
mod solana_token2022_validation;
mod solana_token_2022_devnet_execution;
mod solana_token_2022_devnet_scenarios;
mod solana_token_2022_validation;
mod solana_token_execution;
mod solana_token_lifecycle;
@@ -58,6 +58,44 @@ pub use self::solana_memo_execution::DevnetMemoExecutionRequest;
pub use self::solana_memo_execution::DevnetMemoExecutionSummary;
/// Executes one SPL Memo v4 Devnet simulation or explicitly authorized submission.
pub use self::solana_memo_execution::execute_devnet_memo;
/// Complete request for one Devnet Token-2022 execution.
pub use self::solana_token_2022_devnet_execution::DevnetSplToken2022ExecutionRequest;
/// Complete result of one Devnet Token-2022 execution.
pub use self::solana_token_2022_devnet_execution::DevnetSplToken2022ExecutionSummary;
/// Executes one Devnet Token-2022 simulation or authorized submission.
pub use self::solana_token_2022_devnet_execution::execute_devnet_spl_token_2022;
/// Simulates one Devnet Token-2022 operation after stateful preflight.
pub use self::solana_token_2022_devnet_execution::simulate_devnet_spl_token_2022;
/// Stable category of one independent Devnet validation scenario.
pub use self::solana_token_2022_devnet_scenarios::DevnetSplValidationFamily;
/// Current implementation status of one Devnet validation scenario.
pub use self::solana_token_2022_devnet_scenarios::DevnetSplValidationImplementationStatus;
/// One independent Devnet validation scenario exposed to applications.
pub use self::solana_token_2022_devnet_scenarios::DevnetSplValidationScenario;
/// Returns the complete ordered Devnet scenario inventory.
pub use self::solana_token_2022_devnet_scenarios::devnet_spl_validation_scenarios;
/// Maximum number of evidence records accepted in one validation report.
pub use self::solana_token_2022_validation::MAX_TOKEN_2022_VALIDATION_EVIDENCE;
/// Required validation environment for one Token-2022 scenario.
pub use self::solana_token_2022_validation::Token2022ValidationEnvironment;
/// One bounded proof attached to a Token-2022 validation scenario.
pub use self::solana_token_2022_validation::Token2022ValidationEvidence;
/// Machine-readable Token-2022 validation matrix.
pub use self::solana_token_2022_validation::Token2022ValidationMatrix;
/// One scenario declared by the canonical validation matrix.
pub use self::solana_token_2022_validation::Token2022ValidationMatrixScenario;
/// Complete bounded Token-2022 validation report.
pub use self::solana_token_2022_validation::Token2022ValidationReport;
/// One declared Token-2022 validation scenario and its observed evidence.
pub use self::solana_token_2022_validation::Token2022ValidationScenario;
/// Exact status of one Token-2022 validation scenario.
pub use self::solana_token_2022_validation::Token2022ValidationStatus;
/// Loads and validates the canonical Token-2022 validation matrix.
pub use self::solana_token_2022_validation::load_token_2022_validation_matrix;
/// Validates one Token-2022 validation matrix.
pub use self::solana_token_2022_validation::validate_token_2022_validation_matrix;
/// Validates one bounded Token-2022 milestone report.
pub use self::solana_token_2022_validation::validate_token_2022_validation_report;
/// Complete request for one Devnet classic SPL Token execution.
pub use self::solana_token_execution::DevnetSplTokenExecutionRequest;
/// Complete result of one Devnet classic SPL Token execution.
@@ -90,44 +128,6 @@ pub use self::solana_token_lifecycle::DevnetSplTokenLifecycleSummary;
pub use self::solana_token_lifecycle::execute_devnet_spl_token_lifecycle;
/// Prepares raw accounts for one controlled Devnet SPL Token lifecycle.
pub use self::solana_token_lifecycle::prepare_devnet_spl_token_lifecycle_accounts;
/// Complete request for one Devnet Token-2022 execution.
pub use self::solana_token2022_devnet_execution::DevnetSplToken2022ExecutionRequest;
/// Complete result of one Devnet Token-2022 execution.
pub use self::solana_token2022_devnet_execution::DevnetSplToken2022ExecutionSummary;
/// Executes one Devnet Token-2022 simulation or authorized submission.
pub use self::solana_token2022_devnet_execution::execute_devnet_spl_token2022;
/// Simulates one Devnet Token-2022 operation after stateful preflight.
pub use self::solana_token2022_devnet_execution::simulate_devnet_spl_token2022;
/// Stable category of one independent Devnet validation scenario.
pub use self::solana_token2022_devnet_scenarios::DevnetSplValidationFamily;
/// Current implementation status of one Devnet validation scenario.
pub use self::solana_token2022_devnet_scenarios::DevnetSplValidationImplementationStatus;
/// One independent Devnet validation scenario exposed to applications.
pub use self::solana_token2022_devnet_scenarios::DevnetSplValidationScenario;
/// Returns the complete ordered Devnet scenario inventory.
pub use self::solana_token2022_devnet_scenarios::devnet_spl_validation_scenarios;
/// Maximum number of evidence records accepted in one validation report.
pub use self::solana_token2022_validation::MAX_TOKEN2022_VALIDATION_EVIDENCE;
/// Required validation environment for one Token-2022 scenario.
pub use self::solana_token2022_validation::Token2022ValidationEnvironment;
/// One bounded proof attached to a Token-2022 validation scenario.
pub use self::solana_token2022_validation::Token2022ValidationEvidence;
/// Machine-readable Token-2022 validation matrix.
pub use self::solana_token2022_validation::Token2022ValidationMatrix;
/// One scenario declared by the canonical validation matrix.
pub use self::solana_token2022_validation::Token2022ValidationMatrixScenario;
/// Complete bounded Token-2022 validation report.
pub use self::solana_token2022_validation::Token2022ValidationReport;
/// One declared Token-2022 validation scenario and its observed evidence.
pub use self::solana_token2022_validation::Token2022ValidationScenario;
/// Exact status of one Token-2022 validation scenario.
pub use self::solana_token2022_validation::Token2022ValidationStatus;
/// Loads and validates the canonical Token-2022 validation matrix.
pub use self::solana_token2022_validation::load_token2022_validation_matrix;
/// Validates one Token-2022 validation matrix.
pub use self::solana_token2022_validation::validate_token2022_validation_matrix;
/// Validates one bounded Token-2022 milestone report.
pub use self::solana_token2022_validation::validate_token2022_validation_report;
/// Canonical tracing target for demo pipeline scenarios.
pub(crate) use self::constants::TRACING_TARGET;

View File

@@ -1,5 +1,5 @@
// file: kb-pipeline-demo-scenarios/src/solana_ata_execution.rs
// version: 6
// version: 7
//! Devnet ATA execution with stateful and canonical post-validation.
@@ -433,8 +433,10 @@ where
},
};
let idempotent = second_replay.failed_inputs == 0
&& second_replay.processing_error_inputs == 0
&& second_replay.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.materialized_outputs == 0
&& processor.materialization_refused == 0;
});
@@ -885,11 +887,13 @@ where
fn decode_completed(summary: &kb_pipeline::DecodeReplaySummary) -> bool {
return summary.failed_inputs == 0
&& summary.processing_error_inputs == 0
&& summary.unmatched == 0
&& !summary.cancelled
&& summary.completed >= 1
&& summary.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.unsupported == 0
&& processor.materialization_refused == 0;
})
@@ -1182,8 +1186,10 @@ mod tests {
}));
assert!(summary.idempotence_replay.as_ref().is_some_and(|value| {
return value.failed_inputs == 0
&& value.processing_error_inputs == 0
&& value.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.materialized_outputs == 0
&& processor.materialization_refused == 0;
});

View File

@@ -1,5 +1,5 @@
// file: kb-pipeline-demo-scenarios/src/solana_execution.rs
// version: 7
// version: 8
//! Devnet Solana execution orchestration with canonical post-validation.
@@ -767,11 +767,14 @@ where
},
};
let processors_clean = decode.processors.iter().all(|processor| {
return processor.failed == 0 && processor.unsupported == 0;
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.unsupported == 0;
});
let decoded_observations =
decode.processors.iter().map(|processor| return processor.decoded).sum::<u64>();
let decode_replayed = decode.failed_inputs == 0
&& decode.processing_error_inputs == 0
&& decode.unmatched == 0
&& !decode.cancelled
&& decode.completed >= 1

View File

@@ -1,5 +1,5 @@
// file: kb-pipeline-demo-scenarios/src/solana_memo_execution.rs
// version: 2
// version: 3
//! Devnet SPL Memo v4 execution with canonical post-validation.
@@ -499,8 +499,10 @@ where
},
};
let idempotent = second_replay.failed_inputs == 0
&& second_replay.processing_error_inputs == 0
&& second_replay.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.materialized_outputs == 0
&& processor.materialization_refused == 0;
});
@@ -736,11 +738,13 @@ where
fn decode_completed(summary: &kb_pipeline::DecodeReplaySummary) -> bool {
return summary.failed_inputs == 0
&& summary.processing_error_inputs == 0
&& summary.unmatched == 0
&& !summary.cancelled
&& summary.completed >= 1
&& summary.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.unsupported == 0
&& processor.materialization_refused == 0;
})

View File

@@ -1,5 +1,5 @@
// file: kb-pipeline-demo-scenarios/src/solana_token2022_devnet_execution.rs
// version: 2
// file: kb-pipeline-demo-scenarios/src/solana_token_2022_devnet_execution.rs
// version: 4
//! Devnet Token-2022 execution with stateful and canonical post-validation.
@@ -112,7 +112,7 @@ struct PreparedToken2022Execution {
}
/// Simulates one Devnet Token-2022 operation after stateful preflight.
pub async fn simulate_devnet_spl_token2022<O>(
pub async fn simulate_devnet_spl_token_2022<O>(
http_pool: &kb_onchain_transport::HttpEndpointPool,
profile: &kb_config::ProfileConfig,
workspace_root: &std::path::Path,
@@ -124,7 +124,7 @@ where
{
if request.submit {
return std::result::Result::Err(kb_core::Error::config(
"simulate_devnet_spl_token2022 requires submit=false",
"simulate_devnet_spl_token_2022 requires submit=false",
));
}
let prepared =
@@ -137,7 +137,7 @@ where
/// Executes one Devnet Token-2022 simulation or authorized submission.
#[allow(clippy::too_many_arguments)]
pub async fn execute_devnet_spl_token2022<S, O>(
pub async fn execute_devnet_spl_token_2022<S, O>(
http_pool: &kb_onchain_transport::HttpEndpointPool,
store: &S,
profile: &kb_config::ProfileConfig,
@@ -335,7 +335,7 @@ where
&signature,
false,
request.force_post_validation_replay,
&[kb_program_ids::SPL_TOKEN2022_PROGRAM_ID],
&[kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID],
decoders,
materializers,
observer,
@@ -372,7 +372,7 @@ where
};
summary.materializations = rows
.into_iter()
.filter(|row| return row.source_decoder_name == "spl_token2022")
.filter(|row| return row.source_decoder_name == "spl_token_2022")
.collect();
diagnostic.materialized =
!summary.plan.policy.post_execution_validation.materialization_required
@@ -382,7 +382,7 @@ where
&signature,
true,
request.force_post_validation_replay,
&[kb_program_ids::SPL_TOKEN2022_PROGRAM_ID],
&[kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID],
decoders,
materializers,
observer,
@@ -399,8 +399,10 @@ where
},
};
let idempotent = second_replay.failed_inputs == 0
&& second_replay.processing_error_inputs == 0
&& second_replay.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.materialized_outputs == 0
&& processor.materialization_refused == 0;
});
@@ -463,7 +465,7 @@ where
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let readiness =
match kb_pipeline::inspect_token2022_preflight(http_pool, &preflight_request).await {
match kb_pipeline::inspect_token_2022_preflight(http_pool, &preflight_request).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
@@ -562,7 +564,7 @@ where
crate::emit(
observer,
crate::SolanaExecutionProgressLevel::Info,
"spl_token2022_simulation",
"spl_token_2022_simulation",
format!("simulating exact Token-2022 message {}", unsigned.message_hash()),
std::option::Option::None,
);
@@ -623,7 +625,7 @@ fn preflight_request(
kb_lib::ExSplToken2022Operation::Instruction { value } => value.as_ref(),
kb_lib::ExSplToken2022Operation::Batch { instructions: _ } => {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token2022_batch_not_supported",
"execution_spl_token_2022_batch_not_supported",
"Devnet Token-2022 validation scenarios require one non-batch operation",
));
},
@@ -749,7 +751,7 @@ fn preflight_request(
},
_ => {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token2022_devnet_operation_unsupported",
"execution_spl_token_2022_devnet_operation_unsupported",
format!(
"Token-2022 Devnet validation does not expose {}",
operation.operation_code()
@@ -760,8 +762,8 @@ fn preflight_request(
return std::result::Result::Ok(kb_pipeline::Token2022PreflightRequest {
query_role: request.query_role.clone(),
min_context_slot: std::option::Option::None,
max_accounts: kb_pipeline::MAX_TOKEN2022_PREFLIGHT_ACCOUNTS,
max_total_data_bytes: kb_pipeline::MAX_TOKEN2022_PREFLIGHT_TOTAL_BYTES,
max_accounts: kb_pipeline::MAX_TOKEN_2022_PREFLIGHT_ACCOUNTS,
max_total_data_bytes: kb_pipeline::MAX_TOKEN_2022_PREFLIGHT_TOTAL_BYTES,
requirements,
elgamal_registry: std::option::Option::None,
});
@@ -770,7 +772,7 @@ fn preflight_request(
fn validate_single_authority(authority: &kb_lib::ExSplTokenAuthority) -> kb_core::Result<()> {
if !authority.multisig_signers.is_empty() {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token2022_devnet_multisig_not_supported",
"execution_spl_token_2022_devnet_multisig_not_supported",
"the Devnet validation UI currently supports one profile-wallet authority",
));
}
@@ -910,7 +912,7 @@ fn validate_profile_wallet_signers(
) -> kb_core::Result<()> {
if required_signers.iter().any(|value| return value.as_str() != wallet_pubkey) {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token2022_external_signer_unavailable",
"execution_spl_token_2022_external_signer_unavailable",
format!(
"the Devnet Token orchestrator can sign only with profile wallet {}; required signers are {}",
wallet_pubkey,

View File

@@ -1,5 +1,5 @@
// file: kb-pipeline-demo-scenarios/src/solana_token2022_devnet_scenarios.rs
// version: 5
// file: kb-pipeline-demo-scenarios/src/solana_token_2022_devnet_scenarios.rs
// version: 6
//! Stable Devnet validation scenarios required to close milestone 0.4.6.
@@ -53,17 +53,17 @@ pub struct DevnetSplValidationScenario {
/// Returns the complete ordered Devnet scenario inventory for milestone 0.4.6.
pub fn devnet_spl_validation_scenarios() -> std::vec::Vec<crate::DevnetSplValidationScenario> {
return vec![
public_scenario("token2022_mint_to_checked", "Token-2022 MintToChecked", kb_lib::EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION, &["TOKEN2022_MINT", "TOKEN2022_SOURCE", "TOKEN2022_AUTHORITY", "TOKEN2022_DECIMALS", "TOKEN2022_MINT_AMOUNT_RAW"]),
public_scenario("token2022_transfer_checked", "Token-2022 TransferChecked", kb_lib::EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION, &["TOKEN2022_SOURCE", "TOKEN2022_MINT", "TOKEN2022_DESTINATION", "TOKEN2022_AUTHORITY", "TOKEN2022_DECIMALS", "TOKEN2022_TRANSFER_AMOUNT_RAW"]),
public_scenario("token2022_approve_checked", "Token-2022 ApproveChecked", kb_lib::EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION, &["TOKEN2022_SOURCE", "TOKEN2022_MINT", "TOKEN2022_DELEGATE", "TOKEN2022_AUTHORITY", "TOKEN2022_DECIMALS", "TOKEN2022_APPROVE_AMOUNT_RAW"]),
public_scenario("token2022_revoke", "Token-2022 Revoke", kb_lib::EX_SPL_TOKEN2022_REVOKE_OPERATION, &["TOKEN2022_SOURCE", "TOKEN2022_AUTHORITY"]),
public_scenario("token2022_burn_checked", "Token-2022 BurnChecked", kb_lib::EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION, &["TOKEN2022_SOURCE", "TOKEN2022_MINT", "TOKEN2022_AUTHORITY", "TOKEN2022_DECIMALS", "TOKEN2022_BURN_AMOUNT_RAW"]),
public_scenario("token2022_freeze_account", "Token-2022 FreezeAccount", kb_lib::EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION, &["TOKEN2022_SOURCE", "TOKEN2022_MINT", "TOKEN2022_FREEZE_AUTHORITY"]),
public_scenario("token2022_thaw_account", "Token-2022 ThawAccount", kb_lib::EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION, &["TOKEN2022_SOURCE", "TOKEN2022_MINT", "TOKEN2022_FREEZE_AUTHORITY"]),
public_scenario("token2022_close_destination", "Token-2022 CloseAccount destination", kb_lib::EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION, &["TOKEN2022_DESTINATION", "KB_DEVNET_WALLET_ADDRESS", "TOKEN2022_AUTHORITY"]),
public_scenario("token_2022_mint_to_checked", "Token-2022 MintToChecked", kb_lib::EX_SPL_TOKEN_2022_MINT_TO_CHECKED_OPERATION, &["TOKEN_2022_MINT", "TOKEN_2022_SOURCE", "TOKEN_2022_AUTHORITY", "TOKEN_2022_DECIMALS", "TOKEN_2022_MINT_AMOUNT_RAW"]),
public_scenario("token_2022_transfer_checked", "Token-2022 TransferChecked", kb_lib::EX_SPL_TOKEN_2022_TRANSFER_CHECKED_OPERATION, &["TOKEN_2022_SOURCE", "TOKEN_2022_MINT", "TOKEN_2022_DESTINATION", "TOKEN_2022_AUTHORITY", "TOKEN_2022_DECIMALS", "TOKEN_2022_TRANSFER_AMOUNT_RAW"]),
public_scenario("token_2022_approve_checked", "Token-2022 ApproveChecked", kb_lib::EX_SPL_TOKEN_2022_APPROVE_CHECKED_OPERATION, &["TOKEN_2022_SOURCE", "TOKEN_2022_MINT", "TOKEN_2022_DELEGATE", "TOKEN_2022_AUTHORITY", "TOKEN_2022_DECIMALS", "TOKEN_2022_APPROVE_AMOUNT_RAW"]),
public_scenario("token_2022_revoke", "Token-2022 Revoke", kb_lib::EX_SPL_TOKEN_2022_REVOKE_OPERATION, &["TOKEN_2022_SOURCE", "TOKEN_2022_AUTHORITY"]),
public_scenario("token_2022_burn_checked", "Token-2022 BurnChecked", kb_lib::EX_SPL_TOKEN_2022_BURN_CHECKED_OPERATION, &["TOKEN_2022_SOURCE", "TOKEN_2022_MINT", "TOKEN_2022_AUTHORITY", "TOKEN_2022_DECIMALS", "TOKEN_2022_BURN_AMOUNT_RAW"]),
public_scenario("token_2022_freeze_account", "Token-2022 FreezeAccount", kb_lib::EX_SPL_TOKEN_2022_FREEZE_ACCOUNT_OPERATION, &["TOKEN_2022_SOURCE", "TOKEN_2022_MINT", "TOKEN_2022_FREEZE_AUTHORITY"]),
public_scenario("token_2022_thaw_account", "Token-2022 ThawAccount", kb_lib::EX_SPL_TOKEN_2022_THAW_ACCOUNT_OPERATION, &["TOKEN_2022_SOURCE", "TOKEN_2022_MINT", "TOKEN_2022_FREEZE_AUTHORITY"]),
public_scenario("token_2022_close_destination", "Token-2022 CloseAccount destination", kb_lib::EX_SPL_TOKEN_2022_CLOSE_ACCOUNT_OPERATION, &["TOKEN_2022_DESTINATION", "KB_DEVNET_WALLET_ADDRESS", "TOKEN_2022_AUTHORITY"]),
registry_scenario("elgamal_registry_create", "ElGamal Registry CreateRegistry", "spl_elgamal_registry.create_registry", &["ELGAMAL_REGISTRY_ADDRESS", "ELGAMAL_PUBKEY_BASE64", "PUBKEY_VALIDITY_PROOF_CONTEXT"]),
registry_scenario("elgamal_registry_update", "ElGamal Registry UpdateRegistry", "spl_elgamal_registry.update_registry", &["ELGAMAL_REGISTRY_ADDRESS", "ELGAMAL_PUBKEY_BASE64", "PUBKEY_VALIDITY_PROOF_CONTEXT"]),
confidential_scenario("token2022_configure_confidential_account", "Token-2022 ConfigureAccountWithRegistry", kb_lib::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION, &["TOKEN2022_SOURCE", "TOKEN2022_MINT", "ELGAMAL_REGISTRY_ADDRESS", "PUBKEY_VALIDITY_PROOF_CONTEXT"]),
confidential_scenario("token_2022_configure_confidential_account", "Token-2022 ConfigureAccountWithRegistry", kb_lib::EX_SPL_TOKEN_2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION, &["TOKEN_2022_SOURCE", "TOKEN_2022_MINT", "ELGAMAL_REGISTRY_ADDRESS", "PUBKEY_VALIDITY_PROOF_CONTEXT"]),
];
}

View File

@@ -1,10 +1,10 @@
// file: kb-pipeline-demo-scenarios/src/solana_token2022_validation.rs
// version: 5
// file: kb-pipeline-demo-scenarios/src/solana_token_2022_validation.rs
// version: 6
//! Machine-readable validation evidence contract for the Token-2022 milestone.
/// Maximum number of evidence records accepted in one validation report.
pub const MAX_TOKEN2022_VALIDATION_EVIDENCE: usize = 64;
pub const MAX_TOKEN_2022_VALIDATION_EVIDENCE: usize = 64;
/// Required validation environment for one scenario.
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
@@ -110,31 +110,31 @@ pub struct Token2022ValidationMatrixScenario {
}
/// Loads and validates the canonical Token-2022 validation matrix.
pub fn load_token2022_validation_matrix() -> kb_core::Result<crate::Token2022ValidationMatrix> {
pub fn load_token_2022_validation_matrix() -> kb_core::Result<crate::Token2022ValidationMatrix> {
let parsed = match serde_json::from_str::<crate::Token2022ValidationMatrix>(include_str!(
"../../test-fixtures/contract-matrices/SPL_TOKEN2022_VALIDATION_MATRIX.json"
"../../test-fixtures/contract-matrices/SPL_TOKEN_2022_VALIDATION_MATRIX.json"
)) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_matrix_invalid_json",
"token_2022_validation_matrix_invalid_json",
format!("Token-2022 validation matrix JSON is invalid: {error}"),
));
},
};
if let std::result::Result::Err(error) = validate_token2022_validation_matrix(&parsed) {
if let std::result::Result::Err(error) = validate_token_2022_validation_matrix(&parsed) {
return std::result::Result::Err(error);
}
return std::result::Result::Ok(parsed);
}
/// Validates schema, scenario inventory, statuses, and observed evidence.
pub fn validate_token2022_validation_matrix(
pub fn validate_token_2022_validation_matrix(
matrix: &crate::Token2022ValidationMatrix,
) -> kb_core::Result<()> {
if matrix.matrix_version != 2 || matrix.milestone != "0.4.6" {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_matrix_contract_mismatch",
"token_2022_validation_matrix_contract_mismatch",
"Token-2022 validation matrix must use version 2 for milestone 0.4.6",
));
}
@@ -147,13 +147,13 @@ pub fn validate_token2022_validation_matrix(
.collect::<std::vec::Vec<&str>>();
if actual_statuses.as_slice() != expected_statuses {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_matrix_status_vocabulary_mismatch",
"token_2022_validation_matrix_status_vocabulary_mismatch",
"Token-2022 validation status vocabulary differs from the compiled contract",
));
}
let expected_ids = [
"offline_full_regression",
"token2022_public_devnet",
"token_2022_public_devnet",
"elgamal_registry_devnet",
"confidential_transfer_localnet_or_devnet",
"confidential_mint_burn_localnet_or_devnet",
@@ -169,16 +169,16 @@ pub fn validate_token2022_validation_matrix(
.collect::<std::vec::Vec<&str>>();
if actual_ids.as_slice() != expected_ids {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_matrix_scenario_inventory_mismatch",
"token_2022_validation_matrix_scenario_inventory_mismatch",
"Token-2022 validation scenario inventory or order differs from the compiled contract",
));
}
for scenario in &matrix.scenarios {
if scenario.required_evidence.is_empty()
|| scenario.required_evidence.len() > crate::MAX_TOKEN2022_VALIDATION_EVIDENCE
|| scenario.required_evidence.len() > crate::MAX_TOKEN_2022_VALIDATION_EVIDENCE
{
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_matrix_required_evidence_invalid",
"token_2022_validation_matrix_required_evidence_invalid",
"Every Token-2022 validation scenario must declare bounded required evidence",
));
}
@@ -186,7 +186,7 @@ pub fn validate_token2022_validation_matrix(
for evidence_kind in &scenario.required_evidence {
if evidence_kind.trim().is_empty() || !required.insert(evidence_kind.as_str()) {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_matrix_required_evidence_invalid",
"token_2022_validation_matrix_required_evidence_invalid",
"Required Token-2022 validation evidence must be non-empty and unique",
));
}
@@ -199,7 +199,7 @@ pub fn validate_token2022_validation_matrix(
.collect::<std::collections::BTreeSet<&str>>();
if !required.iter().all(|kind| return observed.contains(kind)) {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_matrix_confirmed_without_required_evidence",
"token_2022_validation_matrix_confirmed_without_required_evidence",
format!(
"Confirmed Token-2022 validation scenario {} lacks required evidence",
scenario.id
@@ -213,7 +213,7 @@ pub fn validate_token2022_validation_matrix(
) && !scenario.evidence.is_empty()
{
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_matrix_unobserved_with_evidence",
"token_2022_validation_matrix_unobserved_with_evidence",
"Not-run or unavailable Token-2022 scenarios must not retain observed evidence",
));
}
@@ -229,7 +229,7 @@ pub struct Token2022ValidationReport {
}
/// Validates that a milestone report is bounded, unique, and does not overclaim evidence.
pub fn validate_token2022_validation_report(
pub fn validate_token_2022_validation_report(
report: &crate::Token2022ValidationReport,
) -> kb_core::Result<()> {
if report.scenarios.is_empty() {
@@ -241,23 +241,23 @@ pub fn validate_token2022_validation_report(
for scenario in &report.scenarios {
if scenario.id.trim().is_empty() || !ids.insert(scenario.id.clone()) {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_scenario_identity_invalid",
"token_2022_validation_scenario_identity_invalid",
"Token-2022 validation scenario ids must be non-empty and unique",
));
}
if scenario.evidence.len() > crate::MAX_TOKEN2022_VALIDATION_EVIDENCE {
if scenario.evidence.len() > crate::MAX_TOKEN_2022_VALIDATION_EVIDENCE {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_evidence_limit_exceeded",
"token_2022_validation_evidence_limit_exceeded",
format!(
"Token-2022 validation accepts at most {} evidence records per scenario",
crate::MAX_TOKEN2022_VALIDATION_EVIDENCE
crate::MAX_TOKEN_2022_VALIDATION_EVIDENCE
),
));
}
for evidence in &scenario.evidence {
if evidence.kind.trim().is_empty() || evidence.value.trim().is_empty() {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_evidence_invalid",
"token_2022_validation_evidence_invalid",
"Token-2022 validation evidence kind and value must be non-empty",
));
}
@@ -271,7 +271,7 @@ pub fn validate_token2022_validation_report(
);
if completed && scenario.evidence.is_empty() {
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_completed_without_evidence",
"token_2022_validation_completed_without_evidence",
"A completed Token-2022 validation scenario must retain evidence",
));
}
@@ -284,7 +284,7 @@ pub fn validate_token2022_validation_report(
&& !has_pipeline_evidence(scenario)
{
return std::result::Result::Err(kb_core::Error::new(
"token2022_validation_confirmed_without_pipeline_evidence",
"token_2022_validation_confirmed_without_pipeline_evidence",
"A confirmed end-to-end Token-2022 scenario must retain hydration, extraction, replay, materialization, and idempotence evidence",
));
}
@@ -362,11 +362,11 @@ mod tests {
let report = crate::Token2022ValidationReport {
scenarios: vec![scenario(crate::Token2022ValidationStatus::Confirmed)],
};
assert!(crate::validate_token2022_validation_report(&report).is_ok());
assert!(crate::validate_token_2022_validation_report(&report).is_ok());
let mut incomplete = scenario(crate::Token2022ValidationStatus::Confirmed);
incomplete.evidence.retain(|evidence| return evidence.kind != "second_replay");
assert!(
crate::validate_token2022_validation_report(&crate::Token2022ValidationReport {
crate::validate_token_2022_validation_report(&crate::Token2022ValidationReport {
scenarios: vec![incomplete]
})
.is_err()
@@ -381,7 +381,7 @@ mod tests {
unavailable.id = "permissioned_burn_devnet".to_string();
unavailable.evidence.clear();
assert!(
crate::validate_token2022_validation_report(&crate::Token2022ValidationReport {
crate::validate_token_2022_validation_report(&crate::Token2022ValidationReport {
scenarios: vec![not_run, unavailable]
})
.is_ok()
@@ -393,7 +393,7 @@ mod tests {
let first = scenario(crate::Token2022ValidationStatus::Confirmed);
let duplicate = first.clone();
assert!(
crate::validate_token2022_validation_report(&crate::Token2022ValidationReport {
crate::validate_token_2022_validation_report(&crate::Token2022ValidationReport {
scenarios: vec![first, duplicate]
})
.is_err()
@@ -401,7 +401,7 @@ mod tests {
let mut failed = scenario(crate::Token2022ValidationStatus::Failed);
failed.evidence.clear();
assert!(
crate::validate_token2022_validation_report(&crate::Token2022ValidationReport {
crate::validate_token_2022_validation_report(&crate::Token2022ValidationReport {
scenarios: vec![failed]
})
.is_err()
@@ -410,7 +410,7 @@ mod tests {
#[test]
fn canonical_matrix_matches_compiled_inventory_and_observed_offline_evidence() {
let matrix = crate::load_token2022_validation_matrix();
let matrix = crate::load_token_2022_validation_matrix();
assert!(matrix.is_ok());
let matrix = match matrix {
std::result::Result::Ok(value) => value,
@@ -428,13 +428,13 @@ mod tests {
#[test]
fn confirmed_matrix_scenario_requires_every_declared_evidence_kind() {
let matrix = crate::load_token2022_validation_matrix();
let matrix = crate::load_token_2022_validation_matrix();
assert!(matrix.is_ok());
let mut matrix = match matrix {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("unexpected matrix error: {error}"),
};
matrix.scenarios[0].evidence.retain(|evidence| return evidence.kind != "clippy");
assert!(crate::validate_token2022_validation_matrix(&matrix).is_err());
assert!(crate::validate_token_2022_validation_matrix(&matrix).is_err());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-pipeline-demo-scenarios/src/solana_token_execution.rs
// version: 6
// version: 7
//! Devnet classic SPL Token execution with stateful and canonical post-validation.
@@ -399,8 +399,10 @@ where
},
};
let idempotent = second_replay.failed_inputs == 0
&& second_replay.processing_error_inputs == 0
&& second_replay.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.materialized_outputs == 0
&& processor.materialization_refused == 0;
});
@@ -956,11 +958,13 @@ where
pub(crate) fn decode_completed(summary: &kb_pipeline::DecodeReplaySummary) -> bool {
return summary.failed_inputs == 0
&& summary.processing_error_inputs == 0
&& summary.unmatched == 0
&& !summary.cancelled
&& summary.completed >= 1
&& summary.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.unsupported == 0
&& processor.materialization_refused == 0;
})
@@ -1207,7 +1211,9 @@ mod tests {
};
assert_eq!(first_replay.failed_inputs, 0);
assert!(first_replay.processors.iter().all(|processor| {
return processor.failed == 0 && processor.materialization_refused == 0;
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.materialization_refused == 0;
}));
let idempotence_replay = match summary.idempotence_replay.as_ref() {
std::option::Option::Some(value) => value,
@@ -1216,6 +1222,7 @@ mod tests {
assert_eq!(idempotence_replay.failed_inputs, 0);
assert!(idempotence_replay.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.materialized_outputs == 0
&& processor.materialization_refused == 0;
}));

View File

@@ -1,5 +1,5 @@
// file: kb-pipeline-demo-scenarios/src/solana_token_lifecycle.rs
// version: 5
// version: 6
//! Controlled Devnet lifecycle for freshly prepared classic SPL Token accounts.
@@ -707,8 +707,10 @@ where
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let idempotent = second_replay.failed_inputs == 0
&& second_replay.processing_error_inputs == 0
&& second_replay.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.materialized_outputs == 0
&& processor.materialization_refused == 0;
});
@@ -1256,8 +1258,10 @@ fn validated_step(
};
let idempotence = summary.idempotence_replay.as_ref().is_some_and(|value| {
return value.failed_inputs == 0
&& value.processing_error_inputs == 0
&& value.processors.iter().all(|processor| {
return processor.failed == 0
&& processor.processing_errors == 0
&& processor.materialized_outputs == 0
&& processor.materialization_refused == 0;
});