mod approval;
mod approval_store;
mod binding;
mod chain_sink;
mod client;
mod exchange;
mod exchange_sync;
mod exchange_retry;
mod exchange_types;
mod floor;
mod floor_preview;
mod gate;
#[cfg(all(feature = "workload-runtime", unix))]
mod http_transport;
mod links;
mod mesh_config;
mod persist;
mod policy;
mod relay;
mod renewal;
mod request;
mod run_gate;
mod store;
mod steward;
mod steward_client;
mod store_accept;
mod store_load;
mod store_status;
mod store_sync;
mod service_links;
#[cfg(test)]
mod tests_common;
#[cfg(test)]
mod tests_exchange;
#[cfg(test)]
mod tests_fixes;
#[cfg(test)]
mod tests_sync;
#[cfg(test)]
mod tests_service_links;
#[cfg(test)]
mod tests_policy;
#[cfg(test)]
mod tests_relay;
#[cfg(test)]
mod tests_relay_local;
#[cfg(test)]
mod tests_request;
#[cfg(test)]
mod tests_stub;
#[cfg(test)]
mod tests_review;
#[cfg(test)]
mod tests_seed_service;
#[cfg(test)]
mod tests_store;
#[cfg(test)]
mod tests_types;
#[cfg(test)]
mod tests_run_gate;
#[cfg(all(test, feature = "workload-runtime", unix))]
mod tests_http;
#[cfg(all(test, feature = "workload-runtime", unix))]
mod tests_http_e2e;
#[cfg(all(test, feature = "workload-runtime", unix))]
mod tests_renewal;
#[cfg(test)]
mod tests_renewal_cursor;
use std::sync::{Arc, Mutex, RwLock};
#[allow(unused_imports)]
use ed25519_dalek::{Signature, Signer, SigningKey, VerifyingKey};
#[allow(unused_imports)]
use serde::{Deserialize, Serialize};
#[allow(unused_imports)]
use crate::workload_pkg::codec::{hex_decode_exact, hex_encode};
pub use approval::{Approval, SignedApproval, sign_approval, verify_approval, verify_approval_signature};
pub use approval_store::{APPROVALS_FILE, ApprovalStore};
pub use binding::{
AdmissionPosture, BindState, BindingExtraCheck, BindingRecord, NoExtraChecks, SignedBinding,
sign_binding, verify_binding_member,
};
pub use chain_sink::{ChainLicenceSink, LICENCE_EVENT_PREFIX};
pub use client::{
ARTIFACT_PATH, CHECKOUT_PATH, CheckoutWire, ClockMs, system_clock_ms, GRANTS_PATH, GrantsPage, RENEW_PATH, LicenceClient, LicenceClientError,
LicenceResponse, LicenceTransport, SignedLicenceClient,
};
pub use exchange::{
CtxAdmission, ExchangeError, LicenceExchange, LicenceExchangeConfig, LicenceExchangeParts,
PeerAdmission, PostureFn, Receipt, Spend, sign_unbind,
};
pub use exchange_retry::MAX_SYNC_RETRIES;
pub use exchange_sync::{GrantCursor, SYNC_MAX_BYTES, SYNC_MAX_ENTRIES, SyncMsg};
pub use floor::FloorState;
pub use floor_preview::{FloorPreview, RevivedGrant};
pub use gate::{RunDenied, RunPermit, RunRequest, may_run};
#[cfg(all(feature = "workload-runtime", unix))]
pub use http_transport::{
DEFAULT_MAX_ARTIFACT_BYTES, HttpLicenceTransport, LicenceLinkConfig, TransportLimits,
};
pub use renewal::{
EVENT_KIND_CHECKOUT_LAPSED, EVENT_KIND_CHECKOUT_RENEWED, RenewalConfig, RenewalReport, Renewer,
};
pub use run_gate::{CognitumRunGate, RunRefusal, RunVerdict, StoreRunGate, check_run};
pub use steward_client::{SharedTransport, StewardLicenceClient};
pub use store_status::{ApprovalRow, BOUND_MARKER, GrantRow};
pub use links::LicenceLinks;
pub use service_links::{
LICENCE_TOPICS, MAX_REPLY_SENDS, MAX_REPLY_SENDS_PER_PEER, PEER_REFRESH, PeerDirectory, PeerSnapshot, ServiceLicenceLinks, ServiceLinksCounters,
is_licence_topic,
};
pub use weft_licence_wire::{
APPROVAL_DOMAIN, BINDING_DOMAIN, CheckoutGrant, FAR_FUTURE_CLAMP_SECS, GRANT_DOMAIN,
GRANT_SKEW_SECS, GrantArtifact, LicenceError, LicenceRef, MAX_APPROVALS, MAX_GRANT_SLOTS,
MAX_ARTIFACT_BYTES, MAX_FLOORS, MAX_GRANT_TTL_SECS, MAX_PAYLOAD_BYTES, MAX_STORE_BYTES, MAX_UNIX_TIME, MESH_ID_DOMAIN, MeshId,
SignedEnvelope, SignedGrant, key_id, sha256_hex, sign_grant, verify_grant,
};
#[allow(unused_imports)]
pub(crate) use weft_licence_wire::{
envelope_key, parse_canonical, sign_envelope, signed_bytes, valid_hex32, valid_token,
verify_envelope, verify_grant_signature,
};
pub use mesh_config::{MeshIdConfigError, mesh_id_from_config};
pub use policy::MeshCheckoutPolicy;
pub use relay::{
CheckoutCaller, CheckoutRefusal, CheckoutRelay, RelayLimits, EVENT_KIND_CHECKOUT_GRANTED,
EVENT_KIND_CHECKOUT_REFUSED, GATE_ACTION, GrantFlood, NoFlood, install_grant,
};
pub use request::{
CLOCK_FLOOR_SECS, LicenceRequest, REQUEST_DOMAIN, REQUEST_WINDOW_MS, ReplayGuard,
RequestAuth, RequestRefused, sign_request, signing_string, valid_nonce, verify_request,
};
pub use steward::StewardCheck;
pub use store::{CheckoutGrantStore, GRANTS_FILE, VerifiedCheckoutGrant};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Outcome {
Applied,
AppliedUnsaved,
Duplicate,
Ignored,
}
#[derive(Clone, Default)]
pub struct LocalMeshId(Arc<RwLock<Option<MeshId>>>);
impl LocalMeshId {
pub fn new(id: MeshId) -> Self {
Self(Arc::new(RwLock::new(Some(id))))
}
pub fn unset() -> Self {
Self::default()
}
pub fn get(&self) -> Option<MeshId> {
*self.0.read().unwrap_or_else(|p| p.into_inner())
}
pub fn set(&self, id: Option<MeshId>) {
*self.0.write().unwrap_or_else(|p| p.into_inner()) = id;
}
}
pub type Clock = Arc<dyn Fn() -> u64 + Send + Sync>;
pub fn system_clock() -> Clock {
Arc::new(|| {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0)
})
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LicenceEvent {
BindingRefused(String),
BindingConflict(u64),
BindingOrphaned {
stored: String,
local: String,
},
GrantConflict {
cog_id: String,
version: String,
seq: u64,
},
FloorReset(u64),
SyncBadSignature {
peer: String,
},
}
impl LicenceEvent {
pub fn name(&self) -> &'static str {
match self {
Self::BindingRefused(_) => "binding_refused",
Self::BindingConflict(_) => "binding_conflict",
Self::BindingOrphaned { .. } => "binding_orphaned",
Self::GrantConflict { .. } => "grant_conflict",
Self::FloorReset(_) => "floor_reset",
Self::SyncBadSignature { .. } => "sync_bad_signature",
}
}
}
pub trait LicenceEventSink: Send + Sync {
fn emit(&self, event: LicenceEvent);
}
#[derive(Debug, Default)]
pub struct NoopSink;
impl LicenceEventSink for NoopSink {
fn emit(&self, _: LicenceEvent) {}
}
#[derive(Debug, Default)]
pub struct RecordingSink(Mutex<Vec<LicenceEvent>>);
impl RecordingSink {
pub fn events(&self) -> Vec<LicenceEvent> {
self.0.lock().unwrap_or_else(|p| p.into_inner()).clone()
}
}
impl LicenceEventSink for RecordingSink {
fn emit(&self, event: LicenceEvent) {
self.0.lock().unwrap_or_else(|p| p.into_inner()).push(event);
}
}