liminal-server 0.24.5

Standalone server for the liminal messaging bus
Documentation
//! Every stored row that carries a credential digest decodes and re-encodes
//! byte for byte (PROTO-007 R1).
//!
//! Each fixture is a row in the bytes the schema wrote before the digest became
//! a newtype: the digest a bare array of 32 numbers. These tests pass unchanged
//! at ad2aa69a, where the field was `[u8; 32]`, so the fixtures are what that
//! code writes; at every later head they prove the newtype reads those rows and
//! writes them back unchanged.

use std::error::Error;

use serde::Serialize;
use serde::de::DeserializeOwned;

use super::log::{
    StoredDetachedSource, StoredEnrollmentAllocation, StoredLeave, StoredLeaveV3, StoredOperationV2,
};

const LEAVE: &str = r#"{"request":{"conversation_id":61636,"participant_id":7,"capability_generation":3,"attach_secret":[40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71],"token":[80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95]},"request_verifier":[100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131],"receiving_epoch":{"server_incarnation":2,"connection_ordinal":5,"capability_generation":3},"left_transaction_order":41,"left_delivery_seq":17,"ended_binding_epoch":{"server_incarnation":2,"connection_ordinal":4,"capability_generation":3},"prior_terminal_delivery_seq":null}"#;
const ENROLLMENT: &str = r#"{"participant_id":7,"identity_limit":64,"attach_secret":[40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71],"origin_epoch":{"server_incarnation":2,"connection_ordinal":1,"capability_generation":1},"attached_order":9,"attached_seq":4,"receipt_expires_at":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"provenance_expires_at":[20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"enrollment_fingerprint":[100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]}"#;
const V2_DETACHED: &str = r#"{"operation":"detached","request":{"conversation_id":61636,"participant_id":7,"capability_generation":3,"token":[80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95]},"verifier":[100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131],"receiving_epoch":{"server_incarnation":2,"connection_ordinal":5,"capability_generation":3},"terminal_order":43,"terminal_seq":19,"event":[1,2,3]}"#;
const LEAVE_V3: &str = r#"{"request":{"conversation_id":61636,"participant_id":7,"capability_generation":3,"attach_secret":[40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71],"token":[80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95]},"request_verifier":[100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131],"receiving_epoch":{"server_incarnation":2,"connection_ordinal":5,"capability_generation":3},"left_transaction_order":41,"left_delivery_seq":17,"ended_binding_epoch":null,"prior_terminal_delivery_seq":12,"pending_source_sequence":30,"finalizer_presentation":{"presentation":"consume_recovered_reservation","recovered_source_sequence":29}}"#;
const DETACH_COMMITTED: &str = r#"{"source":"explicit_request_committed","request":{"conversation_id":61636,"participant_id":7,"capability_generation":3,"token":[80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95]},"secret_verified":true,"verifier":[100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131],"receiving_epoch":{"server_incarnation":2,"connection_ordinal":5,"capability_generation":3},"event":[4,5]}"#;
const DETACH_PENDING: &str = r#"{"source":"explicit_request_pending","request":{"conversation_id":61636,"participant_id":7,"capability_generation":3,"token":[80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95]},"secret_verified":false,"verifier":[100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131],"receiving_epoch":{"server_incarnation":2,"connection_ordinal":5,"capability_generation":3},"observer_baseline":15}"#;

/// `fixture` decodes as `T` and re-encodes to the same bytes.
fn round_trips<T: Serialize + DeserializeOwned>(fixture: &str) -> Result<(), Box<dyn Error>> {
    let row: T = serde_json::from_str(fixture)?;
    assert_eq!(serde_json::to_string(&row)?, fixture);
    Ok(())
}

#[test]
fn a_stored_leave_row_round_trips_byte_for_byte() -> Result<(), Box<dyn Error>> {
    round_trips::<StoredLeave>(LEAVE)
}

#[test]
fn a_stored_enrollment_allocation_row_round_trips_byte_for_byte() -> Result<(), Box<dyn Error>> {
    round_trips::<StoredEnrollmentAllocation>(ENROLLMENT)
}

#[test]
fn a_v2_detached_operation_row_round_trips_byte_for_byte() -> Result<(), Box<dyn Error>> {
    round_trips::<StoredOperationV2>(V2_DETACHED)
}

#[test]
fn a_stored_leave_v3_row_round_trips_byte_for_byte() -> Result<(), Box<dyn Error>> {
    round_trips::<StoredLeaveV3>(LEAVE_V3)
}

#[test]
fn an_explicit_detach_committed_source_row_round_trips_byte_for_byte() -> Result<(), Box<dyn Error>>
{
    round_trips::<StoredDetachedSource>(DETACH_COMMITTED)
}

#[test]
fn an_explicit_detach_pending_source_row_round_trips_byte_for_byte() -> Result<(), Box<dyn Error>> {
    round_trips::<StoredDetachedSource>(DETACH_PENDING)
}