Skip to main content

clawft_kernel/licence/
chain_sink.rs

1//! Maps [`LicenceEvent`]s onto the node's chain (ADR-106 phase 1b).
2
3use std::sync::Arc;
4
5use serde_json::{Value, json};
6
7use super::{LicenceEvent, LicenceEventSink};
8use crate::chain::ChainManager;
9
10/// Chain event kinds are this prefix plus [`LicenceEvent::name`], for example
11/// `licence.binding_conflict`.
12pub const LICENCE_EVENT_PREFIX: &str = "licence.";
13
14/// Chain source of licence events.
15const SOURCE: &str = "licence";
16
17/// Appends every [`LicenceEvent`] to the chain.
18pub struct ChainLicenceSink {
19    chain: Arc<ChainManager>,
20}
21
22impl ChainLicenceSink {
23    /// A sink appending to `chain`.
24    pub fn new(chain: Arc<ChainManager>) -> Self {
25        Self { chain }
26    }
27
28    /// The chain event kind for `event`.
29    pub fn kind(event: &LicenceEvent) -> String {
30        format!("{LICENCE_EVENT_PREFIX}{}", event.name())
31    }
32
33    /// The chain payload for `event`.
34    pub fn payload(event: &LicenceEvent) -> Value {
35        match event {
36            LicenceEvent::BindingRefused(why) => json!({ "reason": why }),
37            LicenceEvent::BindingConflict(seq) => json!({ "seq": seq }),
38            LicenceEvent::BindingOrphaned { stored, local } => {
39                json!({ "stored_mesh_id": stored, "local_mesh_id": local })
40            }
41            LicenceEvent::GrantConflict { cog_id, version, seq } => {
42                json!({ "cog_id": cog_id, "version": version, "seq": seq })
43            }
44            LicenceEvent::FloorReset(to) => json!({ "to": to }),
45            LicenceEvent::SyncBadSignature { peer } => json!({ "peer": peer }),
46        }
47    }
48}
49
50impl LicenceEventSink for ChainLicenceSink {
51    fn emit(&self, event: LicenceEvent) {
52        self.chain
53            .append(SOURCE, &Self::kind(&event), Some(Self::payload(&event)));
54    }
55}