20260605 ROA增量验证和rsync host失败短路

This commit is contained in:
2026-06-06 15:16:38 +08:00
parent e597c7c124
commit 4045f9a3a5
27 changed files with 2850 additions and 221 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -79,6 +79,7 @@ pub fn run_publication_point_once(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let result = runner

View File

@@ -94,6 +94,7 @@ pub struct RunTreeFromTalAuditOutput {
pub successful_tal_inputs: Vec<TalInputSpec>,
pub tree: TreeRunOutput,
pub publication_points: Vec<PublicationPointAudit>,
pub roa_cache_stats: crate::validation::objects::RoaValidationCacheStats,
pub downloads: Vec<crate::audit::AuditDownloadEvent>,
pub download_stats: crate::audit::AuditDownloadStats,
pub current_repo_objects: Vec<CurrentRepoObject>,
@@ -132,6 +133,7 @@ fn make_live_runner<'a>(
parallel_phase2_config: Option<ParallelPhase2Config>,
ccr_accumulator: Option<CcrAccumulator>,
persist_vcir: bool,
enable_roa_validation_cache: bool,
) -> Rpkiv1PublicationPointRunner<'a> {
let parallel_roa_worker_pool = parallel_phase2_config
.as_ref()
@@ -156,6 +158,7 @@ fn make_live_runner<'a>(
parallel_roa_worker_pool,
ccr_accumulator: ccr_accumulator.map(Mutex::new),
persist_vcir,
enable_roa_validation_cache,
}
}
@@ -186,13 +189,18 @@ where
);
let pool = RepoTransportWorkerPool::new(RepoWorkerPoolConfig::from(&parallel_config), executor)
.map_err(RunTreeFromTalError::Replay)?;
let resolver_rsync_fetcher_arc = Arc::clone(&rsync_fetcher_arc);
let resolver: Arc<dyn Fn(&str) -> String + Send + Sync> =
Arc::new(move |base: &str| rsync_fetcher_arc.dedup_key(base));
Arc::new(move |base: &str| resolver_rsync_fetcher_arc.dedup_key(base));
let failure_rsync_fetcher_arc = Arc::clone(&rsync_fetcher_arc);
let failure_resolver: Arc<dyn Fn(&str) -> Option<String> + Send + Sync> =
Arc::new(move |base: &str| failure_rsync_fetcher_arc.failure_dedup_key(base));
let _ = policy; // policy reserved for later runtime-level decisions
let runtime = Arc::new(Phase1RepoSyncRuntime::new(
let runtime = Arc::new(Phase1RepoSyncRuntime::new_with_failure_scope(
coordinator,
pool,
resolver,
failure_resolver,
policy.sync_preference,
));
Ok((runtime, current_repo_index))
@@ -419,6 +427,7 @@ pub fn run_tree_from_tal_url_serial(
None,
None,
config.persist_vcir,
config.enable_roa_validation_cache,
);
let root = root_handle_from_trust_anchor(
@@ -458,6 +467,7 @@ pub fn run_tree_from_tal_url_serial_audit(
None,
None,
config.persist_vcir,
config.enable_roa_validation_cache,
);
let root = root_handle_from_trust_anchor(
@@ -469,6 +479,7 @@ pub fn run_tree_from_tal_url_serial_audit(
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &runner, config)?;
let downloads = download_log.snapshot_events();
@@ -479,6 +490,7 @@ pub fn run_tree_from_tal_url_serial_audit(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -515,6 +527,7 @@ pub fn run_tree_from_tal_url_serial_audit_with_timing(
None,
None,
config.persist_vcir,
config.enable_roa_validation_cache,
);
let root = root_handle_from_trust_anchor(
@@ -527,6 +540,7 @@ pub fn run_tree_from_tal_url_serial_audit_with_timing(
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &runner, config)?;
let downloads = download_log.snapshot_events();
@@ -537,6 +551,7 @@ pub fn run_tree_from_tal_url_serial_audit_with_timing(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -556,6 +571,7 @@ fn run_single_root_parallel_audit_inner<H, R>(
parallel_config: ParallelPhase1Config,
phase2_config: Option<ParallelPhase2Config>,
collect_current_repo_objects: bool,
timing: Option<TimingHandle>,
) -> Result<RunTreeFromTalAuditOutput, RunTreeFromTalError>
where
H: Fetcher + Clone + 'static,
@@ -569,7 +585,7 @@ where
http_fetcher,
rsync_fetcher,
parallel_config,
None,
timing.clone(),
Some(download_log.clone()),
tal_inputs,
)?;
@@ -580,7 +596,7 @@ where
http_fetcher,
rsync_fetcher,
validation_time,
None,
timing,
Some(download_log.clone()),
Some(current_repo_index),
Some(runtime),
@@ -588,6 +604,7 @@ where
(phase2_enabled && config.build_ccr_accumulator)
.then(|| CcrAccumulator::new(vec![discovery.trust_anchor.clone()])),
config.persist_vcir,
config.enable_roa_validation_cache,
);
let root = root_handle_from_trust_anchor(
@@ -599,6 +616,7 @@ where
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = if phase2_enabled {
run_tree_parallel_phase2_audit(root, &runner, config)?
} else {
@@ -612,6 +630,7 @@ where
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: snapshot_current_repo_objects(
@@ -633,6 +652,7 @@ fn run_multi_root_parallel_audit_inner<H, R>(
parallel_config: ParallelPhase1Config,
phase2_config: Option<ParallelPhase2Config>,
collect_current_repo_objects: bool,
timing: Option<TimingHandle>,
) -> Result<RunTreeFromTalAuditOutput, RunTreeFromTalError>
where
H: Fetcher + Clone + 'static,
@@ -673,7 +693,7 @@ where
http_fetcher,
rsync_fetcher,
parallel_config,
None,
timing.clone(),
Some(download_log.clone()),
successful_tal_inputs.clone(),
)?;
@@ -684,7 +704,7 @@ where
http_fetcher,
rsync_fetcher,
validation_time,
None,
timing,
Some(download_log.clone()),
Some(current_repo_index),
Some(runtime),
@@ -698,11 +718,13 @@ where
)
}),
config.persist_vcir,
config.enable_roa_validation_cache,
);
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = if phase2_enabled {
run_tree_parallel_phase2_audit_multi_root(root_handles, &runner, config)?
} else {
@@ -716,6 +738,7 @@ where
successful_tal_inputs,
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: snapshot_current_repo_objects(
@@ -755,6 +778,7 @@ where
parallel_config,
None,
collect_current_repo_objects,
None,
)
}
@@ -806,6 +830,7 @@ where
parallel_config,
None,
collect_current_repo_objects,
None,
)
}
@@ -835,6 +860,7 @@ where
parallel_config,
None,
collect_current_repo_objects,
None,
)
}
@@ -868,6 +894,42 @@ where
parallel_config,
Some(phase2_config),
collect_current_repo_objects,
None,
)
}
pub fn run_tree_from_tal_url_parallel_phase2_audit_with_timing<H, R>(
store: Arc<crate::storage::RocksStore>,
policy: &crate::policy::Policy,
tal_url: &str,
http_fetcher: &H,
rsync_fetcher: &R,
validation_time: time::OffsetDateTime,
config: &TreeRunConfig,
parallel_config: ParallelPhase1Config,
phase2_config: ParallelPhase2Config,
collect_current_repo_objects: bool,
timing: &TimingHandle,
) -> Result<RunTreeFromTalAuditOutput, RunTreeFromTalError>
where
H: Fetcher + Clone + 'static,
R: crate::fetch::rsync::RsyncFetcher + Clone + 'static,
{
let discovery =
discover_root_ca_instance_from_tal_url_with_policy(policy, http_fetcher, tal_url)?;
run_single_root_parallel_audit_inner(
store,
policy,
discovery,
vec![TalInputSpec::from_url(tal_url.to_string())],
http_fetcher,
rsync_fetcher,
validation_time,
config,
parallel_config,
Some(phase2_config),
collect_current_repo_objects,
Some(timing.clone()),
)
}
@@ -920,6 +982,61 @@ where
parallel_config,
Some(phase2_config),
collect_current_repo_objects,
None,
)
}
pub fn run_tree_from_tal_and_ta_der_parallel_phase2_audit_with_timing<H, R>(
store: Arc<crate::storage::RocksStore>,
policy: &crate::policy::Policy,
tal_bytes: &[u8],
ta_der: &[u8],
resolved_ta_uri: Option<&url::Url>,
http_fetcher: &H,
rsync_fetcher: &R,
validation_time: time::OffsetDateTime,
config: &TreeRunConfig,
parallel_config: ParallelPhase1Config,
phase2_config: ParallelPhase2Config,
collect_current_repo_objects: bool,
timing: &TimingHandle,
) -> Result<RunTreeFromTalAuditOutput, RunTreeFromTalError>
where
H: Fetcher + Clone + 'static,
R: crate::fetch::rsync::RsyncFetcher + Clone + 'static,
{
let discovery = discover_root_ca_instance_from_tal_and_ta_der_with_policy(
policy,
tal_bytes,
ta_der,
resolved_ta_uri,
)?;
let derived_tal_id = derive_tal_id(&discovery);
let tal_inputs = vec![TalInputSpec {
tal_id: derived_tal_id.clone(),
rir_id: derived_tal_id,
source: TalSource::DerBytes {
tal_url: discovery
.tal_url
.clone()
.unwrap_or_else(|| "embedded-tal".to_string()),
tal_bytes: tal_bytes.to_vec(),
ta_der: ta_der.to_vec(),
},
}];
run_single_root_parallel_audit_inner(
store,
policy,
discovery,
tal_inputs,
http_fetcher,
rsync_fetcher,
validation_time,
config,
parallel_config,
Some(phase2_config),
collect_current_repo_objects,
Some(timing.clone()),
)
}
@@ -950,6 +1067,39 @@ where
parallel_config,
Some(phase2_config),
collect_current_repo_objects,
None,
)
}
pub fn run_tree_from_multiple_tals_parallel_phase2_audit_with_timing<H, R>(
store: Arc<crate::storage::RocksStore>,
policy: &crate::policy::Policy,
tal_inputs: Vec<TalInputSpec>,
http_fetcher: &H,
rsync_fetcher: &R,
validation_time: time::OffsetDateTime,
config: &TreeRunConfig,
parallel_config: ParallelPhase1Config,
phase2_config: ParallelPhase2Config,
collect_current_repo_objects: bool,
timing: &TimingHandle,
) -> Result<RunTreeFromTalAuditOutput, RunTreeFromTalError>
where
H: Fetcher + Clone + 'static,
R: crate::fetch::rsync::RsyncFetcher + Clone + 'static,
{
run_multi_root_parallel_audit_inner(
store,
policy,
tal_inputs,
http_fetcher,
rsync_fetcher,
validation_time,
config,
parallel_config,
Some(phase2_config),
collect_current_repo_objects,
Some(timing.clone()),
)
}
@@ -991,6 +1141,7 @@ pub fn run_tree_from_tal_and_ta_der_serial(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
};
let root = root_handle_from_trust_anchor(
@@ -1043,6 +1194,7 @@ pub fn run_tree_from_tal_bytes_serial_audit(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
};
let root = root_handle_from_trust_anchor(
@@ -1054,6 +1206,7 @@ pub fn run_tree_from_tal_bytes_serial_audit(
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &runner, config)?;
let downloads = download_log.snapshot_events();
@@ -1064,6 +1217,7 @@ pub fn run_tree_from_tal_bytes_serial_audit(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -1113,6 +1267,7 @@ pub fn run_tree_from_tal_bytes_serial_audit_with_timing(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
};
let root = root_handle_from_trust_anchor(
@@ -1125,6 +1280,7 @@ pub fn run_tree_from_tal_bytes_serial_audit_with_timing(
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &runner, config)?;
drop(_tree);
@@ -1136,6 +1292,7 @@ pub fn run_tree_from_tal_bytes_serial_audit_with_timing(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -1182,6 +1339,7 @@ pub fn run_tree_from_tal_and_ta_der_serial_audit(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
};
let root = root_handle_from_trust_anchor(
@@ -1193,6 +1351,7 @@ pub fn run_tree_from_tal_and_ta_der_serial_audit(
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &runner, config)?;
let downloads = download_log.snapshot_events();
@@ -1203,6 +1362,7 @@ pub fn run_tree_from_tal_and_ta_der_serial_audit(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -1252,6 +1412,7 @@ pub fn run_tree_from_tal_and_ta_der_serial_audit_with_timing(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
};
let root = root_handle_from_trust_anchor(
@@ -1264,6 +1425,7 @@ pub fn run_tree_from_tal_and_ta_der_serial_audit_with_timing(
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &runner, config)?;
let downloads = download_log.snapshot_events();
@@ -1274,6 +1436,7 @@ pub fn run_tree_from_tal_and_ta_der_serial_audit_with_timing(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -1329,6 +1492,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
};
let root = root_handle_from_trust_anchor(
@@ -1391,6 +1555,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial_audit(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
};
let root = root_handle_from_trust_anchor(
@@ -1402,6 +1567,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial_audit(
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &runner, config)?;
let downloads = download_log.snapshot_events();
@@ -1412,6 +1578,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial_audit(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -1471,6 +1638,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial_audit_with_timing(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
};
let root = root_handle_from_trust_anchor(
@@ -1483,6 +1651,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial_audit_with_timing(
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &runner, config)?;
let downloads = download_log.snapshot_events();
@@ -1493,6 +1662,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial_audit_with_timing(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -1509,6 +1679,7 @@ fn build_payload_replay_runner<'a>(
validation_time: time::OffsetDateTime,
timing: Option<TimingHandle>,
download_log: Option<DownloadLogHandle>,
enable_roa_validation_cache: bool,
) -> Rpkiv1PublicationPointRunner<'a> {
Rpkiv1PublicationPointRunner {
store,
@@ -1530,6 +1701,7 @@ fn build_payload_replay_runner<'a>(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache,
}
}
@@ -1542,6 +1714,7 @@ fn build_payload_delta_replay_runner<'a>(
validation_time: time::OffsetDateTime,
timing: Option<TimingHandle>,
download_log: Option<DownloadLogHandle>,
enable_roa_validation_cache: bool,
) -> Rpkiv1PublicationPointRunner<'a> {
Rpkiv1PublicationPointRunner {
store,
@@ -1563,6 +1736,7 @@ fn build_payload_delta_replay_runner<'a>(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache,
}
}
@@ -1575,6 +1749,7 @@ fn build_payload_delta_replay_current_store_runner<'a>(
validation_time: time::OffsetDateTime,
timing: Option<TimingHandle>,
download_log: Option<DownloadLogHandle>,
enable_roa_validation_cache: bool,
) -> Rpkiv1PublicationPointRunner<'a> {
Rpkiv1PublicationPointRunner {
store,
@@ -1596,6 +1771,7 @@ fn build_payload_delta_replay_current_store_runner<'a>(
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache,
}
}
@@ -1648,6 +1824,7 @@ fn run_payload_delta_replay_audit_inner(
base_validation_time,
Some(t.clone()),
None,
config.enable_roa_validation_cache,
);
let _base = run_tree_serial(root.clone(), &base_runner, config)?;
} else {
@@ -1660,6 +1837,7 @@ fn run_payload_delta_replay_audit_inner(
base_validation_time,
None,
None,
config.enable_roa_validation_cache,
);
let _base = run_tree_serial(root.clone(), &base_runner, config)?;
}
@@ -1668,7 +1846,7 @@ fn run_payload_delta_replay_audit_inner(
.map_err(|e| RunTreeFromTalError::Replay(e.to_string()))?;
let delta_rsync_fetcher = PayloadDeltaReplayRsyncFetcher::new(base_index, delta_index.clone());
let download_log = DownloadLogHandle::new();
let (tree, publication_points) = if let Some(t) = timing.as_ref() {
let (tree, publication_points, roa_cache_stats) = if let Some(t) = timing.as_ref() {
let _phase = t.span_phase("payload_delta_replay_target_total");
let delta_runner = build_payload_delta_replay_runner(
store,
@@ -1679,12 +1857,14 @@ fn run_payload_delta_replay_audit_inner(
base_validation_time,
Some(t.clone()),
Some(download_log.clone()),
config.enable_roa_validation_cache,
);
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &delta_runner, config)?;
(tree, publication_points)
(tree, publication_points, roa_cache_stats)
} else {
let delta_runner = build_payload_delta_replay_runner(
store,
@@ -1695,12 +1875,14 @@ fn run_payload_delta_replay_audit_inner(
validation_time,
None,
Some(download_log.clone()),
config.enable_roa_validation_cache,
);
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &delta_runner, config)?;
(tree, publication_points)
(tree, publication_points, roa_cache_stats)
};
let downloads = download_log.snapshot_events();
let download_stats = DownloadLogHandle::stats_from_events(&downloads);
@@ -1710,6 +1892,7 @@ fn run_payload_delta_replay_audit_inner(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -1822,7 +2005,7 @@ fn run_payload_delta_replay_step_audit_inner(
PayloadDeltaReplayCurrentStoreRsyncFetcher::new(store, delta_index.clone());
let download_log = DownloadLogHandle::new();
let (tree, publication_points) = if let Some(t) = timing.as_ref() {
let (tree, publication_points, roa_cache_stats) = if let Some(t) = timing.as_ref() {
let _phase = t.span_phase("payload_delta_replay_step_total");
let delta_runner = build_payload_delta_replay_current_store_runner(
store,
@@ -1833,12 +2016,14 @@ fn run_payload_delta_replay_step_audit_inner(
validation_time,
Some(t.clone()),
Some(download_log.clone()),
config.enable_roa_validation_cache,
);
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &delta_runner, config)?;
(tree, publication_points)
(tree, publication_points, roa_cache_stats)
} else {
let delta_runner = build_payload_delta_replay_current_store_runner(
store,
@@ -1849,12 +2034,14 @@ fn run_payload_delta_replay_step_audit_inner(
validation_time,
None,
Some(download_log.clone()),
config.enable_roa_validation_cache,
);
let TreeRunAuditOutput {
tree,
publication_points,
roa_cache_stats,
} = run_tree_serial_audit(root, &delta_runner, config)?;
(tree, publication_points)
(tree, publication_points, roa_cache_stats)
};
let downloads = download_log.snapshot_events();
let download_stats = DownloadLogHandle::stats_from_events(&downloads);
@@ -1864,6 +2051,7 @@ fn run_payload_delta_replay_step_audit_inner(
successful_tal_inputs: Vec::new(),
tree,
publication_points,
roa_cache_stats,
downloads,
download_stats,
current_repo_objects: Vec::new(),
@@ -2140,6 +2328,7 @@ mod replay_api_tests {
compact_audit: false,
persist_vcir: true,
build_ccr_accumulator: true,
enable_roa_validation_cache: false,
},
)
.unwrap_err();
@@ -2175,6 +2364,7 @@ mod replay_api_tests {
compact_audit: false,
persist_vcir: true,
build_ccr_accumulator: true,
enable_roa_validation_cache: false,
},
)
.expect("run replay root-only audit");
@@ -2220,6 +2410,7 @@ mod replay_api_tests {
compact_audit: false,
persist_vcir: true,
build_ccr_accumulator: true,
enable_roa_validation_cache: false,
},
)
.expect("run replay root-only audit");
@@ -2266,6 +2457,7 @@ mod replay_api_tests {
compact_audit: false,
persist_vcir: true,
build_ccr_accumulator: true,
enable_roa_validation_cache: false,
},
&timing,
)
@@ -2322,6 +2514,7 @@ mod replay_api_tests {
compact_audit: false,
persist_vcir: true,
build_ccr_accumulator: true,
enable_roa_validation_cache: false,
},
)
.unwrap_err();
@@ -2354,6 +2547,7 @@ mod replay_api_tests {
compact_audit: false,
persist_vcir: true,
build_ccr_accumulator: true,
enable_roa_validation_cache: false,
},
)
.unwrap_err();
@@ -2406,6 +2600,7 @@ mod replay_api_tests {
compact_audit: false,
persist_vcir: true,
build_ccr_accumulator: true,
enable_roa_validation_cache: false,
},
)
.expect("run delta replay root-only audit");
@@ -2467,6 +2662,7 @@ mod replay_api_tests {
compact_audit: false,
persist_vcir: true,
build_ccr_accumulator: true,
enable_roa_validation_cache: false,
},
&timing,
)

View File

@@ -3,7 +3,9 @@ use crate::audit::PublicationPointAudit;
use crate::data_model::rc::{AsResourceSet, IpResourceSet};
use crate::report::Warning;
use crate::validation::manifest::PublicationPointSource;
use crate::validation::objects::{AspaAttestation, ObjectsOutput, RouterKeyPayload, Vrp};
use crate::validation::objects::{
AspaAttestation, ObjectsOutput, RoaValidationCacheStats, RouterKeyPayload, Vrp,
};
use crate::validation::publication_point::PublicationPointSnapshot;
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -18,6 +20,8 @@ pub struct TreeRunConfig {
pub persist_vcir: bool,
/// Build online CCR manifest projections during phase2 validation.
pub build_ccr_accumulator: bool,
/// Reuse accepted ROA validation outputs from previous VCIR when explicitly enabled.
pub enable_roa_validation_cache: bool,
}
impl Default for TreeRunConfig {
@@ -28,6 +32,7 @@ impl Default for TreeRunConfig {
compact_audit: false,
persist_vcir: true,
build_ccr_accumulator: true,
enable_roa_validation_cache: false,
}
}
}
@@ -117,6 +122,7 @@ pub trait PublicationPointRunner {
pub struct TreeRunAuditOutput {
pub tree: TreeRunOutput,
pub publication_points: Vec<PublicationPointAudit>,
pub roa_cache_stats: RoaValidationCacheStats,
}
pub fn run_tree_serial(
@@ -169,6 +175,7 @@ pub fn run_tree_serial_audit_multi_root(
let mut aspas: Vec<AspaAttestation> = Vec::new();
let mut router_keys: Vec<RouterKeyPayload> = Vec::new();
let mut publication_points: Vec<PublicationPointAudit> = Vec::new();
let mut roa_cache_stats = RoaValidationCacheStats::default();
while let Some(node) = queue.pop_front() {
let ca = &node.handle;
@@ -203,6 +210,7 @@ pub fn run_tree_serial_audit_multi_root(
instances_processed += 1;
warnings.extend(res.warnings);
warnings.extend(res.objects.warnings);
roa_cache_stats.add_assign(&res.objects.roa_cache_stats);
vrps.extend(res.objects.vrps);
aspas.extend(res.objects.aspas);
router_keys.extend(res.objects.router_keys);
@@ -255,6 +263,7 @@ pub fn run_tree_serial_audit_multi_root(
router_keys,
},
publication_points,
roa_cache_stats,
})
}
@@ -338,6 +347,7 @@ mod tests {
warnings: Vec::new(),
stats: ObjectsStats::default(),
audit: Vec::new(),
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
},
audit: PublicationPointAudit::default(),
discovered_children: children,

View File

@@ -8,9 +8,11 @@ use crate::parallel::repo_runtime::{RepoSyncRequestStatus, RepoSyncRuntimeOutcom
use crate::parallel::types::RepoIdentity;
use crate::policy::SignedObjectFailurePolicy;
use crate::report::Warning;
use crate::validation::manifest::PublicationPointData;
use crate::validation::objects::{
ObjectsOutput, OwnedRoaTask, ParallelObjectsPrepare, ParallelObjectsStage,
prepare_publication_point_for_parallel_roa, reduce_parallel_roa_stage,
RoaValidationCacheInput, prepare_publication_point_for_parallel_roa_with_cache,
reduce_parallel_roa_stage,
};
use crate::validation::tree::{
CaInstanceHandle, DiscoveredChildCaInstance, PublicationPointRunResult, PublicationPointRunner,
@@ -888,7 +890,32 @@ fn stage_ready_publication_point(
metrics.child_enqueue_ms = elapsed_ms(child_enqueue_started);
let prepare_started = Instant::now();
match prepare_publication_point_for_parallel_roa(
let has_roa = fresh_stage
.fresh_point
.files()
.iter()
.any(|file| file.rsync_uri.ends_with(".roa"));
if runner.enable_roa_validation_cache {
if let Some(timing) = runner.timing.as_ref() {
if has_roa {
timing.record_count("roa_validation_cache_roa_candidate_publication_points", 1);
} else {
timing.record_count("roa_validation_cache_skipped_no_roa_publication_points", 1);
}
}
}
let roa_cache_view = if has_roa {
runner
.roa_validation_cache_view_for_fresh_point(&fresh_stage.fresh_point.manifest_rsync_uri)
} else {
None
};
let roa_cache = if runner.enable_roa_validation_cache && has_roa {
RoaValidationCacheInput::enabled(roa_cache_view.as_ref())
} else {
RoaValidationCacheInput::disabled()
};
match prepare_publication_point_for_parallel_roa_with_cache(
ready.node.id,
&fresh_stage.fresh_point,
runner.policy,
@@ -898,6 +925,7 @@ fn stage_ready_publication_point(
ready.node.handle.effective_as_resources.as_ref(),
runner.validation_time,
runner.persist_vcir,
roa_cache,
) {
ParallelObjectsPrepare::Complete(mut objects) => {
metrics.prepare_ms = elapsed_ms(prepare_started);
@@ -1571,6 +1599,7 @@ fn build_tree_output(mut finished: Vec<FinishedPublicationPoint>) -> TreeRunAudi
let mut aspas = Vec::new();
let mut router_keys = Vec::new();
let mut publication_points = Vec::new();
let mut roa_cache_stats = crate::validation::objects::RoaValidationCacheStats::default();
for item in finished {
match item.result {
@@ -1582,6 +1611,7 @@ fn build_tree_output(mut finished: Vec<FinishedPublicationPoint>) -> TreeRunAudi
instances_processed += 1;
warnings.extend(result_warnings);
warnings.extend(objects.warnings);
roa_cache_stats.add_assign(&objects.roa_cache_stats);
vrps.extend(objects.vrps);
aspas.extend(objects.aspas);
router_keys.extend(objects.router_keys);
@@ -1612,6 +1642,7 @@ fn build_tree_output(mut finished: Vec<FinishedPublicationPoint>) -> TreeRunAudi
router_keys,
},
publication_points,
roa_cache_stats,
}
}
@@ -1669,6 +1700,7 @@ mod tests {
warnings: Vec::new(),
stats: ObjectsStats::default(),
audit: Vec::new(),
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
},
audit: PublicationPointAudit::default(),
discovered_children: Vec::new(),

View File

@@ -45,9 +45,9 @@ use crate::validation::manifest::{
process_manifest_publication_point_fresh_after_repo_sync_with_timing,
};
use crate::validation::objects::{
AspaAttestation, ParallelRoaWorkerPool, RouterKeyPayload, Vrp,
process_publication_point_for_issuer_parallel_roa_with_options,
process_publication_point_for_issuer_parallel_roa_with_pool_options,
AspaAttestation, ParallelRoaWorkerPool, RoaValidationCacheInput, RoaValidationCacheView,
RouterKeyPayload, Vrp, process_publication_point_for_issuer_parallel_roa_with_cache_options,
process_publication_point_for_issuer_parallel_roa_with_pool_cache_options,
};
use crate::validation::publication_point::PublicationPointSnapshot;
use crate::validation::tree::{
@@ -151,9 +151,59 @@ pub struct Rpkiv1PublicationPointRunner<'a> {
/// This is intended for replay/compare-only runs where the caller does not need
/// the resulting DB to be reused by a later delta run.
pub persist_vcir: bool,
pub enable_roa_validation_cache: bool,
}
impl<'a> Rpkiv1PublicationPointRunner<'a> {
pub(crate) fn roa_validation_cache_view_for_fresh_point(
&self,
manifest_rsync_uri: &str,
) -> Option<RoaValidationCacheView> {
if !self.enable_roa_validation_cache {
return None;
}
let load_started = std::time::Instant::now();
let loaded_vcir = self.store.get_vcir(manifest_rsync_uri);
if let Some(timing) = self.timing.as_ref() {
timing.record_phase_nanos(
"roa_validation_cache_vcir_load_total",
load_started.elapsed().as_nanos().min(u128::from(u64::MAX)) as u64,
);
}
match loaded_vcir {
Ok(Some(vcir)) => {
let view_started = std::time::Instant::now();
let view = RoaValidationCacheView::from_vcir(&vcir, self.validation_time);
if let Some(timing) = self.timing.as_ref() {
timing.record_phase_nanos(
"roa_validation_cache_view_build_total",
view_started.elapsed().as_nanos().min(u128::from(u64::MAX)) as u64,
);
}
Some(view)
}
Ok(None) => {
if let Some(timing) = self.timing.as_ref() {
timing.record_count("roa_validation_cache_vcir_missing_publication_points", 1);
}
None
}
Err(err) => {
if let Some(timing) = self.timing.as_ref() {
timing.record_count("roa_validation_cache_vcir_load_errors", 1);
}
crate::progress_log::emit(
"roa_validation_cache_vcir_load_error",
serde_json::json!({
"manifest_rsync_uri": manifest_rsync_uri,
"error": err.to_string(),
}),
);
None
}
}
}
pub(crate) fn ccr_accumulator_snapshot(&self) -> Option<CcrAccumulator> {
self.ccr_accumulator
.as_ref()
@@ -653,6 +703,35 @@ impl<'a> PublicationPointRunner for Rpkiv1PublicationPointRunner<'a> {
} = stage;
warnings.extend(stage_warnings);
let has_roa = fresh_point
.files()
.iter()
.any(|file| file.rsync_uri.ends_with(".roa"));
if self.enable_roa_validation_cache {
if let Some(timing) = self.timing.as_ref() {
if has_roa {
timing.record_count(
"roa_validation_cache_roa_candidate_publication_points",
1,
);
} else {
timing.record_count(
"roa_validation_cache_skipped_no_roa_publication_points",
1,
);
}
}
}
let roa_cache_view = if has_roa {
self.roa_validation_cache_view_for_fresh_point(fresh_point.manifest_rsync_uri())
} else {
None
};
let roa_cache = if self.enable_roa_validation_cache && has_roa {
RoaValidationCacheInput::enabled(roa_cache_view.as_ref())
} else {
RoaValidationCacheInput::disabled()
};
let objects_processing_started = std::time::Instant::now();
let mut objects = {
let _objects_total = self
@@ -660,7 +739,7 @@ impl<'a> PublicationPointRunner for Rpkiv1PublicationPointRunner<'a> {
.as_ref()
.map(|t| t.span_phase("objects_processing_total"));
if let Some(phase2_pool) = self.parallel_roa_worker_pool.as_ref() {
process_publication_point_for_issuer_parallel_roa_with_pool_options(
process_publication_point_for_issuer_parallel_roa_with_pool_cache_options(
&fresh_point,
self.policy,
&ca.ca_certificate_der,
@@ -671,9 +750,10 @@ impl<'a> PublicationPointRunner for Rpkiv1PublicationPointRunner<'a> {
self.timing.as_ref(),
phase2_pool,
false,
roa_cache,
)
} else if let Some(phase2_config) = self.parallel_phase2_config.as_ref() {
process_publication_point_for_issuer_parallel_roa_with_options(
process_publication_point_for_issuer_parallel_roa_with_cache_options(
&fresh_point,
self.policy,
&ca.ca_certificate_der,
@@ -684,9 +764,10 @@ impl<'a> PublicationPointRunner for Rpkiv1PublicationPointRunner<'a> {
self.timing.as_ref(),
phase2_config,
false,
roa_cache,
)
} else {
crate::validation::objects::process_publication_point_for_issuer_with_options(
crate::validation::objects::process_publication_point_for_issuer_with_cache_options(
&fresh_point,
self.policy,
&ca.ca_certificate_der,
@@ -696,6 +777,7 @@ impl<'a> PublicationPointRunner for Rpkiv1PublicationPointRunner<'a> {
self.validation_time,
self.timing.as_ref(),
false,
roa_cache,
)
}
};
@@ -2017,6 +2099,7 @@ fn empty_objects_output() -> crate::validation::objects::ObjectsOutput {
warnings: Vec::new(),
stats: crate::validation::objects::ObjectsStats::default(),
audit: Vec::new(),
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
}
}
@@ -2549,29 +2632,6 @@ fn restore_children_from_vcir(
(children, audits)
}
fn persist_vcir_for_fresh_result(
store: &RocksStore,
ca: &CaInstanceHandle,
pack: &PublicationPointSnapshot,
objects: &mut crate::validation::objects::ObjectsOutput,
warnings: &[Warning],
child_audits: &[ObjectAuditEntry],
discovered_children: &[DiscoveredChildCaInstance],
validation_time: time::OffsetDateTime,
) -> Result<(), String> {
persist_vcir_for_fresh_result_with_timing(
store,
ca,
pack,
objects,
warnings,
child_audits,
discovered_children,
validation_time,
)
.map(|_timing| ())
}
fn persist_vcir_for_fresh_result_with_timing(
store: &RocksStore,
ca: &CaInstanceHandle,
@@ -2616,27 +2676,6 @@ fn persist_vcir_for_fresh_result_with_timing(
Ok(timing)
}
fn build_vcir_from_fresh_result(
ca: &CaInstanceHandle,
pack: &PublicationPointSnapshot,
objects: &mut crate::validation::objects::ObjectsOutput,
warnings: &[Warning],
child_audits: &[ObjectAuditEntry],
discovered_children: &[DiscoveredChildCaInstance],
validation_time: time::OffsetDateTime,
) -> Result<ValidatedCaInstanceResult, String> {
build_vcir_from_fresh_result_with_timing(
ca,
pack,
objects,
warnings,
child_audits,
discovered_children,
validation_time,
)
.map(|(vcir, _timing)| vcir)
}
fn build_vcir_from_fresh_result_with_timing(
ca: &CaInstanceHandle,
pack: &PublicationPointSnapshot,

View File

@@ -68,6 +68,7 @@ fn sample_runner_with_ccr_accumulator<'a>(
parallel_roa_worker_pool: None,
ccr_accumulator: Some(Mutex::new(CcrAccumulator::new(Vec::new()))),
persist_vcir: true,
enable_roa_validation_cache: false,
}
}
@@ -762,6 +763,7 @@ fn build_vcir_local_outputs_prefers_cached_outputs() {
warnings: Vec::new(),
stats: crate::validation::objects::ObjectsStats::default(),
audit: Vec::new(),
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
},
)
.expect("reuse cached outputs");
@@ -957,6 +959,7 @@ fn finalize_fresh_publication_point_releases_local_outputs_cache_after_persist()
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let ca = CaInstanceHandle {
depth: 0,
@@ -1057,7 +1060,7 @@ fn persist_vcir_for_fresh_result_stores_vcir_and_replay_meta_for_real_snapshot()
};
let mut objects = objects;
persist_vcir_for_fresh_result(
persist_vcir_for_fresh_result_with_timing(
&store,
&ca,
&pack,
@@ -1067,6 +1070,7 @@ fn persist_vcir_for_fresh_result_stores_vcir_and_replay_meta_for_real_snapshot()
&[],
validation_time,
)
.map(|_timing| ())
.expect("persist vcir for fresh result");
let vcir = store
@@ -1265,6 +1269,7 @@ fn build_vcir_related_artifacts_classifies_snapshot_files_and_audit_statuses() {
detail: Some("skipped aspa".to_string()),
},
],
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
};
let artifacts = build_vcir_related_artifacts(
&ca,
@@ -1516,6 +1521,7 @@ fn runner_offline_rsync_fixture_produces_pack_and_warnings() {
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
// For this fixture-driven smoke, we provide the correct issuer CA certificate (the CA for
@@ -1577,10 +1583,123 @@ fn runner_offline_rsync_fixture_produces_pack_and_warnings() {
.get_manifest_replay_meta(&manifest_rsync_uri)
.expect("get replay meta")
.expect("replay meta exists");
assert_eq!(replay_meta.manifest_rsync_uri, manifest_rsync_uri);
}
#[test]
fn runner_roa_validation_cache_reuses_vcir_outputs_on_second_fixture_run() {
let fixture_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/repository/rpki.cernet.net/repo/cernet/0");
assert!(fixture_dir.is_dir(), "fixture directory must exist");
let rsync_base_uri = "rsync://rpki.cernet.net/repo/cernet/0/".to_string();
let manifest_file = "05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.mft";
let manifest_rsync_uri = format!("{rsync_base_uri}{manifest_file}");
let fixture_manifest_bytes =
std::fs::read(fixture_dir.join(manifest_file)).expect("read manifest fixture");
let fixture_manifest =
crate::data_model::manifest::ManifestObject::decode_der(&fixture_manifest_bytes)
.expect("decode manifest fixture");
let validation_time = fixture_manifest.manifest.this_update + time::Duration::seconds(60);
let store_dir = tempfile::tempdir().expect("store dir");
let store = RocksStore::open(store_dir.path()).expect("open rocksdb");
let policy = Policy {
sync_preference: crate::policy::SyncPreference::RsyncOnly,
..Policy::default()
};
let issuer_ca_der = std::fs::read(
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(
"tests/fixtures/repository/rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/BfycW4hQb3wNP4YsiJW-1n6fjro.cer",
),
)
.expect("read issuer ca fixture");
let issuer_ca = ResourceCertificate::decode_der(&issuer_ca_der).expect("decode issuer ca");
let handle = CaInstanceHandle {
depth: 0,
tal_id: "test-tal".to_string(),
parent_manifest_rsync_uri: None,
ca_certificate_der: issuer_ca_der,
ca_certificate_rsync_uri: Some("rsync://rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/BfycW4hQb3wNP4YsiJW-1n6fjro.cer".to_string()),
effective_ip_resources: issuer_ca.tbs.extensions.ip_resources.clone(),
effective_as_resources: issuer_ca.tbs.extensions.as_resources.clone(),
rsync_base_uri: rsync_base_uri.clone(),
manifest_rsync_uri: manifest_rsync_uri.clone(),
publication_point_rsync_uri: rsync_base_uri,
rrdp_notification_uri: None,
};
let first_runner = Rpkiv1PublicationPointRunner {
store: &store,
policy: &policy,
http_fetcher: &NeverHttpFetcher,
rsync_fetcher: &LocalDirRsyncFetcher::new(&fixture_dir),
validation_time,
timing: None,
download_log: None,
replay_archive_index: None,
replay_delta_index: None,
rrdp_dedup: false,
rrdp_repo_cache: Mutex::new(HashMap::new()),
rsync_dedup: false,
rsync_repo_cache: Mutex::new(HashMap::new()),
current_repo_index: None,
repo_sync_runtime: None,
parallel_phase2_config: None,
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let first = first_runner
.run_publication_point(&handle)
.expect("first fresh run");
assert!(first.objects.vrps.len() > 1);
assert_eq!(first.objects.roa_cache_stats.hit_roas, 0);
let second_runner = Rpkiv1PublicationPointRunner {
store: &store,
policy: &policy,
http_fetcher: &NeverHttpFetcher,
rsync_fetcher: &LocalDirRsyncFetcher::new(&fixture_dir),
validation_time,
timing: None,
download_log: None,
replay_archive_index: None,
replay_delta_index: None,
rrdp_dedup: false,
rrdp_repo_cache: Mutex::new(HashMap::new()),
rsync_dedup: false,
rsync_repo_cache: Mutex::new(HashMap::new()),
current_repo_index: None,
repo_sync_runtime: None,
parallel_phase2_config: None,
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: true,
};
let second = second_runner
.run_publication_point(&handle)
.expect("second cache-enabled run");
assert_eq!(second.objects.vrps, first.objects.vrps);
assert_eq!(second.objects.roa_cache_stats.enabled_publication_points, 1);
assert_eq!(
replay_meta.manifest_rsync_uri,
manifest_rsync_uri
second.objects.roa_cache_stats.vcir_hit_publication_points,
1
);
assert_eq!(
second.objects.roa_cache_stats.vcir_miss_publication_points,
0
);
assert!(second.objects.roa_cache_stats.hit_roas > 1);
assert_eq!(second.objects.roa_cache_stats.miss_roas, 0);
assert_eq!(second.objects.roa_cache_stats.blocked_roas, 0);
assert_eq!(second.objects.roa_cache_stats.fresh_roas, 0);
}
#[test]
@@ -1669,6 +1788,7 @@ fn runner_rsync_dedup_skips_second_sync_for_same_base() {
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let first = runner.run_publication_point(&handle).expect("first run ok");
@@ -1782,6 +1902,7 @@ fn runner_rsync_dedup_skips_second_sync_for_same_module_scope() {
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let first = runner.run_publication_point(&handle).expect("first run ok");
@@ -1898,6 +2019,7 @@ fn runner_rsync_dedup_works_in_rsync_only_mode_even_when_rrdp_notify_exists() {
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let first = runner.run_publication_point(&handle).expect("first run ok");
@@ -1985,6 +2107,7 @@ fn runner_when_repo_sync_fails_uses_current_instance_vcir_and_keeps_children_emp
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let first = ok_runner
.run_publication_point(&handle)
@@ -2016,6 +2139,7 @@ fn runner_when_repo_sync_fails_uses_current_instance_vcir_and_keeps_children_emp
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let second = bad_runner
.run_publication_point(&handle)
@@ -2063,6 +2187,7 @@ fn build_publication_point_audit_emits_no_audit_entry_for_duplicate_pack_uri() {
warnings: Vec::new(),
stats: crate::validation::objects::ObjectsStats::default(),
audit: Vec::new(),
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
};
let audit = build_publication_point_audit_from_snapshot(
@@ -2131,6 +2256,7 @@ fn build_publication_point_audit_marks_invalid_crl_as_error_and_overlays_roa_aud
result: AuditObjectResult::Ok,
detail: None,
}],
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
};
let audit = build_publication_point_audit_from_snapshot(
@@ -2822,7 +2948,7 @@ fn fresh_and_reuse_paths_produce_equivalent_ccr_manifest_projection() {
discover_children_from_fresh_snapshot_with_audit(&ca, &pack, validation_time, None)
.expect("discover children");
let mut objects = empty_objects_output();
let fresh_vcir = build_vcir_from_fresh_result(
let (fresh_vcir, _timing) = build_vcir_from_fresh_result_with_timing(
&ca,
&pack,
&mut objects,
@@ -3097,6 +3223,7 @@ fn build_publication_point_audit_from_vcir_uses_vcir_metadata_and_overlays_child
result: AuditObjectResult::Error,
detail: Some("overridden from object audit".to_string()),
}],
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
};
let child_audits = vec![ObjectAuditEntry {
rsync_uri: vcir.child_entries[0].child_cert_rsync_uri.clone(),
@@ -3192,6 +3319,7 @@ fn build_publication_point_audit_from_vcir_failed_no_cache_keeps_current_reject_
result: AuditObjectResult::Error,
detail: Some("manifest is not valid at validation_time".to_string()),
}],
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
};
let audit = build_publication_point_audit_from_vcir(
@@ -3327,6 +3455,7 @@ fn build_publication_point_audit_from_vcir_without_cached_inputs_returns_empty_l
warnings: vec![Warning::new("object warning")],
stats: crate::validation::objects::ObjectsStats::default(),
audit: Vec::new(),
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
},
&[],
);
@@ -3609,6 +3738,7 @@ fn runner_dedup_paths_execute_with_timing_enabled() {
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let first = runner_rrdp
.run_publication_point(&handle)
@@ -3643,6 +3773,7 @@ fn runner_dedup_paths_execute_with_timing_enabled() {
parallel_roa_worker_pool: None,
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
};
let third = runner_rsync
.run_publication_point(&handle)