#761 Add a new method `read_chan_signer` to `KeysInterface`

Merged Matt Corallo TheBlueMatt

@@ -3693,7 +3693,7 @@
Loading
3693 3693
	}
3694 3694
}
3695 3695
3696 -
impl<ChanSigner: ChannelKeys + Writeable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelManager<ChanSigner, M, T, K, F, L>
3696 +
impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelManager<ChanSigner, M, T, K, F, L>
3697 3697
	where M::Target: chain::Watch<Keys=ChanSigner>,
3698 3698
        T::Target: BroadcasterInterface,
3699 3699
        K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
@@ -3784,7 +3784,8 @@
Loading
3784 3784
        L::Target: Logger,
3785 3785
{
3786 3786
	/// The keys provider which will give us relevant keys. Some keys will be loaded during
3787 -
	/// deserialization.
3787 +
	/// deserialization and KeysInterface::read_chan_signer will be used to read per-Channel
3788 +
	/// signing data.
3788 3789
	pub keys_manager: K,
3789 3790
3790 3791
	/// The fee_estimator for use in the ChannelManager in the future.
@@ -3846,7 +3847,7 @@
Loading
3846 3847
3847 3848
// Implement ReadableArgs for an Arc'd ChannelManager to make it a bit easier to work with the
3848 3849
// SipmleArcChannelManager type:
3849 -
impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
3850 +
impl<'a, ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
3850 3851
	ReadableArgs<ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F, L>> for (BlockHash, Arc<ChannelManager<ChanSigner, M, T, K, F, L>>)
3851 3852
	where M::Target: chain::Watch<Keys=ChanSigner>,
3852 3853
        T::Target: BroadcasterInterface,
@@ -3860,7 +3861,7 @@
Loading
3860 3861
	}
3861 3862
}
3862 3863
3863 -
impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
3864 +
impl<'a, ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
3864 3865
	ReadableArgs<ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F, L>> for (BlockHash, ChannelManager<ChanSigner, M, T, K, F, L>)
3865 3866
	where M::Target: chain::Watch<Keys=ChanSigner>,
3866 3867
        T::Target: BroadcasterInterface,
@@ -3886,7 +3887,7 @@
Loading
3886 3887
		let mut by_id = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
3887 3888
		let mut short_to_id = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
3888 3889
		for _ in 0..channel_count {
3889 -
			let mut channel: Channel<ChanSigner> = Readable::read(reader)?;
3890 +
			let mut channel: Channel<ChanSigner> = Channel::read(reader, &args.keys_manager)?;
3890 3891
			if channel.last_block_connected != Default::default() && channel.last_block_connected != last_block_hash {
3891 3892
				return Err(DecodeError::InvalidValue);
3892 3893
			}

@@ -29,7 +29,7 @@
Loading
29 29
30 30
extern crate bitcoin;
31 31
#[cfg(any(test, feature = "_test_utils"))] extern crate hex;
32 -
#[cfg(any(test, feature = "_test_utils"))] extern crate regex;
32 +
#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))] extern crate regex;
33 33
34 34
#[macro_use]
35 35
pub mod util;

@@ -26,7 +26,7 @@
Loading
26 26
use util::enforcing_trait_impls::EnforcingChannelKeys;
27 27
use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
28 28
use util::errors::APIError;
29 -
use util::ser::Readable;
29 +
use util::ser::{ReadableArgs, Writeable};
30 30
31 31
use bitcoin::hashes::sha256::Hash as Sha256;
32 32
use bitcoin::hashes::Hash;
@@ -105,9 +105,9 @@
Loading
105 105
		let monitors = nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap();
106 106
		let monitor = monitors.get(&outpoint).unwrap();
107 107
		let mut w = test_utils::TestVecWriter(Vec::new());
108 -
		monitor.serialize_for_disk(&mut w).unwrap();
108 +
		monitor.write(&mut w).unwrap();
109 109
		let new_monitor = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(
110 -
			&mut ::std::io::Cursor::new(&w.0)).unwrap().1;
110 +
			&mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
111 111
		assert!(new_monitor == *monitor);
112 112
		let chain_mon = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister);
113 113
		assert!(chain_mon.watch_channel(outpoint, new_monitor).is_ok());

@@ -43,9 +43,9 @@
Loading
43 43
use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
44 44
use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
45 45
use chain::transaction::{OutPoint, TransactionData};
46 -
use chain::keysinterface::{SpendableOutputDescriptor, ChannelKeys};
46 +
use chain::keysinterface::{SpendableOutputDescriptor, ChannelKeys, KeysInterface};
47 47
use util::logger::Logger;
48 -
use util::ser::{Readable, MaybeReadable, Writer, Writeable, U48};
48 +
use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48};
49 49
use util::byte_utils;
50 50
use util::events::Event;
51 51
@@ -56,7 +56,7 @@
Loading
56 56
57 57
/// An update generated by the underlying Channel itself which contains some new information the
58 58
/// ChannelMonitor should be made aware of.
59 -
#[cfg_attr(any(test, feature = "_test_utils"), derive(PartialEq))]
59 +
#[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))]
60 60
#[derive(Clone)]
61 61
#[must_use]
62 62
pub struct ChannelMonitorUpdate {
@@ -485,7 +485,7 @@
Loading
485 485
const SERIALIZATION_VERSION: u8 = 1;
486 486
const MIN_SERIALIZATION_VERSION: u8 = 1;
487 487
488 -
#[cfg_attr(any(test, feature = "_test_utils"), derive(PartialEq))]
488 +
#[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))]
489 489
#[derive(Clone)]
490 490
pub(crate) enum ChannelMonitorUpdateStep {
491 491
	LatestHolderCommitmentTXInfo {
@@ -617,6 +617,12 @@
Loading
617 617
/// get_and_clear_pending_monitor_events or get_and_clear_pending_events are serialized to disk and
618 618
/// reloaded at deserialize-time. Thus, you must ensure that, when handling events, all events
619 619
/// gotten are fully handled before re-serializing the new state.
620 +
///
621 +
/// Note that the deserializer is only implemented for (Sha256dHash, ChannelMonitor), which
622 +
/// tells you the last block hash which was block_connect()ed. You MUST rescan any blocks along
623 +
/// the "reorg path" (ie disconnecting blocks until you find a common ancestor from both the
624 +
/// returned block hash and the the current chain and then reconnecting blocks to get to the
625 +
/// best chain) upon deserializing the object!
620 626
pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
621 627
	latest_update_id: u64,
622 628
	commitment_transaction_number_obscure_factor: u64,
@@ -626,7 +632,8 @@
Loading
626 632
	counterparty_payment_script: Script,
627 633
	shutdown_script: Script,
628 634
629 -
	keys: ChanSigner,
635 +
	key_derivation_params: (u64, u64),
636 +
	holder_revocation_basepoint: PublicKey,
630 637
	funding_info: (OutPoint, Script),
631 638
	current_counterparty_commitment_txid: Option<Txid>,
632 639
	prev_counterparty_commitment_txid: Option<Txid>,
@@ -721,7 +728,8 @@
Loading
721 728
			self.destination_script != other.destination_script ||
722 729
			self.broadcasted_holder_revokable_script != other.broadcasted_holder_revokable_script ||
723 730
			self.counterparty_payment_script != other.counterparty_payment_script ||
724 -
			self.keys.pubkeys() != other.keys.pubkeys() ||
731 +
			self.key_derivation_params != other.key_derivation_params ||
732 +
			self.holder_revocation_basepoint != other.holder_revocation_basepoint ||
725 733
			self.funding_info != other.funding_info ||
726 734
			self.current_counterparty_commitment_txid != other.current_counterparty_commitment_txid ||
727 735
			self.prev_counterparty_commitment_txid != other.prev_counterparty_commitment_txid ||
@@ -753,15 +761,8 @@
Loading
753 761
	}
754 762
}
755 763
756 -
impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
757 -
	/// Writes this monitor into the given writer, suitable for writing to disk.
758 -
	///
759 -
	/// Note that the deserializer is only implemented for (Sha256dHash, ChannelMonitor), which
760 -
	/// tells you the last block hash which was block_connect()ed. You MUST rescan any blocks along
761 -
	/// the "reorg path" (ie disconnecting blocks until you find a common ancestor from both the
762 -
	/// returned block hash and the the current chain and then reconnecting blocks to get to the
763 -
	/// best chain) upon deserializing the object!
764 -
	pub fn serialize_for_disk<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
764 +
impl<ChanSigner: ChannelKeys> Writeable for ChannelMonitor<ChanSigner> {
765 +
	fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
765 766
		//TODO: We still write out all the serialization here manually instead of using the fancy
766 767
		//serialization framework we have, we should migrate things over to it.
767 768
		writer.write_all(&[SERIALIZATION_VERSION; 1])?;
@@ -785,7 +786,8 @@
Loading
785 786
		self.counterparty_payment_script.write(writer)?;
786 787
		self.shutdown_script.write(writer)?;
787 788
788 -
		self.keys.write(writer)?;
789 +
		self.key_derivation_params.write(writer)?;
790 +
		self.holder_revocation_basepoint.write(writer)?;
789 791
		writer.write_all(&self.funding_info.0.txid[..])?;
790 792
		writer.write_all(&byte_utils::be16_to_array(self.funding_info.0.index))?;
791 793
		self.funding_info.1.write(writer)?;
@@ -965,7 +967,9 @@
Loading
965 967
		let counterparty_htlc_base_key = counterparty_channel_parameters.pubkeys.htlc_basepoint;
966 968
		let counterparty_tx_cache = CounterpartyCommitmentTransaction { counterparty_delayed_payment_base_key, counterparty_htlc_base_key, on_counterparty_tx_csv, per_htlc: HashMap::new() };
967 969
968 -
		let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys.clone(), channel_parameters.clone());
970 +
		let key_derivation_params = keys.key_derivation_params();
971 +
		let holder_revocation_basepoint = keys.pubkeys().revocation_basepoint;
972 +
		let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys, channel_parameters.clone());
969 973
970 974
		let secp_ctx = Secp256k1::new();
971 975
@@ -1001,7 +1005,8 @@
Loading
1001 1005
			counterparty_payment_script,
1002 1006
			shutdown_script,
1003 1007
1004 -
			keys,
1008 +
			key_derivation_params,
1009 +
			holder_revocation_basepoint,
1005 1010
			funding_info,
1006 1011
			current_counterparty_commitment_txid: None,
1007 1012
			prev_counterparty_commitment_txid: None,
@@ -1373,7 +1378,7 @@
Loading
1373 1378
			let secret = self.get_secret(commitment_number).unwrap();
1374 1379
			let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret));
1375 1380
			let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
1376 -
			let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.keys.pubkeys().revocation_basepoint));
1381 +
			let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint));
1377 1382
			let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.counterparty_tx_cache.counterparty_delayed_payment_base_key));
1378 1383
1379 1384
			let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.counterparty_tx_cache.on_counterparty_tx_csv, &delayed_key);
@@ -2205,7 +2210,7 @@
Loading
2205 2210
						per_commitment_point: broadcasted_holder_revokable_script.1,
2206 2211
						to_self_delay: self.on_holder_tx_csv,
2207 2212
						output: outp.clone(),
2208 -
						key_derivation_params: self.keys.key_derivation_params(),
2213 +
						key_derivation_params: self.key_derivation_params,
2209 2214
						revocation_pubkey: broadcasted_holder_revokable_script.2.clone(),
2210 2215
					});
2211 2216
					break;
@@ -2214,7 +2219,7 @@
Loading
2214 2219
				spendable_output = Some(SpendableOutputDescriptor::StaticOutputCounterpartyPayment {
2215 2220
					outpoint: OutPoint { txid: tx.txid(), index: i as u16 },
2216 2221
					output: outp.clone(),
2217 -
					key_derivation_params: self.keys.key_derivation_params(),
2222 +
					key_derivation_params: self.key_derivation_params,
2218 2223
				});
2219 2224
				break;
2220 2225
			} else if outp.script_pubkey == self.shutdown_script {
@@ -2296,8 +2301,9 @@
Loading
2296 2301
2297 2302
const MAX_ALLOC_SIZE: usize = 64*1024;
2298 2303
2299 -
impl<ChanSigner: ChannelKeys + Readable> Readable for (BlockHash, ChannelMonitor<ChanSigner>) {
2300 -
	fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
2304 +
impl<'a, ChanSigner: ChannelKeys, K: KeysInterface<ChanKeySigner = ChanSigner>> ReadableArgs<&'a K>
2305 +
		for (BlockHash, ChannelMonitor<ChanSigner>) {
2306 +
	fn read<R: ::std::io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
2301 2307
		macro_rules! unwrap_obj {
2302 2308
			($key: expr) => {
2303 2309
				match $key {
@@ -2330,7 +2336,8 @@
Loading
2330 2336
		let counterparty_payment_script = Readable::read(reader)?;
2331 2337
		let shutdown_script = Readable::read(reader)?;
2332 2338
2333 -
		let keys = Readable::read(reader)?;
2339 +
		let key_derivation_params = Readable::read(reader)?;
2340 +
		let holder_revocation_basepoint = Readable::read(reader)?;
2334 2341
		// Technically this can fail and serialize fail a round-trip, but only for serialization of
2335 2342
		// barely-init'd ChannelMonitors that we can't do anything with.
2336 2343
		let outpoint = OutPoint {
@@ -2530,7 +2537,7 @@
Loading
2530 2537
				return Err(DecodeError::InvalidValue);
2531 2538
			}
2532 2539
		}
2533 -
		let onchain_tx_handler = Readable::read(reader)?;
2540 +
		let onchain_tx_handler = ReadableArgs::read(reader, keys_manager)?;
2534 2541
2535 2542
		let lockdown_from_offchain = Readable::read(reader)?;
2536 2543
		let holder_tx_signed = Readable::read(reader)?;
@@ -2544,7 +2551,8 @@
Loading
2544 2551
			counterparty_payment_script,
2545 2552
			shutdown_script,
2546 2553
2547 -
			keys,
2554 +
			key_derivation_params,
2555 +
			holder_revocation_basepoint,
2548 2556
			funding_info,
2549 2557
			current_counterparty_commitment_txid,
2550 2558
			prev_counterparty_commitment_txid,

@@ -33,7 +33,7 @@
Loading
33 33
use chain::transaction::{OutPoint, TransactionData};
34 34
use chain::keysinterface::{ChannelKeys, KeysInterface};
35 35
use util::transaction_utils;
36 -
use util::ser::{Readable, Writeable, Writer};
36 +
use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
37 37
use util::logger::Logger;
38 38
use util::errors::APIError;
39 39
use util::config::{UserConfig,ChannelConfig};
@@ -4055,7 +4055,7 @@
Loading
4055 4055
	}
4056 4056
}
4057 4057
4058 -
impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
4058 +
impl<ChanSigner: ChannelKeys> Writeable for Channel<ChanSigner> {
4059 4059
	fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
4060 4060
		// Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been
4061 4061
		// called but include holding cell updates (and obviously we don't modify self).
@@ -4072,7 +4072,13 @@
Loading
4072 4072
4073 4073
		self.latest_monitor_update_id.write(writer)?;
4074 4074
4075 -
		self.holder_keys.write(writer)?;
4075 +
		let mut key_data = VecWriter(Vec::new());
4076 +
		self.holder_keys.write(&mut key_data)?;
4077 +
		assert!(key_data.0.len() < std::usize::MAX);
4078 +
		assert!(key_data.0.len() < std::u32::MAX as usize);
4079 +
		(key_data.0.len() as u32).write(writer)?;
4080 +
		writer.write_all(&key_data.0[..])?;
4081 +
4076 4082
		self.shutdown_pubkey.write(writer)?;
4077 4083
		self.destination_script.write(writer)?;
4078 4084
@@ -4237,8 +4243,10 @@
Loading
4237 4243
	}
4238 4244
}
4239 4245
4240 -
impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
4241 -
	fn read<R : ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
4246 +
const MAX_ALLOC_SIZE: usize = 64*1024;
4247 +
impl<'a, ChanSigner: ChannelKeys, K: Deref> ReadableArgs<&'a K> for Channel<ChanSigner>
4248 +
		where K::Target: KeysInterface<ChanKeySigner = ChanSigner> {
4249 +
	fn read<R : ::std::io::Read>(reader: &mut R, keys_source: &'a K) -> Result<Self, DecodeError> {
4242 4250
		let _ver: u8 = Readable::read(reader)?;
4243 4251
		let min_ver: u8 = Readable::read(reader)?;
4244 4252
		if min_ver > SERIALIZATION_VERSION {
@@ -4254,7 +4262,17 @@
Loading
4254 4262
4255 4263
		let latest_monitor_update_id = Readable::read(reader)?;
4256 4264
4257 -
		let holder_keys = Readable::read(reader)?;
4265 +
		let keys_len: u32 = Readable::read(reader)?;
4266 +
		let mut keys_data = Vec::with_capacity(cmp::min(keys_len as usize, MAX_ALLOC_SIZE));
4267 +
		while keys_data.len() != keys_len as usize {
4268 +
			// Read 1KB at a time to avoid accidentally allocating 4GB on corrupted channel keys
4269 +
			let mut data = [0; 1024];
4270 +
			let read_slice = &mut data[0..cmp::min(1024, keys_len as usize - keys_data.len())];
4271 +
			reader.read_exact(read_slice)?;
4272 +
			keys_data.extend_from_slice(read_slice);
4273 +
		}
4274 +
		let holder_keys = keys_source.read_chan_signer(&keys_data)?;
4275 +
4258 4276
		let shutdown_pubkey = Readable::read(reader)?;
4259 4277
		let destination_script = Readable::read(reader)?;
4260 4278
@@ -4472,7 +4490,7 @@
Loading
4472 4490
	use ln::channel::{Channel,ChannelKeys,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,TxCreationKeys};
4473 4491
	use ln::channel::MAX_FUNDING_SATOSHIS;
4474 4492
	use ln::features::InitFeatures;
4475 -
	use ln::msgs::{OptionalField, DataLossProtect};
4493 +
	use ln::msgs::{OptionalField, DataLossProtect, DecodeError};
4476 4494
	use ln::chan_utils;
4477 4495
	use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
4478 4496
	use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
@@ -4528,6 +4546,7 @@
Loading
4528 4546
			self.chan_keys.clone()
4529 4547
		}
4530 4548
		fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
4549 +
		fn read_chan_signer(&self, _data: &[u8]) -> Result<Self::ChanKeySigner, DecodeError> { panic!(); }
4531 4550
	}
4532 4551
4533 4552
	fn public_from_secret_hex(secp_ctx: &Secp256k1<All>, hex: &str) -> PublicKey {

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Learn more Showing 1 files with coverage changes found.

Changes in lightning/src/ln/functional_tests.rs
-12
+12
Loading file...
Files Coverage
lightning/src -0.07% 91.29%
Project Totals (37 files) 91.29%
Loading