Skip to main content

aven_protocol/
tail.rs

1//! Current membership and generation rules for ordinary tail and image admission.
2//! Storage owners establish prefix identities, saved outcomes, parent state,
3//! attachment completeness and allocator ordering before committing effects.
4use crate::claim::{Secret, membership::Membership};
5use crate::wire::tail::Context;
6use anyhow::{Result, ensure};
7
8/// Authenticate current device authority before checking the publication binding.
9pub fn authenticate(membership: &Membership, context: &Context, bearer: &Secret) -> Result<()> {
10    membership.authenticate(&context.authentication(bearer), false)?;
11    let binding = membership.publication().binding();
12    ensure!(
13        context.stream == binding.stream_id && context.descriptor == binding.descriptor_commitment,
14        "error encrypted-tail-invalid"
15    );
16    Ok(())
17}
18
19/// Only fresh appends require an unfrozen current generation. Saved outcomes
20/// must be resolved first under current authentication, including after rotation.
21pub fn admit_generations(
22    membership: &Membership,
23    generations: impl IntoIterator<Item = [u8; 32]>,
24) -> Result<()> {
25    ensure!(
26        !membership.rotation_pending(),
27        "error membership-rotation-pending"
28    );
29    ensure!(
30        generations
31            .into_iter()
32            .all(|generation| generation == membership.current_generation().id),
33        "error encrypted-tail-invalid"
34    );
35    Ok(())
36}
37
38/// Historical-generation repair requires stored provenance for this exact
39/// descriptor. A known generation alone does not admit a new historical object.
40pub fn eligible_image(membership: &Membership, generation: [u8; 32], admitted: bool) -> Result<()> {
41    ensure!(
42        membership.generations().iter().any(|g| g.id == generation)
43            && (generation == membership.current_generation().id || admitted),
44        "error encrypted-tail-invalid"
45    );
46    Ok(())
47}
48
49pub mod envelope;
50pub mod parent;
51
52#[cfg(test)]
53mod tests;