pub mod budget;
pub mod checkpoint;
pub mod classify;
pub mod entries;
mod etag;
mod extract;
pub mod geometry;
pub mod inspection;
pub mod job;
pub mod publication;
pub mod resolve;
pub mod scheduled;
mod selection;
pub mod state;
pub mod verify;
#[cfg(all(test, feature = "memory"))]
mod extract_tests;
#[cfg(all(test, feature = "memory"))]
mod job_tests;
#[cfg(all(test, feature = "memory"))]
mod tests;
use crate::{ErrorDetail, ServerError};
pub(crate) const PACK_CAP_MESSAGE: &str = "pack exceeds indexed max_pack_bytes";
pub(crate) fn check_pack_cap(bytes: u64, cap: u64) -> Result<(), ServerError> {
if bytes > cap {
return Err(ServerError::invalid_argument(PACK_CAP_MESSAGE));
}
Ok(())
}
#[must_use]
pub fn pending(retry_after_ms: u64) -> ServerError {
let retry_after_ms = retry_after_ms.max(1_000);
let mut value = vec![0x08];
let mut n = retry_after_ms;
while n >= 0x80 {
value.push(u8::try_from(n & 0x7f).unwrap_or(0) | 0x80);
n >>= 7;
}
value.push(u8::try_from(n).unwrap_or(0));
ServerError::unavailable("pack verification pending")
.with_detail(ErrorDetail {
type_name: "mkit.transport.v1.PendingVerification".into(),
value: value.into(),
})
.with_http_status(503)
.with_header("Retry-After", retry_after_ms.div_ceil(1_000).to_string())
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub struct IndexedConfig {
pub max_delta_chain_depth: u32,
pub relay_lag_bound_ms: u64,
pub max_pack_bytes: u64,
pub decode_budget: u64,
pub extract_min_bytes: u64,
pub max_extract_bytes: Option<u64>,
pub verification: VerificationMode,
pub max_ancestry_commits: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum VerificationMode {
#[default]
Inline,
Scheduled,
}
impl IndexedConfig {
#[must_use]
pub fn scheduled(max_pack_bytes: u64) -> Self {
let defaults = Self::default();
Self {
verification: VerificationMode::Scheduled,
max_pack_bytes,
decode_budget: defaults.decode_budget.max(max_pack_bytes),
max_ancestry_commits: SCHEDULED_MAX_ANCESTRY_COMMITS,
..defaults
}
}
#[must_use]
pub fn effective_max_extract_bytes(&self) -> u64 {
self.max_extract_bytes
.unwrap_or_else(|| self.max_pack_bytes.saturating_mul(4))
}
}
pub const MAX_ANCESTRY_COMMITS_LIMIT: u32 = 65_536;
pub const SCHEDULED_MAX_ANCESTRY_COMMITS: u32 = 64;
pub const DEFAULT_MAX_ANCESTRY_COMMITS: u32 = 256;
pub const DEFAULT_EXTRACT_MIN_BYTES: u64 = 64 * 1024;
impl Default for IndexedConfig {
fn default() -> Self {
Self {
max_delta_chain_depth: 50,
relay_lag_bound_ms: crate::relay::RELAY_LAG_BOUND_MS,
max_pack_bytes: 2 << 30,
decode_budget: 2 << 30,
extract_min_bytes: DEFAULT_EXTRACT_MIN_BYTES,
max_extract_bytes: None,
verification: VerificationMode::Inline,
max_ancestry_commits: DEFAULT_MAX_ANCESTRY_COMMITS,
}
}
}