trine-kv 0.6.0

Embedded LSM MVCC key-value database.
Documentation
use super::{
    CONTENT_READER_DRAIN_ATTESTATION_MAGIC, ContentAccessBarrier, ContentAccessBarrierId,
    ContentReaderDrainAttestation, ContentReaderDrainAttestationId,
    ContentReaderDrainAttestationOptions, ContentReaderDrainCoordinatorId,
    ContentReaderDrainEvidenceDigest, ContentReaderDrainKind, Error, Result, StorageDomainId,
    array_at,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct ContentReaderDrainAttestationRecord {
    pub(crate) storage_domain_id: StorageDomainId,
    pub(crate) barrier_id: ContentAccessBarrierId,
    pub(crate) attestation_id: ContentReaderDrainAttestationId,
    pub(crate) options: ContentReaderDrainAttestationOptions,
    pub(crate) barrier_enforced_at: crate::ReadVersion,
    pub(crate) attested_at: crate::ReadVersion,
}

impl ContentReaderDrainAttestationRecord {
    pub(crate) fn encode_prefix(self) -> Vec<u8> {
        const PREFIX_LEN: usize = 8 + 16 + 16 + 16 + 1 + 16 + 33 + 8;
        let mut bytes = Vec::with_capacity(PREFIX_LEN);
        bytes.extend_from_slice(CONTENT_READER_DRAIN_ATTESTATION_MAGIC);
        bytes.extend_from_slice(&self.storage_domain_id.to_bytes());
        bytes.extend_from_slice(&self.barrier_id.to_bytes());
        bytes.extend_from_slice(&self.attestation_id.to_bytes());
        bytes.push(self.options.kind().tag());
        bytes.extend_from_slice(&self.options.coordinator_id().to_bytes());
        bytes.extend_from_slice(&self.options.evidence_digest().to_bytes());
        bytes.extend_from_slice(&self.barrier_enforced_at.as_u64().to_be_bytes());
        bytes
    }

    pub(crate) fn decode(bytes: &[u8], storage_domain_id: StorageDomainId) -> Result<Self> {
        const RECORD_LEN: usize = 8 + 16 + 16 + 16 + 1 + 16 + 33 + 8 + 8;
        if bytes.len() != RECORD_LEN
            || bytes.get(..8) != Some(CONTENT_READER_DRAIN_ATTESTATION_MAGIC)
        {
            return Err(Error::InvalidFormat {
                message: "invalid content reader-drain attestation header or length".to_owned(),
            });
        }
        let stored_domain = StorageDomainId::from_bytes(array_at::<16>(
            bytes,
            8,
            "content reader-drain storage domain",
        )?);
        let barrier_id = ContentAccessBarrierId::from_bytes(array_at::<16>(
            bytes,
            24,
            "content reader-drain barrier identity",
        )?)?;
        let attestation_id = ContentReaderDrainAttestationId::from_bytes(array_at::<16>(
            bytes,
            40,
            "content reader-drain attestation identity",
        )?)?;
        let kind = ContentReaderDrainKind::from_tag(bytes[56])?;
        let coordinator_id = ContentReaderDrainCoordinatorId::from_bytes(array_at::<16>(
            bytes,
            57,
            "content reader-drain coordinator identity",
        )?);
        let evidence_digest = ContentReaderDrainEvidenceDigest::from_bytes(array_at::<33>(
            bytes,
            73,
            "content reader-drain evidence digest",
        )?)?;
        let barrier_enforced_at = crate::ReadVersion::from_u64(u64::from_be_bytes(array_at::<8>(
            bytes,
            106,
            "content reader-drain barrier sequence",
        )?));
        let attested_at = crate::ReadVersion::from_u64(u64::from_be_bytes(array_at::<8>(
            bytes,
            114,
            "content reader-drain attestation sequence",
        )?));
        if stored_domain != storage_domain_id
            || barrier_enforced_at.as_u64() == 0
            || attested_at.as_u64() < barrier_enforced_at.as_u64()
        {
            return Err(Error::Corruption {
                message: "content reader-drain attestation has invalid protected coordinates"
                    .to_owned(),
            });
        }
        Ok(Self {
            storage_domain_id,
            barrier_id,
            attestation_id,
            options: ContentReaderDrainAttestationOptions::new(
                kind,
                coordinator_id,
                evidence_digest,
            ),
            barrier_enforced_at,
            attested_at,
        })
    }

    pub(crate) fn matches_request(
        self,
        barrier: ContentAccessBarrier,
        attestation_id: ContentReaderDrainAttestationId,
        options: ContentReaderDrainAttestationOptions,
    ) -> bool {
        self.storage_domain_id == barrier.storage_domain_id()
            && self.barrier_id == barrier.barrier_id()
            && self.attestation_id == attestation_id
            && self.options == options
            && self.barrier_enforced_at == barrier.enforced_at()
    }

    pub(crate) const fn into_public(self) -> ContentReaderDrainAttestation {
        ContentReaderDrainAttestation {
            storage_domain_id: self.storage_domain_id,
            barrier_id: self.barrier_id,
            attestation_id: self.attestation_id,
            options: self.options,
            barrier_enforced_at: self.barrier_enforced_at,
            attested_at: self.attested_at,
        }
    }
}

pub(crate) fn content_reader_drain_attestation_key(storage_domain_id: StorageDomainId) -> Vec<u8> {
    let mut key = Vec::with_capacity(6 + 16);
    key.extend_from_slice(b"drain:");
    key.extend_from_slice(&storage_domain_id.to_bytes());
    key
}