Skip to content

Commit

Permalink
Merge pull request #59 from getAlby/transient-graph
Browse files Browse the repository at this point in the history
Implement transient network graph option
  • Loading branch information
rolznz authored Dec 23, 2024
2 parents fac838a + 399b02b commit 1027958
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
1 change: 1 addition & 0 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dictionary Config {
LogLevel log_level;
AnchorChannelsConfig? anchor_channels_config;
SendingParameters? sending_parameters;
boolean transient_network_graph;
};

dictionary AnchorChannelsConfig {
Expand Down
12 changes: 9 additions & 3 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::connection::ConnectionManager;
use crate::event::EventQueue;
use crate::fee_estimator::OnchainFeeEstimator;
use crate::gossip::GossipSource;
use crate::io::sqlite_store::SqliteStore;
use crate::io::sqlite_store::{SqliteStore, SqliteStoreConfig};
use crate::io::utils::{read_node_metrics, write_node_metrics};
use crate::io::vss_store::VssStore;
use crate::io::{
Expand Down Expand Up @@ -383,11 +383,14 @@ impl NodeBuilder {
let storage_dir_path = self.config.storage_dir_path.clone();
fs::create_dir_all(storage_dir_path.clone())
.map_err(|_| BuildError::StoragePathAccessFailed)?;
let sql_store_config =
SqliteStoreConfig { transient_graph: self.config.transient_network_graph };
let kv_store = Arc::new(
SqliteStore::new(
SqliteStore::with_config(
storage_dir_path.into(),
Some(io::sqlite_store::SQLITE_DB_FILE_NAME.to_string()),
Some(io::sqlite_store::KV_TABLE_NAME.to_string()),
sql_store_config,
)
.map_err(|_| BuildError::KVStoreSetupFailed)?,
);
Expand Down Expand Up @@ -554,11 +557,14 @@ impl NodeBuilder {

// Alby: use a secondary KV store for non-essential data (not needed by VSS)
let storage_dir_path = config.storage_dir_path.clone();
let sql_store_config =
SqliteStoreConfig { transient_graph: self.config.transient_network_graph };
let secondary_kv_store = Arc::new(
SqliteStore::new(
SqliteStore::with_config(
storage_dir_path.into(),
Some(io::sqlite_store::SQLITE_DB_FILE_NAME.to_string()),
Some(io::sqlite_store::KV_TABLE_NAME.to_string()),
sql_store_config,
)
.map_err(|_| BuildError::KVStoreSetupFailed)?,
) as Arc<DynStore>;
Expand Down
6 changes: 6 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ pub struct Config {
/// **Note:** If unset, default parameters will be used, and you will be able to override the
/// parameters on a per-payment basis in the corresponding method calls.
pub sending_parameters: Option<SendingParameters>,
/// Alby: Transient network graph.
///
/// If set to `true`, the graph is not persisted in the database and is only kept in memory.
/// It will be rebuilt on each restart.
pub transient_network_graph: bool,
}

impl Default for Config {
Expand All @@ -181,6 +186,7 @@ impl Default for Config {
anchor_channels_config: Some(AnchorChannelsConfig::default()),
sending_parameters: None,
node_alias: None,
transient_network_graph: false,
}
}
}
Expand Down
59 changes: 57 additions & 2 deletions src/io/sqlite_store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
use crate::io::utils::check_namespace_key_validity;

use lightning::io;
use lightning::util::persist::KVStore;
use lightning::util::persist::{
KVStore, NETWORK_GRAPH_PERSISTENCE_KEY, NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE,
NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE,
};
use lightning::util::string::PrintableString;

use rusqlite::{named_params, Connection};
Expand Down Expand Up @@ -41,6 +44,19 @@ pub struct SqliteStore {
connection: Arc<Mutex<Connection>>,
data_dir: PathBuf,
kv_table_name: String,
config: SqliteStoreConfig,
}

/// Alby: extended SqliteStore configuration.
pub struct SqliteStoreConfig {
/// Do not persist network graph.
pub(crate) transient_graph: bool,
}

impl Default for SqliteStoreConfig {
fn default() -> Self {
Self { transient_graph: false }
}
}

impl SqliteStore {
Expand Down Expand Up @@ -120,7 +136,28 @@ impl SqliteStore {
})?;

let connection = Arc::new(Mutex::new(connection));
Ok(Self { connection, data_dir, kv_table_name })
Ok(Self { connection, data_dir, kv_table_name, config: SqliteStoreConfig::default() })
}

/// Alby: constructs a new [`SqliteStore`] with an extended configuration.
pub fn with_config(
data_dir: PathBuf, db_file_name: Option<String>, kv_table_name: Option<String>,
config: SqliteStoreConfig,
) -> io::Result<Self> {
let mut ret = SqliteStore::new(data_dir, db_file_name, kv_table_name)?;

if config.transient_graph {
// Drop existing network graph if it has been persisted before.
ret.remove(
NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE,
NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE,
NETWORK_GRAPH_PERSISTENCE_KEY,
false,
)?;
}

ret.config = config;
Ok(ret)
}

/// Returns the data directory.
Expand All @@ -135,6 +172,15 @@ impl KVStore for SqliteStore {
) -> io::Result<Vec<u8>> {
check_namespace_key_validity(primary_namespace, secondary_namespace, Some(key), "read")?;

if self.config.transient_graph
&& primary_namespace == NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE
&& secondary_namespace == NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE
&& key == NETWORK_GRAPH_PERSISTENCE_KEY
{
// Alby: returning "not found" here will cause the network graph to be rebuilt from scratch.
return Err(io::Error::new(io::ErrorKind::NotFound, "network graph is not persisted"));
}

let locked_conn = self.connection.lock().unwrap();
let sql =
format!("SELECT value FROM {} WHERE primary_namespace=:primary_namespace AND secondary_namespace=:secondary_namespace AND key=:key;",
Expand Down Expand Up @@ -183,6 +229,15 @@ impl KVStore for SqliteStore {
) -> io::Result<()> {
check_namespace_key_validity(primary_namespace, secondary_namespace, Some(key), "write")?;

if self.config.transient_graph
&& primary_namespace == NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE
&& secondary_namespace == NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE
&& key == NETWORK_GRAPH_PERSISTENCE_KEY
{
// Alby: transient network graph is not persisted.
return Ok(());
}

let locked_conn = self.connection.lock().unwrap();

let sql = format!(
Expand Down

0 comments on commit 1027958

Please sign in to comment.