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::chain::channelmonitor;
use crate::chain::channelmonitor::MonitorEvent;
use crate::chain::transaction::OutPoint;
use crate::events::bump_transaction::{WalletSource, Utxo};
use crate::ln::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;
&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));
}
}
}
- 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<
pub struct TestChainMonitor<'a> {
pub added_monitors: Mutex<Vec<(OutPoint, channelmonitor::ChannelMonitor<TestChannelSigner>)>>,
pub monitor_updates: Mutex<HashMap<ChannelId, Vec<channelmonitor::ChannelMonitorUpdate>>>,
- pub latest_monitor_update_id: Mutex<HashMap<ChannelId, (OutPoint, u64, MonitorUpdateId)>>,
+ pub latest_monitor_update_id: Mutex<HashMap<ChannelId, (OutPoint, u64, u64)>>,
pub chain_monitor: chainmonitor::ChainMonitor<TestChannelSigner, &'a TestChainSource, &'a dyn chaininterface::BroadcasterInterface, &'a TestFeeEstimator, &'a TestLogger, &'a dyn chainmonitor::Persist<TestChannelSigner>>,
pub keys_manager: &'a TestKeysInterface,
/// If this is set to Some(), the next update_channel call (not watch_channel) must be a
&mut io::Cursor::new(&w.0), (self.keys_manager, self.keys_manager)).unwrap().1;
assert!(new_monitor == monitor);
self.latest_monitor_update_id.lock().unwrap().insert(monitor.channel_id(),
- (funding_txo, monitor.get_latest_update_id(), MonitorUpdateId::from_new_monitor(&monitor)));
+ (funding_txo, monitor.get_latest_update_id(), monitor.get_latest_update_id()));
self.added_monitors.lock().unwrap().push((funding_txo, monitor));
self.chain_monitor.watch_channel(funding_txo, new_monitor)
}
}
self.latest_monitor_update_id.lock().unwrap().insert(channel_id,
- (funding_txo, update.update_id, MonitorUpdateId::from_monitor_update(update)));
+ (funding_txo, update.update_id, update.update_id));
let update_res = self.chain_monitor.update_channel(funding_txo, update);
// At every point where we get a monitor update, we should be able to send a useful monitor
// to a watchtower and disk...
}
}
+#[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
+ data: &channelmonitor::ChannelMonitor<Signer>
) -> chain::ChannelMonitorUpdateStatus {
- let res = self.persister.persist_new_channel(funding_txo, data, id);
+ let res = self.persister.persist_new_channel(funding_txo, data);
assert!(self.unsigned_justice_tx_data.lock().unwrap()
.insert(funding_txo, VecDeque::new()).is_none());
fn update_persisted_channel(
&self, funding_txo: OutPoint, update: Option<&channelmonitor::ChannelMonitorUpdate>,
- data: &channelmonitor::ChannelMonitor<Signer>, update_id: MonitorUpdateId
+ data: &channelmonitor::ChannelMonitor<Signer>
) -> chain::ChannelMonitorUpdateStatus {
- let res = self.persister.update_persisted_channel(funding_txo, update, data, update_id);
+ let res = self.persister.update_persisted_channel(funding_txo, update, data);
if let Some(update) = update {
let commitment_txs = data.counterparty_commitment_txs_from_update(update);
}
res
}
+
+ fn archive_persisted_channel(&self, funding_txo: OutPoint) {
+ <TestPersister as chainmonitor::Persist<TestChannelSigner>>::archive_persisted_channel(&self.persister, funding_txo);
+ }
}
pub struct TestPersister {
/// returned.
pub update_rets: Mutex<VecDeque<chain::ChannelMonitorUpdateStatus>>,
/// When we get an update_persisted_channel call with no ChannelMonitorUpdate, we insert the
- /// MonitorUpdateId here.
- pub chain_sync_monitor_persistences: Mutex<HashMap<OutPoint, HashSet<MonitorUpdateId>>>,
+ /// MonitorId here.
+ pub chain_sync_monitor_persistences: Mutex<VecDeque<OutPoint>>,
/// When we get an update_persisted_channel call *with* a ChannelMonitorUpdate, we insert the
- /// MonitorUpdateId here.
- pub offchain_monitor_updates: Mutex<HashMap<OutPoint, HashSet<MonitorUpdateId>>>,
+ /// [`ChannelMonitor::get_latest_update_id`] here.
+ ///
+ /// [`ChannelMonitor`]: channelmonitor::ChannelMonitor
+ pub offchain_monitor_updates: Mutex<HashMap<OutPoint, HashSet<u64>>>,
}
impl TestPersister {
pub fn new() -> Self {
Self {
update_rets: Mutex::new(VecDeque::new()),
- chain_sync_monitor_persistences: Mutex::new(new_hash_map()),
+ chain_sync_monitor_persistences: Mutex::new(VecDeque::new()),
offchain_monitor_updates: Mutex::new(new_hash_map()),
}
}
}
}
impl<Signer: sign::ecdsa::WriteableEcdsaChannelSigner> chainmonitor::Persist<Signer> for TestPersister {
- fn persist_new_channel(&self, _funding_txo: OutPoint, _data: &channelmonitor::ChannelMonitor<Signer>, _id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
+ fn persist_new_channel(&self, _funding_txo: OutPoint, _data: &channelmonitor::ChannelMonitor<Signer>) -> chain::ChannelMonitorUpdateStatus {
if let Some(update_ret) = self.update_rets.lock().unwrap().pop_front() {
return update_ret
}
chain::ChannelMonitorUpdateStatus::Completed
}
- fn update_persisted_channel(&self, funding_txo: OutPoint, _update: Option<&channelmonitor::ChannelMonitorUpdate>, _data: &channelmonitor::ChannelMonitor<Signer>, update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
+ fn update_persisted_channel(&self, funding_txo: OutPoint, update: Option<&channelmonitor::ChannelMonitorUpdate>, _data: &channelmonitor::ChannelMonitor<Signer>) -> chain::ChannelMonitorUpdateStatus {
let mut ret = chain::ChannelMonitorUpdateStatus::Completed;
if let Some(update_ret) = self.update_rets.lock().unwrap().pop_front() {
ret = update_ret;
}
- let is_chain_sync = if let UpdateOrigin::ChainSync(_) = update_id.contents { true } else { false };
- if is_chain_sync {
- self.chain_sync_monitor_persistences.lock().unwrap().entry(funding_txo).or_insert(new_hash_set()).insert(update_id);
+
+ if let Some(update) = update {
+ self.offchain_monitor_updates.lock().unwrap().entry(funding_txo).or_insert(new_hash_set()).insert(update.update_id);
} else {
- self.offchain_monitor_updates.lock().unwrap().entry(funding_txo).or_insert(new_hash_set()).insert(update_id);
+ self.chain_sync_monitor_persistences.lock().unwrap().push_back(funding_txo);
}
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.
+ self.chain_sync_monitor_persistences.lock().unwrap().retain(|x| x != &funding_txo);
+ }
+ };
+ }
}
pub struct TestStore {
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 {