use bitcoin::blockdata::opcodes;
use bitcoin::network::constants::Network;
-use bitcoin_hashes::Hash as TraitImport;
-use bitcoin_hashes::hash160::Hash as Hash160;
-use bitcoin_hashes::sha256::Hash as Sha256;
-use bitcoin_hashes::sha256d::Hash as Sha256d;
+use bitcoin::hashes::Hash as TraitImport;
+use bitcoin::hashes::hash160::Hash as Hash160;
+use bitcoin::hashes::sha256::Hash as Sha256;
+use bitcoin::hashes::sha256d::Hash as Sha256d;
use lightning::chain::chaininterface;
use lightning::chain::transaction::OutPoint;
use lightning::chain::keysinterface::{KeysInterface, InMemoryChannelKeys};
use lightning::ln::channelmonitor;
use lightning::ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, HTLCUpdate};
-use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, ChannelManagerReadArgs};
+use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, ChannelManagerReadArgs};
use lightning::ln::router::{Route, RouteHop};
use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, UpdateAddHTLC, Init};
}
}
-pub struct TestChannelMonitor {
+struct TestChannelMonitor {
pub logger: Arc<dyn Logger>,
- pub simple_monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<BroadcasterInterface>, Arc<FeeEstimator>>>,
+ pub simple_monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>>>,
pub update_ret: Mutex<Result<(), channelmonitor::ChannelMonitorUpdateErr>>,
// If we reload a node with an old copy of ChannelMonitors, the ChannelManager deserialization
// logic will automatically force-close our channels for us (as we don't have an up-to-date
pub should_update_manager: atomic::AtomicBool,
}
impl TestChannelMonitor {
- pub fn new(chain_monitor: Arc<dyn chaininterface::ChainWatchInterface>, broadcaster: Arc<dyn chaininterface::BroadcasterInterface>, logger: Arc<dyn Logger>, feeest: Arc<FeeEstimator>) -> Self {
+ pub fn new(chain_monitor: Arc<dyn chaininterface::ChainWatchInterface>, broadcaster: Arc<TestBroadcaster>, logger: Arc<dyn Logger>, feeest: Arc<FuzzEstimator>) -> Self {
Self {
simple_monitor: Arc::new(channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger.clone(), feeest)),
logger,
}
#[inline]
-pub fn do_test(data: &[u8]) {
+pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
let fee_est = Arc::new(FuzzEstimator{});
let broadcast = Arc::new(TestBroadcaster{});
macro_rules! make_node {
($node_id: expr) => { {
- let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string()));
+ let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
let monitor = Arc::new(TestChannelMonitor::new(watch.clone(), broadcast.clone(), logger.clone(), fee_est.clone()));
macro_rules! reload_node {
($ser: expr, $node_id: expr, $old_monitors: expr) => { {
- let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string()));
+ let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
let monitor = Arc::new(TestChannelMonitor::new(watch.clone(), broadcast.clone(), logger.clone(), fee_est.clone()));
($source: expr, $dest: expr) => { {
let payment_hash = Sha256::hash(&[payment_id; 1]);
payment_id = payment_id.wrapping_add(1);
- if let Err(_) = $source.send_payment(Route {
- hops: vec![RouteHop {
+ if let Err(_) = $source.send_payment(&Route {
+ paths: vec![vec![RouteHop {
pubkey: $dest.0.get_our_node_id(),
node_features: NodeFeatures::empty(),
short_channel_id: $dest.1,
channel_features: ChannelFeatures::empty(),
fee_msat: 5000000,
cltv_expiry_delta: 200,
- }],
- }, PaymentHash(payment_hash.into_inner())) {
+ }]],
+ }, PaymentHash(payment_hash.into_inner()), &None) {
// Probably ran out of funds
test_return!();
}
($source: expr, $middle: expr, $dest: expr) => { {
let payment_hash = Sha256::hash(&[payment_id; 1]);
payment_id = payment_id.wrapping_add(1);
- if let Err(_) = $source.send_payment(Route {
- hops: vec![RouteHop {
+ if let Err(_) = $source.send_payment(&Route {
+ paths: vec![vec![RouteHop {
pubkey: $middle.0.get_our_node_id(),
node_features: NodeFeatures::empty(),
short_channel_id: $middle.1,
channel_features: ChannelFeatures::empty(),
fee_msat: 5000000,
cltv_expiry_delta: 200,
- }],
- }, PaymentHash(payment_hash.into_inner())) {
+ }]],
+ }, PaymentHash(payment_hash.into_inner()), &None) {
+ // Probably ran out of funds
+ test_return!();
+ }
+ } }
+ }
+ macro_rules! send_payment_with_secret {
+ ($source: expr, $middle: expr, $dest: expr) => { {
+ let payment_hash = Sha256::hash(&[payment_id; 1]);
+ payment_id = payment_id.wrapping_add(1);
+ let payment_secret = Sha256::hash(&[payment_id; 1]);
+ payment_id = payment_id.wrapping_add(1);
+ if let Err(_) = $source.send_payment(&Route {
+ paths: vec![vec![RouteHop {
+ pubkey: $middle.0.get_our_node_id(),
+ node_features: NodeFeatures::empty(),
+ short_channel_id: $middle.1,
+ channel_features: ChannelFeatures::empty(),
+ fee_msat: 50000,
+ cltv_expiry_delta: 100,
+ },RouteHop {
+ pubkey: $dest.0.get_our_node_id(),
+ node_features: NodeFeatures::empty(),
+ short_channel_id: $dest.1,
+ channel_features: ChannelFeatures::empty(),
+ fee_msat: 5000000,
+ cltv_expiry_delta: 200,
+ }],vec![RouteHop {
+ pubkey: $middle.0.get_our_node_id(),
+ node_features: NodeFeatures::empty(),
+ short_channel_id: $middle.1,
+ channel_features: ChannelFeatures::empty(),
+ fee_msat: 50000,
+ cltv_expiry_delta: 100,
+ },RouteHop {
+ pubkey: $dest.0.get_our_node_id(),
+ node_features: NodeFeatures::empty(),
+ short_channel_id: $dest.1,
+ channel_features: ChannelFeatures::empty(),
+ fee_msat: 5000000,
+ cltv_expiry_delta: 200,
+ }]],
+ }, PaymentHash(payment_hash.into_inner()), &Some(PaymentSecret(payment_secret.into_inner()))) {
// Probably ran out of funds
test_return!();
}
});
for event in events.drain(..) {
match event {
- events::Event::PaymentReceived { payment_hash, .. } => {
+ events::Event::PaymentReceived { payment_hash, payment_secret, .. } => {
if claim_set.insert(payment_hash.0) {
if $fail {
- assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
+ assert!(nodes[$node].fail_htlc_backwards(&payment_hash, &payment_secret));
} else {
- assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), 5_000_000));
+ assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), &payment_secret, 5_000_000));
}
}
},
nodes[2] = node_c.clone();
monitor_c = new_monitor_c;
},
+ 0x22 => send_payment_with_secret!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)),
+ 0x23 => send_payment_with_secret!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)),
// 0x24 defined above
_ => test_return!(),
}
}
}
+pub fn chanmon_consistency_test<Out: test_logger::Output>(data: &[u8], out: Out) {
+ do_test(data, out);
+}
+
#[no_mangle]
pub extern "C" fn chanmon_consistency_run(data: *const u8, datalen: usize) {
- do_test(unsafe { std::slice::from_raw_parts(data, datalen) });
+ do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull{});
}