Skip to content

Commit 1df6791

Browse files
committed
WIP Make NodeSecret mandatory
1 parent 1cad73d commit 1df6791

File tree

3 files changed

+79
-159
lines changed

3 files changed

+79
-159
lines changed

src/builder.rs

Lines changed: 31 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use std::{fmt, fs};
1515

1616
use bdk_wallet::template::Bip84;
1717
use bdk_wallet::{KeychainKind, Wallet as BdkWallet};
18-
use bip39::Mnemonic;
1918
use bitcoin::bip32::{ChildNumber, Xpriv};
2019
use bitcoin::secp256k1::PublicKey;
2120
use bitcoin::{BlockHash, Network};
@@ -45,9 +44,10 @@ use crate::chain::ChainSource;
4544
use crate::config::{
4645
default_user_config, may_announce_channel, AnnounceError, AsyncPaymentsRole,
4746
BitcoindRestClientConfig, Config, ElectrumSyncConfig, EsploraSyncConfig,
48-
DEFAULT_ESPLORA_SERVER_URL, DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL, WALLET_KEYS_SEED_LEN,
47+
DEFAULT_ESPLORA_SERVER_URL, DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL,
4948
};
5049
use crate::connection::ConnectionManager;
50+
use crate::entropy::NodeSecret;
5151
use crate::event::EventQueue;
5252
use crate::fee_estimator::OnchainFeeEstimator;
5353
use crate::gossip::GossipSource;
@@ -101,13 +101,6 @@ enum ChainDataSourceConfig {
101101
},
102102
}
103103

104-
#[derive(Debug, Clone)]
105-
enum EntropySourceConfig {
106-
SeedFile(String),
107-
SeedBytes([u8; WALLET_KEYS_SEED_LEN]),
108-
Bip39Mnemonic { mnemonic: Mnemonic, passphrase: Option<String> },
109-
}
110-
111104
#[derive(Debug, Clone)]
112105
enum GossipSourceConfig {
113106
P2PNetwork,
@@ -245,7 +238,6 @@ impl std::error::Error for BuildError {}
245238
#[derive(Debug)]
246239
pub struct NodeBuilder {
247240
config: Config,
248-
entropy_source_config: Option<EntropySourceConfig>,
249241
chain_data_source_config: Option<ChainDataSourceConfig>,
250242
gossip_source_config: Option<GossipSourceConfig>,
251243
liquidity_source_config: Option<LiquiditySourceConfig>,
@@ -264,7 +256,6 @@ impl NodeBuilder {
264256

265257
/// Creates a new builder instance from an [`Config`].
266258
pub fn from_config(config: Config) -> Self {
267-
let entropy_source_config = None;
268259
let chain_data_source_config = None;
269260
let gossip_source_config = None;
270261
let liquidity_source_config = None;
@@ -273,7 +264,6 @@ impl NodeBuilder {
273264
let pathfinding_scores_sync_config = None;
274265
Self {
275266
config,
276-
entropy_source_config,
277267
chain_data_source_config,
278268
gossip_source_config,
279269
liquidity_source_config,
@@ -294,33 +284,6 @@ impl NodeBuilder {
294284
self
295285
}
296286

297-
/// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
298-
///
299-
/// If the given file does not exist a new random seed file will be generated and
300-
/// stored at the given location.
301-
pub fn set_entropy_seed_path(&mut self, seed_path: String) -> &mut Self {
302-
self.entropy_source_config = Some(EntropySourceConfig::SeedFile(seed_path));
303-
self
304-
}
305-
306-
/// Configures the [`Node`] instance to source its wallet entropy from the given
307-
/// [`WALLET_KEYS_SEED_LEN`] seed bytes.
308-
pub fn set_entropy_seed_bytes(&mut self, seed_bytes: [u8; WALLET_KEYS_SEED_LEN]) -> &mut Self {
309-
self.entropy_source_config = Some(EntropySourceConfig::SeedBytes(seed_bytes));
310-
self
311-
}
312-
313-
/// Configures the [`Node`] instance to source its wallet entropy from a [BIP 39] mnemonic.
314-
///
315-
/// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
316-
pub fn set_entropy_bip39_mnemonic(
317-
&mut self, mnemonic: Mnemonic, passphrase: Option<String>,
318-
) -> &mut Self {
319-
self.entropy_source_config =
320-
Some(EntropySourceConfig::Bip39Mnemonic { mnemonic, passphrase });
321-
self
322-
}
323-
324287
/// Configures the [`Node`] instance to source its chain data from the given Esplora server.
325288
///
326289
/// If no `sync_config` is given, default values are used. See [`EsploraSyncConfig`] for more
@@ -584,7 +547,7 @@ impl NodeBuilder {
584547

585548
/// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
586549
/// previously configured.
587-
pub fn build(&self) -> Result<Node, BuildError> {
550+
pub fn build(&self, node_secret: NodeSecret) -> Result<Node, BuildError> {
588551
let storage_dir_path = self.config.storage_dir_path.clone();
589552
fs::create_dir_all(storage_dir_path.clone())
590553
.map_err(|_| BuildError::StoragePathAccessFailed)?;
@@ -596,19 +559,19 @@ impl NodeBuilder {
596559
)
597560
.map_err(|_| BuildError::KVStoreSetupFailed)?,
598561
);
599-
self.build_with_store(kv_store)
562+
self.build_with_store(node_secret, kv_store)
600563
}
601564

602565
/// Builds a [`Node`] instance with a [`FilesystemStore`] backend and according to the options
603566
/// previously configured.
604-
pub fn build_with_fs_store(&self) -> Result<Node, BuildError> {
567+
pub fn build_with_fs_store(&self, node_secret: NodeSecret) -> Result<Node, BuildError> {
605568
let mut storage_dir_path: PathBuf = self.config.storage_dir_path.clone().into();
606569
storage_dir_path.push("fs_store");
607570

608571
fs::create_dir_all(storage_dir_path.clone())
609572
.map_err(|_| BuildError::StoragePathAccessFailed)?;
610573
let kv_store = Arc::new(FilesystemStore::new(storage_dir_path));
611-
self.build_with_store(kv_store)
574+
self.build_with_store(node_secret, kv_store)
612575
}
613576

614577
/// Builds a [`Node`] instance with a [VSS] backend and according to the options
@@ -629,19 +592,14 @@ impl NodeBuilder {
629592
/// [VSS]: https://github.com/lightningdevkit/vss-server/blob/main/README.md
630593
/// [LNURL-auth]: https://github.com/lnurl/luds/blob/luds/04.md
631594
pub fn build_with_vss_store(
632-
&self, vss_url: String, store_id: String, lnurl_auth_server_url: String,
633-
fixed_headers: HashMap<String, String>,
595+
&self, node_secret: NodeSecret, vss_url: String, store_id: String,
596+
lnurl_auth_server_url: String, fixed_headers: HashMap<String, String>,
634597
) -> Result<Node, BuildError> {
635598
use bitcoin::key::Secp256k1;
636599

637600
let logger = setup_logger(&self.log_writer_config, &self.config)?;
638601

639-
let seed_bytes = seed_bytes_from_config(
640-
&self.config,
641-
self.entropy_source_config.as_ref(),
642-
Arc::clone(&logger),
643-
)?;
644-
602+
let seed_bytes = node_secret.to_seed_bytes();
645603
let config = Arc::new(self.config.clone());
646604

647605
let vss_xprv =
@@ -666,7 +624,12 @@ impl NodeBuilder {
666624

667625
let header_provider = Arc::new(lnurl_auth_jwt_provider);
668626

669-
self.build_with_vss_store_and_header_provider(vss_url, store_id, header_provider)
627+
self.build_with_vss_store_and_header_provider(
628+
node_secret,
629+
vss_url,
630+
store_id,
631+
header_provider,
632+
)
670633
}
671634

672635
/// Builds a [`Node`] instance with a [VSS] backend and according to the options
@@ -682,11 +645,17 @@ impl NodeBuilder {
682645
///
683646
/// [VSS]: https://github.com/lightningdevkit/vss-server/blob/main/README.md
684647
pub fn build_with_vss_store_and_fixed_headers(
685-
&self, vss_url: String, store_id: String, fixed_headers: HashMap<String, String>,
648+
&self, node_secret: NodeSecret, vss_url: String, store_id: String,
649+
fixed_headers: HashMap<String, String>,
686650
) -> Result<Node, BuildError> {
687651
let header_provider = Arc::new(FixedHeaders::new(fixed_headers));
688652

689-
self.build_with_vss_store_and_header_provider(vss_url, store_id, header_provider)
653+
self.build_with_vss_store_and_header_provider(
654+
node_secret,
655+
vss_url,
656+
store_id,
657+
header_provider,
658+
)
690659
}
691660

692661
/// Builds a [`Node`] instance with a [VSS] backend and according to the options
@@ -701,16 +670,12 @@ impl NodeBuilder {
701670
///
702671
/// [VSS]: https://github.com/lightningdevkit/vss-server/blob/main/README.md
703672
pub fn build_with_vss_store_and_header_provider(
704-
&self, vss_url: String, store_id: String, header_provider: Arc<dyn VssHeaderProvider>,
673+
&self, node_secret: NodeSecret, vss_url: String, store_id: String,
674+
header_provider: Arc<dyn VssHeaderProvider>,
705675
) -> Result<Node, BuildError> {
706676
let logger = setup_logger(&self.log_writer_config, &self.config)?;
707677

708-
let seed_bytes = seed_bytes_from_config(
709-
&self.config,
710-
self.entropy_source_config.as_ref(),
711-
Arc::clone(&logger),
712-
)?;
713-
678+
let seed_bytes = node_secret.to_seed_bytes();
714679
let config = Arc::new(self.config.clone());
715680

716681
let vss_xprv = derive_xprv(
@@ -728,11 +693,13 @@ impl NodeBuilder {
728693
BuildError::KVStoreSetupFailed
729694
})?;
730695

731-
self.build_with_store(Arc::new(vss_store))
696+
self.build_with_store(node_secret, Arc::new(vss_store))
732697
}
733698

734699
/// Builds a [`Node`] instance according to the options previously configured.
735-
pub fn build_with_store(&self, kv_store: Arc<DynStore>) -> Result<Node, BuildError> {
700+
pub fn build_with_store(
701+
&self, node_secret: NodeSecret, kv_store: Arc<DynStore>,
702+
) -> Result<Node, BuildError> {
736703
let logger = setup_logger(&self.log_writer_config, &self.config)?;
737704

738705
let runtime = if let Some(handle) = self.runtime_handle.as_ref() {
@@ -744,11 +711,7 @@ impl NodeBuilder {
744711
})?)
745712
};
746713

747-
let seed_bytes = seed_bytes_from_config(
748-
&self.config,
749-
self.entropy_source_config.as_ref(),
750-
Arc::clone(&logger),
751-
)?;
714+
let seed_bytes = node_secret.to_seed_bytes();
752715
let config = Arc::new(self.config.clone());
753716

754717
build_with_store_internal(
@@ -793,37 +756,6 @@ impl ArcedNodeBuilder {
793756
Self { inner }
794757
}
795758

796-
/// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
797-
///
798-
/// If the given file does not exist a new random seed file will be generated and
799-
/// stored at the given location.
800-
pub fn set_entropy_seed_path(&self, seed_path: String) {
801-
self.inner.write().unwrap().set_entropy_seed_path(seed_path);
802-
}
803-
804-
/// Configures the [`Node`] instance to source its wallet entropy from the given
805-
/// [`WALLET_KEYS_SEED_LEN`] seed bytes.
806-
///
807-
/// **Note:** Will return an error if the length of the given `seed_bytes` differs from
808-
/// [`WALLET_KEYS_SEED_LEN`].
809-
pub fn set_entropy_seed_bytes(&self, seed_bytes: Vec<u8>) -> Result<(), BuildError> {
810-
if seed_bytes.len() != WALLET_KEYS_SEED_LEN {
811-
return Err(BuildError::InvalidSeedBytes);
812-
}
813-
let mut bytes = [0u8; WALLET_KEYS_SEED_LEN];
814-
bytes.copy_from_slice(&seed_bytes);
815-
816-
self.inner.write().unwrap().set_entropy_seed_bytes(bytes);
817-
Ok(())
818-
}
819-
820-
/// Configures the [`Node`] instance to source its wallet entropy from a [BIP 39] mnemonic.
821-
///
822-
/// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
823-
pub fn set_entropy_bip39_mnemonic(&self, mnemonic: Mnemonic, passphrase: Option<String>) {
824-
self.inner.write().unwrap().set_entropy_bip39_mnemonic(mnemonic, passphrase);
825-
}
826-
827759
/// Configures the [`Node`] instance to source its chain data from the given Esplora server.
828760
///
829761
/// If no `sync_config` is given, default values are used. See [`EsploraSyncConfig`] for more
@@ -1834,28 +1766,6 @@ fn setup_logger(
18341766
Ok(Arc::new(logger))
18351767
}
18361768

1837-
fn seed_bytes_from_config(
1838-
config: &Config, entropy_source_config: Option<&EntropySourceConfig>, logger: Arc<Logger>,
1839-
) -> Result<[u8; 64], BuildError> {
1840-
match entropy_source_config {
1841-
Some(EntropySourceConfig::SeedBytes(bytes)) => Ok(bytes.clone()),
1842-
Some(EntropySourceConfig::SeedFile(seed_path)) => {
1843-
Ok(io::utils::read_or_generate_seed_file(seed_path, Arc::clone(&logger))
1844-
.map_err(|_| BuildError::InvalidSeedFile)?)
1845-
},
1846-
Some(EntropySourceConfig::Bip39Mnemonic { mnemonic, passphrase }) => match passphrase {
1847-
Some(passphrase) => Ok(mnemonic.to_seed(passphrase)),
1848-
None => Ok(mnemonic.to_seed("")),
1849-
},
1850-
None => {
1851-
// Default to read or generate from the default location generate a seed file.
1852-
let seed_path = format!("{}/keys_seed", config.storage_dir_path);
1853-
Ok(io::utils::read_or_generate_seed_file(&seed_path, Arc::clone(&logger))
1854-
.map_err(|_| BuildError::InvalidSeedFile)?)
1855-
},
1856-
}
1857-
}
1858-
18591769
fn derive_xprv(
18601770
config: Arc<Config>, seed_bytes: &[u8; 64], hardened_child_index: u32, logger: Arc<Logger>,
18611771
) -> Result<Xpriv, BuildError> {

src/entropy.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,45 @@
99
1010
use bip39::Mnemonic;
1111

12+
use crate::config::WALLET_KEYS_SEED_LEN;
13+
use crate::io;
14+
15+
/// TODO
16+
pub struct IOError();
17+
18+
/// TODO
19+
pub struct NodeSecret([u8; WALLET_KEYS_SEED_LEN]);
20+
21+
impl NodeSecret {
22+
/// Configures the [`Node`] instance to source its wallet entropy from a [BIP 39] mnemonic.
23+
///
24+
/// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
25+
pub fn from_bip39_mnemonic(mnemonic: Mnemonic, passphrase: Option<String>) -> Self {
26+
match passphrase {
27+
Some(passphrase) => Self(mnemonic.to_seed(passphrase)),
28+
None => Self(mnemonic.to_seed("")),
29+
}
30+
}
31+
32+
/// Configures the [`Node`] instance to source its wallet entropy from the given
33+
/// [`WALLET_KEYS_SEED_LEN`] seed bytes.
34+
pub fn from_seed_bytes(seed_bytes: [u8; WALLET_KEYS_SEED_LEN]) -> Self {
35+
Self(seed_bytes)
36+
}
37+
38+
/// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
39+
///
40+
/// If the given file does not exist a new random seed file will be generated and
41+
/// stored at the given location.
42+
pub fn from_seed_path(seed_path: String) -> Result<Self, IOError> {
43+
Ok(Self(io::utils::read_or_generate_seed_file(&seed_path).map_err(|_| IOError())?))
44+
}
45+
46+
pub(crate) fn to_seed_bytes(&self) -> [u8; WALLET_KEYS_SEED_LEN] {
47+
self.0
48+
}
49+
}
50+
1251
/// Generates a random [BIP 39] mnemonic with the specified word count.
1352
///
1453
/// If no word count is specified, defaults to 24 words (256-bit entropy).

0 commit comments

Comments
 (0)