run tree from tal pass

This commit is contained in:
2026-02-10 12:09:59 +08:00
parent afc31c02ab
commit 6e135b9d7a
38 changed files with 1667 additions and 1313 deletions

View File

@@ -1,8 +1,9 @@
use crate::audit::DiscoveredFrom;
use crate::audit::PublicationPointAudit;
use crate::data_model::rc::{AsResourceSet, IpResourceSet};
use crate::report::{RfcRef, Warning};
use crate::storage::VerifiedPublicationPointPack;
use crate::validation::manifest::PublicationPointSource;
use crate::audit::PublicationPointAudit;
use crate::data_model::rc::{AsResourceSet, IpResourceSet};
use crate::validation::objects::{AspaAttestation, ObjectsOutput, Vrp};
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -62,7 +63,13 @@ pub struct PublicationPointRunResult {
/// RFC 9286 §6.6 restriction is enforced by the tree engine: if this
/// publication point used verified cache due to failed fetch, children MUST NOT
/// be enqueued/processed in this run.
pub discovered_children: Vec<CaInstanceHandle>,
pub discovered_children: Vec<DiscoveredChildCaInstance>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct DiscoveredChildCaInstance {
pub handle: CaInstanceHandle,
pub discovered_from: DiscoveredFrom,
}
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -87,22 +94,54 @@ pub trait PublicationPointRunner {
) -> Result<PublicationPointRunResult, String>;
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TreeRunAuditOutput {
pub tree: TreeRunOutput,
pub publication_points: Vec<PublicationPointAudit>,
}
pub fn run_tree_serial(
root: CaInstanceHandle,
runner: &dyn PublicationPointRunner,
config: &TreeRunConfig,
) -> Result<TreeRunOutput, TreeRunError> {
let mut queue: std::collections::VecDeque<CaInstanceHandle> = std::collections::VecDeque::new();
queue.push_back(root);
Ok(run_tree_serial_audit(root, runner, config)?.tree)
}
let mut visited_manifest_uris: std::collections::HashSet<String> = std::collections::HashSet::new();
pub fn run_tree_serial_audit(
root: CaInstanceHandle,
runner: &dyn PublicationPointRunner,
config: &TreeRunConfig,
) -> Result<TreeRunAuditOutput, TreeRunError> {
#[derive(Clone, Debug)]
struct QueuedCaInstance {
id: u64,
handle: CaInstanceHandle,
parent_id: Option<u64>,
discovered_from: Option<DiscoveredFrom>,
}
let mut next_id: u64 = 0;
let mut queue: std::collections::VecDeque<QueuedCaInstance> = std::collections::VecDeque::new();
queue.push_back(QueuedCaInstance {
id: next_id,
handle: root,
parent_id: None,
discovered_from: None,
});
next_id += 1;
let mut visited_manifest_uris: std::collections::HashSet<String> =
std::collections::HashSet::new();
let mut instances_processed = 0usize;
let mut instances_failed = 0usize;
let mut warnings: Vec<Warning> = Vec::new();
let mut vrps: Vec<Vrp> = Vec::new();
let mut aspas: Vec<AspaAttestation> = Vec::new();
let mut publication_points: Vec<PublicationPointAudit> = Vec::new();
while let Some(ca) = queue.pop_front() {
while let Some(node) = queue.pop_front() {
let ca = &node.handle;
if !visited_manifest_uris.insert(ca.manifest_rsync_uri.clone()) {
continue;
}
@@ -119,7 +158,7 @@ pub fn run_tree_serial(
}
}
let res = match runner.run_publication_point(&ca) {
let res = match runner.run_publication_point(ca) {
Ok(v) => v,
Err(e) => {
instances_failed += 1;
@@ -137,6 +176,12 @@ pub fn run_tree_serial(
vrps.extend(res.objects.vrps.clone());
aspas.extend(res.objects.aspas.clone());
let mut audit = res.audit.clone();
audit.node_id = Some(node.id);
audit.parent_node_id = node.parent_id;
audit.discovered_from = node.discovered_from.clone();
publication_points.push(audit);
let enqueue_children = res.source == PublicationPointSource::Fresh;
if !enqueue_children && !res.discovered_children.is_empty() {
warnings.push(
@@ -147,17 +192,37 @@ pub fn run_tree_serial(
}
if enqueue_children {
for child in res.discovered_children {
queue.push_back(child.with_depth(ca.depth + 1));
let mut children = res.discovered_children;
children.sort_by(|a, b| {
a.handle
.manifest_rsync_uri
.cmp(&b.handle.manifest_rsync_uri)
.then_with(|| {
a.discovered_from
.child_ca_certificate_rsync_uri
.cmp(&b.discovered_from.child_ca_certificate_rsync_uri)
})
});
for child in children {
queue.push_back(QueuedCaInstance {
id: next_id,
handle: child.handle.with_depth(ca.depth + 1),
parent_id: Some(node.id),
discovered_from: Some(child.discovered_from),
});
next_id += 1;
}
}
}
Ok(TreeRunOutput {
instances_processed,
instances_failed,
warnings,
vrps,
aspas,
Ok(TreeRunAuditOutput {
tree: TreeRunOutput {
instances_processed,
instances_failed,
warnings,
vrps,
aspas,
},
publication_points,
})
}