}
}
}
-impl channelmonitor::ManyChannelMonitor<EnforcingChannelKeys> for TestChannelMonitor {
+impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
+ type Keys = EnforcingChannelKeys;
+
fn add_monitor(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<EnforcingChannelKeys>) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
let mut ser = VecWriter(Vec::new());
monitor.write_for_disk(&mut ser).unwrap();
config.channel_options.fee_proportional_millionths = 0;
config.channel_options.announced_channel = true;
config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
- (Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap()),
+ (Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0)),
monitor)
} }
}
let tx = Transaction { version: $chan_id, lock_time: 0, input: Vec::new(), output: vec![TxOut {
value: *channel_value_satoshis, script_pubkey: output_script.clone(),
}]};
- funding_output = OutPoint::new(tx.txid(), 0);
+ funding_output = OutPoint { txid: tx.txid(), index: 0 };
$source.funding_transaction_generated(&temporary_channel_id, funding_output);
channel_txn.push(tx);
} else { panic!("Wrong event type"); }
}
}
+type ChannelMan = ChannelManager<
+ EnforcingChannelKeys,
+ Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
+ Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>;
+type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan>, Arc<NetGraphMsgHandler<Arc<ChainWatchInterfaceUtil>, Arc<dyn Logger>>>, Arc<dyn Logger>>;
+
struct MoneyLossDetector<'a> {
- manager: Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>,
- monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
- handler: PeerManager<Peer<'a>, Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>, Arc<dyn Logger>>,
+ manager: Arc<ChannelMan>,
+ monitor: Arc<channelmonitor::SimpleManyChannelMonitor<
+ OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
+ handler: PeerMan<'a>,
peers: &'a RefCell<[bool; 256]>,
funding_txn: Vec<Transaction>,
}
impl<'a> MoneyLossDetector<'a> {
pub fn new(peers: &'a RefCell<[bool; 256]>,
- manager: Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>,
+ manager: Arc<ChannelMan>,
monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
- handler: PeerManager<Peer<'a>, Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>, Arc<dyn Logger>>) -> Self {
+ handler: PeerMan<'a>) -> Self {
MoneyLossDetector {
manager,
monitor,
config.channel_options.fee_proportional_millionths = slice_to_be32(get_slice!(4));
config.channel_options.announced_channel = get_slice!(1)[0] != 0;
config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
- let channelmanager = Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap());
+ let channelmanager = Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0));
let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret());
let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(watch.clone(), Arc::clone(&logger)));
let funding_output = 'search_loop: loop {
let funding_txid = tx.txid();
if let None = loss_detector.txids_confirmed.get(&funding_txid) {
- let outpoint = OutPoint::new(funding_txid, 0);
+ let outpoint = OutPoint { txid: funding_txid, index: 0 };
for chan in channelmanager.list_channels() {
if chan.channel_id == outpoint.to_channel_id() {
tx.version += 1;
//! type ChainWatchInterface = dyn lightning::chain::chaininterface::ChainWatchInterface;
//! type ChannelMonitor = lightning::ln::channelmonitor::SimpleManyChannelMonitor<lightning::chain::transaction::OutPoint, lightning::chain::keysinterface::InMemoryChannelKeys, Arc<TxBroadcaster>, Arc<FeeEstimator>, Arc<Logger>, Arc<ChainWatchInterface>>;
//! type ChannelManager = lightning::ln::channelmanager::SimpleArcChannelManager<ChannelMonitor, TxBroadcaster, FeeEstimator, Logger>;
-//! type PeerManager = lightning::ln::peer_handler::SimpleArcPeerManager<lightning_net_tokio::SocketDescriptor, ChannelMonitor, TxBroadcaster, FeeEstimator, Logger>;
+//! type PeerManager = lightning::ln::peer_handler::SimpleArcPeerManager<lightning_net_tokio::SocketDescriptor, ChannelMonitor, TxBroadcaster, FeeEstimator, ChainWatchInterface, Logger>;
//!
//! // Connect to node with pubkey their_node_id at addr:
//! async fn connect_to_node(peer_manager: PeerManager, channel_monitor: Arc<ChannelMonitor>, channel_manager: ChannelManager, their_node_id: PublicKey, addr: SocketAddr) {
use lightning::ln::peer_handler;
use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait;
-use lightning::ln::msgs::ChannelMessageHandler;
+use lightning::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler};
use lightning::util::logger::Logger;
use std::{task, thread};
_ => panic!()
}
}
- async fn schedule_read<CMH: ChannelMessageHandler + 'static, L: Logger + 'static + ?Sized>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, Arc<CMH>, Arc<L>>>, us: Arc<Mutex<Self>>, mut reader: io::ReadHalf<TcpStream>, mut read_wake_receiver: mpsc::Receiver<()>, mut write_avail_receiver: mpsc::Receiver<()>) {
+ async fn schedule_read<CMH, RMH, L>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, Arc<CMH>, Arc<RMH>, Arc<L>>>, us: Arc<Mutex<Self>>, mut reader: io::ReadHalf<TcpStream>, mut read_wake_receiver: mpsc::Receiver<()>, mut write_avail_receiver: mpsc::Receiver<()>) where
+ CMH: ChannelMessageHandler + 'static,
+ RMH: RoutingMessageHandler + 'static,
+ L: Logger + 'static + ?Sized {
let peer_manager_ref = peer_manager.clone();
// 8KB is nice and big but also should never cause any issues with stack overflowing.
let mut buf = [0; 8192];
/// not need to poll the provided future in order to make progress.
///
/// See the module-level documentation for how to handle the event_notify mpsc::Sender.
-pub fn setup_inbound<CMH: ChannelMessageHandler + 'static, L: Logger + 'static + ?Sized>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, Arc<CMH>, Arc<L>>>, event_notify: mpsc::Sender<()>, stream: TcpStream) -> impl std::future::Future<Output=()> {
+pub fn setup_inbound<CMH, RMH, L>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, Arc<CMH>, Arc<RMH>, Arc<L>>>, event_notify: mpsc::Sender<()>, stream: TcpStream) -> impl std::future::Future<Output=()> where
+ CMH: ChannelMessageHandler + 'static,
+ RMH: RoutingMessageHandler + 'static,
+ L: Logger + 'static + ?Sized {
let (reader, write_receiver, read_receiver, us) = Connection::new(event_notify, stream);
#[cfg(debug_assertions)]
let last_us = Arc::clone(&us);
/// not need to poll the provided future in order to make progress.
///
/// See the module-level documentation for how to handle the event_notify mpsc::Sender.
-pub fn setup_outbound<CMH: ChannelMessageHandler + 'static, L: Logger + 'static + ?Sized>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, Arc<CMH>, Arc<L>>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, stream: TcpStream) -> impl std::future::Future<Output=()> {
+pub fn setup_outbound<CMH, RMH, L>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, Arc<CMH>, Arc<RMH>, Arc<L>>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, stream: TcpStream) -> impl std::future::Future<Output=()> where
+ CMH: ChannelMessageHandler + 'static,
+ RMH: RoutingMessageHandler + 'static,
+ L: Logger + 'static + ?Sized {
let (reader, mut write_receiver, read_receiver, us) = Connection::new(event_notify, stream);
#[cfg(debug_assertions)]
let last_us = Arc::clone(&us);
/// make progress.
///
/// See the module-level documentation for how to handle the event_notify mpsc::Sender.
-pub async fn connect_outbound<CMH: ChannelMessageHandler + 'static, L: Logger + 'static + ?Sized>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, Arc<CMH>, Arc<L>>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, addr: SocketAddr) -> Option<impl std::future::Future<Output=()>> {
+pub async fn connect_outbound<CMH, RMH, L>(peer_manager: Arc<peer_handler::PeerManager<SocketDescriptor, Arc<CMH>, Arc<RMH>, Arc<L>>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, addr: SocketAddr) -> Option<impl std::future::Future<Output=()>> where
+ CMH: ChannelMessageHandler + 'static,
+ RMH: RoutingMessageHandler + 'static,
+ L: Logger + 'static + ?Sized {
if let Ok(Ok(stream)) = time::timeout(Duration::from_secs(10), TcpStream::connect(&addr)).await {
Some(setup_outbound(peer_manager, event_notify, their_node_id, stream))
} else { None }
});
let a_manager = Arc::new(PeerManager::new(MessageHandler {
chan_handler: Arc::clone(&a_handler),
- route_handler: Arc::clone(&a_handler) as Arc<dyn RoutingMessageHandler>,
+ route_handler: Arc::clone(&a_handler),
}, a_key.clone(), &[1; 32], Arc::new(TestLogger())));
let (b_connected_sender, mut b_connected) = mpsc::channel(1);
});
let b_manager = Arc::new(PeerManager::new(MessageHandler {
chan_handler: Arc::clone(&b_handler),
- route_handler: Arc::clone(&b_handler) as Arc<dyn RoutingMessageHandler>,
+ route_handler: Arc::clone(&b_handler),
}, b_key.clone(), &[2; 32], Arc::new(TestLogger())));
// We bind on localhost, hoping the environment is properly configured with a local
}
}
-/// A trait to describe an object which can get user secrets and key material.
-pub trait KeysInterface: Send + Sync {
- /// A type which implements ChannelKeys which will be returned by get_channel_keys.
- type ChanKeySigner : ChannelKeys;
-
- /// Get node secret key (aka node_id or network_key)
- fn get_node_secret(&self) -> SecretKey;
- /// Get destination redeemScript to encumber static protocol exit points.
- fn get_destination_script(&self) -> Script;
- /// Get shutdown_pubkey to use as PublicKey at channel closure
- fn get_shutdown_pubkey(&self) -> PublicKey;
- /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you
- /// restarted with some stale data!
- fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner;
- /// Get a secret and PRNG seed for construting an onion packet
- fn get_onion_rand(&self) -> (SecretKey, [u8; 32]);
- /// Get a unique temporary channel id. Channels will be referred to by this until the funding
- /// transaction is created, at which point they will use the outpoint in the funding
- /// transaction.
- fn get_channel_id(&self) -> [u8; 32];
-}
-
/// Set of lightning keys needed to operate a channel as described in BOLT 3.
///
/// Signing services could be implemented on a hardware wallet. In this case,
fn set_remote_channel_pubkeys(&mut self, channel_points: &ChannelPublicKeys);
}
+/// A trait to describe an object which can get user secrets and key material.
+pub trait KeysInterface: Send + Sync {
+ /// A type which implements ChannelKeys which will be returned by get_channel_keys.
+ type ChanKeySigner : ChannelKeys;
+
+ /// Get node secret key (aka node_id or network_key)
+ fn get_node_secret(&self) -> SecretKey;
+ /// Get destination redeemScript to encumber static protocol exit points.
+ fn get_destination_script(&self) -> Script;
+ /// Get shutdown_pubkey to use as PublicKey at channel closure
+ fn get_shutdown_pubkey(&self) -> PublicKey;
+ /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you
+ /// restarted with some stale data!
+ fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner;
+ /// Get a secret and PRNG seed for constructing an onion packet
+ fn get_onion_rand(&self) -> (SecretKey, [u8; 32]);
+ /// Get a unique temporary channel id. Channels will be referred to by this until the funding
+ /// transaction is created, at which point they will use the outpoint in the funding
+ /// transaction.
+ fn get_channel_id(&self) -> [u8; 32];
+}
+
#[derive(Clone)]
/// A simple implementation of ChannelKeys that just keeps the private keys in memory.
pub struct InMemoryChannelKeys {
/// Note that until the 0.1 release there is no guarantee of backward compatibility between
/// versions. Once the library is more fully supported, the docs will be updated to include a
/// detailed description of the guarantee.
- pub fn new(seed: &[u8; 32], network: Network, starting_time_secs: u64, starting_time_nanos: u32) -> KeysManager {
+ pub fn new(seed: &[u8; 32], network: Network, starting_time_secs: u64, starting_time_nanos: u32) -> Self {
let secp_ctx = Secp256k1::signing_only();
match ExtendedPrivKey::new_master(network.clone(), seed) {
Ok(master_key) => {
}
impl OutPoint {
- /// Creates a new `OutPoint` from the txid and the index.
- pub fn new(txid: Txid, index: u16) -> OutPoint {
- OutPoint { txid, index }
- }
-
/// Convert an `OutPoint` to a lightning channel id.
pub fn to_channel_id(&self) -> [u8; 32] {
let mut res = [0; 32];
use bitcoin::blockdata::script::{Script,Builder};
use bitcoin::blockdata::opcodes;
use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction, SigHashType};
-use bitcoin::consensus::encode::{self, Decodable, Encodable};
+use bitcoin::consensus::encode::{Decodable, Encodable};
+use bitcoin::consensus::encode;
use bitcoin::util::bip143;
use bitcoin::hashes::{Hash, HashEngine};
panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
}
- let funding_txo = OutPoint::new(msg.funding_txid, msg.funding_output_index);
+ let funding_txo = OutPoint{ txid: msg.funding_txid, index: msg.funding_output_index };
self.funding_txo = Some(funding_txo.clone());
let (remote_initial_commitment_tx, local_initial_commitment_tx, our_signature) = match self.funding_created_signature(&msg.signature, logger) {
let tx = Transaction { version: 1, lock_time: 0, input: Vec::new(), output: vec![TxOut {
value: 10000000, script_pubkey: output_script.clone(),
}]};
- let funding_outpoint = OutPoint::new(tx.txid(), 0);
+ let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
let funding_created_msg = node_a_chan.get_outbound_funding_created(funding_outpoint, &&logger).unwrap();
let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, &&logger).unwrap();
chan.their_to_self_delay = 144;
chan.our_dust_limit_satoshis = 546;
- let funding_info = OutPoint::new(Txid::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);
+ let funding_info = OutPoint{ txid: Txid::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), index: 0 };
chan.funding_txo = Some(funding_info);
let their_pubkeys = ChannelPublicKeys {
/// SimpleArcChannelManager when you require a ChannelManager with a static lifetime, such as when
/// you're using lightning-net-tokio.
pub struct ChannelManager<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
}
impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<ChanSigner, M, T, K, F, L>
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
/// the ChannelManager as a listener to the BlockNotifier and call the BlockNotifier's
/// `block_(dis)connected` methods, which will notify all registered listeners in one
/// go.
- pub fn new(network: Network, fee_est: F, monitor: M, tx_broadcaster: T, logger: L, keys_manager: K, config: UserConfig, current_blockchain_height: usize) -> Result<ChannelManager<ChanSigner, M, T, K, F, L>, secp256k1::Error> {
+ pub fn new(network: Network, fee_est: F, monitor: M, tx_broadcaster: T, logger: L, keys_manager: K, config: UserConfig, current_blockchain_height: usize) -> Self {
let secp_ctx = Secp256k1::new();
- let res = ChannelManager {
+ ChannelManager {
default_configuration: config.clone(),
genesis_hash: genesis_block(network).header.bitcoin_hash(),
fee_estimator: fee_est,
keys_manager,
logger,
- };
-
- Ok(res)
+ }
}
/// Creates a new outbound channel to the given remote node and with the given value.
}
impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> events::MessageSendEventsProvider for ChannelManager<ChanSigner, M, T, K, F, L>
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
}
impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> events::EventsProvider for ChannelManager<ChanSigner, M, T, K, F, L>
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
impl<ChanSigner: ChannelKeys, M: Deref + Sync + Send, T: Deref + Sync + Send, K: Deref + Sync + Send, F: Deref + Sync + Send, L: Deref + Sync + Send>
ChainListener for ChannelManager<ChanSigner, M, T, K, F, L>
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
impl<ChanSigner: ChannelKeys, M: Deref + Sync + Send, T: Deref + Sync + Send, K: Deref + Sync + Send, F: Deref + Sync + Send, L: Deref + Sync + Send>
ChannelMessageHandler for ChannelManager<ChanSigner, M, T, K, F, L>
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
}
impl<ChanSigner: ChannelKeys + Writeable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelManager<ChanSigner, M, T, K, F, L>
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
/// 6) Disconnect/connect blocks on the ChannelManager.
/// 7) Register the new ChannelManager with your ChainWatchInterface.
pub struct ChannelManagerReadArgs<'a, ChanSigner: 'a + ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
// SipmleArcChannelManager type:
impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
ReadableArgs<ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F, L>> for (BlockHash, Arc<ChannelManager<ChanSigner, M, T, K, F, L>>)
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
ReadableArgs<ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F, L>> for (BlockHash, ChannelManager<ChanSigner, M, T, K, F, L>)
- where M::Target: ManyChannelMonitor<ChanSigner>,
+ where M::Target: ManyChannelMonitor<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
F::Target: FeeEstimator,
}
impl_writeable!(HTLCUpdate, 0, { payment_hash, payment_preimage, source });
-/// Simple trait indicating ability to track a set of ChannelMonitors and multiplex events between
-/// them. Generally should be implemented by keeping a local SimpleManyChannelMonitor and passing
-/// events to it, while also taking any add/update_monitor events and passing them to some remote
-/// server(s).
-///
-/// In general, you must always have at least one local copy in memory, which must never fail to
-/// update (as it is responsible for broadcasting the latest state in case the channel is closed),
-/// and then persist it to various on-disk locations. If, for some reason, the in-memory copy fails
-/// to update (eg out-of-memory or some other condition), you must immediately shut down without
-/// taking any further action such as writing the current state to disk. This should likely be
-/// accomplished via panic!() or abort().
-///
-/// Note that any updates to a channel's monitor *must* be applied to each instance of the
-/// channel's monitor everywhere (including remote watchtowers) *before* this function returns. If
-/// an update occurs and a remote watchtower is left with old state, it may broadcast transactions
-/// which we have revoked, allowing our counterparty to claim all funds in the channel!
-///
-/// User needs to notify implementors of ManyChannelMonitor when a new block is connected or
-/// disconnected using their `block_connected` and `block_disconnected` methods. However, rather
-/// than calling these methods directly, the user should register implementors as listeners to the
-/// BlockNotifier and call the BlockNotifier's `block_(dis)connected` methods, which will notify
-/// all registered listeners in one go.
-pub trait ManyChannelMonitor<ChanSigner: ChannelKeys>: Send + Sync {
- /// Adds a monitor for the given `funding_txo`.
- ///
- /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
- /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
- /// callbacks with the funding transaction, or any spends of it.
- ///
- /// Further, the implementer must also ensure that each output returned in
- /// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
- /// any spends of any of the outputs.
- ///
- /// Any spends of outputs which should have been registered which aren't passed to
- /// ChannelMonitors via block_connected may result in FUNDS LOSS.
- fn add_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor<ChanSigner>) -> Result<(), ChannelMonitorUpdateErr>;
-
- /// Updates a monitor for the given `funding_txo`.
- ///
- /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
- /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
- /// callbacks with the funding transaction, or any spends of it.
- ///
- /// Further, the implementer must also ensure that each output returned in
- /// monitor.get_watch_outputs() is registered to ensure that the provided monitor learns about
- /// any spends of any of the outputs.
- ///
- /// Any spends of outputs which should have been registered which aren't passed to
- /// ChannelMonitors via block_connected may result in FUNDS LOSS.
- fn update_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitorUpdate) -> Result<(), ChannelMonitorUpdateErr>;
-
- /// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated
- /// with success or failure.
- ///
- /// You should probably just call through to
- /// ChannelMonitor::get_and_clear_pending_htlcs_updated() for each ChannelMonitor and return
- /// the full list.
- fn get_and_clear_pending_htlcs_updated(&self) -> Vec<HTLCUpdate>;
-}
-
/// A simple implementation of a ManyChannelMonitor and ChainListener. Can be used to create a
/// watchtower or watch our own channels.
///
}
}
-impl<ChanSigner: ChannelKeys, T: Deref + Sync + Send, F: Deref + Sync + Send, L: Deref + Sync + Send, C: Deref + Sync + Send> ManyChannelMonitor<ChanSigner> for SimpleManyChannelMonitor<OutPoint, ChanSigner, T, F, L, C>
+impl<ChanSigner: ChannelKeys, T: Deref + Sync + Send, F: Deref + Sync + Send, L: Deref + Sync + Send, C: Deref + Sync + Send> ManyChannelMonitor for SimpleManyChannelMonitor<OutPoint, ChanSigner, T, F, L, C>
where T::Target: BroadcasterInterface,
F::Target: FeeEstimator,
L::Target: Logger,
C::Target: ChainWatchInterface,
{
+ type Keys = ChanSigner;
+
fn add_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor<ChanSigner>) -> Result<(), ChannelMonitorUpdateErr> {
match self.add_monitor_by_key(funding_txo, monitor) {
Ok(_) => Ok(()),
secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit...
}
+/// Simple trait indicating ability to track a set of ChannelMonitors and multiplex events between
+/// them. Generally should be implemented by keeping a local SimpleManyChannelMonitor and passing
+/// events to it, while also taking any add/update_monitor events and passing them to some remote
+/// server(s).
+///
+/// In general, you must always have at least one local copy in memory, which must never fail to
+/// update (as it is responsible for broadcasting the latest state in case the channel is closed),
+/// and then persist it to various on-disk locations. If, for some reason, the in-memory copy fails
+/// to update (eg out-of-memory or some other condition), you must immediately shut down without
+/// taking any further action such as writing the current state to disk. This should likely be
+/// accomplished via panic!() or abort().
+///
+/// Note that any updates to a channel's monitor *must* be applied to each instance of the
+/// channel's monitor everywhere (including remote watchtowers) *before* this function returns. If
+/// an update occurs and a remote watchtower is left with old state, it may broadcast transactions
+/// which we have revoked, allowing our counterparty to claim all funds in the channel!
+///
+/// User needs to notify implementors of ManyChannelMonitor when a new block is connected or
+/// disconnected using their `block_connected` and `block_disconnected` methods. However, rather
+/// than calling these methods directly, the user should register implementors as listeners to the
+/// BlockNotifier and call the BlockNotifier's `block_(dis)connected` methods, which will notify
+/// all registered listeners in one go.
+pub trait ManyChannelMonitor: Send + Sync {
+ /// The concrete type which signs for transactions and provides access to our channel public
+ /// keys.
+ type Keys: ChannelKeys;
+
+ /// Adds a monitor for the given `funding_txo`.
+ ///
+ /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
+ /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
+ /// callbacks with the funding transaction, or any spends of it.
+ ///
+ /// Further, the implementer must also ensure that each output returned in
+ /// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
+ /// any spends of any of the outputs.
+ ///
+ /// Any spends of outputs which should have been registered which aren't passed to
+ /// ChannelMonitors via block_connected may result in FUNDS LOSS.
+ fn add_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor<Self::Keys>) -> Result<(), ChannelMonitorUpdateErr>;
+
+ /// Updates a monitor for the given `funding_txo`.
+ ///
+ /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
+ /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
+ /// callbacks with the funding transaction, or any spends of it.
+ ///
+ /// Further, the implementer must also ensure that each output returned in
+ /// monitor.get_watch_outputs() is registered to ensure that the provided monitor learns about
+ /// any spends of any of the outputs.
+ ///
+ /// Any spends of outputs which should have been registered which aren't passed to
+ /// ChannelMonitors via block_connected may result in FUNDS LOSS.
+ fn update_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitorUpdate) -> Result<(), ChannelMonitorUpdateErr>;
+
+ /// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated
+ /// with success or failure.
+ ///
+ /// You should probably just call through to
+ /// ChannelMonitor::get_and_clear_pending_htlcs_updated() for each ChannelMonitor and return
+ /// the full list.
+ fn get_and_clear_pending_htlcs_updated(&self) -> Vec<HTLCUpdate>;
+}
+
#[cfg(any(test, feature = "fuzztarget"))]
/// Used only in testing and fuzztarget to check serialization roundtrips don't change the
/// underlying object
let tx = Transaction { version: chan_id as u32, lock_time: 0, input: Vec::new(), output: vec![TxOut {
value: *channel_value_satoshis, script_pubkey: output_script.clone(),
}]};
- let funding_outpoint = OutPoint::new(tx.txid(), 0);
+ let funding_outpoint = OutPoint { txid: tx.txid(), index: 0 };
(*temporary_channel_id, tx, funding_outpoint)
},
_ => panic!("Unexpected event"),
default_config.channel_options.announced_channel = true;
default_config.peer_channel_config_limits.force_announced_channel_preference = false;
default_config.own_channel_config.our_htlc_minimum_msat = 1000; // sanitization being done by the sender, to exerce receiver logic we need to lift of limit
- let node = ChannelManager::new(Network::Testnet, cfgs[i].fee_estimator, &cfgs[i].chan_monitor, cfgs[i].tx_broadcaster, cfgs[i].logger.clone(), &cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { default_config }, 0).unwrap();
+ let node = ChannelManager::new(Network::Testnet, cfgs[i].fee_estimator, &cfgs[i].chan_monitor, cfgs[i].tx_broadcaster, cfgs[i].logger.clone(), &cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { default_config }, 0);
chanmgrs.push(node);
}
nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![tx.clone()]}, 1);
nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![tx.clone()]}, 1);
- nodes[0].node.close_channel(&OutPoint::new(tx.txid(), 0).to_channel_id()).unwrap();
+ nodes[0].node.close_channel(&OutPoint { txid: tx.txid(), index: 0 }.to_channel_id()).unwrap();
let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
// Now check that if we add the preimage to ChannelMonitor it broadcasts our HTLC-Success..
{
let mut monitors = nodes[2].chan_monitor.simple_monitor.monitors.lock().unwrap();
- monitors.get_mut(&OutPoint::new(Txid::from_slice(&payment_event.commitment_msg.channel_id[..]).unwrap(), 0)).unwrap()
+ monitors.get_mut(&OutPoint{ txid: Txid::from_slice(&payment_event.commitment_msg.channel_id[..]).unwrap(), index: 0 }).unwrap()
.provide_payment_preimage(&our_payment_hash, &our_payment_preimage);
}
nodes[2].block_notifier.block_connected_checked(&header, 1, &[&tx], &[1]);
// We test that in case of peer committing upfront to a script, if it changes at closing, we refuse to sign
let flags = InitFeatures::known();
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone());
- nodes[0].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
let mut node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id());
node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
// Test we enforce upfront_scriptpbukey if by providing a diffrent one at closing that we disconnect peer
// We test that in case of peer committing upfront to a script, if it doesn't change at closing, we sign
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone());
- nodes[0].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id());
// We test that in case of peer committing upfront to a script, if it oesn't change at closing, we sign
nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
// We test that if case of peer non-signaling we don't enforce committed script at channel opening
let flags_no = InitFeatures::known().clear_upfront_shutdown_script();
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags_no, flags.clone());
- nodes[0].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
let mut node_1_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
node_1_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_1_shutdown);
// We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close
// channel smoothly, opt-out is from channel initiator here
let chan = create_announced_chan_between_nodes_with_value(&nodes, 1, 0, 1000000, 1000000, flags.clone(), flags.clone());
- nodes[1].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
let mut node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
//// We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close
//// channel smoothly
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags.clone(), flags.clone());
- nodes[1].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
let mut node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
connect_blocks(&nodes[0].block_notifier, 5, 130, false, header_130.bitcoin_hash());
{
let monitors = nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap();
- if let Some(monitor) = monitors.get(&OutPoint::new(chan.3.txid(), 0)) {
+ if let Some(monitor) = monitors.get(&OutPoint { txid: chan.3.txid(), index: 0 }) {
assert!(monitor.onchain_tx_handler.pending_claim_requests.is_empty());
assert!(monitor.onchain_tx_handler.claimable_outpoints.is_empty());
}
use ln::features::InitFeatures;
use ln::msgs;
-use ln::msgs::ChannelMessageHandler;
+use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler};
use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager};
use util::ser::{VecWriter, Writeable};
use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
use util::byte_utils;
use util::events::{MessageSendEvent, MessageSendEventsProvider};
use util::logger::Logger;
+use routing::network_graph::NetGraphMsgHandler;
use std::collections::{HashMap,hash_map,HashSet,LinkedList};
use std::sync::{Arc, Mutex};
use bitcoin::hashes::{HashEngine, Hash};
/// Provides references to trait impls which handle different types of messages.
-pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandler {
+pub struct MessageHandler<CM: Deref, RM: Deref> where
+ CM::Target: ChannelMessageHandler,
+ RM::Target: RoutingMessageHandler {
/// A message handler which handles messages specific to channels. Usually this is just a
/// ChannelManager object.
pub chan_handler: CM,
/// A message handler which handles messages updating our knowledge of the network channel
/// graph. Usually this is just a NetGraphMsgHandlerMonitor object.
- pub route_handler: Arc<msgs::RoutingMessageHandler>,
+ pub route_handler: RM,
}
/// Provides an object which can be used to send data to and which uniquely identifies a connection
pub struct PeerHandleError {
/// Used to indicate that we probably can't make any future connections to this peer, implying
/// we should go ahead and force-close any channels we have with it.
- no_connection_possible: bool,
+ pub no_connection_possible: bool,
}
impl fmt::Debug for PeerHandleError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
/// lifetimes). Other times you can afford a reference, which is more efficient, in which case
/// SimpleRefPeerManager is the more appropriate type. Defining these type aliases prevents
/// issues such as overly long function definitions.
-pub type SimpleArcPeerManager<SD, M, T, F, L> = Arc<PeerManager<SD, SimpleArcChannelManager<M, T, F, L>, Arc<L>>>;
+pub type SimpleArcPeerManager<SD, M, T, F, C, L> = Arc<PeerManager<SD, SimpleArcChannelManager<M, T, F, L>, Arc<NetGraphMsgHandler<Arc<C>, Arc<L>>>, Arc<L>>>;
/// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference
/// counterpart to the SimpleArcPeerManager type alias. Use this type by default when you don't
/// usage of lightning-net-tokio (since tokio::spawn requires parameters with static lifetimes).
/// But if this is not necessary, using a reference is more efficient. Defining these type aliases
/// helps with issues such as long function definitions.
-pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, SD, M, T, F, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L>, &'e L>;
+pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L>, &'e NetGraphMsgHandler<&'g C, &'f L>, &'f L>;
/// A PeerManager manages a set of peers, described by their SocketDescriptor and marshalls socket
/// events into messages which it passes on to its MessageHandlers.
/// essentially you should default to using a SimpleRefPeerManager, and use a
/// SimpleArcPeerManager when you require a PeerManager with a static lifetime, such as when
/// you're using lightning-net-tokio.
-pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, L: Deref> where CM::Target: msgs::ChannelMessageHandler, L::Target: Logger {
- message_handler: MessageHandler<CM>,
+pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref> where
+ CM::Target: ChannelMessageHandler,
+ RM::Target: RoutingMessageHandler,
+ L::Target: Logger {
+ message_handler: MessageHandler<CM, RM>,
peers: Mutex<PeerHolder<Descriptor>>,
our_node_secret: SecretKey,
ephemeral_key_midstate: Sha256Engine,
/// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
/// PeerIds may repeat, but only after socket_disconnected() has been called.
-impl<Descriptor: SocketDescriptor, CM: Deref, L: Deref> PeerManager<Descriptor, CM, L> where CM::Target: msgs::ChannelMessageHandler, L::Target: Logger {
+impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref> PeerManager<Descriptor, CM, RM, L> where
+ CM::Target: ChannelMessageHandler,
+ RM::Target: RoutingMessageHandler,
+ L::Target: Logger {
/// Constructs a new PeerManager with the given message handlers and node_id secret key
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
/// cryptographically secure random bytes.
- pub fn new(message_handler: MessageHandler<CM>, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: L) -> PeerManager<Descriptor, CM, L> {
+ pub fn new(message_handler: MessageHandler<CM, RM>, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: L) -> Self {
let mut ephemeral_key_midstate = Sha256::engine();
ephemeral_key_midstate.input(ephemeral_random_data);
#[cfg(test)]
mod tests {
- use bitcoin::secp256k1::Signature;
- use bitcoin::BitcoinHash;
- use bitcoin::network::constants::Network;
- use bitcoin::blockdata::constants::genesis_block;
use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor};
use ln::msgs;
- use ln::features::ChannelFeatures;
use util::events;
use util::test_utils;
use rand::{thread_rng, Rng};
use std;
- use std::cmp::min;
use std::sync::{Arc, Mutex};
- use std::sync::atomic::{AtomicUsize, Ordering};
+ use std::sync::atomic::Ordering;
#[derive(Clone)]
struct FileDescriptor {
struct PeerManagerCfg {
chan_handler: test_utils::TestChannelMessageHandler,
+ routing_handler: test_utils::TestRoutingMessageHandler,
logger: test_utils::TestLogger,
}
fn create_peermgr_cfgs(peer_count: usize) -> Vec<PeerManagerCfg> {
let mut cfgs = Vec::new();
for _ in 0..peer_count {
- let chan_handler = test_utils::TestChannelMessageHandler::new();
- let logger = test_utils::TestLogger::new();
cfgs.push(
PeerManagerCfg{
- chan_handler,
- logger,
+ chan_handler: test_utils::TestChannelMessageHandler::new(),
+ logger: test_utils::TestLogger::new(),
+ routing_handler: test_utils::TestRoutingMessageHandler::new(),
}
);
}
cfgs
}
- fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>, routing_handlers: Option<&'a Vec<Arc<msgs::RoutingMessageHandler>>>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>> {
+ fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>> {
let mut peers = Vec::new();
let mut rng = thread_rng();
let mut ephemeral_bytes = [0; 32];
rng.fill_bytes(&mut ephemeral_bytes);
for i in 0..peer_count {
- let router = if let Some(routers) = routing_handlers { routers[i].clone() } else {
- Arc::new(test_utils::TestRoutingMessageHandler::new())
- };
let node_id = {
let mut key_slice = [0;32];
rng.fill_bytes(&mut key_slice);
SecretKey::from_slice(&key_slice).unwrap()
};
- let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: router };
+ let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: &cfgs[i].routing_handler };
let peer = PeerManager::new(msg_handler, node_id, &ephemeral_bytes, &cfgs[i].logger);
peers.push(peer);
}
peers
}
- fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>) -> (FileDescriptor, FileDescriptor) {
+ fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>) -> (FileDescriptor, FileDescriptor) {
let secp_ctx = Secp256k1::new();
let a_id = PublicKey::from_secret_key(&secp_ctx, &peer_a.our_node_secret);
let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
(fd_a.clone(), fd_b.clone())
}
- fn establish_connection_and_read_events<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>) -> (FileDescriptor, FileDescriptor) {
+ fn establish_connection_and_read_events<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>) -> (FileDescriptor, FileDescriptor) {
let (mut fd_a, mut fd_b) = establish_connection(peer_a, peer_b);
assert_eq!(peer_b.read_event(&mut fd_b, &fd_a.outbound_data.lock().unwrap().split_off(0)).unwrap(), false);
assert_eq!(peer_a.read_event(&mut fd_a, &fd_b.outbound_data.lock().unwrap().split_off(0)).unwrap(), false);
// push a DisconnectPeer event to remove the node flagged by id
let cfgs = create_peermgr_cfgs(2);
let chan_handler = test_utils::TestChannelMessageHandler::new();
- let mut peers = create_network(2, &cfgs, None);
+ let mut peers = create_network(2, &cfgs);
establish_connection(&peers[0], &peers[1]);
assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1);
fn test_timer_tick_occurred() {
// Create peers, a vector of two peer managers, perform initial set up and check that peers[0] has one Peer.
let cfgs = create_peermgr_cfgs(2);
- let peers = create_network(2, &cfgs, None);
+ let peers = create_network(2, &cfgs);
establish_connection(&peers[0], &peers[1]);
assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1);
assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 0);
}
- pub struct TestRoutingMessageHandler {
- pub chan_upds_recvd: AtomicUsize,
- pub chan_anns_recvd: AtomicUsize,
- pub chan_anns_sent: AtomicUsize,
- }
-
- impl TestRoutingMessageHandler {
- pub fn new() -> Self {
- TestRoutingMessageHandler {
- chan_upds_recvd: AtomicUsize::new(0),
- chan_anns_recvd: AtomicUsize::new(0),
- chan_anns_sent: AtomicUsize::new(0),
- }
- }
-
- }
- impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
- fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result<bool, msgs::LightningError> {
- Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
- }
- fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result<bool, msgs::LightningError> {
- self.chan_anns_recvd.fetch_add(1, Ordering::AcqRel);
- Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
- }
- fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result<bool, msgs::LightningError> {
- self.chan_upds_recvd.fetch_add(1, Ordering::AcqRel);
- Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
- }
- fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {}
- fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> {
- let mut chan_anns = Vec::new();
- const TOTAL_UPDS: u64 = 100;
- let end: u64 = min(starting_point + batch_amount as u64, TOTAL_UPDS - self.chan_anns_sent.load(Ordering::Acquire) as u64);
- for i in starting_point..end {
- let chan_upd_1 = get_dummy_channel_update(i);
- let chan_upd_2 = get_dummy_channel_update(i);
- let chan_ann = get_dummy_channel_announcement(i);
-
- chan_anns.push((chan_ann, Some(chan_upd_1), Some(chan_upd_2)));
- }
-
- self.chan_anns_sent.fetch_add(chan_anns.len(), Ordering::AcqRel);
- chan_anns
- }
-
- fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec<msgs::NodeAnnouncement> {
- Vec::new()
- }
-
- fn should_request_full_sync(&self, _node_id: &PublicKey) -> bool {
- true
- }
- }
-
- fn get_dummy_channel_announcement(short_chan_id: u64) -> msgs::ChannelAnnouncement {
- use bitcoin::secp256k1::ffi::Signature as FFISignature;
- let secp_ctx = Secp256k1::new();
- let network = Network::Testnet;
- let node_1_privkey = SecretKey::from_slice(&[42; 32]).unwrap();
- let node_2_privkey = SecretKey::from_slice(&[41; 32]).unwrap();
- let node_1_btckey = SecretKey::from_slice(&[40; 32]).unwrap();
- let node_2_btckey = SecretKey::from_slice(&[39; 32]).unwrap();
- let unsigned_ann = msgs::UnsignedChannelAnnouncement {
- features: ChannelFeatures::known(),
- chain_hash: genesis_block(network).header.bitcoin_hash(),
- short_channel_id: short_chan_id,
- node_id_1: PublicKey::from_secret_key(&secp_ctx, &node_1_privkey),
- node_id_2: PublicKey::from_secret_key(&secp_ctx, &node_2_privkey),
- bitcoin_key_1: PublicKey::from_secret_key(&secp_ctx, &node_1_btckey),
- bitcoin_key_2: PublicKey::from_secret_key(&secp_ctx, &node_2_btckey),
- excess_data: Vec::new(),
- };
-
- msgs::ChannelAnnouncement {
- node_signature_1: Signature::from(FFISignature::new()),
- node_signature_2: Signature::from(FFISignature::new()),
- bitcoin_signature_1: Signature::from(FFISignature::new()),
- bitcoin_signature_2: Signature::from(FFISignature::new()),
- contents: unsigned_ann,
- }
- }
-
- fn get_dummy_channel_update(short_chan_id: u64) -> msgs::ChannelUpdate {
- use bitcoin::secp256k1::ffi::Signature as FFISignature;
- let network = Network::Testnet;
- msgs::ChannelUpdate {
- signature: Signature::from(FFISignature::new()),
- contents: msgs::UnsignedChannelUpdate {
- chain_hash: genesis_block(network).header.bitcoin_hash(),
- short_channel_id: short_chan_id,
- timestamp: 0,
- flags: 0,
- cltv_expiry_delta: 0,
- htlc_minimum_msat: 0,
- fee_base_msat: 0,
- fee_proportional_millionths: 0,
- excess_data: vec![],
- }
- }
- }
-
#[test]
fn test_do_attempt_write_data() {
// Create 2 peers with custom TestRoutingMessageHandlers and connect them.
let cfgs = create_peermgr_cfgs(2);
- let mut routing_handlers: Vec<Arc<msgs::RoutingMessageHandler>> = Vec::new();
- let mut routing_handlers_concrete: Vec<Arc<TestRoutingMessageHandler>> = Vec::new();
- for _ in 0..2 {
- let routing_handler = Arc::new(TestRoutingMessageHandler::new());
- routing_handlers.push(routing_handler.clone());
- routing_handlers_concrete.push(routing_handler.clone());
- }
- let peers = create_network(2, &cfgs, Some(&routing_handlers));
+ cfgs[0].routing_handler.request_full_sync.store(true, Ordering::Release);
+ cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release);
+ let peers = create_network(2, &cfgs);
// By calling establish_connect, we trigger do_attempt_write_data between
// the peers. Previously this function would mistakenly enter an infinite loop
// Check that each peer has received the expected number of channel updates and channel
// announcements.
- assert_eq!(routing_handlers_concrete[0].clone().chan_upds_recvd.load(Ordering::Acquire), 100);
- assert_eq!(routing_handlers_concrete[0].clone().chan_anns_recvd.load(Ordering::Acquire), 50);
- assert_eq!(routing_handlers_concrete[1].clone().chan_upds_recvd.load(Ordering::Acquire), 100);
- assert_eq!(routing_handlers_concrete[1].clone().chan_anns_recvd.load(Ordering::Acquire), 50);
+ assert_eq!(cfgs[0].routing_handler.chan_upds_recvd.load(Ordering::Acquire), 100);
+ assert_eq!(cfgs[0].routing_handler.chan_anns_recvd.load(Ordering::Acquire), 50);
+ assert_eq!(cfgs[1].routing_handler.chan_upds_recvd.load(Ordering::Acquire), 100);
+ assert_eq!(cfgs[1].routing_handler.chan_anns_recvd.load(Ordering::Acquire), 50);
}
#[test]
// Inbound peer 0 requests initial_routing_sync, but outbound peer 1 does not.
{
let cfgs = create_peermgr_cfgs(2);
- let routing_handlers: Vec<Arc<msgs::RoutingMessageHandler>> = vec![
- Arc::new(test_utils::TestRoutingMessageHandler::new().set_request_full_sync()),
- Arc::new(test_utils::TestRoutingMessageHandler::new()),
- ];
- let peers = create_network(2, &cfgs, Some(&routing_handlers));
+ cfgs[0].routing_handler.request_full_sync.store(true, Ordering::Release);
+ let peers = create_network(2, &cfgs);
let (fd_0_to_1, fd_1_to_0) = establish_connection_and_read_events(&peers[0], &peers[1]);
let peer_0 = peers[0].peers.lock().unwrap();
// Outbound peer 1 requests initial_routing_sync, but inbound peer 0 does not.
{
let cfgs = create_peermgr_cfgs(2);
- let routing_handlers: Vec<Arc<msgs::RoutingMessageHandler>> = vec![
- Arc::new(test_utils::TestRoutingMessageHandler::new()),
- Arc::new(test_utils::TestRoutingMessageHandler::new().set_request_full_sync()),
- ];
- let peers = create_network(2, &cfgs, Some(&routing_handlers));
+ cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release);
+ let peers = create_network(2, &cfgs);
let (fd_0_to_1, fd_1_to_0) = establish_connection_and_read_events(&peers[0], &peers[1]);
let peer_0 = peers[0].peers.lock().unwrap();
pub(crate) struct DebugFundingChannelId<'a>(pub &'a Txid, pub u16);
impl<'a> std::fmt::Display for DebugFundingChannelId<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
- for i in OutPoint::new(self.0.clone(), self.1).to_channel_id().iter() {
+ for i in (OutPoint { txid: self.0.clone(), index: self.1 }).to_channel_id().iter() {
write!(f, "{:02x}", i)?;
}
Ok(())
use chain::transaction::OutPoint;
use chain::keysinterface;
use ln::channelmonitor;
-use ln::features::InitFeatures;
+use ln::features::{ChannelFeatures, InitFeatures};
use ln::msgs;
-use ln::msgs::LightningError;
use ln::channelmonitor::HTLCUpdate;
use util::enforcing_trait_impls::EnforcingChannelKeys;
use util::events;
use util::logger::{Logger, Level, Record};
use util::ser::{Readable, Writer, Writeable};
+use bitcoin::BitcoinHash;
+use bitcoin::blockdata::constants::genesis_block;
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::blockdata::script::{Builder, Script};
use bitcoin::blockdata::block::Block;
use bitcoin::network::constants::Network;
use bitcoin::hash_types::{Txid, BlockHash};
-use bitcoin::secp256k1::{SecretKey, PublicKey};
+use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1, Signature};
use std::time::{SystemTime, UNIX_EPOCH};
use std::sync::Mutex;
-use std::mem;
+use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
+use std::{cmp, mem};
use std::collections::HashMap;
pub struct TestVecWriter(pub Vec<u8>);
}
}
}
-impl<'a> channelmonitor::ManyChannelMonitor<EnforcingChannelKeys> for TestChannelMonitor<'a> {
+impl<'a> channelmonitor::ManyChannelMonitor for TestChannelMonitor<'a> {
+ type Keys = EnforcingChannelKeys;
+
fn add_monitor(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<EnforcingChannelKeys>) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
// At every point where we get a monitor update, we should be able to send a useful monitor
// to a watchtower and disk...
}
}
+fn get_dummy_channel_announcement(short_chan_id: u64) -> msgs::ChannelAnnouncement {
+ use bitcoin::secp256k1::ffi::Signature as FFISignature;
+ let secp_ctx = Secp256k1::new();
+ let network = Network::Testnet;
+ let node_1_privkey = SecretKey::from_slice(&[42; 32]).unwrap();
+ let node_2_privkey = SecretKey::from_slice(&[41; 32]).unwrap();
+ let node_1_btckey = SecretKey::from_slice(&[40; 32]).unwrap();
+ let node_2_btckey = SecretKey::from_slice(&[39; 32]).unwrap();
+ let unsigned_ann = msgs::UnsignedChannelAnnouncement {
+ features: ChannelFeatures::known(),
+ chain_hash: genesis_block(network).header.bitcoin_hash(),
+ short_channel_id: short_chan_id,
+ node_id_1: PublicKey::from_secret_key(&secp_ctx, &node_1_privkey),
+ node_id_2: PublicKey::from_secret_key(&secp_ctx, &node_2_privkey),
+ bitcoin_key_1: PublicKey::from_secret_key(&secp_ctx, &node_1_btckey),
+ bitcoin_key_2: PublicKey::from_secret_key(&secp_ctx, &node_2_btckey),
+ excess_data: Vec::new(),
+ };
+
+ msgs::ChannelAnnouncement {
+ node_signature_1: Signature::from(FFISignature::new()),
+ node_signature_2: Signature::from(FFISignature::new()),
+ bitcoin_signature_1: Signature::from(FFISignature::new()),
+ bitcoin_signature_2: Signature::from(FFISignature::new()),
+ contents: unsigned_ann,
+ }
+}
+
+fn get_dummy_channel_update(short_chan_id: u64) -> msgs::ChannelUpdate {
+ use bitcoin::secp256k1::ffi::Signature as FFISignature;
+ let network = Network::Testnet;
+ msgs::ChannelUpdate {
+ signature: Signature::from(FFISignature::new()),
+ contents: msgs::UnsignedChannelUpdate {
+ chain_hash: genesis_block(network).header.bitcoin_hash(),
+ short_channel_id: short_chan_id,
+ timestamp: 0,
+ flags: 0,
+ cltv_expiry_delta: 0,
+ htlc_minimum_msat: 0,
+ fee_base_msat: 0,
+ fee_proportional_millionths: 0,
+ excess_data: vec![],
+ }
+ }
+}
+
pub struct TestRoutingMessageHandler {
- request_full_sync: bool,
+ pub chan_upds_recvd: AtomicUsize,
+ pub chan_anns_recvd: AtomicUsize,
+ pub chan_anns_sent: AtomicUsize,
+ pub request_full_sync: AtomicBool,
}
impl TestRoutingMessageHandler {
pub fn new() -> Self {
TestRoutingMessageHandler {
- request_full_sync: false,
+ chan_upds_recvd: AtomicUsize::new(0),
+ chan_anns_recvd: AtomicUsize::new(0),
+ chan_anns_sent: AtomicUsize::new(0),
+ request_full_sync: AtomicBool::new(false),
}
}
-
- pub fn set_request_full_sync(mut self) -> Self {
- self.request_full_sync = true;
- self
- }
}
impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
- fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result<bool, LightningError> {
- Err(LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
+ fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result<bool, msgs::LightningError> {
+ Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
}
- fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result<bool, LightningError> {
- Err(LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
+ fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result<bool, msgs::LightningError> {
+ self.chan_anns_recvd.fetch_add(1, Ordering::AcqRel);
+ Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
}
- fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result<bool, LightningError> {
- Err(LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
+ fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result<bool, msgs::LightningError> {
+ self.chan_upds_recvd.fetch_add(1, Ordering::AcqRel);
+ Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
}
fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {}
- fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> {
- Vec::new()
+ fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> {
+ let mut chan_anns = Vec::new();
+ const TOTAL_UPDS: u64 = 100;
+ let end: u64 = cmp::min(starting_point + batch_amount as u64, TOTAL_UPDS - self.chan_anns_sent.load(Ordering::Acquire) as u64);
+ for i in starting_point..end {
+ let chan_upd_1 = get_dummy_channel_update(i);
+ let chan_upd_2 = get_dummy_channel_update(i);
+ let chan_ann = get_dummy_channel_announcement(i);
+
+ chan_anns.push((chan_ann, Some(chan_upd_1), Some(chan_upd_2)));
+ }
+
+ self.chan_anns_sent.fetch_add(chan_anns.len(), Ordering::AcqRel);
+ chan_anns
}
+
fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec<msgs::NodeAnnouncement> {
Vec::new()
}
+
fn should_request_full_sync(&self, _node_id: &PublicKey) -> bool {
- self.request_full_sync
+ self.request_full_sync.load(Ordering::Acquire)
}
}