Add DecodeError::DangerousValue for decoding invalid channel managers
authorbenthecarman <benthecarman@live.com>
Wed, 27 Mar 2024 18:42:19 +0000 (13:42 -0500)
committerbenthecarman <benthecarman@live.com>
Thu, 28 Mar 2024 17:30:13 +0000 (12:30 -0500)
This would help distinguish different types of errors when deserialzing
a channel manager. InvalidValue was used previously but this could be
because it is an old serialization format, whereas DangerousValue is a
lot more clear on why the deserialization failed.

fuzz/src/router.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/msgs.rs
lightning/src/ln/peer_handler.rs
lightning/src/ln/reload_tests.rs

index bf94c910531573335f2db2594ce1df41304b0f3d..ad4373c4793bc704f66d6cc095b83a5e82013cf7 100644 (file)
@@ -157,6 +157,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                        msgs::DecodeError::ShortRead => panic!("We picked the length..."),
                                        msgs::DecodeError::Io(e) => panic!("{:?}", e),
                                        msgs::DecodeError::UnsupportedCompression => return,
+                                       msgs::DecodeError::DangerousValue => return,
                                }
                        }
                }}
index 546b317ee26ddf65b04ab64488c53520353c2ba0..cd9cfdda585aa7b9069130f59dd817fe6f04d484 100644 (file)
@@ -10918,7 +10918,7 @@ where
                                                }
                                        }
                                        if chan.get_latest_unblocked_monitor_update_id() > max_in_flight_update_id {
-                                               // If the channel is ahead of the monitor, return InvalidValue:
+                                               // If the channel is ahead of the monitor, return DangerousValue:
                                                log_error!(logger, "A ChannelMonitor is stale compared to the current ChannelManager! This indicates a potentially-critical violation of the chain::Watch API!");
                                                log_error!(logger, " The ChannelMonitor for channel {} is at update_id {} with update_id through {} in-flight",
                                                        chan.context.channel_id(), monitor.get_latest_update_id(), max_in_flight_update_id);
@@ -10927,7 +10927,7 @@ where
                                                log_error!(logger, " client applications must ensure that ChannelMonitor data is always available and the latest to avoid funds loss!");
                                                log_error!(logger, " Without the latest ChannelMonitor we cannot continue without risking funds.");
                                                log_error!(logger, " Please ensure the chain::Watch API requirements are met and file a bug report at https://github.com/lightningdevkit/rust-lightning");
-                                               return Err(DecodeError::InvalidValue);
+                                               return Err(DecodeError::DangerousValue);
                                        }
                                } else {
                                        // We shouldn't have persisted (or read) any unfunded channel types so none should have been
index 034b2451693975f04da3a310b432be6b2ea4de85..6a278046defeae25753664cb77cfbdaf37430191 100644 (file)
@@ -91,6 +91,16 @@ pub enum DecodeError {
        Io(io::ErrorKind),
        /// The message included zlib-compressed values, which we don't support.
        UnsupportedCompression,
+       /// Value is validly encoded but is dangerous to use.
+       ///
+       /// This is used for things like [`ChannelManager`] deserialization where we want to ensure
+       /// that we don't use a [`ChannelManager`] which is in out of sync with the [`ChannelMonitor`].
+       /// This indicates that there is a critical implementation flaw in the storage implementation
+       /// and it's unsafe to continue.
+       ///
+       /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
+       /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
+       DangerousValue,
 }
 
 /// An [`init`] message to be sent to or received from a peer.
@@ -1796,6 +1806,7 @@ impl fmt::Display for DecodeError {
                        DecodeError::BadLengthDescriptor => f.write_str("A length descriptor in the packet didn't describe the later data correctly"),
                        DecodeError::Io(ref e) => fmt::Debug::fmt(e, f),
                        DecodeError::UnsupportedCompression => f.write_str("We don't support receiving messages with zlib-compressed fields"),
+                       DecodeError::DangerousValue => f.write_str("Value would be dangerous to continue execution with"),
                }
        }
 }
index 11cdd906abad191ec163c7b0a55766b3101fb223..19f505b2c0d3c95f26c49c5e0d3c0fa925ad1ca2 100644 (file)
@@ -1551,6 +1551,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                                                                                                }
                                                                                                (msgs::DecodeError::BadLengthDescriptor, _) => return Err(PeerHandleError { }),
                                                                                                (msgs::DecodeError::Io(_), _) => return Err(PeerHandleError { }),
+                                                                                               (msgs::DecodeError::DangerousValue, _) => return Err(PeerHandleError { }),
                                                                                        }
                                                                                }
                                                                        };
index 4422af1e8c70c63a81b93ece1aac38e2553d00a0..fa216bc15f4355f2b9b7fcd55cf844061451c1db 100644 (file)
@@ -412,7 +412,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
        }
 
        let mut nodes_0_read = &nodes_0_serialized[..];
-       if let Err(msgs::DecodeError::InvalidValue) =
+       if let Err(msgs::DecodeError::DangerousValue) =
                <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
                default_config: UserConfig::default(),
                entropy_source: keys_manager,