Run chanmon_consistency_test with anchor outputs channels
[rust-lightning] / fuzz / src / chanmon_consistency.rs
index 309faaa95522f0773080cd9a82bd0aa822f6165b..767d7b4e1a7f58321798849fdde28bf46b9833d7 100644 (file)
@@ -44,7 +44,9 @@ use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
 use lightning::ln::msgs::{self, CommitmentUpdate, ChannelMessageHandler, DecodeError, UpdateAddHTLC, Init};
 use lightning::ln::script::ShutdownScript;
 use lightning::ln::functional_test_utils::*;
-use lightning::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
+use lightning::offers::invoice::UnsignedBolt12Invoice;
+use lightning::offers::invoice_request::UnsignedInvoiceRequest;
+use lightning::util::test_channel_signer::{TestChannelSigner, EnforcementState};
 use lightning::util::errors::APIError;
 use lightning::util::logger::Logger;
 use lightning::util::config::UserConfig;
@@ -57,6 +59,7 @@ use crate::utils::test_persister::TestPersister;
 use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1};
 use bitcoin::secp256k1::ecdh::SharedSecret;
 use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
+use bitcoin::secp256k1::schnorr;
 
 use std::mem;
 use std::cmp::{self, Ordering};
@@ -77,9 +80,10 @@ impl FeeEstimator for FuzzEstimator {
                // always return a HighPriority feerate here which is >= the maximum Normal feerate and a
                // Background feerate which is <= the minimum Normal feerate.
                match conf_target {
-                       ConfirmationTarget::HighPriority => MAX_FEE,
-                       ConfirmationTarget::Background => 253,
-                       ConfirmationTarget::Normal => cmp::min(self.ret_val.load(atomic::Ordering::Acquire), MAX_FEE),
+                       ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee => MAX_FEE * 10,
+                       ConfirmationTarget::OnChainSweep => MAX_FEE,
+                       ConfirmationTarget::ChannelCloseMinimum|ConfirmationTarget::AnchorChannelFee|ConfirmationTarget::MinAllowedAnchorChannelRemoteFee|ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee => 253,
+                       ConfirmationTarget::NonAnchorChannelFee => cmp::min(self.ret_val.load(atomic::Ordering::Acquire), MAX_FEE),
                }
        }
 }
@@ -89,7 +93,7 @@ struct FuzzRouter {}
 impl Router for FuzzRouter {
        fn find_route(
                &self, _payer: &PublicKey, _params: &RouteParameters, _first_hops: Option<&[&ChannelDetails]>,
-               _inflight_htlcs: &InFlightHtlcs
+               _inflight_htlcs: InFlightHtlcs
        ) -> Result<Route, msgs::LightningError> {
                Err(msgs::LightningError {
                        err: String::from("Not implemented"),
@@ -115,14 +119,13 @@ struct TestChainMonitor {
        pub logger: Arc<dyn Logger>,
        pub keys: Arc<KeyProvider>,
        pub persister: Arc<TestPersister>,
-       pub chain_monitor: Arc<chainmonitor::ChainMonitor<EnforcingSigner, Arc<dyn chain::Filter>, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<TestPersister>>>,
+       pub chain_monitor: Arc<chainmonitor::ChainMonitor<TestChannelSigner, Arc<dyn chain::Filter>, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<TestPersister>>>,
        // 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
        // monitor implying we are not able to punish misbehaving counterparties). Because this test
        // "fails" if we ever force-close a channel, we avoid doing so, always saving the latest
        // fully-serialized monitor state here, as well as the corresponding update_id.
        pub latest_monitors: Mutex<HashMap<OutPoint, (u64, Vec<u8>)>>,
-       pub should_update_manager: atomic::AtomicBool,
 }
 impl TestChainMonitor {
        pub fn new(broadcaster: Arc<TestBroadcaster>, logger: Arc<dyn Logger>, feeest: Arc<FuzzEstimator>, persister: Arc<TestPersister>, keys: Arc<KeyProvider>) -> Self {
@@ -132,18 +135,16 @@ impl TestChainMonitor {
                        keys,
                        persister,
                        latest_monitors: Mutex::new(HashMap::new()),
-                       should_update_manager: atomic::AtomicBool::new(false),
                }
        }
 }
-impl chain::Watch<EnforcingSigner> for TestChainMonitor {
-       fn watch_channel(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<EnforcingSigner>) -> chain::ChannelMonitorUpdateStatus {
+impl chain::Watch<TestChannelSigner> for TestChainMonitor {
+       fn watch_channel(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<TestChannelSigner>) -> Result<chain::ChannelMonitorUpdateStatus, ()> {
                let mut ser = VecWriter(Vec::new());
                monitor.write(&mut ser).unwrap();
                if let Some(_) = self.latest_monitors.lock().unwrap().insert(funding_txo, (monitor.get_latest_update_id(), ser.0)) {
                        panic!("Already had monitor pre-watch_channel");
                }
-               self.should_update_manager.store(true, atomic::Ordering::Relaxed);
                self.chain_monitor.watch_channel(funding_txo, monitor)
        }
 
@@ -153,13 +154,12 @@ impl chain::Watch<EnforcingSigner> for TestChainMonitor {
                        hash_map::Entry::Occupied(entry) => entry,
                        hash_map::Entry::Vacant(_) => panic!("Didn't have monitor on update call"),
                };
-               let deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::
+               let deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::
                        read(&mut Cursor::new(&map_entry.get().1), (&*self.keys, &*self.keys)).unwrap().1;
-               deserialized_monitor.update_monitor(update, &&TestBroadcaster{}, &FuzzEstimator { ret_val: atomic::AtomicU32::new(253) }, &self.logger).unwrap();
+               deserialized_monitor.update_monitor(update, &&TestBroadcaster{}, &&FuzzEstimator { ret_val: atomic::AtomicU32::new(253) }, &self.logger).unwrap();
                let mut ser = VecWriter(Vec::new());
                deserialized_monitor.write(&mut ser).unwrap();
                map_entry.insert((update.update_id, ser.0));
-               self.should_update_manager.store(true, atomic::Ordering::Relaxed);
                self.chain_monitor.update_channel(funding_txo, update)
        }
 
@@ -211,6 +211,18 @@ impl NodeSigner for KeyProvider {
                unreachable!()
        }
 
+       fn sign_bolt12_invoice_request(
+               &self, _invoice_request: &UnsignedInvoiceRequest
+       ) -> Result<schnorr::Signature, ()> {
+               unreachable!()
+       }
+
+       fn sign_bolt12_invoice(
+               &self, _invoice: &UnsignedBolt12Invoice,
+       ) -> Result<schnorr::Signature, ()> {
+               unreachable!()
+       }
+
        fn sign_gossip_message(&self, msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
                let msg_hash = Message::from_slice(&Sha256dHash::hash(&msg.encode()[..])[..]).map_err(|_| ())?;
                let secp_ctx = Secp256k1::signing_only();
@@ -219,7 +231,7 @@ impl NodeSigner for KeyProvider {
 }
 
 impl SignerProvider for KeyProvider {
-       type Signer = EnforcingSigner;
+       type Signer = TestChannelSigner;
 
        fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] {
                let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed) as u8;
@@ -242,7 +254,7 @@ impl SignerProvider for KeyProvider {
                        channel_keys_id,
                );
                let revoked_commitment = self.make_enforcement_state_cell(keys.commitment_seed);
-               EnforcingSigner::new_with_revoked(keys, revoked_commitment, false)
+               TestChannelSigner::new_with_revoked(keys, revoked_commitment, false)
        }
 
        fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, DecodeError> {
@@ -251,7 +263,7 @@ impl SignerProvider for KeyProvider {
                let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?;
                let state = self.make_enforcement_state_cell(inner.commitment_seed);
 
-               Ok(EnforcingSigner {
+               Ok(TestChannelSigner {
                        inner,
                        state,
                        disable_revocation_policy_check: false,
@@ -360,8 +372,9 @@ fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, p
                        channel_features: dest.channel_features(),
                        fee_msat: amt,
                        cltv_expiry_delta: 200,
+                       maybe_announced_channel: true,
                }], blinded_tail: None }],
-               payment_params: None,
+               route_params: None,
        }, payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_id)) {
                check_payment_err(err, amt > max_value_sendable || amt < min_value_sendable);
                false
@@ -394,15 +407,17 @@ fn send_hop_payment(source: &ChanMan, middle: &ChanMan, middle_chan_id: u64, des
                        channel_features: middle.channel_features(),
                        fee_msat: first_hop_fee,
                        cltv_expiry_delta: 100,
-               },RouteHop {
+                       maybe_announced_channel: true,
+               }, RouteHop {
                        pubkey: dest.get_our_node_id(),
                        node_features: dest.node_features(),
                        short_channel_id: dest_chan_id,
                        channel_features: dest.channel_features(),
                        fee_msat: amt,
                        cltv_expiry_delta: 200,
+                       maybe_announced_channel: true,
                }], blinded_tail: None }],
-               payment_params: None,
+               route_params: None,
        }, payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_id)) {
                let sent_amt = amt + first_hop_fee;
                check_payment_err(err, sent_amt < min_value_sendable || sent_amt > max_value_sendable);
@@ -417,7 +432,7 @@ fn send_hop_payment(source: &ChanMan, middle: &ChanMan, middle_chan_id: u64, des
 }
 
 #[inline]
-pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
+pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
        let out = SearchingOutput::new(underlying_out);
        let broadcast = Arc::new(TestBroadcaster{});
        let router = FuzzRouter {};
@@ -435,12 +450,17 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        let mut config = UserConfig::default();
                        config.channel_config.forwarding_fee_proportional_millionths = 0;
                        config.channel_handshake_config.announced_channel = true;
+                       if anchors {
+                               config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
+                               config.manually_accept_inbound_channels = true;
+                       }
                        let network = Network::Bitcoin;
+                       let best_block_timestamp = genesis_block(network).header.time;
                        let params = ChainParameters {
                                network,
                                best_block: BestBlock::from_network(network),
                        };
-                       (ChannelManager::new($fee_estimator.clone(), monitor.clone(), broadcast.clone(), &router, Arc::clone(&logger), keys_manager.clone(), keys_manager.clone(), keys_manager.clone(), config, params),
+                       (ChannelManager::new($fee_estimator.clone(), monitor.clone(), broadcast.clone(), &router, Arc::clone(&logger), keys_manager.clone(), keys_manager.clone(), keys_manager.clone(), config, params, best_block_timestamp),
                        monitor, keys_manager)
                } }
        }
@@ -457,11 +477,15 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        let mut config = UserConfig::default();
                        config.channel_config.forwarding_fee_proportional_millionths = 0;
                        config.channel_handshake_config.announced_channel = true;
+                       if anchors {
+                               config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
+                               config.manually_accept_inbound_channels = true;
+                       }
 
                        let mut monitors = HashMap::new();
                        let mut old_monitors = $old_monitors.latest_monitors.lock().unwrap();
                        for (outpoint, (update_id, monitor_ser)) in old_monitors.drain() {
-                               monitors.insert(outpoint, <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(&monitor_ser), (&*$keys_manager, &*$keys_manager)).expect("Failed to read monitor").1);
+                               monitors.insert(outpoint, <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(&mut Cursor::new(&monitor_ser), (&*$keys_manager, &*$keys_manager)).expect("Failed to read monitor").1);
                                chain_monitor.latest_monitors.lock().unwrap().insert(outpoint, (update_id, monitor_ser));
                        }
                        let mut monitor_refs = HashMap::new();
@@ -485,7 +509,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        let res = (<(BlockHash, ChanMan)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, chain_monitor.clone());
                        for (funding_txo, mon) in monitors.drain() {
                                assert_eq!(chain_monitor.chain_monitor.watch_channel(funding_txo, mon),
-                                       ChannelMonitorUpdateStatus::Completed);
+                                       Ok(ChannelMonitorUpdateStatus::Completed));
                        }
                        res
                } }
@@ -493,7 +517,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
 
        let mut channel_txn = Vec::new();
        macro_rules! make_channel {
-               ($source: expr, $dest: expr, $chan_id: expr) => { {
+               ($source: expr, $dest: expr, $dest_keys_manager: expr, $chan_id: expr) => { {
                        $source.peer_connected(&$dest.get_our_node_id(), &Init {
                                features: $dest.init_features(), networks: None, remote_network_address: None
                        }, true).unwrap();
@@ -512,6 +536,22 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
 
                        $dest.handle_open_channel(&$source.get_our_node_id(), &open_channel);
                        let accept_channel = {
+                               if anchors {
+                                       let events = $dest.get_and_clear_pending_events();
+                                       assert_eq!(events.len(), 1);
+                                       if let events::Event::OpenChannelRequest {
+                                               ref temporary_channel_id, ref counterparty_node_id, ..
+                                       } = events[0] {
+                                               let mut random_bytes = [0u8; 16];
+                                               random_bytes.copy_from_slice(&$dest_keys_manager.get_secure_random_bytes()[..16]);
+                                               let user_channel_id = u128::from_be_bytes(random_bytes);
+                                               $dest.accept_inbound_channel(
+                                                       temporary_channel_id,
+                                                       counterparty_node_id,
+                                                       user_channel_id,
+                                               ).unwrap();
+                                       } else { panic!("Wrong event type"); }
+                               }
                                let events = $dest.get_and_clear_pending_msg_events();
                                assert_eq!(events.len(), 1);
                                if let events::MessageSendEvent::SendAcceptChannel { ref msg, .. } = events[0] {
@@ -623,8 +663,8 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
 
        let mut nodes = [node_a, node_b, node_c];
 
-       let chan_1_funding = make_channel!(nodes[0], nodes[1], 0);
-       let chan_2_funding = make_channel!(nodes[1], nodes[2], 1);
+       let chan_1_funding = make_channel!(nodes[0], nodes[1], keys_manager_b, 0);
+       let chan_2_funding = make_channel!(nodes[1], nodes[2], keys_manager_c, 1);
 
        for node in nodes.iter() {
                confirm_txn!(node);
@@ -1085,11 +1125,9 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                                if !chan_a_disconnected {
                                        nodes[1].peer_disconnected(&nodes[0].get_our_node_id());
                                        chan_a_disconnected = true;
-                                       drain_msg_events_on_disconnect!(0);
-                               }
-                               if monitor_a.should_update_manager.load(atomic::Ordering::Relaxed) {
-                                       node_a_ser.0.clear();
-                                       nodes[0].write(&mut node_a_ser).unwrap();
+                                       push_excess_b_events!(nodes[1].get_and_clear_pending_msg_events().drain(..), Some(0));
+                                       ab_events.clear();
+                                       ba_events.clear();
                                }
                                let (new_node_a, new_monitor_a) = reload_node!(node_a_ser, 0, monitor_a, keys_manager_a, fee_est_a);
                                nodes[0] = new_node_a;
@@ -1118,11 +1156,9 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                                if !chan_b_disconnected {
                                        nodes[1].peer_disconnected(&nodes[2].get_our_node_id());
                                        chan_b_disconnected = true;
-                                       drain_msg_events_on_disconnect!(2);
-                               }
-                               if monitor_c.should_update_manager.load(atomic::Ordering::Relaxed) {
-                                       node_c_ser.0.clear();
-                                       nodes[2].write(&mut node_c_ser).unwrap();
+                                       push_excess_b_events!(nodes[1].get_and_clear_pending_msg_events().drain(..), Some(2));
+                                       bc_events.clear();
+                                       cb_events.clear();
                                }
                                let (new_node_c, new_monitor_c) = reload_node!(node_c_ser, 2, monitor_c, keys_manager_c, fee_est_c);
                                nodes[2] = new_node_c;
@@ -1288,15 +1324,18 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        _ => test_return!(),
                }
 
-               node_a_ser.0.clear();
-               nodes[0].write(&mut node_a_ser).unwrap();
-               monitor_a.should_update_manager.store(false, atomic::Ordering::Relaxed);
-               node_b_ser.0.clear();
-               nodes[1].write(&mut node_b_ser).unwrap();
-               monitor_b.should_update_manager.store(false, atomic::Ordering::Relaxed);
-               node_c_ser.0.clear();
-               nodes[2].write(&mut node_c_ser).unwrap();
-               monitor_c.should_update_manager.store(false, atomic::Ordering::Relaxed);
+               if nodes[0].get_and_clear_needs_persistence() == true {
+                       node_a_ser.0.clear();
+                       nodes[0].write(&mut node_a_ser).unwrap();
+               }
+               if nodes[1].get_and_clear_needs_persistence() == true {
+                       node_b_ser.0.clear();
+                       nodes[1].write(&mut node_b_ser).unwrap();
+               }
+               if nodes[2].get_and_clear_needs_persistence() == true {
+                       node_c_ser.0.clear();
+                       nodes[2].write(&mut node_c_ser).unwrap();
+               }
        }
 }
 
@@ -1323,10 +1362,12 @@ impl<O: Output> SearchingOutput<O> {
 }
 
 pub fn chanmon_consistency_test<Out: Output>(data: &[u8], out: Out) {
-       do_test(data, out);
+       do_test(data, out.clone(), false);
+       do_test(data, out, true);
 }
 
 #[no_mangle]
 pub extern "C" fn chanmon_consistency_run(data: *const u8, datalen: usize) {
-       do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull{});
+       do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull{}, false);
+       do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull{}, true);
 }