breez_sdk_core/greenlight/
backup_transport.rs

1use crate::{
2    backup::{BackupState, BackupTransport},
3    error::{SdkError, SdkResult},
4};
5
6use super::node_api::Greenlight;
7use gl_client::pb::cln;
8use sdk_common::with_connection_retry;
9use std::sync::Arc;
10
11const BREEZ_SDK_DATASTORE_PATH: [&str; 2] = ["breez-sdk", "backup"];
12
13pub(crate) struct GLBackupTransport {
14    pub(crate) inner: Arc<Greenlight>,
15}
16
17impl GLBackupTransport {
18    fn gl_key(&self) -> Vec<String> {
19        BREEZ_SDK_DATASTORE_PATH.map(|s| s.into()).to_vec()
20    }
21}
22
23#[tonic::async_trait]
24impl BackupTransport for GLBackupTransport {
25    async fn pull(&self) -> SdkResult<Option<BackupState>> {
26        let key = self.gl_key();
27        let mut client = self.inner.get_node_client().await?;
28
29        let req = cln::ListdatastoreRequest { key };
30        let response: cln::ListdatastoreResponse =
31            with_connection_retry!(client.list_datastore(req.clone()))
32                .await?
33                .into_inner();
34        let store = response.datastore;
35        match store.len() {
36            0 => Ok(None),
37            1 => Ok(Some(BackupState {
38                generation: store[0].generation.unwrap(),
39                data: store[0].clone().hex.unwrap(),
40            })),
41            _ => Err(SdkError::Generic {
42                err: "Get returned multiple values".into(),
43            }),
44        }
45    }
46
47    async fn push(&self, version: Option<u64>, hex: Vec<u8>) -> SdkResult<u64> {
48        let key = self.gl_key();
49        info!("set_value key = {:?} data length={:?}", key, hex.len());
50        let mut client = self.inner.get_node_client().await?;
51
52        let mut mode = cln::datastore_request::DatastoreMode::MustCreate;
53        if version.is_some() {
54            mode = cln::datastore_request::DatastoreMode::MustReplace;
55        }
56        let req = cln::DatastoreRequest {
57            key,
58            string: None,
59            hex: Some(hex),
60            generation: version,
61            mode: Some(mode.into()),
62        };
63        let response = with_connection_retry!(client.datastore(req.clone()))
64            .await?
65            .into_inner();
66        Ok(response.generation.unwrap())
67    }
68}