# Consumer contract
```rust
use std::{path::Path, sync::Arc};
pub use kcode_k1_canonical_chain::{SubmitError, TxId};
pub use kcode_k1_transaction::{GENESIS_PARENT, REGISTER_AT_TIP, SubsystemId};
pub type TestSigner =
Box<dyn FnOnce(&[u8]) -> Result<[u8; 64], String> + Send + 'static>;
pub type TestQueuePropagation =
Box<dyn FnOnce(&[u8]) -> Result<(), String> + Send + 'static>;
pub trait TestSubsystem: Send + Sync + 'static {
fn submit_txn(&self, id: TxId, payload: &[u8]) -> Result<(), String>;
fn reorg(&self) -> Result<(), String>;
}
pub trait OrderingCandidate: Send + Sync + 'static {
fn register_subsystem(
&self,
subsystem: SubsystemId,
after: Option<TxId>,
handler: Arc<dyn TestSubsystem>,
) -> Result<(), String>;
fn submit_txn(&self, transaction: &[u8]) -> Result<(), SubmitError>;
fn submit_local_txn(
&self,
timestamp: u64,
creator: [u8; 32],
subsystem: SubsystemId,
payload: &[u8],
signer: TestSigner,
queue_propagation: TestQueuePropagation,
) -> Result<(TxId, Vec<u8>), String>;
fn contains(&self, id: TxId) -> bool;
fn tip(&self) -> Option<TxId>;
fn between_txids(
&self,
older: TxId,
newer: TxId,
) -> Result<Vec<TxId>, String>;
fn get_txn(&self, id: TxId) -> Result<Option<Vec<u8>>, String>;
}
pub trait OrderingHarness: Send + Sync {
fn open(&self, root: &Path) -> Result<Arc<dyn OrderingCandidate>, String>;
}
pub fn verify_registration_sentinels(
harness: &dyn OrderingHarness,
) -> Result<(), String>;
pub fn verify_queue_before_callback(
harness: &dyn OrderingHarness,
) -> Result<(), String>;
pub fn verify_independent_subsystem_lanes(
harness: &dyn OrderingHarness,
) -> Result<(), String>;
pub fn verify_signing_commit_exclusion(
harness: &dyn OrderingHarness,
) -> Result<(), String>;
pub fn verify_unrelated_callback_reentry(
harness: &dyn OrderingHarness,
) -> Result<(), String>;
```
`TxId` and `SubsystemId` identify transactions and subsystems. `GENESIS_PARENT` denotes the beginning of canonical history, and `REGISTER_AT_TIP` requests registration at the current tip. A `TestSigner` signs the supplied transaction bytes. A `TestQueuePropagation` receives the complete signed transaction bytes.
`TestSubsystem::submit_txn` receives a committed transaction ID and its subsystem payload. Performance: Consumer-defined and not benchmarked by this package.
`TestSubsystem::reorg` reports that previously delivered canonical history was reorganized. Performance: Consumer-defined and not benchmarked by this package.
`OrderingCandidate::register_subsystem` registers one handler. `None` and `Some(GENESIS_PARENT)` replay matching canonical transactions from genesis; `Some(REGISTER_AT_TIP)` atomically activates at the current tip without historical delivery; any other cursor must be the last successfully integrated transaction, and replay starts strictly after it. Performance: Candidate-defined and not benchmarked by this package.
`OrderingCandidate::submit_txn` submits complete peer transaction bytes and reports candidate errors through `SubmitError`; callback failures use `SubmitError::Other`. Performance: Candidate-defined and not benchmarked by this package.
`OrderingCandidate::submit_local_txn` invokes the signer and queue closure exactly once each and returns the committed ID and complete signed bytes; the ID must equal `TxId::for_transaction` of those bytes. Postcommit queue, subsystem, and panic failures contain the literal text `was committed`, `TxId`, and the committed ID's `Debug` representation. Performance: Candidate-defined and not benchmarked by this package.
`OrderingCandidate::contains` reports canonical membership. Performance: Candidate-defined and not benchmarked by this package.
`OrderingCandidate::tip` returns the canonical tip. Performance: Candidate-defined and not benchmarked by this package.
`OrderingCandidate::between_txids` returns canonical IDs strictly between the supplied boundaries in canonical order. Performance: Candidate-defined and not benchmarked by this package.
`OrderingCandidate::get_txn` returns complete stored bytes for a canonical ID and `None` for a noncanonical ID. Performance: Candidate-defined and not benchmarked by this package.
`OrderingHarness::open` opens the candidate directly at the requested private root and returns an independently usable instance. Adapters forward candidate behavior without emulating it. Performance: Harness-defined and not benchmarked by this package.
Verifier calls use independent temporary roots and may run concurrently. They return `Ok(())` only after every assertion passes; candidate errors, assertion failures, panics, worker failures, and bounded-wait failures become descriptive `Err` values. Roots are cleaned after ordinary completion and retained when a scenario panics. Cross-thread progress waits expire after two seconds, blocked-state probes observe 50 milliseconds, and an unreturning direct candidate call can still hang its verifier.
`verify_registration_sentinels` verifies genesis replay, tip registration with and without existing history, later matching delivery, and local-submission ID and tip consistency. Performance: Not yet benchmarked; it runs one fixed-size fixture with no input-sized loop.
`verify_queue_before_callback` verifies queue completion before matching callbacks for failing and panicking queues, committed-ID errors, continued integration, and a later successful submission. Performance: Not yet benchmarked; it runs one fixed-size fixture with no input-sized loop.
`verify_independent_subsystem_lanes` verifies in-order serialization within one blocked subsystem while canonical queries, queue propagation, and a complete submission for another subsystem continue independently. Performance: Not yet benchmarked; it runs one fixed-size fixture using the documented two-second waits and 50-millisecond blocked probes.
`verify_signing_commit_exclusion` verifies that a blocked signer excludes another local writer and a tip query until signing and commit finish. Performance: Not yet benchmarked; it runs one fixed-size fixture using the documented two-second waits and 50-millisecond blocked probes.
`verify_unrelated_callback_reentry` verifies that an A callback can synchronously submit to B without caller coordination, and that B commits and receives the exact nested payload before the outer callback returns. Performance: Not yet benchmarked; it runs one fixed-size fixture using the documented two-second waits.