diff --git a/README.md b/README.md index 1877168a0..4e7ba42ab 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,10 @@ LDK Node is a self-custodial Lightning node in library form. Its central goal is The primary abstraction of the library is the [`Node`][api_docs_node], which can be retrieved by setting up and configuring a [`Builder`][api_docs_builder] to your liking and calling one of the `build` methods. `Node` can then be controlled via commands such as `start`, `stop`, `connect_open_channel`, `send_payment`, etc. ```rust -use ldk_node::Builder; +use ldk_node::{Builder, Network}; use ldk_node::lightning_invoice::Invoice; use ldk_node::lightning::ln::msgs::SocketAddress; use ldk_node::bitcoin::secp256k1::PublicKey; -use ldk_node::bitcoin::Network; use std::str::FromStr; fn main() { diff --git a/src/builder.rs b/src/builder.rs index fca8d7b87..b60123844 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -9,8 +9,8 @@ use crate::peer_store::PeerStore; use crate::sweep::OutputSweeper; use crate::tx_broadcaster::TransactionBroadcaster; use crate::types::{ - ChainMonitor, ChannelManager, FakeMessageRouter, GossipSync, KeysManager, NetworkGraph, - OnionMessenger, PeerManager, + ChainMonitor, ChannelManager, FakeMessageRouter, GossipSync, KeysManager, Network, + NetworkGraph, OnionMessenger, PeerManager, }; use crate::wallet::Wallet; use crate::LogLevel; @@ -47,8 +47,6 @@ use bdk::blockchain::esplora::EsploraBlockchain; use bdk::database::SqliteDatabase; use bdk::template::Bip84; -use bitcoin::Network; - use bip39::Mnemonic; use bitcoin::BlockHash; @@ -436,8 +434,8 @@ fn build_with_store_internal( logger: Arc, kv_store: Arc, ) -> Result, BuildError> { // Initialize the on-chain wallet and chain access - let xprv = - bitcoin::bip32::ExtendedPrivKey::new_master(config.network, &seed_bytes).map_err(|e| { + let xprv = bitcoin::bip32::ExtendedPrivKey::new_master(config.network.into(), &seed_bytes) + .map_err(|e| { log_error!(logger, "Failed to derive master secret: {}", e); BuildError::InvalidSeedBytes })?; @@ -445,7 +443,7 @@ fn build_with_store_internal( let wallet_name = bdk::wallet::wallet_name_from_descriptor( Bip84(xprv, bdk::KeychainKind::External), Some(Bip84(xprv, bdk::KeychainKind::Internal)), - config.network, + config.network.into(), &Secp256k1::new(), ) .map_err(|e| { @@ -459,7 +457,7 @@ fn build_with_store_internal( let bdk_wallet = bdk::Wallet::new( Bip84(xprv, bdk::KeychainKind::External), Some(Bip84(xprv, bdk::KeychainKind::Internal)), - config.network, + config.network.into(), database, ) .map_err(|e| { @@ -537,7 +535,7 @@ fn build_with_store_internal( Ok(graph) => Arc::new(graph), Err(e) => { if e.kind() == std::io::ErrorKind::NotFound { - Arc::new(NetworkGraph::new(config.network, Arc::clone(&logger))) + Arc::new(NetworkGraph::new(config.network.into(), Arc::clone(&logger))) } else { return Err(BuildError::ReadFailed); } @@ -629,10 +627,10 @@ fn build_with_store_internal( } else { // We're starting a fresh node. let genesis_block_hash = - bitcoin::blockdata::constants::genesis_block(config.network).block_hash(); + bitcoin::blockdata::constants::genesis_block(config.network.into()).block_hash(); let chain_params = ChainParameters { - network: config.network, + network: config.network.into(), best_block: BestBlock::new(genesis_block_hash, 0), }; channelmanager::ChannelManager::new( diff --git a/src/lib.rs b/src/lib.rs index 9c5f609a2..2f09f2fd3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,11 +26,10 @@ //! [`send_payment`], etc.: //! //! ```no_run -//! use ldk_node::Builder; +//! use ldk_node::{Builder, Network}; //! use ldk_node::lightning_invoice::Bolt11Invoice; //! use ldk_node::lightning::ln::msgs::SocketAddress; //! use ldk_node::bitcoin::secp256k1::PublicKey; -//! use ldk_node::bitcoin::Network; //! use std::str::FromStr; //! //! fn main() { @@ -125,7 +124,7 @@ use types::{ Broadcaster, ChainMonitor, ChannelManager, FeeEstimator, KeysManager, NetworkGraph, PeerManager, Router, Scorer, Sweeper, Wallet, }; -pub use types::{ChannelDetails, PeerDetails, UserChannelId}; +pub use types::{ChannelDetails, Network, PeerDetails, UserChannelId}; use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger}; @@ -150,7 +149,6 @@ use lightning_invoice::{payment, Bolt11Invoice, Currency}; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; use bitcoin::secp256k1::PublicKey; -use bitcoin::Network; use bitcoin::{Address, Txid}; @@ -1498,7 +1496,7 @@ impl Node { fn receive_payment_inner( &self, amount_msat: Option, description: &str, expiry_secs: u32, ) -> Result { - let currency = Currency::from(self.config.network); + let currency = Currency::from(bitcoin::Network::from(self.config.network)); let keys_manager = Arc::clone(&self.keys_manager); let invoice = match lightning_invoice::utils::create_invoice_from_channelmanager( &self.channel_manager, @@ -1551,8 +1549,7 @@ impl Node { /// /// For example, you could retrieve all stored outbound payments as follows: /// ``` - /// # use ldk_node::{Builder, Config, PaymentDirection}; - /// # use ldk_node::bitcoin::Network; + /// # use ldk_node::{Builder, Config, Network, PaymentDirection}; /// # let mut config = Config::default(); /// # config.network = Network::Regtest; /// # config.storage_dir_path = "/tmp/ldk_node_test/".to_string(); diff --git a/src/test/functional_tests.rs b/src/test/functional_tests.rs index dbb120b93..3600ee116 100644 --- a/src/test/functional_tests.rs +++ b/src/test/functional_tests.rs @@ -2,7 +2,7 @@ use crate::builder::NodeBuilder; use crate::io::test_utils::TestSyncStore; use crate::test::utils::*; use crate::test::utils::{expect_channel_pending_event, expect_event, open_channel, random_config}; -use crate::{Error, Event, Node, PaymentDirection, PaymentStatus}; +use crate::{Error, Event, Network, Node, PaymentDirection, PaymentStatus}; use bitcoin::Amount; use electrsd::bitcoind::BitcoinD; @@ -409,7 +409,7 @@ fn multi_hop_sending() { #[test] fn connect_to_public_testnet_esplora() { let mut config = random_config(); - config.network = bitcoin::Network::Testnet; + config.network = Network::Testnet; let mut builder = NodeBuilder::from_config(config); builder.set_esplora_server("https://blockstream.info/testnet/api".to_string()); let node = builder.build().unwrap(); diff --git a/src/test/utils.rs b/src/test/utils.rs index f4782312b..ea1ac1bc0 100644 --- a/src/test/utils.rs +++ b/src/test/utils.rs @@ -1,11 +1,11 @@ use crate::builder::NodeBuilder; use crate::io::test_utils::TestSyncStore; -use crate::{Config, Event, Node}; +use crate::{Config, Event, Network, Node}; use lightning::ln::msgs::SocketAddress; use lightning::util::logger::{Level, Logger, Record}; use lightning::util::persist::KVStore; -use bitcoin::{Address, Amount, Network, OutPoint, Txid}; +use bitcoin::{Address, Amount, OutPoint, Txid}; use bitcoind::bitcoincore_rpc::RpcApi; use electrsd::bitcoind::bitcoincore_rpc::bitcoincore_rpc_json::AddressType; @@ -239,7 +239,7 @@ pub fn generate_blocks_and_wait(bitcoind: &BitcoinD, electrsd: &ElectrsD, num: u .client .get_new_address(Some("test"), Some(AddressType::Legacy)) .expect("failed to get new address") - .require_network(Network::Regtest) + .require_network(bitcoin::Network::Regtest) .expect("failed to get new address"); // TODO: expect this Result once the WouldBlock issue is resolved upstream. let _block_hashes_res = bitcoind.client.generate_to_address(num as u64, &address); diff --git a/src/types.rs b/src/types.rs index 708cd495a..b5926cb99 100644 --- a/src/types.rs +++ b/src/types.rs @@ -21,6 +21,8 @@ use lightning_transaction_sync::EsploraSyncClient; use bitcoin::secp256k1::{self, PublicKey, Secp256k1}; use bitcoin::OutPoint; +use std::fmt; +use std::str::FromStr; use std::sync::{Arc, Mutex, RwLock}; pub(crate) type ChainMonitor = chainmonitor::ChainMonitor< @@ -137,6 +139,58 @@ pub(crate) type Sweeper = OutputSweeper< Arc, >; +/// The cryptocurrency network to act on. +#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Debug)] +pub enum Network { + /// Mainnet Bitcoin. + Bitcoin, + /// Bitcoin's testnet network. + Testnet, + /// Bitcoin's signet network. + Signet, + /// Bitcoin's regtest network. + Regtest, +} + +impl TryFrom for Network { + type Error = (); + + fn try_from(network: bitcoin::Network) -> Result { + match network { + bitcoin::Network::Bitcoin => Ok(Self::Bitcoin), + bitcoin::Network::Testnet => Ok(Self::Testnet), + bitcoin::Network::Signet => Ok(Self::Signet), + bitcoin::Network::Regtest => Ok(Self::Regtest), + _ => Err(()), + } + } +} + +impl From for bitcoin::Network { + fn from(network: Network) -> Self { + match network { + Network::Bitcoin => bitcoin::Network::Bitcoin, + Network::Testnet => bitcoin::Network::Testnet, + Network::Signet => bitcoin::Network::Signet, + Network::Regtest => bitcoin::Network::Regtest, + } + } +} + +impl fmt::Display for Network { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + bitcoin::Network::from(*self).fmt(f) + } +} + +impl FromStr for Network { + type Err = (); + + fn from_str(s: &str) -> Result { + bitcoin::Network::from_str(s).map_err(|_| ())?.try_into() + } +} + /// A local, potentially user-provided, identifier of a channel. /// /// By default, this will be randomly generated for the user to ensure local uniqueness. diff --git a/tests/common.rs b/tests/common.rs index 6536a312a..381827d7f 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -1,10 +1,10 @@ #![cfg(cln_test)] -use ldk_node::{Config, LogLevel}; +use ldk_node::{Config, LogLevel, Network}; use lightning::ln::msgs::SocketAddress; -use bitcoin::{Address, Amount, Network, OutPoint, Txid}; +use bitcoin::{Address, Amount, OutPoint, Txid}; use bitcoincore_rpc::bitcoincore_rpc_json::AddressType; use bitcoincore_rpc::Client as BitcoindClient; @@ -126,7 +126,7 @@ pub(crate) fn generate_blocks_and_wait( let address = bitcoind .get_new_address(Some("test"), Some(AddressType::Legacy)) .expect("failed to get new address") - .require_network(Network::Regtest) + .require_network(bitcoin::Network::Regtest) .expect("failed to get new address"); // TODO: expect this Result once the WouldBlock issue is resolved upstream. let _block_hashes_res = bitcoind.generate_to_address(num as u64, &address);