gl_client/
persist.rs

1use lightning_signer::bitcoin::secp256k1::PublicKey;
2use lightning_signer::chain::tracker::ChainTracker;
3use lightning_signer::channel::ChannelId;
4use lightning_signer::channel::ChannelStub;
5use lightning_signer::node::NodeConfig;
6use lightning_signer::node::NodeState;
7use lightning_signer::persist::ChainTrackerListenerEntry;
8use lightning_signer::persist::{Error, Persist, SignerId};
9use lightning_signer::policy::validator::ValidatorFactory;
10use lightning_signer::SendSync;
11use log::{trace, warn};
12use serde::{Deserialize, Serialize};
13use std::collections::BTreeMap;
14use std::sync::Arc;
15use std::sync::Mutex;
16
17const NODE_PREFIX: &str = "nodes";
18const NODE_STATE_PREFIX: &str = "nodestates";
19const CHANNEL_PREFIX: &str = "channels";
20const ALLOWLIST_PREFIX: &str = "allowlists";
21const TRACKER_PREFIX: &str = "trackers";
22
23#[derive(Clone, Serialize, Deserialize)]
24pub struct State {
25    values: BTreeMap<String, (u64, serde_json::Value)>,
26}
27
28impl State {
29    fn insert_node(
30        &mut self,
31        key: &str,
32        node_entry: vls_persist::model::NodeEntry,
33        node_state_entry: vls_persist::model::NodeStateEntry,
34    ) -> Result<(), Error> {
35        let node_key = format!("{NODE_PREFIX}/{key}");
36        let state_key = format!("{NODE_STATE_PREFIX}/{key}");
37        assert!(!self.values.contains_key(&node_key), "inserting node twice");
38        assert!(
39            !self.values.contains_key(&state_key),
40            "inserting node_state twice"
41        );
42
43        self.values
44            .insert(node_key, (0u64, serde_json::to_value(node_entry).unwrap()));
45        self.values.insert(
46            state_key,
47            (0u64, serde_json::to_value(node_state_entry).unwrap()),
48        );
49        Ok(())
50    }
51
52    fn update_node(
53        &mut self,
54        key: &str,
55        node_state: vls_persist::model::NodeStateEntry,
56    ) -> Result<(), Error> {
57        trace!(
58            "Update node: {}",
59            serde_json::to_string(&node_state).unwrap()
60        );
61        let key = format!("{NODE_STATE_PREFIX}/{key}");
62        let v = self
63            .values
64            .get_mut(&key)
65            .expect("attempting to update non-existent node");
66        *v = (v.0 + 1, serde_json::to_value(node_state).unwrap());
67        Ok(())
68    }
69
70    fn delete_node(&mut self, key: &str) -> Result<(), Error> {
71        let node_key = format!("{NODE_PREFIX}/{key}");
72        let state_key = format!("{NODE_STATE_PREFIX}/{key}");
73
74        self.values.remove(&node_key);
75        self.values.remove(&state_key);
76        Ok(())
77    }
78
79    fn insert_channel(
80        &mut self,
81        key: &str,
82        channel_entry: vls_persist::model::ChannelEntry,
83    ) -> Result<(), Error> {
84        let key = format!("{CHANNEL_PREFIX}/{key}");
85        assert!(!self.values.contains_key(&key));
86        self.values
87            .insert(key, (0u64, serde_json::to_value(channel_entry).unwrap()));
88        Ok(())
89    }
90
91    fn delete_channel(&mut self, key: &str) {
92        self.values.remove(key);
93    }
94
95    fn update_channel(
96        &mut self,
97        key: &str,
98        channel_entry: vls_persist::model::ChannelEntry,
99    ) -> Result<(), Error> {
100        trace!("Updating channel {key}");
101        let key = format!("{CHANNEL_PREFIX}/{key}");
102        let v = self
103            .values
104            .get_mut(&key)
105            .expect("attempting to update non-existent channel");
106        *v = (v.0 + 1, serde_json::to_value(channel_entry).unwrap());
107        Ok(())
108    }
109
110    fn get_channel(
111        &self,
112        key: &str,
113    ) -> Result<lightning_signer::persist::model::ChannelEntry, Error> {
114        let key = format!("{CHANNEL_PREFIX}/{key}");
115        let value = self.values.get(&key).unwrap();
116        let entry: vls_persist::model::ChannelEntry =
117            serde_json::from_value(value.1.clone()).unwrap();
118        Ok(entry.into())
119    }
120
121    fn get_node_channels(
122        &self,
123        node_id: &PublicKey,
124    ) -> Result<
125        Vec<(
126            lightning_signer::channel::ChannelId,
127            lightning_signer::persist::model::ChannelEntry,
128        )>,
129        Error,
130    > {
131        let prefix = hex::encode(node_id.serialize());
132        let prefix = format!("{CHANNEL_PREFIX}/{prefix}");
133        Ok(self
134            .values
135            .iter()
136            .filter(|(k, _)| k.starts_with(&prefix))
137            .map(|(k, v)| {
138                let key = k.split('/').last().unwrap();
139                let key = vls_persist::model::NodeChannelId(hex::decode(&key).unwrap());
140
141                let value: vls_persist::model::ChannelEntry =
142                    serde_json::from_value(v.1.clone()).unwrap();
143                (key.channel_id(), value.into())
144            })
145            .collect())
146    }
147
148    fn new_chain_tracker(
149        &mut self,
150        node_id: &PublicKey,
151        tracker: &ChainTracker<lightning_signer::monitor::ChainMonitor>,
152    ) -> Result<(), Error> {
153        let key = hex::encode(node_id.serialize());
154        let key = format!("{TRACKER_PREFIX}/{key}");
155        assert!(!self.values.contains_key(&key));
156
157        let tracker: vls_persist::model::ChainTrackerEntry = tracker.into();
158
159        self.values
160            .insert(key, (0u64, serde_json::to_value(tracker).unwrap()));
161        Ok(())
162    }
163
164    pub fn clear(&mut self) -> Result<(), Error> {
165        self.values.clear();
166        Ok(())
167    }
168}
169
170#[derive(Debug)]
171pub struct StateChange {
172    key: String,
173    old: Option<(u64, serde_json::Value)>,
174    new: (u64, serde_json::Value),
175}
176
177use core::fmt::Display;
178
179impl Display for StateChange {
180    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
181        match &self.old {
182            Some(o) => f.write_str(&format!(
183                "StateChange[{}]: old_version={}, new_version={}, old_value={}, new_value={}",
184                self.key,
185                o.0,
186                self.new.0,
187                serde_json::to_string(&o.1).unwrap(),
188                serde_json::to_string(&self.new.1).unwrap()
189            )),
190            None => f.write_str(&format!(
191                "StateChange[{}]: old_version=null, new_version={}, old_value=null, new_value={}",
192                self.key,
193                self.new.0,
194                serde_json::to_string(&self.new.1).unwrap()
195            )),
196        }
197    }
198}
199
200impl State {
201    pub fn new() -> Self {
202        State {
203            values: BTreeMap::new(),
204        }
205    }
206
207    /// Take another `State` and attempt to update ourselves with any
208    /// entry that is newer than ours. This may fail if the other
209    /// state includes states that are older than our own.
210    pub fn merge(&mut self, other: &State) -> anyhow::Result<Vec<(String, Option<u64>, u64)>> {
211        let mut res = Vec::new();
212        for (key, (newver, newval)) in other.values.iter() {
213            let local = self.values.get_mut(key);
214
215            match local {
216                None => {
217                    trace!("Insert new key {}: version={}", key, newver);
218                    res.push((key.to_owned(), None, *newver));
219                    self.values.insert(key.clone(), (*newver, newval.clone()));
220                }
221                Some(v) => {
222                    if v.0 == *newver {
223                        continue;
224                    } else if v.0 > *newver {
225                        warn!("Ignoring outdated state version newver={}, we have oldver={}: newval={:?} vs oldval={:?}", newver, v.0, serde_json::to_string(newval), serde_json::to_string(&v.1));
226                        continue;
227                    } else {
228                        trace!(
229                            "Updating key {}: version={} => version={}",
230                            key,
231                            v.0,
232                            *newver
233                        );
234                        res.push((key.to_owned(), Some(v.0), *newver));
235                        *v = (*newver, newval.clone());
236                    }
237                }
238            }
239        }
240        Ok(res)
241    }
242
243    pub fn diff(&self, other: &State) -> anyhow::Result<Vec<StateChange>> {
244        Ok(other
245            .values
246            .iter()
247            .map(|(key, (ver, val))| (key, self.values.get(key), (ver, val)))
248            .map(|(key, old, new)| StateChange {
249                key: key.clone(),
250                old: old.map(|o| o.clone()),
251                new: (*new.0, new.1.clone()),
252            })
253            .filter(|c| match (&c.old, &c.new) {
254                (None, _) => true,
255                (Some((oldver, _)), (newver, _)) => oldver < newver,
256            })
257            .collect())
258    }
259}
260
261impl Into<Vec<crate::pb::SignerStateEntry>> for State {
262    fn into(self) -> Vec<crate::pb::SignerStateEntry> {
263        self.values
264            .iter()
265            .map(|(k, v)| crate::pb::SignerStateEntry {
266                key: k.to_owned(),
267                value: serde_json::to_vec(&v.1).unwrap(),
268                version: v.0,
269            })
270            .collect()
271    }
272}
273
274impl From<Vec<crate::pb::SignerStateEntry>> for State {
275    fn from(v: Vec<crate::pb::SignerStateEntry>) -> State {
276        use std::iter::FromIterator;
277        let values = BTreeMap::from_iter(v.iter().map(|v| {
278            (
279                v.key.to_owned(),
280                (v.version, serde_json::from_slice(&v.value).unwrap()),
281            )
282        }));
283
284        State { values }
285    }
286}
287
288pub(crate) struct MemoryPersister {
289    state: Arc<Mutex<State>>,
290}
291
292impl MemoryPersister {
293    pub fn new() -> Self {
294        let state = Arc::new(Mutex::new(State {
295            values: BTreeMap::new(),
296        }));
297        MemoryPersister { state }
298    }
299
300    pub fn state(&self) -> Arc<Mutex<State>> {
301        self.state.clone()
302    }
303}
304
305impl SendSync for MemoryPersister {}
306
307impl Persist for MemoryPersister {
308    fn new_node(
309        &self,
310        node_id: &lightning_signer::bitcoin::secp256k1::PublicKey,
311        config: &NodeConfig,
312        state: &NodeState,
313    ) -> Result<(), Error> {
314        let key = hex::encode(node_id.serialize());
315        self.state.lock().unwrap().insert_node(
316            &key,
317            vls_persist::model::NodeEntry {
318                key_derivation_style: config.key_derivation_style as u8,
319                network: config.network.to_string(),
320            },
321            state.into(),
322        )
323    }
324
325    fn delete_channel(&self, node_id: &PublicKey, channel: &ChannelId) -> Result<(), Error> {
326        let node_channel_id = vls_persist::model::NodeChannelId::new(node_id, &channel);
327        let id = hex::encode(node_channel_id.0);
328        self.state.lock().unwrap().delete_channel(&id);
329        Ok(())
330    }
331
332    fn update_node(
333        &self,
334        node_id: &lightning_signer::bitcoin::secp256k1::PublicKey,
335        state: &NodeState,
336    ) -> Result<(), Error> {
337        let key = hex::encode(node_id.serialize());
338        self.state.lock().unwrap().update_node(&key, state.into())
339    }
340
341    fn delete_node(
342        &self,
343        node_id: &lightning_signer::bitcoin::secp256k1::PublicKey,
344    ) -> Result<(), Error> {
345        let key = hex::encode(node_id.serialize());
346        self.state.lock().unwrap().delete_node(&key)
347    }
348
349    fn new_channel(
350        &self,
351        node_id: &lightning_signer::bitcoin::secp256k1::PublicKey,
352        stub: &ChannelStub,
353    ) -> Result<(), Error> {
354        let id = vls_persist::model::NodeChannelId::new(node_id, &stub.id0);
355        let channel_value_satoshis = 0;
356        let enforcement_state = lightning_signer::policy::validator::EnforcementState::new(0);
357        let entry = vls_persist::model::ChannelEntry {
358            channel_value_satoshis,
359            channel_setup: None,
360            id: None,
361            enforcement_state,
362            // birth blockheight for stub, None for channel
363            blockheight: Some(stub.blockheight),
364        };
365        let id = hex::encode(id.0);
366
367        self.state.lock().unwrap().insert_channel(&id, entry)
368    }
369
370    fn update_channel(
371        &self,
372        node_id: &lightning_signer::bitcoin::secp256k1::PublicKey,
373        channel: &lightning_signer::channel::Channel,
374    ) -> Result<(), Error> {
375        let node_channel_id = vls_persist::model::NodeChannelId::new(node_id, &channel.id0);
376        let id = hex::encode(node_channel_id.0);
377        let channel_value_satoshis = channel.setup.channel_value_sat;
378        let entry = vls_persist::model::ChannelEntry {
379            channel_value_satoshis,
380            channel_setup: Some(channel.setup.clone()),
381            id: channel.id.clone(),
382            enforcement_state: channel.enforcement_state.clone(),
383            blockheight: None,
384        };
385        self.state.lock().unwrap().update_channel(&id, entry)
386    }
387
388    fn get_channel(
389        &self,
390        node_id: &PublicKey,
391        channel_id: &ChannelId,
392    ) -> Result<lightning_signer::persist::model::ChannelEntry, Error> {
393        let id = vls_persist::model::NodeChannelId::new(node_id, channel_id);
394        let id = hex::encode(id.0);
395        self.state.lock().unwrap().get_channel(&id)
396    }
397
398    fn new_tracker(
399        &self,
400        node_id: &PublicKey,
401        tracker: &ChainTracker<lightning_signer::monitor::ChainMonitor>,
402    ) -> Result<(), Error> {
403        self.state
404            .lock()
405            .unwrap()
406            .new_chain_tracker(node_id, tracker)
407    }
408
409    fn update_tracker(
410        &self,
411        node_id: &PublicKey,
412        tracker: &ChainTracker<lightning_signer::monitor::ChainMonitor>,
413    ) -> Result<(), Error> {
414        let key = hex::encode(node_id.serialize());
415        let key = format!("{TRACKER_PREFIX}/{key}");
416
417        let mut state = self.state.lock().unwrap();
418        let v = state.values.get_mut(&key).unwrap();
419        let tracker: vls_persist::model::ChainTrackerEntry = tracker.into();
420        *v = (v.0 + 1, serde_json::to_value(tracker).unwrap());
421        Ok(())
422    }
423
424    fn get_tracker(
425        &self,
426        node_id: PublicKey,
427        validator_factory: Arc<dyn ValidatorFactory>,
428    ) -> Result<
429        (
430            ChainTracker<lightning_signer::monitor::ChainMonitor>,
431            Vec<ChainTrackerListenerEntry>,
432        ),
433        Error,
434    > {
435        let key = hex::encode(node_id.serialize());
436        let key = format!("{TRACKER_PREFIX}/{key}");
437
438        let state = self.state.lock().unwrap();
439        let v: vls_persist::model::ChainTrackerEntry =
440            serde_json::from_value(state.values.get(&key).unwrap().1.clone()).unwrap();
441
442        Ok(v.into_tracker(node_id, validator_factory))
443    }
444
445    fn get_node_channels(
446        &self,
447        node_id: &PublicKey,
448    ) -> Result<Vec<(ChannelId, lightning_signer::persist::model::ChannelEntry)>, Error> {
449        self.state.lock().unwrap().get_node_channels(node_id)
450    }
451
452    fn update_node_allowlist(
453        &self,
454        node_id: &PublicKey,
455        allowlist: Vec<std::string::String>,
456    ) -> Result<(), Error> {
457        let key = hex::encode(node_id.serialize());
458        let key = format!("{ALLOWLIST_PREFIX}/{key}");
459
460        let mut state = self.state.lock().unwrap();
461        match state.values.get_mut(&key) {
462            Some(v) => {
463                *v = (v.0 + 1, serde_json::to_value(allowlist).unwrap());
464            }
465            None => {
466                state
467                    .values
468                    .insert(key, (0u64, serde_json::to_value(allowlist).unwrap()));
469            }
470        }
471        Ok(())
472    }
473
474    fn get_node_allowlist(&self, node_id: &PublicKey) -> Result<Vec<std::string::String>, Error> {
475        let state = self.state.lock().unwrap();
476        let key = hex::encode(node_id.serialize());
477        let key = format!("{ALLOWLIST_PREFIX}/{key}");
478        let allowlist: Vec<String> =
479            serde_json::from_value(state.values.get(&key).unwrap().1.clone()).unwrap();
480
481        Ok(allowlist)
482    }
483
484    fn get_nodes(
485        &self,
486    ) -> Result<Vec<(PublicKey, lightning_signer::persist::model::NodeEntry)>, Error> {
487        use lightning_signer::node::NodeState as CoreNodeState;
488
489        let state = self.state.lock().unwrap();
490        let node_ids: Vec<&str> = state
491            .values
492            .keys()
493            .map(|k| k.split('/'))
494            .filter(|k| k.clone().next().unwrap() == NODE_PREFIX)
495            .map(|k| k.clone().last().unwrap())
496            .collect();
497
498        let mut res = Vec::new();
499        for node_id in node_ids.iter() {
500            let node_key = format!("{NODE_PREFIX}/{node_id}");
501            let state_key = format!("{NODE_STATE_PREFIX}/{node_id}");
502
503            let node: vls_persist::model::NodeEntry =
504                serde_json::from_value(state.values.get(&node_key).unwrap().1.clone()).unwrap();
505            let state_e: vls_persist::model::NodeStateEntry =
506                serde_json::from_value(state.values.get(&state_key).unwrap().1.clone()).unwrap();
507
508            let state = CoreNodeState::restore(
509                state_e.invoices,
510                state_e.issued_invoices,
511                state_e.preimages,
512                0,
513                state_e.velocity_control.into(),
514                state_e.fee_velocity_control.into(),
515                0u64,
516                /* dbid_high_water_mark: prevents reuse of
517                 * channel dbid, 0 disables enforcement. */
518            );
519
520            let entry = lightning_signer::persist::model::NodeEntry {
521                key_derivation_style: node.key_derivation_style,
522                network: node.network,
523                state,
524            };
525
526            let key: Vec<u8> = hex::decode(node_id).unwrap();
527            res.push((PublicKey::from_slice(key.as_slice()).unwrap(), entry));
528        }
529
530        let nodes = res;
531        Ok(nodes)
532    }
533    fn clear_database(&self) -> Result<(), Error> {
534        self.state.lock().unwrap().clear()
535    }
536
537    fn signer_id(&self) -> SignerId {
538        // The signers are clones of each other in Greenlight, and as
539        // such we should not need to differentiate them. We therefore
540        // just return a static dummy ID.
541        [0u8; 16]
542    }
543}