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 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 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 );
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 [0u8; 16]
542 }
543}