优化数据对象decode + profile validate;benchmark对比routinator geomean 0.8
This commit is contained in:
933
tests/bench_stage2_collect_selected_der_v2.rs
Normal file
933
tests/bench_stage2_collect_selected_der_v2.rs
Normal file
@@ -0,0 +1,933 @@
|
||||
use serde::Serialize;
|
||||
use sha2::Digest;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use rpki::data_model::aspa::AspaObject;
|
||||
use rpki::data_model::crl::RpkixCrl;
|
||||
use rpki::data_model::manifest::ManifestObject;
|
||||
use rpki::data_model::rc::{AsIdentifierChoice, AsResourceSet, IpAddressChoice, IpResourceSet, ResourceCertificate};
|
||||
use rpki::data_model::roa::RoaObject;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
enum ObjType {
|
||||
Cer,
|
||||
Crl,
|
||||
Manifest,
|
||||
Roa,
|
||||
Aspa,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
enum Part {
|
||||
PackManifest,
|
||||
PackCrl,
|
||||
StoredObject { index: u32 },
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct CandidateRef {
|
||||
pack_index: u32,
|
||||
part: Part,
|
||||
size_bytes: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
struct SampleMeta {
|
||||
obj_type: ObjType,
|
||||
label: String,
|
||||
file_rel_path: String,
|
||||
size_bytes: u32,
|
||||
sha256_hex: String,
|
||||
|
||||
// Provenance (relative to BENCH_STORE_DIR)
|
||||
pack_rel_path: String,
|
||||
pack_update_time_rfc3339_utc: String,
|
||||
manifest_uri: String,
|
||||
object_uri: String,
|
||||
|
||||
// From StoredManifest (if available)
|
||||
manifest_this_update_rfc3339_utc: String,
|
||||
manifest_not_after_rfc3339_utc: String,
|
||||
|
||||
metrics: Metrics,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
enum Metrics {
|
||||
Cer {
|
||||
spki_len: u32,
|
||||
ext_count: u32,
|
||||
ip_resource_count: u32,
|
||||
as_resource_count: u32,
|
||||
},
|
||||
Crl {
|
||||
revoked_count: u32,
|
||||
},
|
||||
Manifest {
|
||||
file_count: u32,
|
||||
},
|
||||
Roa {
|
||||
addr_family_count: u32,
|
||||
prefix_count: u32,
|
||||
max_length_present: u32,
|
||||
},
|
||||
Aspa {
|
||||
provider_count: u32,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
struct SamplesManifest {
|
||||
created_at_rfc3339_utc: String,
|
||||
store_dir_hint: String,
|
||||
per_type: BTreeMap<String, u32>,
|
||||
samples: Vec<SampleMeta>,
|
||||
}
|
||||
|
||||
fn env_string(name: &str) -> Option<String> {
|
||||
std::env::var(name).ok().filter(|s| !s.trim().is_empty())
|
||||
}
|
||||
|
||||
fn env_u64_opt(name: &str) -> Option<u64> {
|
||||
std::env::var(name).ok().and_then(|s| s.parse::<u64>().ok())
|
||||
}
|
||||
|
||||
fn env_bool(name: &str) -> bool {
|
||||
matches!(
|
||||
std::env::var(name).as_deref(),
|
||||
Ok("1") | Ok("true") | Ok("TRUE") | Ok("yes") | Ok("YES")
|
||||
)
|
||||
}
|
||||
|
||||
fn create_parent_dirs(path: &Path) {
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent).unwrap_or_else(|e| {
|
||||
panic!("create_dir_all {}: {e}", parent.display());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_collect_files(root: &Path, out: &mut Vec<PathBuf>) -> std::io::Result<()> {
|
||||
for entry in std::fs::read_dir(root)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
let meta = entry.metadata()?;
|
||||
if meta.is_dir() {
|
||||
walk_collect_files(&path, out)?;
|
||||
continue;
|
||||
}
|
||||
if meta.is_file() {
|
||||
out.push(path);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ext_from_uri_bytes(uri: &[u8]) -> Option<&[u8]> {
|
||||
let mut last_dot = None;
|
||||
for (i, &b) in uri.iter().enumerate() {
|
||||
if b == b'.' {
|
||||
last_dot = Some(i);
|
||||
}
|
||||
}
|
||||
let dot = last_dot?;
|
||||
if dot + 1 >= uri.len() {
|
||||
return None;
|
||||
}
|
||||
Some(&uri[dot + 1..])
|
||||
}
|
||||
|
||||
fn ext_matches_ascii_case_insensitive(ext: &[u8], needle_lower: &[u8]) -> bool {
|
||||
if ext.len() != needle_lower.len() {
|
||||
return false;
|
||||
}
|
||||
ext.iter()
|
||||
.zip(needle_lower.iter())
|
||||
.all(|(&a, &b)| a.to_ascii_lowercase() == b)
|
||||
}
|
||||
|
||||
fn percentile_index(len: usize, q: f64) -> usize {
|
||||
if len == 0 {
|
||||
return 0;
|
||||
}
|
||||
if len == 1 {
|
||||
return 0;
|
||||
}
|
||||
let q = q.clamp(0.0, 1.0);
|
||||
(((len - 1) as f64) * q).round() as usize
|
||||
}
|
||||
|
||||
fn quantile_labels() -> Vec<(&'static str, f64)> {
|
||||
vec![
|
||||
("min", 0.0),
|
||||
("p01", 0.01),
|
||||
("p10", 0.10),
|
||||
("p25", 0.25),
|
||||
("p50", 0.50),
|
||||
("p75", 0.75),
|
||||
("p90", 0.90),
|
||||
("p95", 0.95),
|
||||
("p99", 0.99),
|
||||
("max", 1.0),
|
||||
]
|
||||
}
|
||||
|
||||
fn fmt_rfc3339_utc(t: time::OffsetDateTime) -> String {
|
||||
use time::format_description::well_known::Rfc3339;
|
||||
t.to_offset(time::UtcOffset::UTC)
|
||||
.format(&Rfc3339)
|
||||
.expect("format RFC3339")
|
||||
}
|
||||
|
||||
fn scan_pack_candidates(
|
||||
pack_index: u32,
|
||||
bytes: &[u8],
|
||||
out_cer: &mut Vec<CandidateRef>,
|
||||
out_crl: &mut Vec<CandidateRef>,
|
||||
out_manifest: &mut Vec<CandidateRef>,
|
||||
out_roa: &mut Vec<CandidateRef>,
|
||||
out_aspa: &mut Vec<CandidateRef>,
|
||||
) -> Result<(), String> {
|
||||
let mut cur = ByteCursor::new(bytes);
|
||||
|
||||
let _version = cur.read_u8()?;
|
||||
cur.skip_string_u32()?; // manifest_uri
|
||||
cur.skip_option_string_u32()?; // rpki_notify
|
||||
|
||||
let update_kind = cur.read_u8()?;
|
||||
cur.skip_i64()?; // update time
|
||||
if update_kind != 0 {
|
||||
// LastAttempt: no StoredManifest + objects
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
cur.skip_i64()?; // not_after
|
||||
cur.skip(20)?; // manifest_number
|
||||
cur.skip_i64()?; // this_update
|
||||
cur.skip_string_u32()?; // ca_repository
|
||||
|
||||
let mft_len = cur.peek_u64_as_usize()?;
|
||||
cur.skip_bytes_u64()?; // manifest DER
|
||||
out_manifest.push(CandidateRef {
|
||||
pack_index,
|
||||
part: Part::PackManifest,
|
||||
size_bytes: mft_len as u32,
|
||||
});
|
||||
|
||||
cur.skip_string_u32()?; // crl_uri
|
||||
let crl_len = cur.peek_u64_as_usize()?;
|
||||
cur.skip_bytes_u64()?;
|
||||
out_crl.push(CandidateRef {
|
||||
pack_index,
|
||||
part: Part::PackCrl,
|
||||
size_bytes: crl_len as u32,
|
||||
});
|
||||
|
||||
let mut object_index = 0u32;
|
||||
while cur.remaining() > 0 {
|
||||
let uri_bytes = cur.read_bytes_u32()?;
|
||||
let ext = ext_from_uri_bytes(uri_bytes);
|
||||
|
||||
let hash_type = cur.read_u8()?;
|
||||
if hash_type == 1 {
|
||||
cur.skip(32)?;
|
||||
} else if hash_type != 0 {
|
||||
return Err(format!("unsupported stored object hash_type {hash_type}"));
|
||||
}
|
||||
|
||||
let content_len = cur.peek_u64_as_usize()?;
|
||||
cur.skip_bytes_u64()?;
|
||||
|
||||
let cand = CandidateRef {
|
||||
pack_index,
|
||||
part: Part::StoredObject { index: object_index },
|
||||
size_bytes: content_len as u32,
|
||||
};
|
||||
if let Some(ext) = ext {
|
||||
if ext_matches_ascii_case_insensitive(ext, b"cer") {
|
||||
out_cer.push(cand);
|
||||
} else if ext_matches_ascii_case_insensitive(ext, b"roa") {
|
||||
out_roa.push(cand);
|
||||
} else if ext_matches_ascii_case_insensitive(ext, b"asa") {
|
||||
out_aspa.push(cand);
|
||||
}
|
||||
}
|
||||
|
||||
object_index += 1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct Extracted {
|
||||
pack_update_time_utc: time::OffsetDateTime,
|
||||
manifest_uri: String,
|
||||
manifest_this_update_utc: time::OffsetDateTime,
|
||||
manifest_not_after_utc: time::OffsetDateTime,
|
||||
object_uri: String,
|
||||
der: Vec<u8>,
|
||||
}
|
||||
|
||||
fn extract_candidate(pack_path: &Path, cand: CandidateRef) -> Result<Extracted, String> {
|
||||
let bytes = std::fs::read(pack_path).map_err(|e| format!("read {}: {e}", pack_path.display()))?;
|
||||
let mut cur = ByteCursor::new(bytes.as_slice());
|
||||
|
||||
let _version = cur.read_u8()?;
|
||||
let manifest_uri = cur.read_string_u32()?;
|
||||
cur.skip_option_string_u32()?; // rpki_notify
|
||||
|
||||
let update_kind = cur.read_u8()?;
|
||||
let pack_update_time_utc = cur.read_time_utc_i64_be()?;
|
||||
if update_kind != 0 {
|
||||
return Err("pack is LastAttempt".to_string());
|
||||
}
|
||||
|
||||
let manifest_not_after_utc = cur.read_time_utc_i64_be()?;
|
||||
cur.skip(20)?; // manifest_number
|
||||
let manifest_this_update_utc = cur.read_time_utc_i64_be()?;
|
||||
cur.skip_string_u32()?; // ca_repository
|
||||
|
||||
let manifest_der = cur.read_bytes_u64_vec()?; // manifest DER
|
||||
|
||||
if cand.part == Part::PackManifest {
|
||||
return Ok(Extracted {
|
||||
pack_update_time_utc,
|
||||
manifest_uri: manifest_uri.clone(),
|
||||
manifest_this_update_utc,
|
||||
manifest_not_after_utc,
|
||||
object_uri: manifest_uri,
|
||||
der: manifest_der,
|
||||
});
|
||||
}
|
||||
|
||||
let crl_uri = cur.read_string_u32()?;
|
||||
let crl_der = cur.read_bytes_u64_vec()?;
|
||||
|
||||
match cand.part {
|
||||
Part::PackManifest => unreachable!("handled above"),
|
||||
Part::PackCrl => Ok(Extracted {
|
||||
pack_update_time_utc,
|
||||
manifest_uri,
|
||||
manifest_this_update_utc,
|
||||
manifest_not_after_utc,
|
||||
object_uri: crl_uri,
|
||||
der: crl_der,
|
||||
}),
|
||||
Part::StoredObject { index } => {
|
||||
let mut object_index = 0u32;
|
||||
while cur.remaining() > 0 {
|
||||
let uri = cur.read_string_u32()?;
|
||||
let hash_type = cur.read_u8()?;
|
||||
if hash_type == 1 {
|
||||
cur.skip(32)?;
|
||||
} else if hash_type != 0 {
|
||||
return Err(format!("unsupported stored object hash_type {hash_type}"));
|
||||
}
|
||||
let content = cur.read_bytes_u64_vec()?;
|
||||
if object_index == index {
|
||||
return Ok(Extracted {
|
||||
pack_update_time_utc,
|
||||
manifest_uri,
|
||||
manifest_this_update_utc,
|
||||
manifest_not_after_utc,
|
||||
object_uri: uri,
|
||||
der: content,
|
||||
});
|
||||
}
|
||||
object_index += 1;
|
||||
}
|
||||
Err(format!("stored object index {index} out of range"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ip_resource_count(set: &IpResourceSet) -> u32 {
|
||||
let mut n = 0u32;
|
||||
for fam in &set.families {
|
||||
match &fam.choice {
|
||||
IpAddressChoice::Inherit => n = n.saturating_add(1),
|
||||
IpAddressChoice::AddressesOrRanges(items) => {
|
||||
n = n.saturating_add(items.len() as u32)
|
||||
}
|
||||
}
|
||||
}
|
||||
n
|
||||
}
|
||||
|
||||
fn as_choice_count(choice: &AsIdentifierChoice) -> u32 {
|
||||
match choice {
|
||||
AsIdentifierChoice::Inherit => 1,
|
||||
AsIdentifierChoice::AsIdsOrRanges(items) => items.len() as u32,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_resource_count(set: &AsResourceSet) -> u32 {
|
||||
let mut n = 0u32;
|
||||
if let Some(c) = set.asnum.as_ref() {
|
||||
n = n.saturating_add(as_choice_count(c));
|
||||
}
|
||||
if let Some(c) = set.rdi.as_ref() {
|
||||
n = n.saturating_add(as_choice_count(c));
|
||||
}
|
||||
n
|
||||
}
|
||||
|
||||
fn metrics_for(obj_type: ObjType, der: &[u8]) -> Result<Metrics, String> {
|
||||
match obj_type {
|
||||
ObjType::Cer => {
|
||||
let parsed = ResourceCertificate::parse_der(der).map_err(|e| e.to_string())?;
|
||||
let spki_len = parsed.subject_public_key_info.len() as u32;
|
||||
let ext_count = (parsed.extensions.basic_constraints_ca.len()
|
||||
+ parsed.extensions.subject_key_identifier.len()
|
||||
+ parsed.extensions.authority_key_identifier.len()
|
||||
+ parsed.extensions.crl_distribution_points.len()
|
||||
+ parsed.extensions.authority_info_access.len()
|
||||
+ parsed.extensions.subject_info_access.len()
|
||||
+ parsed.extensions.certificate_policies.len()
|
||||
+ parsed.extensions.ip_resources.len()
|
||||
+ parsed.extensions.as_resources.len()) as u32;
|
||||
let cert = parsed.validate_profile().map_err(|e| e.to_string())?;
|
||||
let ip_resource_count = cert
|
||||
.tbs
|
||||
.extensions
|
||||
.ip_resources
|
||||
.as_ref()
|
||||
.map(ip_resource_count)
|
||||
.unwrap_or(0);
|
||||
let as_resource_count = cert
|
||||
.tbs
|
||||
.extensions
|
||||
.as_resources
|
||||
.as_ref()
|
||||
.map(as_resource_count)
|
||||
.unwrap_or(0);
|
||||
Ok(Metrics::Cer {
|
||||
spki_len,
|
||||
ext_count,
|
||||
ip_resource_count,
|
||||
as_resource_count,
|
||||
})
|
||||
}
|
||||
ObjType::Crl => {
|
||||
let parsed = RpkixCrl::parse_der(der).map_err(|e| e.to_string())?;
|
||||
let crl = parsed.validate_profile().map_err(|e| e.to_string())?;
|
||||
Ok(Metrics::Crl {
|
||||
revoked_count: crl.revoked_certs.len() as u32,
|
||||
})
|
||||
}
|
||||
ObjType::Manifest => {
|
||||
let mft = ManifestObject::decode_der(der).map_err(|e| e.to_string())?;
|
||||
Ok(Metrics::Manifest {
|
||||
file_count: mft.manifest.file_count() as u32,
|
||||
})
|
||||
}
|
||||
ObjType::Roa => {
|
||||
let roa = RoaObject::decode_der(der).map_err(|e| e.to_string())?;
|
||||
let addr_family_count = roa.roa.ip_addr_blocks.len() as u32;
|
||||
let mut prefix_count = 0u32;
|
||||
let mut max_length_present = 0u32;
|
||||
for fam in &roa.roa.ip_addr_blocks {
|
||||
for a in &fam.addresses {
|
||||
prefix_count += 1;
|
||||
if a.max_length.is_some() {
|
||||
max_length_present += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Metrics::Roa {
|
||||
addr_family_count,
|
||||
prefix_count,
|
||||
max_length_present,
|
||||
})
|
||||
}
|
||||
ObjType::Aspa => {
|
||||
let asa = AspaObject::decode_der(der).map_err(|e| e.to_string())?;
|
||||
Ok(Metrics::Aspa {
|
||||
provider_count: asa.aspa.provider_as_ids.len() as u32,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_sample(out_dir: &Path, obj_type: ObjType, label: &str, der: &[u8]) -> PathBuf {
|
||||
let (subdir, ext) = match obj_type {
|
||||
ObjType::Cer => ("cer", "cer"),
|
||||
ObjType::Crl => ("crl", "crl"),
|
||||
ObjType::Manifest => ("manifest", "mft"),
|
||||
ObjType::Roa => ("roa", "roa"),
|
||||
ObjType::Aspa => ("aspa", "asa"),
|
||||
};
|
||||
let path = out_dir.join(subdir).join(format!("{label}.{ext}"));
|
||||
create_parent_dirs(&path);
|
||||
std::fs::write(&path, der).unwrap_or_else(|e| panic!("write {}: {e}", path.display()));
|
||||
path
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "manual: collect representative CER/CRL/MFT/ROA/ASA DER fixtures from routinator stored/ SAP packs"]
|
||||
fn stage2_collect_selected_der_v2_from_routinator_store() {
|
||||
let store_dir = env_string("BENCH_STORE_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| panic!("set BENCH_STORE_DIR to routinator stored/ dir"));
|
||||
let out_dir = env_string("BENCH_OUT_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/benchmark/selected_der_v2")
|
||||
});
|
||||
let max_packs = env_u64_opt("BENCH_MAX_PACKS");
|
||||
let clean = env_bool("BENCH_CLEAN");
|
||||
let dry_run = env_bool("BENCH_DRY_RUN");
|
||||
let verbose = env_bool("BENCH_VERBOSE");
|
||||
|
||||
if clean && !dry_run && out_dir.exists() {
|
||||
std::fs::remove_dir_all(&out_dir)
|
||||
.unwrap_or_else(|e| panic!("remove_dir_all {}: {e}", out_dir.display()));
|
||||
}
|
||||
|
||||
let mut pack_paths = Vec::new();
|
||||
walk_collect_files(&store_dir, &mut pack_paths)
|
||||
.unwrap_or_else(|e| panic!("walk {}: {e}", store_dir.display()));
|
||||
pack_paths.retain(|p| p.extension().and_then(|s| s.to_str()) == Some("mft"));
|
||||
pack_paths.sort();
|
||||
if let Some(max) = max_packs {
|
||||
pack_paths.truncate(max as usize);
|
||||
}
|
||||
|
||||
println!("# Stage2 collect: selected_der_v2 (from routinator stored/ SAP packs)");
|
||||
println!();
|
||||
println!("- store_dir: {}", store_dir.display());
|
||||
println!("- out_dir: {}", out_dir.display());
|
||||
println!("- pack_files_found: {}", pack_paths.len());
|
||||
if let Some(max) = max_packs {
|
||||
println!("- max_packs: {} (truncating input list)", max);
|
||||
}
|
||||
println!("- clean: {}", clean);
|
||||
println!("- dry_run: {}", dry_run);
|
||||
println!();
|
||||
|
||||
let mut cer = Vec::<CandidateRef>::new();
|
||||
let mut crl = Vec::<CandidateRef>::new();
|
||||
let mut mft = Vec::<CandidateRef>::new();
|
||||
let mut roa = Vec::<CandidateRef>::new();
|
||||
let mut asa = Vec::<CandidateRef>::new();
|
||||
|
||||
for (i, p) in pack_paths.iter().enumerate() {
|
||||
let bytes = match std::fs::read(p) {
|
||||
Ok(v) => v,
|
||||
Err(_) => continue,
|
||||
};
|
||||
if let Err(e) = scan_pack_candidates(
|
||||
i as u32,
|
||||
bytes.as_slice(),
|
||||
&mut cer,
|
||||
&mut crl,
|
||||
&mut mft,
|
||||
&mut roa,
|
||||
&mut asa,
|
||||
) {
|
||||
if verbose {
|
||||
eprintln!("# scan error {}: {}", p.display(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut by_type: BTreeMap<ObjType, Vec<CandidateRef>> = BTreeMap::new();
|
||||
by_type.insert(ObjType::Cer, cer);
|
||||
by_type.insert(ObjType::Crl, crl);
|
||||
by_type.insert(ObjType::Manifest, mft);
|
||||
by_type.insert(ObjType::Roa, roa);
|
||||
by_type.insert(ObjType::Aspa, asa);
|
||||
|
||||
let mut samples = Vec::<SampleMeta>::new();
|
||||
let mut per_type_out = BTreeMap::<String, u32>::new();
|
||||
|
||||
for (obj_type, mut cands) in by_type {
|
||||
cands.sort_by(|a, b| {
|
||||
a.size_bytes
|
||||
.cmp(&b.size_bytes)
|
||||
.then_with(|| a.pack_index.cmp(&b.pack_index))
|
||||
.then_with(|| match (a.part, b.part) {
|
||||
(Part::PackManifest, Part::PackManifest) => std::cmp::Ordering::Equal,
|
||||
(Part::PackManifest, _) => std::cmp::Ordering::Less,
|
||||
(_, Part::PackManifest) => std::cmp::Ordering::Greater,
|
||||
(Part::PackCrl, Part::PackCrl) => std::cmp::Ordering::Equal,
|
||||
(Part::PackCrl, Part::StoredObject { .. }) => std::cmp::Ordering::Less,
|
||||
(Part::StoredObject { .. }, Part::PackCrl) => std::cmp::Ordering::Greater,
|
||||
(Part::StoredObject { index: ai }, Part::StoredObject { index: bi }) => ai.cmp(&bi),
|
||||
})
|
||||
});
|
||||
|
||||
println!("## {:?}", obj_type);
|
||||
println!();
|
||||
println!("- candidates: {}", cands.len());
|
||||
if cands.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut selected_sha = HashSet::<String>::new();
|
||||
let mut selected_ptrs = HashSet::<(u32, Part)>::new();
|
||||
|
||||
for (label, q) in quantile_labels() {
|
||||
let target = percentile_index(cands.len(), q);
|
||||
|
||||
let mut found = None;
|
||||
for off in 0.. {
|
||||
let mut tried_any = false;
|
||||
if off == 0 {
|
||||
let j = target as i32;
|
||||
if j < 0 || (j as usize) >= cands.len() {
|
||||
tried_any = false;
|
||||
} else {
|
||||
tried_any = true;
|
||||
let cand = cands[j as usize];
|
||||
if selected_ptrs.contains(&(cand.pack_index, cand.part)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let pack_path = &pack_paths[cand.pack_index as usize];
|
||||
let extracted = match extract_candidate(pack_path.as_path(), cand) {
|
||||
Ok(v) => v,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if extracted.der.len() != cand.size_bytes as usize {
|
||||
continue;
|
||||
}
|
||||
|
||||
let sha256 = sha2::Sha256::digest(extracted.der.as_slice());
|
||||
let sha256_hex = hex::encode(sha256);
|
||||
if selected_sha.contains(&sha256_hex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let metrics = match metrics_for(obj_type, extracted.der.as_slice()) {
|
||||
Ok(m) => m,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if !dry_run {
|
||||
let p = write_sample(
|
||||
out_dir.as_path(),
|
||||
obj_type,
|
||||
label,
|
||||
extracted.der.as_slice(),
|
||||
);
|
||||
if verbose {
|
||||
println!(
|
||||
"- wrote {} -> {}",
|
||||
label,
|
||||
p.strip_prefix(PathBuf::from(env!("CARGO_MANIFEST_DIR")))
|
||||
.unwrap_or(&p)
|
||||
.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let pack_rel_path = pack_path
|
||||
.strip_prefix(&store_dir)
|
||||
.unwrap_or(pack_path.as_path())
|
||||
.display()
|
||||
.to_string();
|
||||
|
||||
let file_rel_path = format!(
|
||||
"tests/benchmark/selected_der_v2/{}/{}.{}",
|
||||
match obj_type {
|
||||
ObjType::Cer => "cer",
|
||||
ObjType::Crl => "crl",
|
||||
ObjType::Manifest => "manifest",
|
||||
ObjType::Roa => "roa",
|
||||
ObjType::Aspa => "aspa",
|
||||
},
|
||||
label,
|
||||
match obj_type {
|
||||
ObjType::Cer => "cer",
|
||||
ObjType::Crl => "crl",
|
||||
ObjType::Manifest => "mft",
|
||||
ObjType::Roa => "roa",
|
||||
ObjType::Aspa => "asa",
|
||||
}
|
||||
);
|
||||
|
||||
let sha256_hex_for_set = sha256_hex.clone();
|
||||
samples.push(SampleMeta {
|
||||
obj_type,
|
||||
label: label.to_string(),
|
||||
file_rel_path,
|
||||
size_bytes: cand.size_bytes,
|
||||
sha256_hex,
|
||||
pack_rel_path,
|
||||
pack_update_time_rfc3339_utc: fmt_rfc3339_utc(
|
||||
extracted.pack_update_time_utc,
|
||||
),
|
||||
manifest_uri: extracted.manifest_uri,
|
||||
object_uri: extracted.object_uri,
|
||||
manifest_this_update_rfc3339_utc: fmt_rfc3339_utc(
|
||||
extracted.manifest_this_update_utc,
|
||||
),
|
||||
manifest_not_after_rfc3339_utc: fmt_rfc3339_utc(
|
||||
extracted.manifest_not_after_utc,
|
||||
),
|
||||
metrics,
|
||||
});
|
||||
|
||||
selected_ptrs.insert((cand.pack_index, cand.part));
|
||||
selected_sha.insert(sha256_hex_for_set);
|
||||
found = Some(());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for delta in [off as i32, -(off as i32)] {
|
||||
let j = target as i32 + delta;
|
||||
if j < 0 || (j as usize) >= cands.len() {
|
||||
continue;
|
||||
}
|
||||
tried_any = true;
|
||||
let cand = cands[j as usize];
|
||||
if selected_ptrs.contains(&(cand.pack_index, cand.part)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let pack_path = &pack_paths[cand.pack_index as usize];
|
||||
let extracted = match extract_candidate(pack_path.as_path(), cand) {
|
||||
Ok(v) => v,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if extracted.der.len() != cand.size_bytes as usize {
|
||||
continue;
|
||||
}
|
||||
|
||||
let sha256 = sha2::Sha256::digest(extracted.der.as_slice());
|
||||
let sha256_hex = hex::encode(sha256);
|
||||
if selected_sha.contains(&sha256_hex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let metrics = match metrics_for(obj_type, extracted.der.as_slice()) {
|
||||
Ok(m) => m,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if !dry_run {
|
||||
let p = write_sample(
|
||||
out_dir.as_path(),
|
||||
obj_type,
|
||||
label,
|
||||
extracted.der.as_slice(),
|
||||
);
|
||||
if verbose {
|
||||
println!(
|
||||
"- wrote {} -> {}",
|
||||
label,
|
||||
p.strip_prefix(PathBuf::from(env!("CARGO_MANIFEST_DIR")))
|
||||
.unwrap_or(&p)
|
||||
.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let pack_rel_path = pack_path
|
||||
.strip_prefix(&store_dir)
|
||||
.unwrap_or(pack_path.as_path())
|
||||
.display()
|
||||
.to_string();
|
||||
|
||||
let file_rel_path = format!(
|
||||
"tests/benchmark/selected_der_v2/{}/{}.{}",
|
||||
match obj_type {
|
||||
ObjType::Cer => "cer",
|
||||
ObjType::Crl => "crl",
|
||||
ObjType::Manifest => "manifest",
|
||||
ObjType::Roa => "roa",
|
||||
ObjType::Aspa => "aspa",
|
||||
},
|
||||
label,
|
||||
match obj_type {
|
||||
ObjType::Cer => "cer",
|
||||
ObjType::Crl => "crl",
|
||||
ObjType::Manifest => "mft",
|
||||
ObjType::Roa => "roa",
|
||||
ObjType::Aspa => "asa",
|
||||
}
|
||||
);
|
||||
|
||||
let sha256_hex_for_set = sha256_hex.clone();
|
||||
samples.push(SampleMeta {
|
||||
obj_type,
|
||||
label: label.to_string(),
|
||||
file_rel_path,
|
||||
size_bytes: cand.size_bytes,
|
||||
sha256_hex,
|
||||
pack_rel_path,
|
||||
pack_update_time_rfc3339_utc: fmt_rfc3339_utc(
|
||||
extracted.pack_update_time_utc,
|
||||
),
|
||||
manifest_uri: extracted.manifest_uri,
|
||||
object_uri: extracted.object_uri,
|
||||
manifest_this_update_rfc3339_utc: fmt_rfc3339_utc(
|
||||
extracted.manifest_this_update_utc,
|
||||
),
|
||||
manifest_not_after_rfc3339_utc: fmt_rfc3339_utc(
|
||||
extracted.manifest_not_after_utc,
|
||||
),
|
||||
metrics,
|
||||
});
|
||||
|
||||
selected_ptrs.insert((cand.pack_index, cand.part));
|
||||
selected_sha.insert(sha256_hex_for_set);
|
||||
found = Some(());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if found.is_some() {
|
||||
break;
|
||||
}
|
||||
if !tried_any {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
per_type_out.insert(format!("{:?}", obj_type).to_lowercase(), selected_sha.len() as u32);
|
||||
println!();
|
||||
}
|
||||
|
||||
samples.sort_by(|a, b| a.obj_type.cmp(&b.obj_type).then_with(|| a.label.cmp(&b.label)));
|
||||
|
||||
let created_at_rfc3339_utc = fmt_rfc3339_utc(time::OffsetDateTime::now_utc());
|
||||
let manifest = SamplesManifest {
|
||||
created_at_rfc3339_utc,
|
||||
store_dir_hint: store_dir.display().to_string(),
|
||||
per_type: per_type_out,
|
||||
samples,
|
||||
};
|
||||
|
||||
if !dry_run {
|
||||
let meta_path = out_dir.join("meta").join("samples.json");
|
||||
create_parent_dirs(&meta_path);
|
||||
let bytes = serde_json::to_vec_pretty(&manifest).expect("encode samples manifest");
|
||||
std::fs::write(&meta_path, bytes)
|
||||
.unwrap_or_else(|e| panic!("write {}: {e}", meta_path.display()));
|
||||
println!("- wrote meta: {}", meta_path.display());
|
||||
}
|
||||
}
|
||||
|
||||
struct ByteCursor<'a> {
|
||||
bytes: &'a [u8],
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
impl<'a> ByteCursor<'a> {
|
||||
fn new(bytes: &'a [u8]) -> Self {
|
||||
Self { bytes, pos: 0 }
|
||||
}
|
||||
|
||||
fn remaining(&self) -> usize {
|
||||
self.bytes.len().saturating_sub(self.pos)
|
||||
}
|
||||
|
||||
fn skip(&mut self, len: usize) -> Result<(), String> {
|
||||
if len > self.remaining() {
|
||||
return Err("truncated input".to_string());
|
||||
}
|
||||
self.pos += len;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_exact(&mut self, len: usize) -> Result<&'a [u8], String> {
|
||||
if len > self.remaining() {
|
||||
return Err(format!(
|
||||
"truncated input: need {len} bytes, have {}",
|
||||
self.remaining()
|
||||
));
|
||||
}
|
||||
let start = self.pos;
|
||||
self.pos += len;
|
||||
Ok(&self.bytes[start..start + len])
|
||||
}
|
||||
|
||||
fn read_u8(&mut self) -> Result<u8, String> {
|
||||
Ok(self.read_exact(1)?[0])
|
||||
}
|
||||
|
||||
fn read_u32_be(&mut self) -> Result<u32, String> {
|
||||
let b = self.read_exact(4)?;
|
||||
Ok(u32::from_be_bytes([b[0], b[1], b[2], b[3]]))
|
||||
}
|
||||
|
||||
fn read_u64_be(&mut self) -> Result<u64, String> {
|
||||
let b = self.read_exact(8)?;
|
||||
Ok(u64::from_be_bytes([
|
||||
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
|
||||
]))
|
||||
}
|
||||
|
||||
fn peek_u64_as_usize(&mut self) -> Result<usize, String> {
|
||||
let start = self.pos;
|
||||
let v = self.read_u64_be()?;
|
||||
self.pos = start;
|
||||
usize::try_from(v).map_err(|_| format!("length too large: {v}"))
|
||||
}
|
||||
|
||||
fn skip_i64(&mut self) -> Result<(), String> {
|
||||
self.skip(8)
|
||||
}
|
||||
|
||||
fn read_i64_be(&mut self) -> Result<i64, String> {
|
||||
let b = self.read_exact(8)?;
|
||||
Ok(i64::from_be_bytes([
|
||||
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
|
||||
]))
|
||||
}
|
||||
|
||||
fn read_time_utc_i64_be(&mut self) -> Result<time::OffsetDateTime, String> {
|
||||
let ts = self.read_i64_be()?;
|
||||
time::OffsetDateTime::from_unix_timestamp(ts).map_err(|e| {
|
||||
format!("invalid unix timestamp {ts}: {e}")
|
||||
})
|
||||
}
|
||||
|
||||
fn read_bytes_u32(&mut self) -> Result<&'a [u8], String> {
|
||||
let len = self.read_u32_be()? as usize;
|
||||
self.read_exact(len)
|
||||
}
|
||||
|
||||
fn skip_string_u32(&mut self) -> Result<(), String> {
|
||||
let len = self.read_u32_be()? as usize;
|
||||
self.skip(len)
|
||||
}
|
||||
|
||||
fn read_string_u32(&mut self) -> Result<String, String> {
|
||||
let b = self.read_bytes_u32()?;
|
||||
std::str::from_utf8(b)
|
||||
.map(|s| s.to_string())
|
||||
.map_err(|e| format!("invalid UTF-8 string: {e}"))
|
||||
}
|
||||
|
||||
fn skip_option_string_u32(&mut self) -> Result<(), String> {
|
||||
let len = self.read_u32_be()? as usize;
|
||||
if len == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
self.skip(len)
|
||||
}
|
||||
|
||||
fn skip_bytes_u64(&mut self) -> Result<(), String> {
|
||||
let len_u64 = self.read_u64_be()?;
|
||||
let len = usize::try_from(len_u64).map_err(|_| {
|
||||
format!("data block too large for this system: {len_u64}")
|
||||
})?;
|
||||
self.skip(len)
|
||||
}
|
||||
|
||||
fn read_bytes_u64_vec(&mut self) -> Result<Vec<u8>, String> {
|
||||
let len_u64 = self.read_u64_be()?;
|
||||
let len = usize::try_from(len_u64).map_err(|_| {
|
||||
format!("data block too large for this system: {len_u64}")
|
||||
})?;
|
||||
Ok(self.read_exact(len)?.to_vec())
|
||||
}
|
||||
}
|
||||
700
tests/bench_stage2_decode_profile_selected_der_v2.rs
Normal file
700
tests/bench_stage2_decode_profile_selected_der_v2.rs
Normal file
@@ -0,0 +1,700 @@
|
||||
use rpki::data_model::aspa::AspaObject;
|
||||
use rpki::data_model::crl::RpkixCrl;
|
||||
use rpki::data_model::manifest::ManifestObject;
|
||||
use rpki::data_model::rc::{AsIdentifierChoice, AsResourceSet, IpAddressChoice, IpResourceSet, ResourceCertificate};
|
||||
use rpki::data_model::roa::RoaObject;
|
||||
|
||||
use rpki::storage::pack::PackFile;
|
||||
use rpki::storage::RocksStore;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum ObjType {
|
||||
Cer,
|
||||
Crl,
|
||||
Manifest,
|
||||
Roa,
|
||||
Aspa,
|
||||
}
|
||||
|
||||
impl ObjType {
|
||||
fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
ObjType::Cer => "cer",
|
||||
ObjType::Crl => "crl",
|
||||
ObjType::Manifest => "manifest",
|
||||
ObjType::Roa => "roa",
|
||||
ObjType::Aspa => "aspa",
|
||||
}
|
||||
}
|
||||
|
||||
fn ext(self) -> &'static str {
|
||||
match self {
|
||||
ObjType::Cer => "cer",
|
||||
ObjType::Crl => "crl",
|
||||
ObjType::Manifest => "mft",
|
||||
ObjType::Roa => "roa",
|
||||
ObjType::Aspa => "asa",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Sample {
|
||||
obj_type: ObjType,
|
||||
name: String,
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
fn default_samples_dir() -> PathBuf {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/benchmark/selected_der_v2")
|
||||
}
|
||||
|
||||
fn read_samples(root: &Path) -> Vec<Sample> {
|
||||
let mut out = Vec::new();
|
||||
for obj_type in [
|
||||
ObjType::Cer,
|
||||
ObjType::Crl,
|
||||
ObjType::Manifest,
|
||||
ObjType::Roa,
|
||||
ObjType::Aspa,
|
||||
] {
|
||||
let dir = root.join(obj_type.as_str());
|
||||
let rd = match std::fs::read_dir(&dir) {
|
||||
Ok(rd) => rd,
|
||||
Err(_) => continue,
|
||||
};
|
||||
for ent in rd.flatten() {
|
||||
let path = ent.path();
|
||||
if path.extension().and_then(|s| s.to_str()) != Some(obj_type.ext()) {
|
||||
continue;
|
||||
}
|
||||
let name = path
|
||||
.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or("unknown")
|
||||
.to_string();
|
||||
out.push(Sample { obj_type, name, path });
|
||||
}
|
||||
}
|
||||
out.sort_by(|a, b| a.obj_type.cmp(&b.obj_type).then_with(|| a.name.cmp(&b.name)));
|
||||
out
|
||||
}
|
||||
|
||||
fn env_u64(name: &str, default: u64) -> u64 {
|
||||
std::env::var(name)
|
||||
.ok()
|
||||
.and_then(|s| s.parse::<u64>().ok())
|
||||
.unwrap_or(default)
|
||||
}
|
||||
|
||||
fn env_u64_opt(name: &str) -> Option<u64> {
|
||||
std::env::var(name).ok().and_then(|s| s.parse::<u64>().ok())
|
||||
}
|
||||
|
||||
fn env_bool(name: &str) -> bool {
|
||||
matches!(
|
||||
std::env::var(name).as_deref(),
|
||||
Ok("1") | Ok("true") | Ok("TRUE") | Ok("yes") | Ok("YES")
|
||||
)
|
||||
}
|
||||
|
||||
fn env_string(name: &str) -> Option<String> {
|
||||
std::env::var(name).ok().filter(|s| !s.trim().is_empty())
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum BenchMode {
|
||||
Both,
|
||||
DecodeValidate,
|
||||
Landing,
|
||||
}
|
||||
|
||||
impl BenchMode {
|
||||
fn parse(s: &str) -> Result<Self, String> {
|
||||
match s {
|
||||
"" | "both" => Ok(Self::Both),
|
||||
"decode" | "decode_validate" | "decode+validate" => Ok(Self::DecodeValidate),
|
||||
"landing" => Ok(Self::Landing),
|
||||
_ => Err(format!(
|
||||
"invalid BENCH_MODE='{s}', expected one of: both, decode_validate, landing"
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn do_decode(self) -> bool {
|
||||
matches!(self, BenchMode::Both | BenchMode::DecodeValidate)
|
||||
}
|
||||
|
||||
fn do_landing(self) -> bool {
|
||||
matches!(self, BenchMode::Both | BenchMode::Landing)
|
||||
}
|
||||
|
||||
fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
BenchMode::Both => "both",
|
||||
BenchMode::DecodeValidate => "decode_validate",
|
||||
BenchMode::Landing => "landing",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn escape_md(s: &str) -> String {
|
||||
s.replace('|', "\\|").replace('\n', " ")
|
||||
}
|
||||
|
||||
fn create_parent_dirs(path: &Path) {
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent).unwrap_or_else(|e| {
|
||||
panic!("create_dir_all {}: {e}", parent.display());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn write_text_file(path: &Path, content: &str) {
|
||||
create_parent_dirs(path);
|
||||
std::fs::write(path, content).unwrap_or_else(|e| panic!("write {}: {e}", path.display()));
|
||||
}
|
||||
|
||||
fn fmt_rfc3339_utc_now() -> String {
|
||||
use time::format_description::well_known::Rfc3339;
|
||||
time::OffsetDateTime::now_utc()
|
||||
.to_offset(time::UtcOffset::UTC)
|
||||
.format(&Rfc3339)
|
||||
.unwrap_or_else(|_| "unknown".to_string())
|
||||
}
|
||||
|
||||
fn choose_iters_adaptive<F: FnMut()>(mut op: F, min_round_ms: u64, max_iters: u64) -> u64 {
|
||||
let min_secs = (min_round_ms as f64) / 1e3;
|
||||
let mut iters: u64 = 1;
|
||||
loop {
|
||||
let start = Instant::now();
|
||||
for _ in 0..iters {
|
||||
op();
|
||||
}
|
||||
let elapsed = start.elapsed().as_secs_f64();
|
||||
if elapsed >= min_secs {
|
||||
return iters;
|
||||
}
|
||||
if iters >= max_iters {
|
||||
return iters;
|
||||
}
|
||||
iters = (iters.saturating_mul(2)).min(max_iters);
|
||||
}
|
||||
}
|
||||
|
||||
fn ip_resource_count(set: &IpResourceSet) -> u64 {
|
||||
let mut n = 0u64;
|
||||
for fam in &set.families {
|
||||
match &fam.choice {
|
||||
IpAddressChoice::Inherit => n = n.saturating_add(1),
|
||||
IpAddressChoice::AddressesOrRanges(items) => n = n.saturating_add(items.len() as u64),
|
||||
}
|
||||
}
|
||||
n
|
||||
}
|
||||
|
||||
fn as_choice_count(choice: &AsIdentifierChoice) -> u64 {
|
||||
match choice {
|
||||
AsIdentifierChoice::Inherit => 1,
|
||||
AsIdentifierChoice::AsIdsOrRanges(items) => items.len() as u64,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_resource_count(set: &AsResourceSet) -> u64 {
|
||||
let mut n = 0u64;
|
||||
if let Some(c) = set.asnum.as_ref() {
|
||||
n = n.saturating_add(as_choice_count(c));
|
||||
}
|
||||
if let Some(c) = set.rdi.as_ref() {
|
||||
n = n.saturating_add(as_choice_count(c));
|
||||
}
|
||||
n
|
||||
}
|
||||
|
||||
fn complexity_main(obj_type: ObjType, bytes: &[u8]) -> u64 {
|
||||
match obj_type {
|
||||
ObjType::Cer => {
|
||||
let cert = ResourceCertificate::decode_der(bytes).expect("decode cert");
|
||||
let ip = cert
|
||||
.tbs
|
||||
.extensions
|
||||
.ip_resources
|
||||
.as_ref()
|
||||
.map(ip_resource_count)
|
||||
.unwrap_or(0);
|
||||
let asn = cert
|
||||
.tbs
|
||||
.extensions
|
||||
.as_resources
|
||||
.as_ref()
|
||||
.map(as_resource_count)
|
||||
.unwrap_or(0);
|
||||
ip.saturating_add(asn)
|
||||
}
|
||||
ObjType::Crl => {
|
||||
let crl = RpkixCrl::decode_der(bytes).expect("decode crl");
|
||||
crl.revoked_certs.len() as u64
|
||||
}
|
||||
ObjType::Manifest => {
|
||||
let mft = ManifestObject::decode_der(bytes).expect("decode manifest");
|
||||
mft.manifest.file_count() as u64
|
||||
}
|
||||
ObjType::Roa => {
|
||||
let roa = RoaObject::decode_der(bytes).expect("decode roa");
|
||||
let mut n = 0u64;
|
||||
for fam in &roa.roa.ip_addr_blocks {
|
||||
n = n.saturating_add(fam.addresses.len() as u64);
|
||||
}
|
||||
n
|
||||
}
|
||||
ObjType::Aspa => {
|
||||
let asa = AspaObject::decode_der(bytes).expect("decode aspa");
|
||||
asa.aspa.provider_as_ids.len() as u64
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_validate(obj_type: ObjType, bytes: &[u8]) {
|
||||
match obj_type {
|
||||
ObjType::Cer => {
|
||||
let decoded = ResourceCertificate::decode_der(std::hint::black_box(bytes))
|
||||
.expect("decode cert");
|
||||
std::hint::black_box(decoded);
|
||||
}
|
||||
ObjType::Crl => {
|
||||
let decoded = RpkixCrl::decode_der(std::hint::black_box(bytes)).expect("decode crl");
|
||||
std::hint::black_box(decoded);
|
||||
}
|
||||
ObjType::Manifest => {
|
||||
let decoded =
|
||||
ManifestObject::decode_der(std::hint::black_box(bytes)).expect("decode manifest");
|
||||
std::hint::black_box(decoded);
|
||||
}
|
||||
ObjType::Roa => {
|
||||
let decoded = RoaObject::decode_der(std::hint::black_box(bytes)).expect("decode roa");
|
||||
std::hint::black_box(decoded);
|
||||
}
|
||||
ObjType::Aspa => {
|
||||
let decoded = AspaObject::decode_der(std::hint::black_box(bytes)).expect("decode aspa");
|
||||
std::hint::black_box(decoded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn landing_packfile_cbor_put(
|
||||
store: &RocksStore,
|
||||
obj_type: ObjType,
|
||||
sample: &str,
|
||||
bytes: &[u8],
|
||||
) {
|
||||
let rsync_uri = format!("rsync://bench.invalid/{}/{}.{}", obj_type.as_str(), sample, obj_type.ext());
|
||||
let pf = PackFile::from_bytes_compute_sha256(rsync_uri, bytes.to_vec());
|
||||
let encoded = serde_cbor::to_vec(std::hint::black_box(&pf)).expect("cbor encode packfile");
|
||||
let key = format!("bench:packfile:{}:{}", obj_type.as_str(), sample);
|
||||
store.put_raw(&key, &encoded).expect("store put_raw");
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize)]
|
||||
struct RunConfig {
|
||||
dir: String,
|
||||
mode: String,
|
||||
obj_type: Option<String>,
|
||||
sample: Option<String>,
|
||||
fixed_iters: Option<u64>,
|
||||
warmup_iters: u64,
|
||||
rounds: u64,
|
||||
min_round_ms: u64,
|
||||
max_adaptive_iters: u64,
|
||||
timestamp_utc: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize)]
|
||||
struct ResultRow {
|
||||
obj_type: String,
|
||||
sample: String,
|
||||
size_bytes: usize,
|
||||
complexity: u64,
|
||||
avg_ns_per_op: f64,
|
||||
ops_per_sec: f64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize)]
|
||||
struct BenchmarkOutput {
|
||||
config: RunConfig,
|
||||
rows: Vec<ResultRow>,
|
||||
}
|
||||
|
||||
fn render_markdown(title: &str, rows: &[ResultRow]) -> String {
|
||||
let mut out = String::new();
|
||||
out.push_str(&format!("# {title}\n\n"));
|
||||
out.push_str("| type | sample | size_bytes | complexity | avg ns/op | ops/s |\n");
|
||||
out.push_str("|---|---|---:|---:|---:|---:|\n");
|
||||
for r in rows {
|
||||
out.push_str(&format!(
|
||||
"| {} | {} | {} | {} | {:.2} | {:.2} |\n",
|
||||
escape_md(&r.obj_type),
|
||||
escape_md(&r.sample),
|
||||
r.size_bytes,
|
||||
r.complexity,
|
||||
r.avg_ns_per_op,
|
||||
r.ops_per_sec
|
||||
));
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
fn render_csv(rows: &[ResultRow]) -> String {
|
||||
let mut out = String::new();
|
||||
out.push_str("type,sample,size_bytes,complexity,avg_ns_per_op,ops_per_sec\n");
|
||||
for r in rows {
|
||||
// sample names are controlled by our fixtures; keep it simple but safe for commas/quotes.
|
||||
let sample = r.sample.replace('"', "\"\"");
|
||||
out.push_str(&format!(
|
||||
"{},{},{},{},{:.6},{:.6}\n",
|
||||
r.obj_type,
|
||||
format!("\"{}\"", sample),
|
||||
r.size_bytes,
|
||||
r.complexity,
|
||||
r.avg_ns_per_op,
|
||||
r.ops_per_sec
|
||||
));
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "manual performance benchmark; decode+validate and landing for selected_der_v2"]
|
||||
fn stage2_decode_validate_and_landing_benchmark_selected_der_v2() {
|
||||
let dir = env_string("BENCH_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(default_samples_dir);
|
||||
|
||||
let mode = env_string("BENCH_MODE")
|
||||
.as_deref()
|
||||
.map(BenchMode::parse)
|
||||
.transpose()
|
||||
.unwrap_or_else(|e| panic!("{e}"))
|
||||
.unwrap_or(BenchMode::Both);
|
||||
|
||||
let type_filter = env_string("BENCH_TYPE");
|
||||
let sample_filter = env_string("BENCH_SAMPLE");
|
||||
let fixed_iters = env_u64_opt("BENCH_ITERS");
|
||||
let warmup_iters = env_u64("BENCH_WARMUP_ITERS", 50);
|
||||
let rounds = env_u64("BENCH_ROUNDS", 5);
|
||||
let min_round_ms = env_u64("BENCH_MIN_ROUND_MS", 200);
|
||||
let max_adaptive_iters = env_u64("BENCH_MAX_ITERS", 1_000_000);
|
||||
let verbose = env_bool("BENCH_VERBOSE");
|
||||
let out_md = env_string("BENCH_OUT_MD").map(PathBuf::from);
|
||||
let out_json = env_string("BENCH_OUT_JSON").map(PathBuf::from);
|
||||
let out_csv = env_string("BENCH_OUT_CSV").map(PathBuf::from);
|
||||
let out_md_landing = env_string("BENCH_OUT_MD_LANDING").map(PathBuf::from);
|
||||
let out_json_landing = env_string("BENCH_OUT_JSON_LANDING").map(PathBuf::from);
|
||||
let out_csv_landing = env_string("BENCH_OUT_CSV_LANDING").map(PathBuf::from);
|
||||
|
||||
if let Some(n) = fixed_iters {
|
||||
assert!(n >= 1, "BENCH_ITERS must be >= 1");
|
||||
}
|
||||
assert!(rounds >= 1, "BENCH_ROUNDS must be >= 1");
|
||||
assert!(min_round_ms >= 1, "BENCH_MIN_ROUND_MS must be >= 1");
|
||||
assert!(max_adaptive_iters >= 1, "BENCH_MAX_ITERS must be >= 1");
|
||||
|
||||
let mut samples = read_samples(&dir);
|
||||
assert!(
|
||||
!samples.is_empty(),
|
||||
"no samples found under: {}",
|
||||
dir.display()
|
||||
);
|
||||
|
||||
if let Some(t) = type_filter.as_deref() {
|
||||
samples.retain(|s| s.obj_type.as_str() == t);
|
||||
assert!(!samples.is_empty(), "no sample matched BENCH_TYPE={t}");
|
||||
}
|
||||
if let Some(filter) = sample_filter.as_deref() {
|
||||
samples.retain(|s| s.name == filter);
|
||||
assert!(!samples.is_empty(), "no sample matched BENCH_SAMPLE={filter}");
|
||||
}
|
||||
|
||||
println!("# Stage2 decode+validate benchmark (selected_der_v2)");
|
||||
println!();
|
||||
println!("- dir: {}", dir.display());
|
||||
println!("- mode: {}", mode.as_str());
|
||||
if let Some(t) = type_filter.as_deref() {
|
||||
println!("- type: {}", t);
|
||||
}
|
||||
if let Some(s) = sample_filter.as_deref() {
|
||||
println!("- sample: {}", s);
|
||||
}
|
||||
if let Some(n) = fixed_iters {
|
||||
println!("- iters: {} (fixed)", n);
|
||||
} else {
|
||||
println!(
|
||||
"- warmup: {} iters, rounds: {}, min_round: {}ms (adaptive iters, max {})",
|
||||
warmup_iters, rounds, min_round_ms, max_adaptive_iters
|
||||
);
|
||||
}
|
||||
if verbose {
|
||||
println!("- verbose: true");
|
||||
}
|
||||
if let Some(p) = out_md.as_ref() {
|
||||
println!("- out_md: {}", p.display());
|
||||
}
|
||||
if let Some(p) = out_json.as_ref() {
|
||||
println!("- out_json: {}", p.display());
|
||||
}
|
||||
if let Some(p) = out_csv.as_ref() {
|
||||
println!("- out_csv: {}", p.display());
|
||||
}
|
||||
if let Some(p) = out_md_landing.as_ref() {
|
||||
println!("- out_md_landing: {}", p.display());
|
||||
}
|
||||
if let Some(p) = out_json_landing.as_ref() {
|
||||
println!("- out_json_landing: {}", p.display());
|
||||
}
|
||||
if let Some(p) = out_csv_landing.as_ref() {
|
||||
println!("- out_csv_landing: {}", p.display());
|
||||
}
|
||||
println!();
|
||||
|
||||
if mode.do_decode() {
|
||||
println!("## decode+validate");
|
||||
println!();
|
||||
println!("| type | sample | size_bytes | complexity | avg ns/op | ops/s |");
|
||||
println!("|---|---|---:|---:|---:|---:|");
|
||||
}
|
||||
|
||||
let mut decode_rows: Vec<ResultRow> = Vec::with_capacity(samples.len());
|
||||
|
||||
let temp = tempfile::tempdir().expect("tempdir");
|
||||
let store = RocksStore::open(temp.path()).expect("open rocksdb");
|
||||
|
||||
let mut landing_rows: Vec<ResultRow> = Vec::with_capacity(samples.len());
|
||||
|
||||
for s in &samples {
|
||||
let bytes = std::fs::read(&s.path).unwrap_or_else(|e| panic!("read {}: {e}", s.path.display()));
|
||||
let size_bytes = bytes.len();
|
||||
let complexity = if mode.do_decode() {
|
||||
complexity_main(s.obj_type, bytes.as_slice())
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
if mode.do_decode() {
|
||||
// Warm-up decode+validate.
|
||||
for _ in 0..warmup_iters {
|
||||
decode_validate(s.obj_type, bytes.as_slice());
|
||||
}
|
||||
|
||||
let mut per_round_ns_per_op = Vec::with_capacity(rounds as usize);
|
||||
for round in 0..rounds {
|
||||
let iters = if let Some(n) = fixed_iters {
|
||||
n
|
||||
} else {
|
||||
choose_iters_adaptive(
|
||||
|| decode_validate(s.obj_type, bytes.as_slice()),
|
||||
min_round_ms,
|
||||
max_adaptive_iters,
|
||||
)
|
||||
};
|
||||
|
||||
let start = Instant::now();
|
||||
for _ in 0..iters {
|
||||
decode_validate(s.obj_type, bytes.as_slice());
|
||||
}
|
||||
let elapsed = start.elapsed();
|
||||
let total_ns = elapsed.as_secs_f64() * 1e9;
|
||||
let ns_per_op = total_ns / (iters as f64);
|
||||
per_round_ns_per_op.push(ns_per_op);
|
||||
|
||||
if verbose {
|
||||
println!(
|
||||
"# {}.{} round {}: iters={} total_ms={:.2} ns/op={:.2}",
|
||||
s.obj_type.as_str(),
|
||||
s.name,
|
||||
round + 1,
|
||||
iters,
|
||||
elapsed.as_secs_f64() * 1e3,
|
||||
ns_per_op
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let avg_ns =
|
||||
per_round_ns_per_op.iter().sum::<f64>() / (per_round_ns_per_op.len() as f64);
|
||||
let ops_per_sec = 1e9_f64 / avg_ns;
|
||||
|
||||
println!(
|
||||
"| {} | {} | {} | {} | {:.2} | {:.2} |",
|
||||
s.obj_type.as_str(),
|
||||
s.name,
|
||||
size_bytes,
|
||||
complexity,
|
||||
avg_ns,
|
||||
ops_per_sec
|
||||
);
|
||||
|
||||
decode_rows.push(ResultRow {
|
||||
obj_type: s.obj_type.as_str().to_string(),
|
||||
sample: s.name.clone(),
|
||||
size_bytes,
|
||||
complexity,
|
||||
avg_ns_per_op: avg_ns,
|
||||
ops_per_sec,
|
||||
});
|
||||
}
|
||||
|
||||
if mode.do_landing() {
|
||||
// Landing benchmark: PackFile(from_bytes_compute_sha256) + CBOR + RocksDB put_raw.
|
||||
let mut per_round_ns_per_op = Vec::with_capacity(rounds as usize);
|
||||
for _ in 0..warmup_iters {
|
||||
landing_packfile_cbor_put(&store, s.obj_type, &s.name, bytes.as_slice());
|
||||
}
|
||||
for round in 0..rounds {
|
||||
let iters = if let Some(n) = fixed_iters {
|
||||
n
|
||||
} else {
|
||||
choose_iters_adaptive(
|
||||
|| landing_packfile_cbor_put(&store, s.obj_type, &s.name, bytes.as_slice()),
|
||||
min_round_ms,
|
||||
max_adaptive_iters,
|
||||
)
|
||||
};
|
||||
|
||||
let start = Instant::now();
|
||||
for _ in 0..iters {
|
||||
landing_packfile_cbor_put(&store, s.obj_type, &s.name, bytes.as_slice());
|
||||
}
|
||||
let elapsed = start.elapsed();
|
||||
let total_ns = elapsed.as_secs_f64() * 1e9;
|
||||
let ns_per_op = total_ns / (iters as f64);
|
||||
per_round_ns_per_op.push(ns_per_op);
|
||||
|
||||
if verbose {
|
||||
println!(
|
||||
"# landing {}.{} round {}: iters={} total_ms={:.2} ns/op={:.2}",
|
||||
s.obj_type.as_str(),
|
||||
s.name,
|
||||
round + 1,
|
||||
iters,
|
||||
elapsed.as_secs_f64() * 1e3,
|
||||
ns_per_op
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let avg_ns =
|
||||
per_round_ns_per_op.iter().sum::<f64>() / (per_round_ns_per_op.len() as f64);
|
||||
let ops_per_sec = 1e9_f64 / avg_ns;
|
||||
|
||||
landing_rows.push(ResultRow {
|
||||
obj_type: s.obj_type.as_str().to_string(),
|
||||
sample: s.name.clone(),
|
||||
size_bytes,
|
||||
complexity,
|
||||
avg_ns_per_op: avg_ns,
|
||||
ops_per_sec,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if mode.do_decode() {
|
||||
println!();
|
||||
}
|
||||
if mode.do_landing() {
|
||||
println!("## landing (PackFile::from_bytes_compute_sha256 + CBOR + RocksDB put_raw)");
|
||||
println!();
|
||||
println!("| type | sample | size_bytes | complexity | avg ns/op | ops/s |");
|
||||
println!("|---|---|---:|---:|---:|---:|");
|
||||
for r in &landing_rows {
|
||||
println!(
|
||||
"| {} | {} | {} | {} | {:.2} | {:.2} |",
|
||||
escape_md(&r.obj_type),
|
||||
escape_md(&r.sample),
|
||||
r.size_bytes,
|
||||
r.complexity,
|
||||
r.avg_ns_per_op,
|
||||
r.ops_per_sec
|
||||
);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
if mode.do_decode() && (out_md.is_some() || out_json.is_some() || out_csv.is_some()) {
|
||||
let timestamp_utc = fmt_rfc3339_utc_now();
|
||||
let cfg = RunConfig {
|
||||
dir: dir.display().to_string(),
|
||||
mode: "decode_validate".to_string(),
|
||||
obj_type: type_filter.clone(),
|
||||
sample: sample_filter.clone(),
|
||||
fixed_iters,
|
||||
warmup_iters,
|
||||
rounds,
|
||||
min_round_ms,
|
||||
max_adaptive_iters,
|
||||
timestamp_utc,
|
||||
};
|
||||
|
||||
if let Some(path) = out_md {
|
||||
let md = render_markdown("Stage2 decode+validate benchmark (selected_der_v2)", &decode_rows);
|
||||
write_text_file(&path, &md);
|
||||
eprintln!("Wrote {}", path.display());
|
||||
}
|
||||
if let Some(path) = out_json {
|
||||
let json = serde_json::to_string_pretty(&BenchmarkOutput {
|
||||
config: cfg,
|
||||
rows: decode_rows.clone(),
|
||||
})
|
||||
.expect("serialize json");
|
||||
write_text_file(&path, &json);
|
||||
eprintln!("Wrote {}", path.display());
|
||||
}
|
||||
if let Some(path) = out_csv {
|
||||
let csv = render_csv(&decode_rows);
|
||||
write_text_file(&path, &csv);
|
||||
eprintln!("Wrote {}", path.display());
|
||||
}
|
||||
}
|
||||
|
||||
if mode.do_landing()
|
||||
&& (out_md_landing.is_some() || out_json_landing.is_some() || out_csv_landing.is_some())
|
||||
{
|
||||
let timestamp_utc = fmt_rfc3339_utc_now();
|
||||
let cfg = RunConfig {
|
||||
dir: dir.display().to_string(),
|
||||
mode: "landing_packfile_cbor_put".to_string(),
|
||||
obj_type: type_filter,
|
||||
sample: sample_filter,
|
||||
fixed_iters,
|
||||
warmup_iters,
|
||||
rounds,
|
||||
min_round_ms,
|
||||
max_adaptive_iters,
|
||||
timestamp_utc,
|
||||
};
|
||||
|
||||
if let Some(path) = out_md_landing {
|
||||
let md = render_markdown(
|
||||
"Stage2 landing benchmark (PackFile CBOR + RocksDB put_raw)",
|
||||
&landing_rows,
|
||||
);
|
||||
write_text_file(&path, &md);
|
||||
eprintln!("Wrote {}", path.display());
|
||||
}
|
||||
if let Some(path) = out_json_landing {
|
||||
let json = serde_json::to_string_pretty(&BenchmarkOutput {
|
||||
config: cfg,
|
||||
rows: landing_rows.clone(),
|
||||
})
|
||||
.expect("serialize json");
|
||||
write_text_file(&path, &json);
|
||||
eprintln!("Wrote {}", path.display());
|
||||
}
|
||||
if let Some(path) = out_csv_landing {
|
||||
let csv = render_csv(&landing_rows);
|
||||
write_text_file(&path, &csv);
|
||||
eprintln!("Wrote {}", path.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
235
tests/bench_stage2_inventory_sap.rs
Normal file
235
tests/bench_stage2_inventory_sap.rs
Normal file
@@ -0,0 +1,235 @@
|
||||
#[path = "benchmark/sap.rs"]
|
||||
mod sap;
|
||||
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct Sizes {
|
||||
vals: Vec<u64>,
|
||||
total: u64,
|
||||
}
|
||||
|
||||
impl Sizes {
|
||||
fn push(&mut self, v: u64) {
|
||||
self.vals.push(v);
|
||||
self.total = self.total.saturating_add(v);
|
||||
}
|
||||
|
||||
fn summarize(&mut self) -> Option<SizesSummary> {
|
||||
if self.vals.is_empty() {
|
||||
return None;
|
||||
}
|
||||
self.vals.sort_unstable();
|
||||
let min = *self.vals.first().unwrap();
|
||||
let max = *self.vals.last().unwrap();
|
||||
let p50 = percentile(&self.vals, 0.50);
|
||||
let p90 = percentile(&self.vals, 0.90);
|
||||
let p99 = percentile(&self.vals, 0.99);
|
||||
Some(SizesSummary {
|
||||
count: self.vals.len() as u64,
|
||||
total_bytes: self.total,
|
||||
min,
|
||||
p50,
|
||||
p90,
|
||||
p99,
|
||||
max,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
struct SizesSummary {
|
||||
count: u64,
|
||||
total_bytes: u64,
|
||||
min: u64,
|
||||
p50: u64,
|
||||
p90: u64,
|
||||
p99: u64,
|
||||
max: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
struct InventoryReport {
|
||||
store_dir: String,
|
||||
pack_files_found: u64,
|
||||
packs_success: u64,
|
||||
packs_last_attempt: u64,
|
||||
packs_decode_error: u64,
|
||||
objects_total: u64,
|
||||
by_type: BTreeMap<String, SizesSummary>,
|
||||
}
|
||||
|
||||
fn percentile(sorted: &[u64], p: f64) -> u64 {
|
||||
if sorted.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
if sorted.len() == 1 {
|
||||
return sorted[0];
|
||||
}
|
||||
let p = p.clamp(0.0, 1.0);
|
||||
let idx = ((sorted.len() - 1) as f64 * p).round() as usize;
|
||||
sorted[idx]
|
||||
}
|
||||
|
||||
fn env_string(name: &str) -> Option<String> {
|
||||
std::env::var(name).ok().filter(|s| !s.trim().is_empty())
|
||||
}
|
||||
|
||||
fn env_u64_opt(name: &str) -> Option<u64> {
|
||||
std::env::var(name).ok().and_then(|s| s.parse::<u64>().ok())
|
||||
}
|
||||
|
||||
fn create_parent_dirs(path: &Path) {
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent).unwrap_or_else(|e| {
|
||||
panic!("create_dir_all {}: {e}", parent.display());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_collect_files(root: &Path, out: &mut Vec<PathBuf>) -> std::io::Result<()> {
|
||||
for entry in std::fs::read_dir(root)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
let meta = entry.metadata()?;
|
||||
if meta.is_dir() {
|
||||
walk_collect_files(&path, out)?;
|
||||
continue;
|
||||
}
|
||||
if !meta.is_file() {
|
||||
continue;
|
||||
}
|
||||
out.push(path);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn object_type_from_rsync_uri(uri: &str) -> String {
|
||||
let file = uri.rsplit('/').next().unwrap_or(uri);
|
||||
if let Some((_, ext)) = file.rsplit_once('.') {
|
||||
return ext.to_ascii_lowercase();
|
||||
}
|
||||
"unknown".to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "manual inventory of routinator stored publication point packs (SAP)"]
|
||||
fn stage2_inventory_routinator_sap_store() {
|
||||
let store_dir = env_string("BENCH_STORE_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"set BENCH_STORE_DIR to routinator stored/ dir, e.g. /home/yuyr/dev/rust_playground/routinator/bench/full/cache/stored"
|
||||
)
|
||||
});
|
||||
let max_packs = env_u64_opt("BENCH_MAX_PACKS");
|
||||
let out_json = env_string("BENCH_OUT_JSON").map(PathBuf::from);
|
||||
|
||||
let mut pack_paths = Vec::new();
|
||||
walk_collect_files(&store_dir, &mut pack_paths)
|
||||
.unwrap_or_else(|e| panic!("walk {}: {e}", store_dir.display()));
|
||||
pack_paths.retain(|p| p.extension().and_then(|s| s.to_str()) == Some("mft"));
|
||||
pack_paths.sort();
|
||||
|
||||
if let Some(max) = max_packs {
|
||||
pack_paths.truncate(max as usize);
|
||||
}
|
||||
|
||||
println!("# Stage2 inventory: routinator SAP packs");
|
||||
println!();
|
||||
println!("- store_dir: {}", store_dir.display());
|
||||
println!("- pack_files_found: {}", pack_paths.len());
|
||||
if let Some(max) = max_packs {
|
||||
println!("- max_packs: {} (truncating input list)", max);
|
||||
}
|
||||
if let Some(p) = out_json.as_ref() {
|
||||
println!("- out_json: {}", p.display());
|
||||
}
|
||||
println!();
|
||||
|
||||
let mut by_type: BTreeMap<String, Sizes> = BTreeMap::new();
|
||||
let mut packs_success = 0u64;
|
||||
let mut packs_last_attempt = 0u64;
|
||||
let mut packs_decode_error = 0u64;
|
||||
let mut objects_total = 0u64;
|
||||
|
||||
for p in &pack_paths {
|
||||
let sap = match sap::SapPublicationPoint::decode_path(p.as_path()) {
|
||||
Ok(v) => v,
|
||||
Err(_e) => {
|
||||
packs_decode_error += 1;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
match sap.header.update_status {
|
||||
sap::SapUpdateStatus::LastAttempt { .. } => {
|
||||
packs_last_attempt += 1;
|
||||
continue;
|
||||
}
|
||||
sap::SapUpdateStatus::Success { .. } => {
|
||||
packs_success += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let Some(m) = sap.manifest.as_ref() else {
|
||||
packs_decode_error += 1;
|
||||
continue;
|
||||
};
|
||||
|
||||
by_type
|
||||
.entry("mft".to_string())
|
||||
.or_default()
|
||||
.push(m.manifest_der.len() as u64);
|
||||
by_type
|
||||
.entry("crl".to_string())
|
||||
.or_default()
|
||||
.push(m.crl_der.len() as u64);
|
||||
objects_total += 2;
|
||||
|
||||
for o in &sap.objects {
|
||||
let typ = object_type_from_rsync_uri(&o.uri);
|
||||
by_type
|
||||
.entry(typ)
|
||||
.or_default()
|
||||
.push(o.content_der.len() as u64);
|
||||
objects_total += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let mut summaries: BTreeMap<String, SizesSummary> = BTreeMap::new();
|
||||
for (typ, mut sizes) in by_type {
|
||||
if let Some(summary) = sizes.summarize() {
|
||||
summaries.insert(typ, summary);
|
||||
}
|
||||
}
|
||||
|
||||
let report = InventoryReport {
|
||||
store_dir: store_dir.display().to_string(),
|
||||
pack_files_found: pack_paths.len() as u64,
|
||||
packs_success,
|
||||
packs_last_attempt,
|
||||
packs_decode_error,
|
||||
objects_total,
|
||||
by_type: summaries.clone(),
|
||||
};
|
||||
|
||||
println!("| type | count | total_bytes | p50 | p90 | p99 | max |");
|
||||
println!("|---|---:|---:|---:|---:|---:|---:|");
|
||||
for (typ, s) in &summaries {
|
||||
println!(
|
||||
"| {} | {} | {} | {} | {} | {} | {} |",
|
||||
typ, s.count, s.total_bytes, s.p50, s.p90, s.p99, s.max
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(path) = out_json.as_ref() {
|
||||
create_parent_dirs(path);
|
||||
let bytes = serde_json::to_vec_pretty(&report).expect("encode json");
|
||||
std::fs::write(path, bytes)
|
||||
.unwrap_or_else(|e| panic!("write {}: {e}", path.display()));
|
||||
}
|
||||
}
|
||||
|
||||
191
tests/benchmark/profile_stage2_m5_hotspots.sh
Executable file
191
tests/benchmark/profile_stage2_m5_hotspots.sh
Executable file
@@ -0,0 +1,191 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# M5: Generate perf profiles + flamegraphs + hotspots for Stage2 objects.
|
||||
# Default target is ROA max sample since it is currently the largest gap in
|
||||
# ours-vs-routinator decode comparison.
|
||||
#
|
||||
# Outputs (under rpki/target/bench):
|
||||
# - perf_stage2_ours_<type>_<sample>_decode.data
|
||||
# - flamegraph_stage2_ours_<type>_<sample>_decode_release.svg
|
||||
# - hotspots_stage2_ours_<type>_<sample>_decode_release.txt
|
||||
# - perf_stage2_ours_<type>_<sample>_landing.data
|
||||
# - flamegraph_stage2_ours_<type>_<sample>_landing_release.svg
|
||||
# - hotspots_stage2_ours_<type>_<sample>_landing_release.txt
|
||||
# - perf_stage2_routinator_<type>_<sample>_decode.data
|
||||
# - flamegraph_stage2_routinator_<type>_<sample>_decode_release.svg
|
||||
# - hotspots_stage2_routinator_<type>_<sample>_decode_release.txt
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
OUT_DIR="$ROOT_DIR/target/bench"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
TYPE="${BENCH_TYPE:-roa}" # cer|crl|roa
|
||||
SAMPLE="${BENCH_SAMPLE:-max}" # e.g. max|p99|p50
|
||||
|
||||
ITERS="${BENCH_ITERS:-2000}"
|
||||
WARMUP="${BENCH_WARMUP_ITERS:-50}"
|
||||
FREQ="${FLAMEGRAPH_FREQ:-99}"
|
||||
|
||||
PROFILE_LANDING="${PROFILE_LANDING:-1}" # 0|1
|
||||
|
||||
if ! command -v perf >/dev/null 2>&1; then
|
||||
echo "ERROR: perf not found." >&2
|
||||
exit 2
|
||||
fi
|
||||
if ! command -v flamegraph >/dev/null 2>&1; then
|
||||
echo "ERROR: flamegraph not found. Install with: cargo install flamegraph" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# On WSL2, /usr/bin/perf is often a wrapper that errors because there is no
|
||||
# kernel-matched perf binary. In that case, prefer a real perf binary under
|
||||
# /usr/lib/linux-tools/*/perf by putting a shim earlier in PATH.
|
||||
PERF_WRAPPER_OK=1
|
||||
PERF_VERSION_OUT="$(perf --version 2>&1 || true)"
|
||||
if echo "${PERF_VERSION_OUT}" | grep -q "WARNING: perf not found for kernel"; then
|
||||
PERF_WRAPPER_OK=0
|
||||
fi
|
||||
|
||||
if [[ "${PERF_WRAPPER_OK}" == "0" ]]; then
|
||||
PERF_REAL="$(ls -1 /usr/lib/linux-tools/*/perf 2>/dev/null | head -n 1 || true)"
|
||||
if [[ -z "${PERF_REAL}" ]]; then
|
||||
echo "ERROR: perf wrapper found, but no real perf binary under /usr/lib/linux-tools/*/perf" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
SHIM_DIR="$OUT_DIR/tools"
|
||||
mkdir -p "${SHIM_DIR}"
|
||||
cat > "${SHIM_DIR}/perf" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
exec "${PERF_REAL}" "\$@"
|
||||
EOF
|
||||
chmod +x "${SHIM_DIR}/perf"
|
||||
export PATH="${SHIM_DIR}:${PATH}"
|
||||
echo "Using perf shim -> ${PERF_REAL}" >&2
|
||||
fi
|
||||
|
||||
echo "type=${TYPE} sample=${SAMPLE} iters=${ITERS} warmup=${WARMUP} freq=${FREQ}" >&2
|
||||
|
||||
build_ours_test_bin() {
|
||||
(cd "$ROOT_DIR" && cargo test --release --test bench_stage2_decode_profile_selected_der_v2 --no-run -q)
|
||||
local bin
|
||||
bin="$(find "$ROOT_DIR/target/release/deps" -maxdepth 1 -type f -executable -name 'bench_stage2_decode_profile_selected_der_v2-*' | head -n 1 || true)"
|
||||
if [[ -z "${bin}" ]]; then
|
||||
echo "ERROR: failed to locate ours test binary under target/release/deps" >&2
|
||||
exit 2
|
||||
fi
|
||||
echo "${bin}"
|
||||
}
|
||||
|
||||
build_routinator_bin() {
|
||||
(cd "$ROOT_DIR/benchmark/routinator_object_bench" && cargo build --release -q)
|
||||
local bin="$ROOT_DIR/benchmark/routinator_object_bench/target/release/routinator-object-bench"
|
||||
if [[ ! -x "${bin}" ]]; then
|
||||
echo "ERROR: failed to locate routinator-object-bench binary: ${bin}" >&2
|
||||
exit 2
|
||||
fi
|
||||
echo "${bin}"
|
||||
}
|
||||
|
||||
run_perf_profile() {
|
||||
local perfdata="$1"
|
||||
shift
|
||||
echo "[perf record] $perfdata" >&2
|
||||
perf record -o "$perfdata" -F "$FREQ" --call-graph dwarf -g -- "$@"
|
||||
}
|
||||
|
||||
gen_flamegraph() {
|
||||
local perfdata="$1"
|
||||
local out_svg="$2"
|
||||
local title="$3"
|
||||
local subtitle="$4"
|
||||
echo "[flamegraph] $out_svg" >&2
|
||||
flamegraph --perfdata "$perfdata" --output "$out_svg" --title "$title" --subtitle "$subtitle" >/dev/null
|
||||
}
|
||||
|
||||
gen_hotspots() {
|
||||
local perfdata="$1"
|
||||
local out_txt="$2"
|
||||
echo "[perf report] $out_txt" >&2
|
||||
# Keep it deterministic enough for diffing; avoid call-graph children view.
|
||||
perf report --stdio -i "$perfdata" --no-children --sort overhead,symbol,dso > "$out_txt" || true
|
||||
}
|
||||
|
||||
OURS_BIN="$(build_ours_test_bin)"
|
||||
ROUT_BIN="$(build_routinator_bin)"
|
||||
|
||||
# OURS decode+validate
|
||||
OURS_DECODE_PERF="$OUT_DIR/perf_stage2_ours_${TYPE}_${SAMPLE}_decode.data"
|
||||
OURS_DECODE_SVG="$OUT_DIR/flamegraph_stage2_ours_${TYPE}_${SAMPLE}_decode_release.svg"
|
||||
OURS_DECODE_HOT="$OUT_DIR/hotspots_stage2_ours_${TYPE}_${SAMPLE}_decode_release.txt"
|
||||
|
||||
run_perf_profile "$OURS_DECODE_PERF" \
|
||||
env \
|
||||
BENCH_MODE=decode_validate \
|
||||
BENCH_TYPE="$TYPE" \
|
||||
BENCH_SAMPLE="$SAMPLE" \
|
||||
BENCH_ITERS="$ITERS" \
|
||||
BENCH_ROUNDS=1 \
|
||||
BENCH_WARMUP_ITERS="$WARMUP" \
|
||||
"$OURS_BIN" --ignored --nocapture >/dev/null
|
||||
|
||||
gen_flamegraph "$OURS_DECODE_PERF" "$OURS_DECODE_SVG" \
|
||||
"stage2 ours decode_validate ${TYPE}.${SAMPLE}" "iters=${ITERS} warmup=${WARMUP} freq=${FREQ}"
|
||||
gen_hotspots "$OURS_DECODE_PERF" "$OURS_DECODE_HOT"
|
||||
|
||||
# OURS landing
|
||||
if [[ "${PROFILE_LANDING}" == "1" ]]; then
|
||||
OURS_LAND_PERF="$OUT_DIR/perf_stage2_ours_${TYPE}_${SAMPLE}_landing.data"
|
||||
OURS_LAND_SVG="$OUT_DIR/flamegraph_stage2_ours_${TYPE}_${SAMPLE}_landing_release.svg"
|
||||
OURS_LAND_HOT="$OUT_DIR/hotspots_stage2_ours_${TYPE}_${SAMPLE}_landing_release.txt"
|
||||
|
||||
run_perf_profile "$OURS_LAND_PERF" \
|
||||
env \
|
||||
BENCH_MODE=landing \
|
||||
BENCH_TYPE="$TYPE" \
|
||||
BENCH_SAMPLE="$SAMPLE" \
|
||||
BENCH_ITERS="$ITERS" \
|
||||
BENCH_ROUNDS=1 \
|
||||
BENCH_WARMUP_ITERS="$WARMUP" \
|
||||
"$OURS_BIN" --ignored --nocapture >/dev/null
|
||||
|
||||
gen_flamegraph "$OURS_LAND_PERF" "$OURS_LAND_SVG" \
|
||||
"stage2 ours landing ${TYPE}.${SAMPLE}" "iters=${ITERS} warmup=${WARMUP} freq=${FREQ}"
|
||||
gen_hotspots "$OURS_LAND_PERF" "$OURS_LAND_HOT"
|
||||
fi
|
||||
|
||||
# Routinator baseline decode
|
||||
ROUT_DECODE_PERF="$OUT_DIR/perf_stage2_routinator_${TYPE}_${SAMPLE}_decode.data"
|
||||
ROUT_DECODE_SVG="$OUT_DIR/flamegraph_stage2_routinator_${TYPE}_${SAMPLE}_decode_release.svg"
|
||||
ROUT_DECODE_HOT="$OUT_DIR/hotspots_stage2_routinator_${TYPE}_${SAMPLE}_decode_release.txt"
|
||||
|
||||
run_perf_profile "$ROUT_DECODE_PERF" \
|
||||
"$ROUT_BIN" \
|
||||
--dir "$ROOT_DIR/tests/benchmark/selected_der_v2" \
|
||||
--type "$TYPE" \
|
||||
--sample "$SAMPLE" \
|
||||
--iters "$ITERS" \
|
||||
--rounds 1 \
|
||||
--warmup-iters "$WARMUP" \
|
||||
--min-round-ms 1 \
|
||||
--max-iters 1000000 \
|
||||
--strict true \
|
||||
--out-csv "$OUT_DIR/_tmp_routinator_profile.csv" \
|
||||
--out-md "$OUT_DIR/_tmp_routinator_profile.md" \
|
||||
>/dev/null
|
||||
|
||||
gen_flamegraph "$ROUT_DECODE_PERF" "$ROUT_DECODE_SVG" \
|
||||
"stage2 routinator decode ${TYPE}.${SAMPLE}" "iters=${ITERS} warmup=${WARMUP} freq=${FREQ}"
|
||||
gen_hotspots "$ROUT_DECODE_PERF" "$ROUT_DECODE_HOT"
|
||||
|
||||
echo "Done." >&2
|
||||
echo "- ours decode flamegraph: $OURS_DECODE_SVG" >&2
|
||||
echo "- ours decode hotspots: $OURS_DECODE_HOT" >&2
|
||||
if [[ "${PROFILE_LANDING}" == "1" ]]; then
|
||||
echo "- ours landing flamegraph: $OURS_LAND_SVG" >&2
|
||||
echo "- ours landing hotspots: $OURS_LAND_HOT" >&2
|
||||
fi
|
||||
echo "- rout decode flamegraph: $ROUT_DECODE_SVG" >&2
|
||||
echo "- rout decode hotspots: $ROUT_DECODE_HOT" >&2
|
||||
|
||||
255
tests/benchmark/sap.rs
Normal file
255
tests/benchmark/sap.rs
Normal file
@@ -0,0 +1,255 @@
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct SapPublicationPoint {
|
||||
pub header: SapPointHeader,
|
||||
pub manifest: Option<SapStoredManifest>,
|
||||
pub objects: Vec<SapStoredObject>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct SapPointHeader {
|
||||
pub version: u8,
|
||||
pub manifest_uri: String,
|
||||
pub rpki_notify: Option<String>,
|
||||
pub update_status: SapUpdateStatus,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum SapUpdateStatus {
|
||||
Success { time_utc: time::OffsetDateTime },
|
||||
LastAttempt { time_utc: time::OffsetDateTime },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct SapStoredManifest {
|
||||
pub not_after_utc: time::OffsetDateTime,
|
||||
pub manifest_number: [u8; 20],
|
||||
pub this_update_utc: time::OffsetDateTime,
|
||||
pub ca_repository: String,
|
||||
pub manifest_der: Vec<u8>,
|
||||
pub crl_uri: String,
|
||||
pub crl_der: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct SapStoredObject {
|
||||
pub uri: String,
|
||||
pub hash_sha256: Option<[u8; 32]>,
|
||||
pub content_der: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum SapDecodeError {
|
||||
#[error("I/O error reading {path}: {err}")]
|
||||
Io { path: String, err: String },
|
||||
|
||||
#[error("SAP decode error: {0}")]
|
||||
Decode(String),
|
||||
}
|
||||
|
||||
impl SapPublicationPoint {
|
||||
pub fn decode_path(path: &Path) -> Result<Self, SapDecodeError> {
|
||||
let bytes = std::fs::read(path).map_err(|e| SapDecodeError::Io {
|
||||
path: path.display().to_string(),
|
||||
err: e.to_string(),
|
||||
})?;
|
||||
Self::decode_bytes(&bytes)
|
||||
}
|
||||
|
||||
pub fn decode_bytes(bytes: &[u8]) -> Result<Self, SapDecodeError> {
|
||||
let mut cur = Cursor::new(bytes);
|
||||
|
||||
let version = cur.read_u8()?;
|
||||
let manifest_uri = cur.read_string_u32()?;
|
||||
let rpki_notify = cur.read_option_string_u32()?;
|
||||
|
||||
let update_kind = cur.read_u8()?;
|
||||
let update_time_utc = cur.read_time_utc_i64_be()?;
|
||||
let update_status = match update_kind {
|
||||
0 => SapUpdateStatus::Success {
|
||||
time_utc: update_time_utc,
|
||||
},
|
||||
1 => SapUpdateStatus::LastAttempt {
|
||||
time_utc: update_time_utc,
|
||||
},
|
||||
_ => {
|
||||
return Err(SapDecodeError::Decode(format!(
|
||||
"invalid update_status kind: {update_kind}"
|
||||
)));
|
||||
}
|
||||
};
|
||||
|
||||
let header = SapPointHeader {
|
||||
version,
|
||||
manifest_uri,
|
||||
rpki_notify,
|
||||
update_status: update_status.clone(),
|
||||
};
|
||||
|
||||
match update_status {
|
||||
SapUpdateStatus::LastAttempt { .. } => Ok(SapPublicationPoint {
|
||||
header,
|
||||
manifest: None,
|
||||
objects: Vec::new(),
|
||||
}),
|
||||
SapUpdateStatus::Success { .. } => {
|
||||
let not_after_utc = cur.read_time_utc_i64_be()?;
|
||||
let manifest_number = cur.read_array_20()?;
|
||||
let this_update_utc = cur.read_time_utc_i64_be()?;
|
||||
let ca_repository = cur.read_string_u32()?;
|
||||
let manifest_der = cur.read_bytes_u64_vec()?;
|
||||
let crl_uri = cur.read_string_u32()?;
|
||||
let crl_der = cur.read_bytes_u64_vec()?;
|
||||
|
||||
let manifest = SapStoredManifest {
|
||||
not_after_utc,
|
||||
manifest_number,
|
||||
this_update_utc,
|
||||
ca_repository,
|
||||
manifest_der,
|
||||
crl_uri,
|
||||
crl_der,
|
||||
};
|
||||
|
||||
let mut objects = Vec::new();
|
||||
while cur.remaining() > 0 {
|
||||
let uri = match cur.try_read_string_u32() {
|
||||
Ok(Some(v)) => v,
|
||||
Ok(None) => break,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
let hash_type = cur.read_u8()?;
|
||||
let hash_sha256 = match hash_type {
|
||||
0 => None,
|
||||
1 => Some(cur.read_array_32()?),
|
||||
other => {
|
||||
return Err(SapDecodeError::Decode(format!(
|
||||
"unsupported hash_type {other} for stored object {uri}"
|
||||
)));
|
||||
}
|
||||
};
|
||||
let content_der = cur.read_bytes_u64_vec()?;
|
||||
objects.push(SapStoredObject {
|
||||
uri,
|
||||
hash_sha256,
|
||||
content_der,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(SapPublicationPoint {
|
||||
header,
|
||||
manifest: Some(manifest),
|
||||
objects,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Cursor<'a> {
|
||||
bytes: &'a [u8],
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
impl<'a> Cursor<'a> {
|
||||
fn new(bytes: &'a [u8]) -> Self {
|
||||
Self { bytes, pos: 0 }
|
||||
}
|
||||
|
||||
fn remaining(&self) -> usize {
|
||||
self.bytes.len().saturating_sub(self.pos)
|
||||
}
|
||||
|
||||
fn read_exact(&mut self, len: usize) -> Result<&'a [u8], SapDecodeError> {
|
||||
if len > self.remaining() {
|
||||
return Err(SapDecodeError::Decode(format!(
|
||||
"truncated input: need {len} bytes, have {}",
|
||||
self.remaining()
|
||||
)));
|
||||
}
|
||||
let start = self.pos;
|
||||
self.pos += len;
|
||||
Ok(&self.bytes[start..start + len])
|
||||
}
|
||||
|
||||
fn read_u8(&mut self) -> Result<u8, SapDecodeError> {
|
||||
Ok(self.read_exact(1)?[0])
|
||||
}
|
||||
|
||||
fn read_u32_be(&mut self) -> Result<u32, SapDecodeError> {
|
||||
let b = self.read_exact(4)?;
|
||||
Ok(u32::from_be_bytes([b[0], b[1], b[2], b[3]]))
|
||||
}
|
||||
|
||||
fn read_u64_be(&mut self) -> Result<u64, SapDecodeError> {
|
||||
let b = self.read_exact(8)?;
|
||||
Ok(u64::from_be_bytes([
|
||||
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
|
||||
]))
|
||||
}
|
||||
|
||||
fn read_i64_be(&mut self) -> Result<i64, SapDecodeError> {
|
||||
let b = self.read_exact(8)?;
|
||||
Ok(i64::from_be_bytes([
|
||||
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
|
||||
]))
|
||||
}
|
||||
|
||||
fn read_time_utc_i64_be(&mut self) -> Result<time::OffsetDateTime, SapDecodeError> {
|
||||
let ts = self.read_i64_be()?;
|
||||
time::OffsetDateTime::from_unix_timestamp(ts).map_err(|e| {
|
||||
SapDecodeError::Decode(format!("invalid unix timestamp {ts}: {e}"))
|
||||
})
|
||||
}
|
||||
|
||||
fn read_string_u32(&mut self) -> Result<String, SapDecodeError> {
|
||||
let len = self.read_u32_be()? as usize;
|
||||
let b = self.read_exact(len)?;
|
||||
std::str::from_utf8(b)
|
||||
.map(|s| s.to_string())
|
||||
.map_err(|e| SapDecodeError::Decode(format!("invalid UTF-8 string: {e}")))
|
||||
}
|
||||
|
||||
fn try_read_string_u32(&mut self) -> Result<Option<String>, SapDecodeError> {
|
||||
if self.remaining() == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
Ok(Some(self.read_string_u32()?))
|
||||
}
|
||||
|
||||
fn read_option_string_u32(&mut self) -> Result<Option<String>, SapDecodeError> {
|
||||
let len = self.read_u32_be()? as usize;
|
||||
if len == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
let b = self.read_exact(len)?;
|
||||
let s = std::str::from_utf8(b)
|
||||
.map_err(|e| SapDecodeError::Decode(format!("invalid UTF-8 string: {e}")))?;
|
||||
Ok(Some(s.to_string()))
|
||||
}
|
||||
|
||||
fn read_bytes_u64_vec(&mut self) -> Result<Vec<u8>, SapDecodeError> {
|
||||
let len_u64 = self.read_u64_be()?;
|
||||
let len = usize::try_from(len_u64).map_err(|_| {
|
||||
SapDecodeError::Decode(format!("data block too large for this system: {len_u64}"))
|
||||
})?;
|
||||
Ok(self.read_exact(len)?.to_vec())
|
||||
}
|
||||
|
||||
fn read_array_20(&mut self) -> Result<[u8; 20], SapDecodeError> {
|
||||
let b = self.read_exact(20)?;
|
||||
let mut out = [0u8; 20];
|
||||
out.copy_from_slice(b);
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn read_array_32(&mut self) -> Result<[u8; 32], SapDecodeError> {
|
||||
let b = self.read_exact(32)?;
|
||||
let mut out = [0u8; 32];
|
||||
out.copy_from_slice(b);
|
||||
Ok(out)
|
||||
}
|
||||
}
|
||||
|
||||
BIN
tests/benchmark/selected_der_v2/aspa/max.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/max.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/aspa/min.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/min.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/aspa/p01.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/p01.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/aspa/p10.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/p10.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/aspa/p25.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/p25.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/aspa/p50.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/p50.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/aspa/p75.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/p75.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/aspa/p90.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/p90.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/aspa/p95.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/p95.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/aspa/p99.asa
Normal file
BIN
tests/benchmark/selected_der_v2/aspa/p99.asa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/max.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/max.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/min.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/min.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/p01.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/p01.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/p10.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/p10.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/p25.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/p25.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/p50.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/p50.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/p75.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/p75.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/p90.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/p90.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/p95.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/p95.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/cer/p99.cer
Normal file
BIN
tests/benchmark/selected_der_v2/cer/p99.cer
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/max.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/max.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/min.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/min.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/p01.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/p01.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/p10.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/p10.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/p25.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/p25.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/p50.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/p50.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/p75.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/p75.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/p90.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/p90.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/p95.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/p95.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/crl/p99.crl
Normal file
BIN
tests/benchmark/selected_der_v2/crl/p99.crl
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/max.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/max.mft
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/min.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/min.mft
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/p01.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/p01.mft
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/p10.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/p10.mft
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/p25.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/p25.mft
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/p50.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/p50.mft
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/p75.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/p75.mft
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/p90.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/p90.mft
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/p95.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/p95.mft
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/manifest/p99.mft
Normal file
BIN
tests/benchmark/selected_der_v2/manifest/p99.mft
Normal file
Binary file not shown.
913
tests/benchmark/selected_der_v2/meta/samples.json
Normal file
913
tests/benchmark/selected_der_v2/meta/samples.json
Normal file
@@ -0,0 +1,913 @@
|
||||
{
|
||||
"created_at_rfc3339_utc": "2026-02-25T07:45:23.460363033Z",
|
||||
"store_dir_hint": "/home/yuyr/dev/rust_playground/routinator/bench/full/cache/stored",
|
||||
"per_type": {
|
||||
"aspa": 10,
|
||||
"cer": 10,
|
||||
"crl": 10,
|
||||
"manifest": 10,
|
||||
"roa": 10
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "max",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/max.cer",
|
||||
"size_bytes": 101541,
|
||||
"sha256_hex": "6eb39fd890725623c7fb02fd9eb7940118264c24bbd5a1cf5fe508375d94f2a6",
|
||||
"pack_rel_path": "rrdp/rrdp.lacnic.net/b4460caf6e2ae89d1e7133d19861729c100528f5bf30cc8ffec1eabb2279b4bf/rsync/repository.lacnic.net/rpki/lacnic/A1531B24BF50C461C7F574CD65267A8B0DC325DAAA10075F67165B98C4F4EFC3/0/05BAF2939E37DDDE1793A803162A35594ACBB405.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:24:35Z",
|
||||
"manifest_uri": "rsync://repository.lacnic.net/rpki/lacnic/A1531B24BF50C461C7F574CD65267A8B0DC325DAAA10075F67165B98C4F4EFC3/0/05BAF2939E37DDDE1793A803162A35594ACBB405.mft",
|
||||
"object_uri": "rsync://repository.lacnic.net/rpki/lacnic/A1531B24BF50C461C7F574CD65267A8B0DC325DAAA10075F67165B98C4F4EFC3/0/605432E9E1B05A7E6C208B2946FDC9C967CA8A4B.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-02T15:00:09Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-07T21:50:09Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 294,
|
||||
"ext_count": 9,
|
||||
"ip_resource_count": 12560,
|
||||
"as_resource_count": 387
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "min",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/min.cer",
|
||||
"size_bytes": 898,
|
||||
"sha256_hex": "0eb0d58bf262a6149f7ff2949581eb4a36eb5b5ce055d7ea51cb1ce9375ecfbe",
|
||||
"pack_rel_path": "rrdp/chloe.sobornost.net/a4ae76c5702d98db9df10a8a83f3450d9d07f06afd431e60721be71a84cf15b4/rsync/chloe.sobornost.net/rpki/RIPE-nljobsnijders/yqgF26w2R0m5sRVZCrbvD5cM29g.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:32:08Z",
|
||||
"manifest_uri": "rsync://chloe.sobornost.net/rpki/RIPE-nljobsnijders/yqgF26w2R0m5sRVZCrbvD5cM29g.mft",
|
||||
"object_uri": "rsync://chloe.sobornost.net/rpki/RIPE-nljobsnijders/XUJQ4tgdREjYop786R0p_wdeyeI.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T04:24:59Z",
|
||||
"manifest_not_after_rfc3339_utc": "2027-07-01T00:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 91,
|
||||
"ext_count": 6,
|
||||
"ip_resource_count": 0,
|
||||
"as_resource_count": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "p01",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/p01.cer",
|
||||
"size_bytes": 1378,
|
||||
"sha256_hex": "b00ff8d2746d735f23592abdfb812a6d48d3f8ea3df3f25431711535fb6e1644",
|
||||
"pack_rel_path": "rrdp/rrdp.twnic.tw/9e5ef8f1eb47c1bd46d2c578ebefa6a774fe140dbfbfeff1a018f1ebfc1de14b/rsync/rpkica.twnic.tw/rpki/TWNICCA/ojp8Y1RxGKrkl_A-ExIclqs0VH4.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T03:25:43Z",
|
||||
"manifest_uri": "rsync://rpkica.twnic.tw/rpki/TWNICCA/ojp8Y1RxGKrkl_A-ExIclqs0VH4.mft",
|
||||
"object_uri": "rsync://rpkica.twnic.tw/rpki/TWNICCA/6Vlz64b1l8rmEsZ5Ke2TUucLVSg.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T03:18:26Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-09-30T00:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 294,
|
||||
"ext_count": 8,
|
||||
"ip_resource_count": 2,
|
||||
"as_resource_count": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "p10",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/p10.cer",
|
||||
"size_bytes": 1537,
|
||||
"sha256_hex": "2ebde61f5f5587561b6d390db9a76bfa86cdfd1571e9147e956dc2288be7ec7d",
|
||||
"pack_rel_path": "rrdp/rrdp.apnic.net/020675249928c63c162a11d00ab299c0b2d0e2c3ca4d27a8ebf933ace26a66a6/rsync/rpki.apnic.net/repository/B3A24F201D6611E28AC8837C72FD1FF2/dAFlqA0QcZcKvAnAK3HBrHwdbg4.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T03:25:13Z",
|
||||
"manifest_uri": "rsync://rpki.apnic.net/repository/B3A24F201D6611E28AC8837C72FD1FF2/dAFlqA0QcZcKvAnAK3HBrHwdbg4.mft",
|
||||
"object_uri": "rsync://rpki.apnic.net/repository/B3A24F201D6611E28AC8837C72FD1FF2/gmqoO74CQNE5BqurRkMX6eercO8.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T02:50:14Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-10T02:50:14Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 294,
|
||||
"ext_count": 8,
|
||||
"ip_resource_count": 1,
|
||||
"as_resource_count": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "p25",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/p25.cer",
|
||||
"size_bytes": 1581,
|
||||
"sha256_hex": "4b519d26e07bbce5407b09717a0102ff9361b80e3d18bc9ef3ff5764b87853ec",
|
||||
"pack_rel_path": "rrdp/rrdp.apnic.net/020675249928c63c162a11d00ab299c0b2d0e2c3ca4d27a8ebf933ace26a66a6/rsync/rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/DmWk9f02tb1o6zySNAiXjJB6p58.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:29:30Z",
|
||||
"manifest_uri": "rsync://rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/DmWk9f02tb1o6zySNAiXjJB6p58.mft",
|
||||
"object_uri": "rsync://rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/J39oYmhAcrYqFW3fdd13JcOPUdA.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T03:47:20Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-10T03:47:20Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 294,
|
||||
"ext_count": 9,
|
||||
"ip_resource_count": 2,
|
||||
"as_resource_count": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "p50",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/p50.cer",
|
||||
"size_bytes": 1594,
|
||||
"sha256_hex": "818d24d7dd2fcafc97a8e3783f2b7bd2844096850e2fdea81f4d69d2b45764f4",
|
||||
"pack_rel_path": "rrdp/rrdp.apnic.net/020675249928c63c162a11d00ab299c0b2d0e2c3ca4d27a8ebf933ace26a66a6/rsync/rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/DmWk9f02tb1o6zySNAiXjJB6p58.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:29:30Z",
|
||||
"manifest_uri": "rsync://rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/DmWk9f02tb1o6zySNAiXjJB6p58.mft",
|
||||
"object_uri": "rsync://rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/TxeC6ZVkwoo27twZ-XPR2SdHgf4.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T03:47:20Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-10T03:47:20Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 294,
|
||||
"ext_count": 9,
|
||||
"ip_resource_count": 3,
|
||||
"as_resource_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "p75",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/p75.cer",
|
||||
"size_bytes": 1793,
|
||||
"sha256_hex": "f59769ebe6b3114db70579fc8dc64c256dac4eff714a8e192a6f34ae5424445c",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/fde169ed-d0d2-4165-8308-df2597e343f8/fde169ed-d0d2-4165-8308-df2597e343f8.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:22:56Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/fde169ed-d0d2-4165-8308-df2597e343f8/fde169ed-d0d2-4165-8308-df2597e343f8.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/fde169ed-d0d2-4165-8308-df2597e343f8/be801a76-17f5-4096-843c-c6728fe01188.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-04T02:10:03Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T18:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 294,
|
||||
"ext_count": 8,
|
||||
"ip_resource_count": 2,
|
||||
"as_resource_count": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "p90",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/p90.cer",
|
||||
"size_bytes": 1825,
|
||||
"sha256_hex": "6930e4f019b59d64a135514da8da6bff6a2725e03178ae4914c68c2bc1af8d78",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/fde169ed-d0d2-4165-8308-df2597e343f8/fde169ed-d0d2-4165-8308-df2597e343f8.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:22:56Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/fde169ed-d0d2-4165-8308-df2597e343f8/fde169ed-d0d2-4165-8308-df2597e343f8.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/fde169ed-d0d2-4165-8308-df2597e343f8/2ce98e57-da60-49a3-b167-e6998e0d2945.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-04T02:10:03Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T18:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 294,
|
||||
"ext_count": 9,
|
||||
"ip_resource_count": 3,
|
||||
"as_resource_count": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "p95",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/p95.cer",
|
||||
"size_bytes": 1839,
|
||||
"sha256_hex": "de8a89f3089560b21d0bf2021d79e41d4d259b8efcfb5fd795b349b031b3d527",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/0357272c-a79a-45bf-9586-92dd49ef3223.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:34Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/0357272c-a79a-45bf-9586-92dd49ef3223.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/24597156-139e-456b-b7b5-78502f61a0ca.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-04T01:00:09Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T01:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 294,
|
||||
"ext_count": 9,
|
||||
"ip_resource_count": 4,
|
||||
"as_resource_count": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "cer",
|
||||
"label": "p99",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/cer/p99.cer",
|
||||
"size_bytes": 1957,
|
||||
"sha256_hex": "9bc72415e60011489d1d4e87e60e18511ee57997d5597805702306e83adc5c32",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/f60c9f32-a87c-4339-a2f3-6299a3b02e29/f60c9f32-a87c-4339-a2f3-6299a3b02e29.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:59Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/f60c9f32-a87c-4339-a2f3-6299a3b02e29/f60c9f32-a87c-4339-a2f3-6299a3b02e29.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/f60c9f32-a87c-4339-a2f3-6299a3b02e29/45de47ca-0b52-44ab-af26-767d8a671192.cer",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T21:00:08Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-05T21:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "cer",
|
||||
"spki_len": 294,
|
||||
"ext_count": 9,
|
||||
"ip_resource_count": 22,
|
||||
"as_resource_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "max",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/max.crl",
|
||||
"size_bytes": 895053,
|
||||
"sha256_hex": "87bb4d0cced69cf0be5dd94d0e7fe77dd6de4f2e6f5df71b42c78f47ad50b253",
|
||||
"pack_rel_path": "rrdp/rpki.cnnic.cn/d91215e7f18122c7165f486789e5ec6859e60d4acc113741c389b13efb42c6bc/rsync/rpki.cnnic.cn/rpki/A9162E3D0000/1663/iuTPeLSd8LLB0p0y5IqUOuT0Gsw.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:26:01Z",
|
||||
"manifest_uri": "rsync://rpki.cnnic.cn/rpki/A9162E3D0000/1663/iuTPeLSd8LLB0p0y5IqUOuT0Gsw.mft",
|
||||
"object_uri": "rsync://rpki.cnnic.cn/rpki/A9162E3D0000/1663/iuTPeLSd8LLB0p0y5IqUOuT0Gsw.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-02T23:28:58Z",
|
||||
"manifest_not_after_rfc3339_utc": "2027-01-09T08:23:18Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 41411
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "min",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/min.crl",
|
||||
"size_bytes": 409,
|
||||
"sha256_hex": "80919a481ad03799f996a7911635f43e2ce0709a940d95b84ea059dc5aa7cbea",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/arin-rpki-ta.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:28:48Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/arin-rpki-ta.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/arin-rpki-ta.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2025-08-19T17:19:47Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-04-19T17:19:47Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "p01",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/p01.crl",
|
||||
"size_bytes": 433,
|
||||
"sha256_hex": "e570e2fb424749381c8b331f37504cfa7ee4ff2ae2438c92d972ccdef47eaaeb",
|
||||
"pack_rel_path": "rrdp/rrdp.lacnic.net/b4460caf6e2ae89d1e7133d19861729c100528f5bf30cc8ffec1eabb2279b4bf/rsync/repository.lacnic.net/rpki/lacnic/91274329588638C015CCBA8F9D89E1FEDD9BFDA8B46FE1567059F96B0BA87379/0/5F5C0DFD76D6DC1D850EE2157BD0F4E5F6ED2EBB.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:24:39Z",
|
||||
"manifest_uri": "rsync://repository.lacnic.net/rpki/lacnic/91274329588638C015CCBA8F9D89E1FEDD9BFDA8B46FE1567059F96B0BA87379/0/5F5C0DFD76D6DC1D850EE2157BD0F4E5F6ED2EBB.mft",
|
||||
"object_uri": "rsync://repository.lacnic.net/rpki/lacnic/91274329588638C015CCBA8F9D89E1FEDD9BFDA8B46FE1567059F96B0BA87379/0/5F5C0DFD76D6DC1D850EE2157BD0F4E5F6ED2EBB.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-01T23:22:13Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-07T06:44:13Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "p10",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/p10.crl",
|
||||
"size_bytes": 475,
|
||||
"sha256_hex": "62754c72974e31156253f95e30d07cd3072f184c9ae37df665b4ecbbe20b3d94",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/93ec9d2b-8293-4a44-a996-77893f2d4008/93ec9d2b-8293-4a44-a996-77893f2d4008.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:47Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/93ec9d2b-8293-4a44-a996-77893f2d4008/93ec9d2b-8293-4a44-a996-77893f2d4008.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/93ec9d2b-8293-4a44-a996-77893f2d4008/93ec9d2b-8293-4a44-a996-77893f2d4008.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T19:00:04Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-05T19:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "p25",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/p25.crl",
|
||||
"size_bytes": 514,
|
||||
"sha256_hex": "5cb9aca6321edea55bcffa73faba4b128dfc6f065b44247496b5fc0b988e8589",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/9b13d137-bc85-4935-b740-e59f0078def5/9b13d137-bc85-4935-b740-e59f0078def5.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:42Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/9b13d137-bc85-4935-b740-e59f0078def5/9b13d137-bc85-4935-b740-e59f0078def5.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/9b13d137-bc85-4935-b740-e59f0078def5/9b13d137-bc85-4935-b740-e59f0078def5.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T20:00:08Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T20:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "p50",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/p50.crl",
|
||||
"size_bytes": 540,
|
||||
"sha256_hex": "738ea6345fdda75fe00f10b66eec108502ce1495f0688e9f0ca69a441ed4a1ea",
|
||||
"pack_rel_path": "rrdp/rrdp.apnic.net/020675249928c63c162a11d00ab299c0b2d0e2c3ca4d27a8ebf933ace26a66a6/rsync/rpki.apnic.net/member_repository/A913E23F/C64CAAA43E5211EDAAD4B64FC4F9AE02/AgtgbdnoiYp9XfXqHKPZlgKOddk.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:25:14Z",
|
||||
"manifest_uri": "rsync://rpki.apnic.net/member_repository/A913E23F/C64CAAA43E5211EDAAD4B64FC4F9AE02/AgtgbdnoiYp9XfXqHKPZlgKOddk.mft",
|
||||
"object_uri": "rsync://rpki.apnic.net/member_repository/A913E23F/C64CAAA43E5211EDAAD4B64FC4F9AE02/AgtgbdnoiYp9XfXqHKPZlgKOddk.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T01:03:21Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-10T01:03:21Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "p75",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/p75.crl",
|
||||
"size_bytes": 554,
|
||||
"sha256_hex": "5eb9bbca1c8fb200fe68541671b62a3bd654cb50dc0946780d49c9a191f37f5a",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/69fd0156-bb1f-48b6-bf32-c9492286f195/44b921f7-65dd-4b33-b399-9d372fb4a9e5/44b921f7-65dd-4b33-b399-9d372fb4a9e5.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:12Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/69fd0156-bb1f-48b6-bf32-c9492286f195/44b921f7-65dd-4b33-b399-9d372fb4a9e5/44b921f7-65dd-4b33-b399-9d372fb4a9e5.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/69fd0156-bb1f-48b6-bf32-c9492286f195/44b921f7-65dd-4b33-b399-9d372fb4a9e5/44b921f7-65dd-4b33-b399-9d372fb4a9e5.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T19:00:04Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T19:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "p90",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/p90.crl",
|
||||
"size_bytes": 633,
|
||||
"sha256_hex": "a7aff3478dc5f602ee15aba331163a53f843a83837281544f19e2d6fa6987f2e",
|
||||
"pack_rel_path": "rrdp/rrdp.lacnic.net/b4460caf6e2ae89d1e7133d19861729c100528f5bf30cc8ffec1eabb2279b4bf/rsync/repository.lacnic.net/rpki/lacnic/4343B2828241D18D49CED12666F5034D90C1A11663270CCFE62C8E67AE1937D7/0/7A06C1864524D4D6B3F3D941A758895DEA60A24F.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:25:22Z",
|
||||
"manifest_uri": "rsync://repository.lacnic.net/rpki/lacnic/4343B2828241D18D49CED12666F5034D90C1A11663270CCFE62C8E67AE1937D7/0/7A06C1864524D4D6B3F3D941A758895DEA60A24F.mft",
|
||||
"object_uri": "rsync://repository.lacnic.net/rpki/lacnic/4343B2828241D18D49CED12666F5034D90C1A11663270CCFE62C8E67AE1937D7/0/7A06C1864524D4D6B3F3D941A758895DEA60A24F.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-02T13:33:21Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-07T14:30:21Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "p95",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/p95.crl",
|
||||
"size_bytes": 772,
|
||||
"sha256_hex": "a0fb838e8b072a928748972895d8f837427b1ba797ca6c901a9e009b652da88b",
|
||||
"pack_rel_path": "rrdp/rrdp.ripe.net/2315d99a99627f34bc597569abc7c177ad45108a37f173f3d06dbabd64962f3c/rsync/rpki.ripe.net/repository/DEFAULT/61/17e450-8818-4a27-9f35-518cd14713eb/1/t3M-nelIW0RnHI5RHaIh5BU8cRs.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:30:53Z",
|
||||
"manifest_uri": "rsync://rpki.ripe.net/repository/DEFAULT/61/17e450-8818-4a27-9f35-518cd14713eb/1/t3M-nelIW0RnHI5RHaIh5BU8cRs.mft",
|
||||
"object_uri": "rsync://rpki.ripe.net/repository/DEFAULT/61/17e450-8818-4a27-9f35-518cd14713eb/1/t3M-nelIW0RnHI5RHaIh5BU8cRs.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T04:01:11Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-04T04:01:11Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 9
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "crl",
|
||||
"label": "p99",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/crl/p99.crl",
|
||||
"size_bytes": 1843,
|
||||
"sha256_hex": "7a511d49d8f7972b4055d2da2fb213dceb1ae30a6fab896073fd9773f3264777",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/5ef79eb4-544e-4504-9a6f-d1ddff5bcd45/5ef79eb4-544e-4504-9a6f-d1ddff5bcd45.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:23:07Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/5ef79eb4-544e-4504-9a6f-d1ddff5bcd45/5ef79eb4-544e-4504-9a6f-d1ddff5bcd45.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/5ef79eb4-544e-4504-9a6f-d1ddff5bcd45/5ef79eb4-544e-4504-9a6f-d1ddff5bcd45.crl",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T14:00:03Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T14:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "crl",
|
||||
"revoked_count": 36
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "max",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/max.mft",
|
||||
"size_bytes": 3867132,
|
||||
"sha256_hex": "64a9a90da435b53a45289d869e21b80daca2a242508f18dff371a546d414c792",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/2a246947-2d62-4a6c-ba05-87187f0099b2/4e95a28e-27fe-479a-b086-2cc9809d54f6/4e95a28e-27fe-479a-b086-2cc9809d54f6.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:23:24Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/2a246947-2d62-4a6c-ba05-87187f0099b2/4e95a28e-27fe-479a-b086-2cc9809d54f6/4e95a28e-27fe-479a-b086-2cc9809d54f6.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/2a246947-2d62-4a6c-ba05-87187f0099b2/4e95a28e-27fe-479a-b086-2cc9809d54f6/4e95a28e-27fe-479a-b086-2cc9809d54f6.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-04T02:02:08Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T10:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 48923
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "min",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/min.mft",
|
||||
"size_bytes": 1786,
|
||||
"sha256_hex": "aa3a23ab546dece484fbb43d6ba1546a610f2317ef4e89e0b381e9b24538e7cd",
|
||||
"pack_rel_path": "rrdp/rrdp.ripe.net/2315d99a99627f34bc597569abc7c177ad45108a37f173f3d06dbabd64962f3c/rsync/rpki.ripe.net/repository/ripe-ncc-ta.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:24:12Z",
|
||||
"manifest_uri": "rsync://rpki.ripe.net/repository/ripe-ncc-ta.mft",
|
||||
"object_uri": "rsync://rpki.ripe.net/repository/ripe-ncc-ta.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-01-14T10:50:01Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-04-14T10:50:01Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "p01",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/p01.mft",
|
||||
"size_bytes": 1924,
|
||||
"sha256_hex": "be00f9a0bc379fd15f89cb5ff0397629dd3bc8334cc0cddefd9fb54f39929cfb",
|
||||
"pack_rel_path": "rrdp/rrdp.ripe.net/2315d99a99627f34bc597569abc7c177ad45108a37f173f3d06dbabd64962f3c/rsync/rpki.ripe.net/repository/DEFAULT/45/031138-86e1-4182-a7a6-0107ec33e5b7/1/1W_iwM_XaRBE7jeEXPz1ThqEmXQ.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:30:08Z",
|
||||
"manifest_uri": "rsync://rpki.ripe.net/repository/DEFAULT/45/031138-86e1-4182-a7a6-0107ec33e5b7/1/1W_iwM_XaRBE7jeEXPz1ThqEmXQ.mft",
|
||||
"object_uri": "rsync://rpki.ripe.net/repository/DEFAULT/45/031138-86e1-4182-a7a6-0107ec33e5b7/1/1W_iwM_XaRBE7jeEXPz1ThqEmXQ.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T04:01:07Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-04T04:01:07Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "p10",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/p10.mft",
|
||||
"size_bytes": 2012,
|
||||
"sha256_hex": "f9654d60136983a5c8fce1c7d46d1051d570e801bfd1e95b9486c4583c142e57",
|
||||
"pack_rel_path": "rrdp/rpki-repository.nic.ad.jp/aa83379c70e8dfe1337af6d0ae686a02631ded2a4138538d1a34917c84c123f2/rsync/rpki-repository.nic.ad.jp/ap/A91A73810000/30366/GUkc8TjsVYI8fTvhsuweTIDV8uU.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:25:35Z",
|
||||
"manifest_uri": "rsync://rpki-repository.nic.ad.jp/ap/A91A73810000/30366/GUkc8TjsVYI8fTvhsuweTIDV8uU.mft",
|
||||
"object_uri": "rsync://rpki-repository.nic.ad.jp/ap/A91A73810000/30366/GUkc8TjsVYI8fTvhsuweTIDV8uU.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T01:25:11Z",
|
||||
"manifest_not_after_rfc3339_utc": "2027-01-15T01:30:02Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "p25",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/p25.mft",
|
||||
"size_bytes": 2113,
|
||||
"sha256_hex": "72981b97caffddf00fcf13d11bbd3df8d2a9276b37f6c7877bfa3e47c46f9b0a",
|
||||
"pack_rel_path": "rrdp/rrdp.apnic.net/020675249928c63c162a11d00ab299c0b2d0e2c3ca4d27a8ebf933ace26a66a6/rsync/rpki.apnic.net/member_repository/A915343B/6A0383E650A511EA976CB77FC4F9AE02/1mAaggCAx5DwpRpsN2X1tLDQGzc.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:24:06Z",
|
||||
"manifest_uri": "rsync://rpki.apnic.net/member_repository/A915343B/6A0383E650A511EA976CB77FC4F9AE02/1mAaggCAx5DwpRpsN2X1tLDQGzc.mft",
|
||||
"object_uri": "rsync://rpki.apnic.net/member_repository/A915343B/6A0383E650A511EA976CB77FC4F9AE02/1mAaggCAx5DwpRpsN2X1tLDQGzc.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-02T18:58:11Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-09T18:58:11Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "p50",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/p50.mft",
|
||||
"size_bytes": 2220,
|
||||
"sha256_hex": "cb94f3b73bacfa2014461574e7f3afdd380bb53fa9efe6d90e074be97fbcb47f",
|
||||
"pack_rel_path": "rrdp/rrdp.lacnic.net/b4460caf6e2ae89d1e7133d19861729c100528f5bf30cc8ffec1eabb2279b4bf/rsync/repository.lacnic.net/rpki/lacnic/F192D3E65B741BC96E61B6810943E6A8F832DFB178388046815B4288805D4D08/0/3F0974925580D1783B4D99DCE063F669C26152F5.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:24:59Z",
|
||||
"manifest_uri": "rsync://repository.lacnic.net/rpki/lacnic/F192D3E65B741BC96E61B6810943E6A8F832DFB178388046815B4288805D4D08/0/3F0974925580D1783B4D99DCE063F669C26152F5.mft",
|
||||
"object_uri": "rsync://repository.lacnic.net/rpki/lacnic/F192D3E65B741BC96E61B6810943E6A8F832DFB178388046815B4288805D4D08/0/3F0974925580D1783B4D99DCE063F669C26152F5.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-01-31T13:10:28Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T08:23:28Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "p75",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/p75.mft",
|
||||
"size_bytes": 2424,
|
||||
"sha256_hex": "30930241ccd9af792a212f4f9b1e8e01d306aae97fa3c3f1946592a6a1e6188a",
|
||||
"pack_rel_path": "rrdp/rrdp.lacnic.net/b4460caf6e2ae89d1e7133d19861729c100528f5bf30cc8ffec1eabb2279b4bf/rsync/repository.lacnic.net/rpki/lacnic/C4D72FDA9D9D4649BACD178B2C0FCCBD56680A1D743605C0A204D1487A56E154/0/6F2E85684756BECBED992F0B17433B71F691DBB2.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:24:47Z",
|
||||
"manifest_uri": "rsync://repository.lacnic.net/rpki/lacnic/C4D72FDA9D9D4649BACD178B2C0FCCBD56680A1D743605C0A204D1487A56E154/0/6F2E85684756BECBED992F0B17433B71F691DBB2.mft",
|
||||
"object_uri": "rsync://repository.lacnic.net/rpki/lacnic/C4D72FDA9D9D4649BACD178B2C0FCCBD56680A1D743605C0A204D1487A56E154/0/6F2E85684756BECBED992F0B17433B71F691DBB2.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-01T10:49:31Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T21:25:31Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "p90",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/p90.mft",
|
||||
"size_bytes": 2707,
|
||||
"sha256_hex": "c5712b14980d481591699815a64be415df697d085220395e042418a3fb7269ed",
|
||||
"pack_rel_path": "rrdp/rrdp.lacnic.net/b4460caf6e2ae89d1e7133d19861729c100528f5bf30cc8ffec1eabb2279b4bf/rsync/repository.lacnic.net/rpki/lacnic/760CC0DA4C90C1F0023C05DFEE0070E5744BD89B60F4CD9C02EF81695E71099D/0/17444832D4DFC5B5F0EDB45E0DD0380E36A684B7.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:25:01Z",
|
||||
"manifest_uri": "rsync://repository.lacnic.net/rpki/lacnic/760CC0DA4C90C1F0023C05DFEE0070E5744BD89B60F4CD9C02EF81695E71099D/0/17444832D4DFC5B5F0EDB45E0DD0380E36A684B7.mft",
|
||||
"object_uri": "rsync://repository.lacnic.net/rpki/lacnic/760CC0DA4C90C1F0023C05DFEE0070E5744BD89B60F4CD9C02EF81695E71099D/0/17444832D4DFC5B5F0EDB45E0DD0380E36A684B7.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-01T22:41:49Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T13:29:49Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 7
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "p95",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/p95.mft",
|
||||
"size_bytes": 3189,
|
||||
"sha256_hex": "748b46f40db2de36e38baf74f636bafbe65f87750cd11885fdfdfee595872ebb",
|
||||
"pack_rel_path": "rrdp/rpki-repo.registro.br/026b1847a231e62a6bcf46a3794665f4dcbe0e609f90c0e54d7062dbf72114d9/rsync/rpki-repo.registro.br/repo/31ECeNa6JFrQNNySZguSi82Sz114gA5jRxQYM2Por1qQ/1/8BB23FB0F38F7CDE17852DC61BD234DCEBC3BB90.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:27:22Z",
|
||||
"manifest_uri": "rsync://rpki-repo.registro.br/repo/31ECeNa6JFrQNNySZguSi82Sz114gA5jRxQYM2Por1qQ/1/8BB23FB0F38F7CDE17852DC61BD234DCEBC3BB90.mft",
|
||||
"object_uri": "rsync://rpki-repo.registro.br/repo/31ECeNa6JFrQNNySZguSi82Sz114gA5jRxQYM2Por1qQ/1/8BB23FB0F38F7CDE17852DC61BD234DCEBC3BB90.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T01:45:17Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-04T05:48:17Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 13
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "manifest",
|
||||
"label": "p99",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/manifest/p99.mft",
|
||||
"size_bytes": 7579,
|
||||
"sha256_hex": "d70a0cb76cef6eae4222cf2e9c530fe76c4d0e1ca790d8f7a69435193d317f9c",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/521eb33f-9672-4cd9-acce-137227e971ac/dcf48eb5-c08a-4793-8dd8-a83f660c3f82/dcf48eb5-c08a-4793-8dd8-a83f660c3f82.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:25Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/521eb33f-9672-4cd9-acce-137227e971ac/dcf48eb5-c08a-4793-8dd8-a83f660c3f82/dcf48eb5-c08a-4793-8dd8-a83f660c3f82.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/521eb33f-9672-4cd9-acce-137227e971ac/dcf48eb5-c08a-4793-8dd8-a83f660c3f82/dcf48eb5-c08a-4793-8dd8-a83f660c3f82.mft",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T17:00:03Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-05T17:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "manifest",
|
||||
"file_count": 68
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "max",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/max.roa",
|
||||
"size_bytes": 49026,
|
||||
"sha256_hex": "92e302f8d81a2a339c592508ddd598577f4fbf54374cc359843e7ee0ebd3461f",
|
||||
"pack_rel_path": "rrdp/rrdp.apnic.net/020675249928c63c162a11d00ab299c0b2d0e2c3ca4d27a8ebf933ace26a66a6/rsync/rpki.apnic.net/member_repository/A91DFB70/2983647C838F11E586FC5812C4F9AE02/XS3RVLXc4h-3hsUm297xsEWSirg.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:24:53Z",
|
||||
"manifest_uri": "rsync://rpki.apnic.net/member_repository/A91DFB70/2983647C838F11E586FC5812C4F9AE02/XS3RVLXc4h-3hsUm297xsEWSirg.mft",
|
||||
"object_uri": "rsync://rpki.apnic.net/member_repository/A91DFB70/2983647C838F11E586FC5812C4F9AE02/9B22F928BFE311EE949C2918C4F9AE02.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-02T15:44:10Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-09T15:44:10Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 2,
|
||||
"prefix_count": 4268,
|
||||
"max_length_present": 4268
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "min",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/min.roa",
|
||||
"size_bytes": 1724,
|
||||
"sha256_hex": "5e2b9467c52689d5cdf2104b49a68aff4cbf03fd2620f3c85b863245cb36a548",
|
||||
"pack_rel_path": "rrdp/chloe.sobornost.net/a4ae76c5702d98db9df10a8a83f3450d9d07f06afd431e60721be71a84cf15b4/rsync/chloe.sobornost.net/rpki/RIPE-nljobsnijders/yqgF26w2R0m5sRVZCrbvD5cM29g.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:32:08Z",
|
||||
"manifest_uri": "rsync://chloe.sobornost.net/rpki/RIPE-nljobsnijders/yqgF26w2R0m5sRVZCrbvD5cM29g.mft",
|
||||
"object_uri": "rsync://chloe.sobornost.net/rpki/RIPE-nljobsnijders/euv64En05073B5-r95s2Uu_UwJg.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T04:24:59Z",
|
||||
"manifest_not_after_rfc3339_utc": "2027-07-01T00:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 1,
|
||||
"prefix_count": 1,
|
||||
"max_length_present": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "p01",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/p01.roa",
|
||||
"size_bytes": 1757,
|
||||
"sha256_hex": "141cbcbd8482f8cc17d014ee6475ce725d5250c61c1d04be80a56cd238c45446",
|
||||
"pack_rel_path": "rrdp/rrdp.twnic.tw/9e5ef8f1eb47c1bd46d2c578ebefa6a774fe140dbfbfeff1a018f1ebfc1de14b/rsync/rpkica.twnic.tw/rpki/TWNICCA/TUNGHO/62dfk4yFAhN0yrHhr1CZMZsRCwc.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:27:51Z",
|
||||
"manifest_uri": "rsync://rpkica.twnic.tw/rpki/TWNICCA/TUNGHO/62dfk4yFAhN0yrHhr1CZMZsRCwc.mft",
|
||||
"object_uri": "rsync://rpkica.twnic.tw/rpki/TWNICCA/TUNGHO/cIJ9FaRp5lfrLAxp7ucVIU2RW-M.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-02T04:17:15Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-08-22T08:14:28Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 1,
|
||||
"prefix_count": 1,
|
||||
"max_length_present": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "p10",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/p10.roa",
|
||||
"size_bytes": 1919,
|
||||
"sha256_hex": "9a69ca473003754b53c38566b062e12154a53d65814d5dd6a48c23686cf4ef8a",
|
||||
"pack_rel_path": "rrdp/rrdp.apnic.net/020675249928c63c162a11d00ab299c0b2d0e2c3ca4d27a8ebf933ace26a66a6/rsync/rpki.apnic.net/member_repository/A918ACB2/9FE760A6B83C11EE8741902EC4F9AE02/6Ihh_0pFOAJnqBtY-pnkia0AG70.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:29:43Z",
|
||||
"manifest_uri": "rsync://rpki.apnic.net/member_repository/A918ACB2/9FE760A6B83C11EE8741902EC4F9AE02/6Ihh_0pFOAJnqBtY-pnkia0AG70.mft",
|
||||
"object_uri": "rsync://rpki.apnic.net/member_repository/A918ACB2/9FE760A6B83C11EE8741902EC4F9AE02/BD1A38D4984B11EFB342C220C4F9AE02.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T03:28:59Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-10T03:28:59Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 1,
|
||||
"prefix_count": 1,
|
||||
"max_length_present": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "p25",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/p25.roa",
|
||||
"size_bytes": 2044,
|
||||
"sha256_hex": "27473f640b696fd5701c0f17dc6e9192992ab7c8889d20e05336aa7b709480fe",
|
||||
"pack_rel_path": "rrdp/rrdp.afrinic.net/6a5a58f9bfe26843ee174cd41e801eeecbfd15b8bb0dd7fa3952941d726730b6/rsync/rpki.afrinic.net/repository/member_repository/F368F2D0/92F86E1C6E0511E8A1B5854BF8AEA228/eX2I2BPiD_-YLMdBnpabrqa_1ps.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:29:29Z",
|
||||
"manifest_uri": "rsync://rpki.afrinic.net/repository/member_repository/F368F2D0/92F86E1C6E0511E8A1B5854BF8AEA228/eX2I2BPiD_-YLMdBnpabrqa_1ps.mft",
|
||||
"object_uri": "rsync://rpki.afrinic.net/repository/member_repository/F368F2D0/92F86E1C6E0511E8A1B5854BF8AEA228/618ABDFCD9BF11F0B2E65198DAE4EC9C.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T03:40:48Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-05T03:40:48Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 1,
|
||||
"prefix_count": 10,
|
||||
"max_length_present": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "p50",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/p50.roa",
|
||||
"size_bytes": 2125,
|
||||
"sha256_hex": "57dc478a33980a05922d9789cac407295532b109d10e8a4b9e014dc8469b19e7",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/18800324-5150-4981-a144-bdb80e6bcb7c/18800324-5150-4981-a144-bdb80e6bcb7c.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:23:03Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/18800324-5150-4981-a144-bdb80e6bcb7c/18800324-5150-4981-a144-bdb80e6bcb7c.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/18800324-5150-4981-a144-bdb80e6bcb7c/9293d640-8dc0-3613-862d-4dfc5d30586c.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-04T02:02:08Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-05T19:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 1,
|
||||
"prefix_count": 1,
|
||||
"max_length_present": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "p75",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/p75.roa",
|
||||
"size_bytes": 2126,
|
||||
"sha256_hex": "fa0855d366f4dc657d5911b82806370366c19b9fb7ca2b125e4776162b90cc64",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/d7c5f272-a2ae-458a-a75f-3cf41f19b603/d7c5f272-a2ae-458a-a75f-3cf41f19b603.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:23:05Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/d7c5f272-a2ae-458a-a75f-3cf41f19b603/d7c5f272-a2ae-458a-a75f-3cf41f19b603.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/d7c5f272-a2ae-458a-a75f-3cf41f19b603/2b935f54-a6b7-3f61-8adb-bce43ad4b075.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T14:02:08Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T13:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 1,
|
||||
"prefix_count": 1,
|
||||
"max_length_present": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "p90",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/p90.roa",
|
||||
"size_bytes": 2132,
|
||||
"sha256_hex": "8ec9f949cf6f499672357ccaa2c560b12ef5b5f2acba3e627be97582dc01d73d",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/2a246947-2d62-4a6c-ba05-87187f0099b2/4e95a28e-27fe-479a-b086-2cc9809d54f6/4e95a28e-27fe-479a-b086-2cc9809d54f6.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:23:24Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/2a246947-2d62-4a6c-ba05-87187f0099b2/4e95a28e-27fe-479a-b086-2cc9809d54f6/4e95a28e-27fe-479a-b086-2cc9809d54f6.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/2a246947-2d62-4a6c-ba05-87187f0099b2/4e95a28e-27fe-479a-b086-2cc9809d54f6/300d5263-ba19-312e-9ba8-7d527b888d9e.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-04T02:02:08Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T10:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 1,
|
||||
"prefix_count": 1,
|
||||
"max_length_present": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "p95",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/p95.roa",
|
||||
"size_bytes": 2136,
|
||||
"sha256_hex": "97fcd42de1a2f346d17edc58b671e04aafabef818f3ef9498609aa1fc684eee7",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/521eb33f-9672-4cd9-acce-137227e971ac/90dcf2c0-6606-4bd9-b445-77b183ef2ff4/90dcf2c0-6606-4bd9-b445-77b183ef2ff4.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:29Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/521eb33f-9672-4cd9-acce-137227e971ac/90dcf2c0-6606-4bd9-b445-77b183ef2ff4/90dcf2c0-6606-4bd9-b445-77b183ef2ff4.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/521eb33f-9672-4cd9-acce-137227e971ac/90dcf2c0-6606-4bd9-b445-77b183ef2ff4/5fdeae31-baab-3255-a593-abfb66a6396f.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-04T02:02:08Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T02:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 1,
|
||||
"prefix_count": 1,
|
||||
"max_length_present": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "roa",
|
||||
"label": "p99",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/roa/p99.roa",
|
||||
"size_bytes": 2209,
|
||||
"sha256_hex": "7bce2c12746b2f665624aa3f192ebdb4fc8cbc4f3d5eed2fa8e2661ad7135f7c",
|
||||
"pack_rel_path": "rrdp/rrdp.afrinic.net/6a5a58f9bfe26843ee174cd41e801eeecbfd15b8bb0dd7fa3952941d726730b6/rsync/rpki.afrinic.net/repository/member_repository/F368F2D0/7F4A98EA6E0511E89C0D6E4BF8AEA228/JdY-COq-fPpnhdTB1tNBFt4Vs9w.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T03:24:56Z",
|
||||
"manifest_uri": "rsync://rpki.afrinic.net/repository/member_repository/F368F2D0/7F4A98EA6E0511E89C0D6E4BF8AEA228/JdY-COq-fPpnhdTB1tNBFt4Vs9w.mft",
|
||||
"object_uri": "rsync://rpki.afrinic.net/repository/member_repository/F368F2D0/7F4A98EA6E0511E89C0D6E4BF8AEA228/E77E611EE6E611F0825B6ED4DAE4EC9C.roa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T03:02:20Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-05T03:02:20Z",
|
||||
"metrics": {
|
||||
"kind": "roa",
|
||||
"addr_family_count": 1,
|
||||
"prefix_count": 20,
|
||||
"max_length_present": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "max",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/max.asa",
|
||||
"size_bytes": 2157,
|
||||
"sha256_hex": "2e1daefad00193eb31dfa0e66706005e3c873fe4f079badf3b5b2c6d10462505",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/fde169ed-d0d2-4165-8308-df2597e343f8/c0efcdab-fc76-4717-8db9-db07467f9fe0/c0efcdab-fc76-4717-8db9-db07467f9fe0.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:22:58Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/fde169ed-d0d2-4165-8308-df2597e343f8/c0efcdab-fc76-4717-8db9-db07467f9fe0/c0efcdab-fc76-4717-8db9-db07467f9fe0.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/fde169ed-d0d2-4165-8308-df2597e343f8/c0efcdab-fc76-4717-8db9-db07467f9fe0/053373c0-f494-3063-a255-8d4430bf6133.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T13:00:09Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-05T13:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 12
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "min",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/min.asa",
|
||||
"size_bytes": 1685,
|
||||
"sha256_hex": "5a6451ce5349f7483a74d555c44c946c17db8314c6707fc95950bdac282eae58",
|
||||
"pack_rel_path": "rrdp/rpki.pudu.be/8d06bbb84ab1cf6124ee8f0f6bbdd9c28fc22ede46a3b55e9744a28a80263fe1/rsync/rpki.pudu.be/repo/pudu/1/CF7DC5A4F702D3DC9D56EA35B9EE202EC549647E.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:31:47Z",
|
||||
"manifest_uri": "rsync://rpki.pudu.be/repo/pudu/1/CF7DC5A4F702D3DC9D56EA35B9EE202EC549647E.mft",
|
||||
"object_uri": "rsync://rpki.pudu.be/repo/pudu/1/AS56762.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T04:07:32Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-04T05:17:32Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "p01",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/p01.asa",
|
||||
"size_bytes": 1736,
|
||||
"sha256_hex": "28a98f95d617b77cac316d739a40dcb871306558fef582eaa671cfa4d899eb02",
|
||||
"pack_rel_path": "rrdp/rpki.roa.net/78e0c5f52b7514947e9ef499c811d15797db7c65ea9051c27b11555439a0c010/rsync/rpki.roa.net/rrdp/xTom/58/5B1AD82F0E7DC771819A9A26674992A3951B9373.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T02:26:07Z",
|
||||
"manifest_uri": "rsync://rpki.roa.net/rrdp/xTom/58/5B1AD82F0E7DC771819A9A26674992A3951B9373.mft",
|
||||
"object_uri": "rsync://rpki.roa.net/rrdp/xTom/58/AS138038.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T02:13:19Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-04T05:43:19Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "p10",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/p10.asa",
|
||||
"size_bytes": 1789,
|
||||
"sha256_hex": "857a667b95f8962e94b19425d65e00fee0a2e2886b9408e94a644873f6bcb20c",
|
||||
"pack_rel_path": "rrdp/rrdp.ripe.net/2315d99a99627f34bc597569abc7c177ad45108a37f173f3d06dbabd64962f3c/rsync/rpki.ripe.net/repository/DEFAULT/31/de9d72-fcd4-4c7c-89ca-de4ba786f872/1/3l5sIzCRG8HcjIPUEe9rEgizu9Y.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:30:59Z",
|
||||
"manifest_uri": "rsync://rpki.ripe.net/repository/DEFAULT/31/de9d72-fcd4-4c7c-89ca-de4ba786f872/1/3l5sIzCRG8HcjIPUEe9rEgizu9Y.mft",
|
||||
"object_uri": "rsync://rpki.ripe.net/repository/DEFAULT/31/de9d72-fcd4-4c7c-89ca-de4ba786f872/1/G0H1NZGAbtsyoA2e--eIMeks25w.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T04:00:42Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-04T04:00:42Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "p25",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/p25.asa",
|
||||
"size_bytes": 1796,
|
||||
"sha256_hex": "512afb7f399ac0559b88bd6a0bc6f369f9b6ad3f3e46aa1cd9e067087cf10cc9",
|
||||
"pack_rel_path": "rrdp/rrdp.ripe.net/2315d99a99627f34bc597569abc7c177ad45108a37f173f3d06dbabd64962f3c/rsync/rpki.ripe.net/repository/DEFAULT/46/cadd6e-65c6-44da-9ee9-efea65dc3020/1/1-EAlIIyFaM6OWN4a59g--NKydCQ.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T04:30:18Z",
|
||||
"manifest_uri": "rsync://rpki.ripe.net/repository/DEFAULT/46/cadd6e-65c6-44da-9ee9-efea65dc3020/1/1-EAlIIyFaM6OWN4a59g--NKydCQ.mft",
|
||||
"object_uri": "rsync://rpki.ripe.net/repository/DEFAULT/46/cadd6e-65c6-44da-9ee9-efea65dc3020/1/BNbYCTwC4UEQcd5nV0lyvO8_FF4.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T04:00:31Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-04T04:00:31Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "p50",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/p50.asa",
|
||||
"size_bytes": 1856,
|
||||
"sha256_hex": "2895646ffad9bac7df603e6bee1f535a68154d0d39735819de8a1f2d9eea6d06",
|
||||
"pack_rel_path": "rrdp/rrdp.paas.rpki.ripe.net/bcd30c8fe6a4120dcd88ad3eeb82a7ea26f8ecce57fe1d5cb45e5e34c3a94a9b/rsync/rsync.paas.rpki.ripe.net/repository/97b5f6f4-24be-4ae0-82a8-e5d82842e229/0/A0BBB954570CFA6E856937043DD2C1745A0A05C2.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-03T03:27:39Z",
|
||||
"manifest_uri": "rsync://rsync.paas.rpki.ripe.net/repository/97b5f6f4-24be-4ae0-82a8-e5d82842e229/0/A0BBB954570CFA6E856937043DD2C1745A0A05C2.mft",
|
||||
"object_uri": "rsync://rsync.paas.rpki.ripe.net/repository/97b5f6f4-24be-4ae0-82a8-e5d82842e229/0/AS214757.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T03:09:43Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-04T05:59:43Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 14
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "p75",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/p75.asa",
|
||||
"size_bytes": 2116,
|
||||
"sha256_hex": "e9ea6e871e0e435a5a3b7a019fd9f8761628504668c9ba0a744ad7f337fe4825",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/59adcb6d-cc06-4e2c-b5df-20bfcd83176e/59adcb6d-cc06-4e2c-b5df-20bfcd83176e.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:35Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/59adcb6d-cc06-4e2c-b5df-20bfcd83176e/59adcb6d-cc06-4e2c-b5df-20bfcd83176e.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/0357272c-a79a-45bf-9586-92dd49ef3223/59adcb6d-cc06-4e2c-b5df-20bfcd83176e/8314341a-405c-33d6-ad94-3e8c6d770291.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T19:00:04Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T19:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "p90",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/p90.asa",
|
||||
"size_bytes": 2124,
|
||||
"sha256_hex": "e1c33906ef3bdbec47fe0cc7c9fc163d427234b4f5581895dc5279df7f278614",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/e7060a03-da54-4766-9b77-667ebbb66ffe/e7060a03-da54-4766-9b77-667ebbb66ffe.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:23:06Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/e7060a03-da54-4766-9b77-667ebbb66ffe/e7060a03-da54-4766-9b77-667ebbb66ffe.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/746e0111-fafb-430f-b778-d204cfcd99a8/e7060a03-da54-4766-9b77-667ebbb66ffe/4f4bee4f-0c5a-38c0-a421-5b81029d9452.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T19:00:04Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-05T19:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "p95",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/p95.asa",
|
||||
"size_bytes": 2131,
|
||||
"sha256_hex": "87f9d2611bda2851a348619505c8b872bd34c26ce1ddfc46cb5d21bc8d055e5d",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/f60c9f32-a87c-4339-a2f3-6299a3b02e29/f2f0585e-a28e-4ead-9b1c-defd291ce54d/f2f0585e-a28e-4ead-9b1c-defd291ce54d.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:59Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/f60c9f32-a87c-4339-a2f3-6299a3b02e29/f2f0585e-a28e-4ead-9b1c-defd291ce54d/f2f0585e-a28e-4ead-9b1c-defd291ce54d.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/f60c9f32-a87c-4339-a2f3-6299a3b02e29/f2f0585e-a28e-4ead-9b1c-defd291ce54d/3dfa4a5a-70d2-39a3-8e69-18afc586e9ec.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-03T13:00:09Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-06T13:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"obj_type": "aspa",
|
||||
"label": "p99",
|
||||
"file_rel_path": "tests/benchmark/selected_der_v2/aspa/p99.asa",
|
||||
"size_bytes": 2147,
|
||||
"sha256_hex": "8a7e34f96cbb16a3dce913dbf38f1f3fa806130100f6d38cc0b7a399f1a77e83",
|
||||
"pack_rel_path": "rrdp/rrdp.arin.net/e2c8cb4b372d841061fc231dcdc28a679c244f4f630d41cfe01c8c3aaa3a36f7/rsync/rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/d9d1572f-6cbb-4cf7-b599-e9d0e981d9bf/4ee37184-86de-48c9-af35-5d102d140fa6/4ee37184-86de-48c9-af35-5d102d140fa6.mft",
|
||||
"pack_update_time_rfc3339_utc": "2026-02-04T03:24:17Z",
|
||||
"manifest_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/d9d1572f-6cbb-4cf7-b599-e9d0e981d9bf/4ee37184-86de-48c9-af35-5d102d140fa6/4ee37184-86de-48c9-af35-5d102d140fa6.mft",
|
||||
"object_uri": "rsync://rpki.arin.net/repository/arin-rpki-ta/5e4a23ea-e80a-403e-b08c-2171da2157d3/d9d1572f-6cbb-4cf7-b599-e9d0e981d9bf/4ee37184-86de-48c9-af35-5d102d140fa6/c00a162c-b8fa-3da5-8257-7074076c1ed6.asa",
|
||||
"manifest_this_update_rfc3339_utc": "2026-02-04T03:00:08Z",
|
||||
"manifest_not_after_rfc3339_utc": "2026-02-07T03:00:00Z",
|
||||
"metrics": {
|
||||
"kind": "aspa",
|
||||
"provider_count": 8
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
tests/benchmark/selected_der_v2/roa/max.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/max.roa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/roa/min.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/min.roa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/roa/p01.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/p01.roa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/roa/p10.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/p10.roa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/roa/p25.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/p25.roa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/roa/p50.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/p50.roa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/roa/p75.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/p75.roa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/roa/p90.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/p90.roa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/roa/p95.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/p95.roa
Normal file
Binary file not shown.
BIN
tests/benchmark/selected_der_v2/roa/p99.roa
Normal file
BIN
tests/benchmark/selected_der_v2/roa/p99.roa
Normal file
Binary file not shown.
@@ -2,6 +2,7 @@ use der_parser::num_bigint::BigUint;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use rpki::data_model::aspa::{AspaEContent, AspaValidateError};
|
||||
use rpki::data_model::common::X509NameDer;
|
||||
use rpki::data_model::rc::{
|
||||
AsIdOrRange, AsIdentifierChoice, AsResourceSet, IpResourceSet, RcExtensions, ResourceCertKind,
|
||||
ResourceCertificate, RpkixTbsCertificate, SubjectInfoAccess,
|
||||
@@ -17,8 +18,8 @@ fn dummy_ee(
|
||||
version: 2,
|
||||
serial_number: BigUint::from(1u8),
|
||||
signature_algorithm: "1.2.840.113549.1.1.11".to_string(),
|
||||
issuer_dn: "CN=issuer".to_string(),
|
||||
subject_dn: "CN=subject".to_string(),
|
||||
issuer_name: X509NameDer(b"CN=issuer".to_vec()),
|
||||
subject_name: X509NameDer(b"CN=subject".to_vec()),
|
||||
validity_not_before: OffsetDateTime::UNIX_EPOCH,
|
||||
validity_not_after: OffsetDateTime::UNIX_EPOCH,
|
||||
subject_public_key_info: vec![],
|
||||
|
||||
@@ -127,8 +127,8 @@ impl From<&RpkixTbsCertificate> for RpkixTbsCertificatePretty {
|
||||
version: v.version,
|
||||
serial_number: hex::encode(v.serial_number.to_bytes_be()),
|
||||
signature_algorithm: v.signature_algorithm.clone(),
|
||||
issuer_dn: v.issuer_dn.clone(),
|
||||
subject_dn: v.subject_dn.clone(),
|
||||
issuer_dn: v.issuer_name.to_string(),
|
||||
subject_dn: v.subject_name.to_string(),
|
||||
validity_not_before: v.validity_not_before,
|
||||
validity_not_after: v.validity_not_after,
|
||||
subject_public_key_info: bytes_fmt(&v.subject_public_key_info),
|
||||
|
||||
@@ -120,7 +120,7 @@ fn canonicalize_sorts_families_sorts_and_dedups_addresses() {
|
||||
IpPrefix {
|
||||
afi: RoaAfi::Ipv4,
|
||||
prefix_len: 24,
|
||||
addr: vec![192, 0, 2, 0],
|
||||
addr: [192, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use der_parser::num_bigint::BigUint;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use rpki::data_model::common::X509NameDer;
|
||||
use rpki::data_model::rc::{
|
||||
Afi, AsResourceSet, IpAddressChoice, IpAddressFamily, IpAddressOrRange, IpPrefix,
|
||||
IpResourceSet, RcExtensions, ResourceCertKind, ResourceCertificate, RpkixTbsCertificate,
|
||||
@@ -20,8 +21,8 @@ fn dummy_ee(
|
||||
version: 2,
|
||||
serial_number: BigUint::from(1u8),
|
||||
signature_algorithm: "1.2.840.113549.1.1.11".to_string(),
|
||||
issuer_dn: "CN=issuer".to_string(),
|
||||
subject_dn: "CN=subject".to_string(),
|
||||
issuer_name: X509NameDer(b"CN=issuer".to_vec()),
|
||||
subject_name: X509NameDer(b"CN=subject".to_vec()),
|
||||
validity_not_before: OffsetDateTime::UNIX_EPOCH,
|
||||
validity_not_after: OffsetDateTime::UNIX_EPOCH,
|
||||
subject_public_key_info: vec![],
|
||||
@@ -55,7 +56,7 @@ fn test_roa_single_v4_prefix() -> RoaEContent {
|
||||
prefix: rpki::data_model::roa::IpPrefix {
|
||||
afi: RoaAfi::Ipv4,
|
||||
prefix_len: 8,
|
||||
addr: vec![10, 0, 0, 0],
|
||||
addr: [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
},
|
||||
max_length: Some(24),
|
||||
}],
|
||||
@@ -159,7 +160,24 @@ fn contains_prefix_handles_non_octet_boundary_prefix_len() {
|
||||
prefix: rpki::data_model::roa::IpPrefix {
|
||||
afi: RoaAfi::Ipv4,
|
||||
prefix_len: 16,
|
||||
addr: vec![0b1010_0000, 0x12, 0, 0], // 160.18.0.0/16
|
||||
addr: [
|
||||
0b1010_0000,
|
||||
0x12,
|
||||
0,
|
||||
0, // 160.18.0.0/16
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
},
|
||||
max_length: None,
|
||||
}],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use der_parser::num_bigint::BigUint;
|
||||
use rpki::data_model::common::X509NameDer;
|
||||
use rpki::data_model::oid::OID_CP_IPADDR_ASNUMBER;
|
||||
use rpki::data_model::rc::{
|
||||
Afi, AsIdOrRange, AsIdentifierChoice, AsResourceSet, IpAddressChoice, IpAddressFamily,
|
||||
@@ -17,8 +18,8 @@ fn dummy_rc_ca(ext: RcExtensions) -> ResourceCertificate {
|
||||
version: 2,
|
||||
serial_number: BigUint::from(1u32),
|
||||
signature_algorithm: "1.2.840.113549.1.1.11".into(),
|
||||
issuer_dn: "CN=TA".into(),
|
||||
subject_dn: "CN=TA".into(),
|
||||
issuer_name: X509NameDer(b"CN=TA".to_vec()),
|
||||
subject_name: X509NameDer(b"CN=TA".to_vec()),
|
||||
validity_not_before: t,
|
||||
validity_not_after: t,
|
||||
subject_public_key_info: Vec::new(),
|
||||
|
||||
@@ -107,23 +107,16 @@ fn audit_helpers_format_roa_ip_prefix_smoke() {
|
||||
let v4 = IpPrefix {
|
||||
afi: RoaAfi::Ipv4,
|
||||
prefix_len: 24,
|
||||
addr: vec![192, 0, 2, 0],
|
||||
addr: [192, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
};
|
||||
assert_eq!(rpki::audit::format_roa_ip_prefix(&v4), "192.0.2.0/24");
|
||||
|
||||
let v6 = IpPrefix {
|
||||
afi: RoaAfi::Ipv6,
|
||||
prefix_len: 32,
|
||||
addr: vec![0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
addr: [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
};
|
||||
assert!(rpki::audit::format_roa_ip_prefix(&v6).ends_with("/32"));
|
||||
|
||||
let bad = IpPrefix {
|
||||
afi: RoaAfi::Ipv4,
|
||||
prefix_len: 8,
|
||||
addr: vec![1, 2, 3],
|
||||
};
|
||||
assert!(rpki::audit::format_roa_ip_prefix(&bad).starts_with("ipv4:"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user