20260607 完成transport预热、roa cache和finalize长尾优化

This commit is contained in:
2026-06-07 20:35:47 +08:00
parent 4045f9a3a5
commit 8e6e2f1318
24 changed files with 2377 additions and 155 deletions

View File

@@ -15,9 +15,9 @@ use crate::parallel::object_worker::{
use crate::policy::{Policy, SignedObjectFailurePolicy};
use crate::report::{RfcRef, Warning};
use crate::storage::{
PackFile, PackTime, ValidatedCaInstanceResult, VcirArtifactKind, VcirArtifactRole,
VcirArtifactValidationStatus, VcirLocalOutput, VcirLocalOutputPayload, VcirOutputType,
VcirSourceObjectType,
PackFile, PackTime, RoaCacheProjection, ValidatedCaInstanceResult, VcirArtifactKind,
VcirArtifactRole, VcirArtifactValidationStatus, VcirLocalOutput, VcirLocalOutputPayload,
VcirOutputType, VcirSourceObjectType,
};
use crate::validation::cert_path::{CertPathError, validate_signed_object_ee_cert_path_fast};
use crate::validation::manifest::PublicationPointData;
@@ -264,6 +264,65 @@ pub struct CachedRoaValidationResult {
}
impl RoaValidationCacheView {
pub fn from_projection(
projection: &RoaCacheProjection,
validation_time: time::OffsetDateTime,
) -> Self {
let mut entries_by_uri: HashMap<String, CachedRoaValidationResult> =
HashMap::with_capacity(projection.entries.len());
let issuer_ca_sha256_hex = projection.issuer_ca_sha256_hex.clone();
let crl_sha256_by_uri = projection
.crl_sha256_by_uri
.iter()
.map(|crl| (crl.uri.clone(), crl.sha256.clone()))
.collect::<HashMap<_, _>>();
let blocked = projection
.instance_effective_until
.parse()
.map(|effective_until| effective_until <= validation_time)
.unwrap_or(true);
if blocked {
return Self {
entries_by_uri,
issuer_ca_sha256_hex,
crl_sha256_by_uri,
blocked,
};
}
for entry in &projection.entries {
let outputs = entry
.outputs
.iter()
.map(|output| VcirLocalOutput {
output_type: VcirOutputType::Vrp,
item_effective_until: output.item_effective_until.clone(),
source_object_uri: entry.source_object_uri.clone(),
source_object_type: VcirSourceObjectType::Roa,
source_object_hash: entry.source_object_hash,
source_ee_cert_hash: output.source_ee_cert_hash,
payload: output.payload.clone(),
rule_hash: output.rule_hash,
})
.collect::<Vec<_>>();
entries_by_uri.insert(
entry.source_object_uri.clone(),
CachedRoaValidationResult {
source_object_hash: entry.source_object_hash,
outputs,
},
);
}
Self {
entries_by_uri,
issuer_ca_sha256_hex,
crl_sha256_by_uri,
blocked,
}
}
pub fn from_vcir(
vcir: &ValidatedCaInstanceResult,
validation_time: time::OffsetDateTime,
@@ -3067,8 +3126,8 @@ mod tests {
};
use crate::policy::Policy;
use crate::storage::{
PackTime, ValidatedManifestMeta, VcirAuditSummary, VcirCcrManifestProjection,
VcirInstanceGate, VcirRelatedArtifact, VcirSummary,
PackTime, RoaCacheProjection, ValidatedManifestMeta, VcirAuditSummary,
VcirCcrManifestProjection, VcirInstanceGate, VcirRelatedArtifact, VcirSummary,
};
use crate::validation::publication_point::PublicationPointSnapshot;
use std::collections::HashMap;
@@ -3214,6 +3273,120 @@ mod tests {
assert_eq!(ok.local_outputs.len(), 1);
}
#[test]
fn roa_validation_cache_view_from_projection_matches_vcir_view() {
let validation_time = fixed_time("2026-06-05T00:00:00Z");
let issuer_der = b"issuer-ca";
let crl_hash = [0x22; 32];
let roa_hash = [0x11; 32];
let vcir = sample_roa_cache_vcir(
issuer_der,
crl_hash,
roa_hash,
fixed_time("2026-06-07T00:00:00Z"),
fixed_time("2026-06-08T00:00:00Z"),
);
let projection = RoaCacheProjection::from_vcir(&vcir)
.expect("build projection")
.expect("projection exists");
let view = RoaValidationCacheView::from_projection(&projection, validation_time);
let files = vec![
PackFile::from_bytes_with_sha256(
"rsync://example.test/repo/a.roa",
vec![0x01],
roa_hash,
),
PackFile::from_bytes_with_sha256(
"rsync://example.test/repo/current.crl",
vec![0x02],
crl_hash,
),
];
assert!(view.matches_current_context(issuer_der, &files));
let hit = view.lookup(&files[0], validation_time);
let RoaCacheLookupResult::Hit(ok) = hit else {
panic!("expected projection cache hit, got {hit:?}");
};
assert!(ok.reused_from_cache);
assert_eq!(ok.vrps.len(), 1);
assert_eq!(ok.vrps[0].asn, 64500);
assert_eq!(ok.local_outputs.len(), 1);
assert_eq!(
ok.local_outputs[0].source_object_uri,
"rsync://example.test/repo/a.roa"
);
}
#[test]
fn roa_validation_cache_view_from_projection_blocks_on_gates() {
let validation_time = fixed_time("2026-06-05T00:00:00Z");
let issuer_der = b"issuer-ca";
let crl_hash = [0x22; 32];
let roa_hash = [0x11; 32];
let vcir = sample_roa_cache_vcir(
issuer_der,
crl_hash,
roa_hash,
fixed_time("2026-06-07T00:00:00Z"),
fixed_time("2026-06-08T00:00:00Z"),
);
let mut projection = RoaCacheProjection::from_vcir(&vcir)
.expect("build projection")
.expect("projection exists");
let files = vec![
PackFile::from_bytes_with_sha256(
"rsync://example.test/repo/a.roa",
vec![0x01],
roa_hash,
),
PackFile::from_bytes_with_sha256(
"rsync://example.test/repo/current.crl",
vec![0x02],
crl_hash,
),
];
projection.issuer_ca_sha256_hex = Some("00".repeat(32));
let issuer_changed = RoaValidationCacheView::from_projection(&projection, validation_time);
assert!(!issuer_changed.matches_current_context(issuer_der, &files));
let mut projection = RoaCacheProjection::from_vcir(&vcir)
.expect("build projection")
.expect("projection exists");
projection.crl_sha256_by_uri[0].sha256 = "11".repeat(32);
let crl_changed = RoaValidationCacheView::from_projection(&projection, validation_time);
assert!(!crl_changed.matches_current_context(issuer_der, &files));
let mut projection = RoaCacheProjection::from_vcir(&vcir)
.expect("build projection")
.expect("projection exists");
projection.entries[0].source_object_hash = [0xff; 32];
let roa_changed = RoaValidationCacheView::from_projection(&projection, validation_time);
assert!(matches!(
roa_changed.lookup(&files[0], validation_time),
RoaCacheLookupResult::Blocked
));
let expired_vcir = sample_roa_cache_vcir(
issuer_der,
crl_hash,
roa_hash,
fixed_time("2026-06-07T00:00:00Z"),
fixed_time("2026-06-04T00:00:00Z"),
);
let expired_projection = RoaCacheProjection::from_vcir(&expired_vcir)
.expect("build projection")
.expect("projection exists");
let expired_view =
RoaValidationCacheView::from_projection(&expired_projection, validation_time);
assert!(!expired_view.matches_current_context(issuer_der, &files));
assert!(matches!(
expired_view.lookup(&files[0], validation_time),
RoaCacheLookupResult::Blocked
));
}
#[test]
fn roa_validation_cache_view_blocks_when_context_changes() {
let validation_time = fixed_time("2026-06-05T00:00:00Z");