From 45d4d26987666c45832814649233462d9d194c62 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 25 Nov 2020 12:23:47 -0500 Subject: [PATCH] Add a new method `read_chan_signer` to `KeysInterface` This adds a new method to the general cross-channel `KeysInterface` which requires it to handle the deserialization of per-channel signer objects. This allows the deserialization of per-channel signers to have more context available, which, in the case of the C bindings, includes the actual KeysInterface information itself. --- fuzz/src/chanmon_consistency.rs | 6 +++++- fuzz/src/full_stack.rs | 8 +++++++- lightning/src/chain/keysinterface.rs | 12 ++++++++++++ lightning/src/ln/channel.rs | 3 ++- lightning/src/ln/functional_tests.rs | 2 +- lightning/src/util/test_utils.rs | 4 ++++ 6 files changed, 31 insertions(+), 4 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 732f0f5b1..06bcfa4b7 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -37,7 +37,7 @@ use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, use lightning::chain::keysinterface::{KeysInterface, InMemoryChannelKeys}; use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, PaymentSendFailure, ChannelManagerReadArgs}; use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; -use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, UpdateAddHTLC, Init}; +use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, DecodeError, ErrorAction, UpdateAddHTLC, Init}; use lightning::util::enforcing_trait_impls::EnforcingChannelKeys; use lightning::util::errors::APIError; use lightning::util::events; @@ -184,6 +184,10 @@ impl KeysInterface for KeyProvider { let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed); [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, id, 11, self.node_id] } + + fn read_chan_signer(&self, data: &[u8]) -> Result { + EnforcingChannelKeys::read(&mut std::io::Cursor::new(data)) + } } #[inline] diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 6375d0765..915a6cba1 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -33,12 +33,14 @@ use lightning::chain::transaction::OutPoint; use lightning::chain::keysinterface::{InMemoryChannelKeys, KeysInterface}; use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret}; use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor}; +use lightning::ln::msgs::DecodeError; use lightning::routing::router::get_route; use lightning::routing::network_graph::NetGraphMsgHandler; +use lightning::util::config::UserConfig; use lightning::util::events::{EventsProvider,Event}; use lightning::util::enforcing_trait_impls::EnforcingChannelKeys; use lightning::util::logger::Logger; -use lightning::util::config::UserConfig; +use lightning::util::ser::Readable; use utils::test_logger; use utils::test_persister::TestPersister; @@ -299,6 +301,10 @@ impl KeysInterface for KeyProvider { [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8] } + + fn read_chan_signer(&self, data: &[u8]) -> Result { + EnforcingChannelKeys::read(&mut std::io::Cursor::new(data)) + } } #[inline] diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index 47ad84bbc..4a3a937a5 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -344,6 +344,14 @@ pub trait KeysInterface: Send + Sync { /// onion packets and for temporary channel IDs. There is no requirement that these be /// persisted anywhere, though they must be unique across restarts. fn get_secure_random_bytes(&self) -> [u8; 32]; + + /// Reads a `ChanKeySigner` for this `KeysInterface` from the given input stream. + /// This is only called during deserialization of other objects which contain + /// `ChannelKeys`-implementing objects (ie `ChannelMonitor`s and `ChannelManager`s). + /// The bytes are exactly those which `::write()` writes, and + /// contain no versioning scheme. You may wish to include your own version prefix and ensure + /// you've read all of the provided bytes to ensure no corruption occurred. + fn read_chan_signer(&self, reader: &[u8]) -> Result; } #[derive(Clone)] @@ -809,4 +817,8 @@ impl KeysInterface for KeysManager { sha.input(b"Unique Secure Random Bytes Salt"); Sha256::from_engine(sha).into_inner() } + + fn read_chan_signer(&self, reader: &[u8]) -> Result { + InMemoryChannelKeys::read(&mut std::io::Cursor::new(reader)) + } } diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 5477485d5..62d3968fd 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -4472,7 +4472,7 @@ mod tests { use ln::channel::{Channel,ChannelKeys,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,TxCreationKeys}; use ln::channel::MAX_FUNDING_SATOSHIS; use ln::features::InitFeatures; - use ln::msgs::{OptionalField, DataLossProtect}; + use ln::msgs::{OptionalField, DataLossProtect, DecodeError}; use ln::chan_utils; use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters}; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; @@ -4528,6 +4528,7 @@ mod tests { self.chan_keys.clone() } fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] } + fn read_chan_signer(&self, data: &[u8]) -> Result { panic!(); } } fn public_from_secret_hex(secp_ctx: &Secp256k1, hex: &str) -> PublicKey { diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 98b166285..8077d644a 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -7322,7 +7322,7 @@ fn test_user_configurable_csv_delay() { let nodes = create_network(2, &node_cfgs, &node_chanmgrs); // We test config.our_to_self > BREAKDOWN_TIMEOUT is enforced in Channel::new_outbound() - let keys_manager: Arc> = Arc::new(test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet)); + let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet)); if let Err(error) = Channel::new_outbound(&&test_utils::TestFeeEstimator { sat_per_kw: 253 }, &keys_manager, nodes[1].node.get_our_node_id(), 1000000, 1000000, 0, &low_our_to_self_config) { match error { APIError::APIMisuseError { err } => { assert!(regex::Regex::new(r"Configured with an unreasonable our_to_self_delay \(\d+\) putting user funds at risks").unwrap().is_match(err.as_str())); }, diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index 6e27e0431..abeb5de26 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -430,6 +430,10 @@ impl keysinterface::KeysInterface for TestKeysInterface { } self.backing.get_secure_random_bytes() } + + fn read_chan_signer(&self, reader: &[u8]) -> Result { + EnforcingChannelKeys::read(&mut std::io::Cursor::new(reader)) + } } impl TestKeysInterface { -- 2.39.5