clawft_kernel/licence/
steward_client.rs1use std::sync::Arc;
12
13use async_trait::async_trait;
14use ed25519_dalek::SigningKey;
15
16use super::client::{
17 CheckoutWire, ClockMs, GrantsPage, LicenceClient, LicenceClientError, LicenceResponse, LicenceTransport,
18 SignedLicenceClient,
19};
20use super::request::LicenceRequest;
21use super::{BindingRecord, CheckoutGrantStore, SignedGrant};
22use crate::workload_pkg::codec::hex_encode;
23
24#[derive(Clone)]
26pub struct SharedTransport(pub Arc<dyn LicenceTransport>);
27
28#[async_trait]
29impl LicenceTransport for SharedTransport {
30 async fn call(&self, req: LicenceRequest) -> Result<LicenceResponse, LicenceClientError> {
31 self.0.call(req).await
32 }
33}
34
35pub struct StewardLicenceClient {
37 store: Arc<CheckoutGrantStore>,
38 key: SigningKey,
39 node_id: String,
40 transport: SharedTransport,
41 clock: ClockMs,
42}
43
44fn refused(code: &str) -> LicenceClientError {
45 LicenceClientError::Refused { status: 0, code: code.into() }
46}
47
48impl StewardLicenceClient {
49 pub fn new(
51 store: Arc<CheckoutGrantStore>,
52 key: SigningKey,
53 node_id: impl Into<String>,
54 transport: Arc<dyn LicenceTransport>,
55 clock: ClockMs,
56 ) -> Arc<Self> {
57 Arc::new(Self { store, key, node_id: node_id.into(), transport: SharedTransport(transport), clock })
58 }
59
60 pub fn steward_binding(&self) -> Result<BindingRecord, LicenceClientError> {
62 let b = self.store.active_binding().ok_or_else(|| refused("seed_not_bound"))?;
63 let me = hex_encode(&self.key.verifying_key().to_bytes());
64 if b.steward_node_id != self.node_id || b.steward_pubkey != me {
65 return Err(refused("not_steward"));
66 }
67 Ok(b)
68 }
69
70 fn signed(&self) -> Result<Arc<SignedLicenceClient<SharedTransport>>, LicenceClientError> {
71 let b = self.steward_binding()?;
72 Ok(SignedLicenceClient::for_binding(self.key.clone(), &b, self.transport.clone(), self.clock.clone()))
73 }
74}
75
76#[async_trait]
77impl LicenceClient for StewardLicenceClient {
78 async fn checkout(&self, req: &CheckoutWire) -> Result<SignedGrant, LicenceClientError> {
79 self.signed()?.checkout(req).await
80 }
81
82 async fn artifact(&self, blake3_hex: &str, max_len: u64) -> Result<Vec<u8>, LicenceClientError> {
83 self.signed()?.artifact(blake3_hex, max_len).await
84 }
85
86 async fn grants_since(&self, since: u64) -> Result<Vec<SignedGrant>, LicenceClientError> {
87 self.signed()?.grants_since(since).await
88 }
89
90 async fn grants_page(&self, since: u64) -> Result<GrantsPage, LicenceClientError> {
91 self.signed()?.grants_page(since).await
92 }
93
94 async fn renew(&self) -> Result<GrantsPage, LicenceClientError> {
95 self.signed()?.renew().await
96 }
97
98 async fn release(&self, cog_id: &str, version: &str) -> Result<GrantsPage, LicenceClientError> {
99 self.signed()?.release(cog_id, version).await
100 }
101}