use crate::chain::WatchedOutput;
use crate::chain::chaininterface;
use crate::chain::chaininterface::ConfirmationTarget;
+#[cfg(test)]
use crate::chain::chaininterface::FEERATE_FLOOR_SATS_PER_KW;
use crate::chain::chainmonitor;
use crate::chain::chainmonitor::{MonitorUpdateId, UpdateOrigin};
use crate::sign;
use crate::events;
use crate::events::bump_transaction::{WalletSource, Utxo};
-use crate::ln::ChannelId;
+use crate::ln::types::ChannelId;
use crate::ln::channelmanager::{ChannelDetails, self};
+#[cfg(test)]
use crate::ln::chan_utils::CommitmentTransaction;
use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
use crate::ln::{msgs, wire};
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
use bitcoin::secp256k1::schnorr;
-#[cfg(any(test, feature = "_test_utils"))]
-use regex;
-
use crate::io;
use crate::prelude::*;
use core::cell::RefCell;
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use core::mem;
use bitcoin::bech32::u5;
-use crate::sign::{InMemorySigner, Recipient, EntropySource, NodeSigner, SignerProvider};
+use crate::sign::{InMemorySigner, RandomBytes, Recipient, EntropySource, NodeSigner, SignerProvider};
#[cfg(feature = "std")]
use std::time::{SystemTime, UNIX_EPOCH};
pub router: DefaultRouter<
Arc<NetworkGraph<&'a TestLogger>>,
&'a TestLogger,
+ Arc<RandomBytes>,
&'a RwLock<TestScorer>,
(),
TestScorer,
>,
+ //pub entropy_source: &'a RandomBytes,
pub network_graph: Arc<NetworkGraph<&'a TestLogger>>,
pub next_routes: Mutex<VecDeque<(RouteParameters, Result<Route, LightningError>)>>,
pub scorer: &'a RwLock<TestScorer>,
impl<'a> TestRouter<'a> {
pub fn new(
network_graph: Arc<NetworkGraph<&'a TestLogger>>, logger: &'a TestLogger,
- scorer: &'a RwLock<TestScorer>
+ scorer: &'a RwLock<TestScorer>,
) -> Self {
+ let entropy_source = Arc::new(RandomBytes::new([42; 32]));
Self {
- router: DefaultRouter::new(network_graph.clone(), logger, [42u8; 32], scorer, ()),
+ router: DefaultRouter::new(network_graph.clone(), logger, entropy_source, scorer, ()),
network_graph,
next_routes: Mutex::new(VecDeque::new()),
scorer,
&self, payer: &PublicKey, params: &RouteParameters, first_hops: Option<&[&ChannelDetails]>,
inflight_htlcs: InFlightHtlcs
) -> Result<Route, msgs::LightningError> {
- if let Some((find_route_query, find_route_res)) = self.next_routes.lock().unwrap().pop_front() {
+ let route_res;
+ let next_route_opt = self.next_routes.lock().unwrap().pop_front();
+ if let Some((find_route_query, find_route_res)) = next_route_opt {
assert_eq!(find_route_query, *params);
if let Ok(ref route) = find_route_res {
assert_eq!(route.route_params, Some(find_route_query));
details: first_hops[idx],
payer_node_id: &node_id,
});
- scorer.channel_penalty_msat(&candidate, usage, &());
+ scorer.channel_penalty_msat(&candidate, usage, &Default::default());
continue;
}
}
info: directed,
short_channel_id: hop.short_channel_id,
});
- scorer.channel_penalty_msat(&candidate, usage, &());
+ scorer.channel_penalty_msat(&candidate, usage, &Default::default());
} else {
let target_node_id = NodeId::from_pubkey(&hop.pubkey);
let route_hint = RouteHintHop {
hint: &route_hint,
target_node_id: &target_node_id,
});
- scorer.channel_penalty_msat(&candidate, usage, &());
+ scorer.channel_penalty_msat(&candidate, usage, &Default::default());
}
prev_hop_node = &hop.pubkey;
}
}
}
- return find_route_res;
- }
+ route_res = find_route_res;
+ } else {
+ route_res = self.router.find_route(payer, params, first_hops, inflight_htlcs);
+ };
- self.router.find_route(payer, params, first_hops, inflight_htlcs)
+ if let Ok(route) = &route_res {
+ // Previously, `Route`s failed to round-trip through serialization due to a write/read
+ // mismatch. Thus, here we test all test-generated routes round-trip:
+ let ser = route.encode();
+ assert_eq!(Route::read(&mut &ser[..]).unwrap(), *route);
+ }
+ route_res
}
fn create_blinded_payment_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
+ T: secp256k1::Signing + secp256k1::Verification
>(
&self, recipient: PublicKey, first_hops: Vec<ChannelDetails>, tlvs: ReceiveTlvs,
- amount_msats: u64, entropy_source: &ES, secp_ctx: &Secp256k1<T>
+ amount_msats: u64, secp_ctx: &Secp256k1<T>,
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
self.router.create_blinded_payment_paths(
- recipient, first_hops, tlvs, amount_msats, entropy_source, secp_ctx
+ recipient, first_hops, tlvs, amount_msats, secp_ctx
)
}
}
}
fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
+ T: secp256k1::Signing + secp256k1::Verification
>(
- &self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
- secp_ctx: &Secp256k1<T>
+ &self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
- self.router.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
+ self.router.create_blinded_paths(recipient, peers, secp_ctx)
}
}
}
pub struct TestMessageRouter<'a> {
- inner: DefaultMessageRouter<Arc<NetworkGraph<&'a TestLogger>>, &'a TestLogger>,
+ inner: DefaultMessageRouter<Arc<NetworkGraph<&'a TestLogger>>, &'a TestLogger, &'a TestKeysInterface>,
}
impl<'a> TestMessageRouter<'a> {
- pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>) -> Self {
- Self { inner: DefaultMessageRouter::new(network_graph) }
+ pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>, entropy_source: &'a TestKeysInterface) -> Self {
+ Self { inner: DefaultMessageRouter::new(network_graph, entropy_source) }
}
}
self.inner.find_path(sender, peers, destination)
}
- fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
- &self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
- secp_ctx: &Secp256k1<T>
+ fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
+ &self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
- self.inner.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
+ self.inner.create_blinded_paths(recipient, peers, secp_ctx)
}
}
}
}
+#[cfg(test)]
struct JusticeTxData {
justice_tx: Transaction,
value: u64,
commitment_number: u64,
}
+#[cfg(test)]
pub(crate) struct WatchtowerPersister {
persister: TestPersister,
/// Upon a new commitment_signed, we'll get a
destination_script: ScriptBuf,
}
+#[cfg(test)]
impl WatchtowerPersister {
#[cfg(test)]
pub(crate) fn new(destination_script: ScriptBuf) -> Self {
}
}
+#[cfg(test)]
impl<Signer: sign::ecdsa::WriteableEcdsaChannelSigner> chainmonitor::Persist<Signer> for WatchtowerPersister {
fn persist_new_channel(&self, funding_txo: OutPoint,
data: &channelmonitor::ChannelMonitor<Signer>, id: MonitorUpdateId
}
res
}
+
+ fn archive_persisted_channel(&self, funding_txo: OutPoint) {
+ <TestPersister as chainmonitor::Persist<TestChannelSigner>>::archive_persisted_channel(&self.persister, funding_txo);
+ }
}
pub struct TestPersister {
}
ret
}
+
+ fn archive_persisted_channel(&self, funding_txo: OutPoint) {
+ // remove the channel from the offchain_monitor_updates map
+ match self.offchain_monitor_updates.lock().unwrap().remove(&funding_txo) {
+ Some(_) => {},
+ None => {
+ // If the channel was not in the offchain_monitor_updates map, it should be in the
+ // chain_sync_monitor_persistences map.
+ assert!(self.chain_sync_monitor_persistences.lock().unwrap().remove(&funding_txo).is_some());
+ }
+ };
+ }
}
pub struct TestStore {
}
}
+unsafe impl Sync for TestStore {}
+unsafe impl Send for TestStore {}
+
pub struct TestBroadcaster {
pub txn_broadcasted: Mutex<Vec<Transaction>>,
pub blocks: Arc<Mutex<Vec<(Block, u32)>>>,
fn handle_stfu(&self, _their_node_id: &PublicKey, msg: &msgs::Stfu) {
self.received_msg(wire::Message::Stfu(msg.clone()));
}
+ #[cfg(splicing)]
fn handle_splice(&self, _their_node_id: &PublicKey, msg: &msgs::Splice) {
self.received_msg(wire::Message::Splice(msg.clone()));
}
+ #[cfg(splicing)]
fn handle_splice_ack(&self, _their_node_id: &PublicKey, msg: &msgs::SpliceAck) {
self.received_msg(wire::Message::SpliceAck(msg.clone()));
}
+ #[cfg(splicing)]
fn handle_splice_locked(&self, _their_node_id: &PublicKey, msg: &msgs::SpliceLocked) {
self.received_msg(wire::Message::SpliceLocked(msg.clone()));
}
pub disable_revocation_policy_check: bool,
enforcement_states: Mutex<HashMap<[u8;32], Arc<Mutex<EnforcementState>>>>,
expectations: Mutex<Option<VecDeque<OnGetShutdownScriptpubkey>>>,
+ pub unavailable_signers: Mutex<HashSet<[u8; 32]>>,
}
impl EntropySource for TestKeysInterface {
fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> TestChannelSigner {
let keys = self.backing.derive_channel_signer(channel_value_satoshis, channel_keys_id);
let state = self.make_enforcement_state_cell(keys.commitment_seed);
- TestChannelSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check)
+ let signer = TestChannelSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check);
+ if self.unavailable_signers.lock().unwrap().contains(&channel_keys_id) {
+ signer.set_available(false);
+ }
+ signer
}
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::EcdsaSigner, msgs::DecodeError> {
disable_revocation_policy_check: false,
enforcement_states: Mutex::new(new_hash_map()),
expectations: Mutex::new(None),
+ unavailable_signers: Mutex::new(new_hash_set()),
}
}
}
pub fn derive_channel_keys(&self, channel_value_satoshis: u64, id: &[u8; 32]) -> TestChannelSigner {
- let keys = self.backing.derive_channel_keys(channel_value_satoshis, id);
- let state = self.make_enforcement_state_cell(keys.commitment_seed);
- TestChannelSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check)
+ self.derive_channel_signer(channel_value_satoshis, *id)
}
fn make_enforcement_state_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<EnforcementState>> {
watched_outputs: Mutex::new(new_hash_set()),
}
}
+ pub fn remove_watched_txn_and_outputs(&self, outpoint: OutPoint, script_pubkey: ScriptBuf) {
+ self.watched_outputs.lock().unwrap().remove(&(outpoint, script_pubkey.clone()));
+ self.watched_txn.lock().unwrap().remove(&(outpoint.txid, script_pubkey));
+ }
}
impl UtxoLookup for TestChainSource {