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;
use lightning::util::config::UserConfig;
use lightning::util::events::{EventsProvider, MessageSendEventsProvider};
use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer};
+use lightning::util::test_utils::OnlyReadsKeysInterface;
use lightning::routing::router::{Route, RouteHop};
fn watch_channel(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<EnforcingChannelKeys>) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
let mut ser = VecWriter(Vec::new());
- monitor.serialize_for_disk(&mut ser).unwrap();
+ 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");
}
hash_map::Entry::Vacant(_) => panic!("Didn't have monitor on update call"),
};
let mut deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::
- read(&mut Cursor::new(&map_entry.get().1)).unwrap().1;
+ read(&mut Cursor::new(&map_entry.get().1), &OnlyReadsKeysInterface {}).unwrap().1;
deserialized_monitor.update_monitor(&update, &&TestBroadcaster{}, &&FuzzEstimator{}, &self.logger).unwrap();
let mut ser = VecWriter(Vec::new());
- deserialized_monitor.serialize_for_disk(&mut ser).unwrap();
+ deserialized_monitor.write(&mut ser).unwrap();
map_entry.insert((update.update_id, ser.0));
self.should_update_manager.store(true, atomic::Ordering::Relaxed);
self.update_ret.lock().unwrap().clone()
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, DecodeError> {
+ EnforcingChannelKeys::read(&mut std::io::Cursor::new(data))
+ }
}
#[inline]
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<EnforcingChannelKeys>)>::read(&mut Cursor::new(&monitor_ser)).expect("Failed to read monitor").1);
+ monitors.insert(outpoint, <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut Cursor::new(&monitor_ser), &OnlyReadsKeysInterface {}).expect("Failed to read monitor").1);
chain_monitor.latest_monitors.lock().unwrap().insert(outpoint, (update_id, monitor_ser));
}
let mut monitor_refs = HashMap::new();
use lightning::chain::channelmonitor;
use lightning::util::enforcing_trait_impls::EnforcingChannelKeys;
-use lightning::util::ser::{Readable, Writer};
+use lightning::util::ser::{ReadableArgs, Writer, Writeable};
+use lightning::util::test_utils::OnlyReadsKeysInterface;
use utils::test_logger;
#[inline]
pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
- if let Ok((latest_block_hash, monitor)) = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::read(&mut Cursor::new(data)) {
+ if let Ok((latest_block_hash, monitor)) = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::read(&mut Cursor::new(data), &OnlyReadsKeysInterface {}) {
let mut w = VecWriter(Vec::new());
- monitor.serialize_for_disk(&mut w).unwrap();
- let deserialized_copy = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::read(&mut Cursor::new(&w.0)).unwrap();
+ monitor.write(&mut w).unwrap();
+ let deserialized_copy = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::read(&mut Cursor::new(&w.0), &OnlyReadsKeysInterface {}).unwrap();
assert!(latest_block_hash == deserialized_copy.0);
assert!(monitor == deserialized_copy.1);
}
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;
[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, DecodeError> {
+ EnforcingChannelKeys::read(&mut std::io::Cursor::new(data))
+ }
}
#[inline]
use lightning::chain::channelmonitor;
use lightning::chain::keysinterface::ChannelKeys;
use lightning::chain::transaction::OutPoint;
-use lightning::util::ser::{Writeable, Readable};
+use lightning::util::ser::Writeable;
use std::fs;
use std::io::Error;
use std::path::{Path, PathBuf};
#[cfg(test)]
use {
+ lightning::chain::keysinterface::KeysInterface,
+ lightning::util::ser::ReadableArgs,
bitcoin::{BlockHash, Txid},
bitcoin::hashes::hex::FromHex,
std::collections::HashMap,
fn write(&self, writer: &mut fs::File) -> Result<(), Error>;
}
-impl<ChanSigner: ChannelKeys + Writeable> DiskWriteable for ChannelMonitor<ChanSigner> {
+impl<ChanSigner: ChannelKeys> DiskWriteable for ChannelMonitor<ChanSigner> {
fn write(&self, writer: &mut fs::File) -> Result<(), Error> {
- self.serialize_for_disk(writer)
+ Writeable::write(self, writer)
}
}
}
#[cfg(test)]
- fn load_channel_data<ChanSigner: ChannelKeys + Readable + Writeable>(&self) ->
- Result<HashMap<OutPoint, ChannelMonitor<ChanSigner>>, ChannelMonitorUpdateErr> {
+ fn load_channel_data<Keys: KeysInterface>(&self, keys: &Keys) ->
+ Result<HashMap<OutPoint, ChannelMonitor<Keys::ChanKeySigner>>, ChannelMonitorUpdateErr> {
if let Err(_) = fs::create_dir_all(&self.path_to_channel_data) {
return Err(ChannelMonitorUpdateErr::PermanentFailure);
}
if contents.is_err() { return Err(ChannelMonitorUpdateErr::PermanentFailure); }
if let Ok((_, loaded_monitor)) =
- <(BlockHash, ChannelMonitor<ChanSigner>)>::read(&mut Cursor::new(&contents.unwrap())) {
+ <(BlockHash, ChannelMonitor<Keys::ChanKeySigner>)>::read(&mut Cursor::new(&contents.unwrap()), keys) {
res.insert(OutPoint { txid: txid.unwrap(), index: index.unwrap() }, loaded_monitor);
} else {
return Err(ChannelMonitorUpdateErr::PermanentFailure);
}
}
-impl<ChanSigner: ChannelKeys + Readable + Writeable + Send + Sync> channelmonitor::Persist<ChanSigner> for FilesystemPersister {
+impl<ChanSigner: ChannelKeys + Send + Sync> channelmonitor::Persist<ChanSigner> for FilesystemPersister {
fn persist_new_channel(&self, funding_txo: OutPoint, monitor: &ChannelMonitor<ChanSigner>) -> Result<(), ChannelMonitorUpdateErr> {
self.write_channel_data(funding_txo, monitor)
.map_err(|_| ChannelMonitorUpdateErr::PermanentFailure)
use lightning::ln::features::InitFeatures;
use lightning::ln::functional_test_utils::*;
use lightning::ln::msgs::ErrorAction;
- use lightning::util::enforcing_trait_impls::EnforcingChannelKeys;
use lightning::util::events::{MessageSendEventsProvider, MessageSendEvent};
use lightning::util::ser::Writer;
use lightning::util::test_utils;
// Check that the persisted channel data is empty before any channels are
// open.
- let mut persisted_chan_data_0 = persister_0.load_channel_data::<EnforcingChannelKeys>().unwrap();
+ let mut persisted_chan_data_0 = persister_0.load_channel_data(nodes[0].keys_manager).unwrap();
assert_eq!(persisted_chan_data_0.keys().len(), 0);
- let mut persisted_chan_data_1 = persister_1.load_channel_data::<EnforcingChannelKeys>().unwrap();
+ let mut persisted_chan_data_1 = persister_1.load_channel_data(nodes[1].keys_manager).unwrap();
assert_eq!(persisted_chan_data_1.keys().len(), 0);
// Helper to make sure the channel is on the expected update ID.
macro_rules! check_persisted_data {
($expected_update_id: expr) => {
- persisted_chan_data_0 = persister_0.load_channel_data::<EnforcingChannelKeys>().unwrap();
+ persisted_chan_data_0 = persister_0.load_channel_data(nodes[0].keys_manager).unwrap();
assert_eq!(persisted_chan_data_0.keys().len(), 1);
for mon in persisted_chan_data_0.values() {
assert_eq!(mon.get_latest_update_id(), $expected_update_id);
}
- persisted_chan_data_1 = persister_1.load_channel_data::<EnforcingChannelKeys>().unwrap();
+ persisted_chan_data_1 = persister_1.load_channel_data(nodes[1].keys_manager).unwrap();
assert_eq!(persisted_chan_data_1.keys().len(), 1);
for mon in persisted_chan_data_1.values() {
assert_eq!(mon.get_latest_update_id(), $expected_update_id);
"""
[features]
-fuzztarget = ["bitcoin/fuzztarget"]
+fuzztarget = ["bitcoin/fuzztarget", "regex"]
# Internal test utilities exposed to other repo crates
_test_utils = ["hex", "regex"]
# Unlog messages superior at targeted level.
use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
use chain::transaction::{OutPoint, TransactionData};
-use chain::keysinterface::{SpendableOutputDescriptor, ChannelKeys};
+use chain::keysinterface::{SpendableOutputDescriptor, ChannelKeys, KeysInterface};
use util::logger::Logger;
-use util::ser::{Readable, MaybeReadable, Writer, Writeable, U48};
+use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48};
use util::byte_utils;
use util::events::Event;
/// An update generated by the underlying Channel itself which contains some new information the
/// ChannelMonitor should be made aware of.
-#[cfg_attr(any(test, feature = "_test_utils"), derive(PartialEq))]
+#[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))]
#[derive(Clone)]
#[must_use]
pub struct ChannelMonitorUpdate {
const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;
-#[cfg_attr(any(test, feature = "_test_utils"), derive(PartialEq))]
+#[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))]
#[derive(Clone)]
pub(crate) enum ChannelMonitorUpdateStep {
LatestHolderCommitmentTXInfo {
/// get_and_clear_pending_monitor_events or get_and_clear_pending_events are serialized to disk and
/// reloaded at deserialize-time. Thus, you must ensure that, when handling events, all events
/// gotten are fully handled before re-serializing the new state.
+///
+/// Note that the deserializer is only implemented for (Sha256dHash, ChannelMonitor), which
+/// tells you the last block hash which was block_connect()ed. You MUST rescan any blocks along
+/// the "reorg path" (ie disconnecting blocks until you find a common ancestor from both the
+/// returned block hash and the the current chain and then reconnecting blocks to get to the
+/// best chain) upon deserializing the object!
pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
latest_update_id: u64,
commitment_transaction_number_obscure_factor: u64,
counterparty_payment_script: Script,
shutdown_script: Script,
- keys: ChanSigner,
+ key_derivation_params: (u64, u64),
+ holder_revocation_basepoint: PublicKey,
funding_info: (OutPoint, Script),
current_counterparty_commitment_txid: Option<Txid>,
prev_counterparty_commitment_txid: Option<Txid>,
self.destination_script != other.destination_script ||
self.broadcasted_holder_revokable_script != other.broadcasted_holder_revokable_script ||
self.counterparty_payment_script != other.counterparty_payment_script ||
- self.keys.pubkeys() != other.keys.pubkeys() ||
+ self.key_derivation_params != other.key_derivation_params ||
+ self.holder_revocation_basepoint != other.holder_revocation_basepoint ||
self.funding_info != other.funding_info ||
self.current_counterparty_commitment_txid != other.current_counterparty_commitment_txid ||
self.prev_counterparty_commitment_txid != other.prev_counterparty_commitment_txid ||
}
}
-impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
- /// Writes this monitor into the given writer, suitable for writing to disk.
- ///
- /// Note that the deserializer is only implemented for (Sha256dHash, ChannelMonitor), which
- /// tells you the last block hash which was block_connect()ed. You MUST rescan any blocks along
- /// the "reorg path" (ie disconnecting blocks until you find a common ancestor from both the
- /// returned block hash and the the current chain and then reconnecting blocks to get to the
- /// best chain) upon deserializing the object!
- pub fn serialize_for_disk<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
+impl<ChanSigner: ChannelKeys> Writeable for ChannelMonitor<ChanSigner> {
+ fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
//TODO: We still write out all the serialization here manually instead of using the fancy
//serialization framework we have, we should migrate things over to it.
writer.write_all(&[SERIALIZATION_VERSION; 1])?;
self.counterparty_payment_script.write(writer)?;
self.shutdown_script.write(writer)?;
- self.keys.write(writer)?;
+ self.key_derivation_params.write(writer)?;
+ self.holder_revocation_basepoint.write(writer)?;
writer.write_all(&self.funding_info.0.txid[..])?;
writer.write_all(&byte_utils::be16_to_array(self.funding_info.0.index))?;
self.funding_info.1.write(writer)?;
let counterparty_htlc_base_key = counterparty_channel_parameters.pubkeys.htlc_basepoint;
let counterparty_tx_cache = CounterpartyCommitmentTransaction { counterparty_delayed_payment_base_key, counterparty_htlc_base_key, on_counterparty_tx_csv, per_htlc: HashMap::new() };
- let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys.clone(), channel_parameters.clone());
+ let key_derivation_params = keys.key_derivation_params();
+ let holder_revocation_basepoint = keys.pubkeys().revocation_basepoint;
+ let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys, channel_parameters.clone());
let secp_ctx = Secp256k1::new();
counterparty_payment_script,
shutdown_script,
- keys,
+ key_derivation_params,
+ holder_revocation_basepoint,
funding_info,
current_counterparty_commitment_txid: None,
prev_counterparty_commitment_txid: None,
let secret = self.get_secret(commitment_number).unwrap();
let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret));
let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
- let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.keys.pubkeys().revocation_basepoint));
+ let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint));
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));
let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.counterparty_tx_cache.on_counterparty_tx_csv, &delayed_key);
per_commitment_point: broadcasted_holder_revokable_script.1,
to_self_delay: self.on_holder_tx_csv,
output: outp.clone(),
- key_derivation_params: self.keys.key_derivation_params(),
+ key_derivation_params: self.key_derivation_params,
revocation_pubkey: broadcasted_holder_revokable_script.2.clone(),
});
break;
spendable_output = Some(SpendableOutputDescriptor::StaticOutputCounterpartyPayment {
outpoint: OutPoint { txid: tx.txid(), index: i as u16 },
output: outp.clone(),
- key_derivation_params: self.keys.key_derivation_params(),
+ key_derivation_params: self.key_derivation_params,
});
break;
} else if outp.script_pubkey == self.shutdown_script {
const MAX_ALLOC_SIZE: usize = 64*1024;
-impl<ChanSigner: ChannelKeys + Readable> Readable for (BlockHash, ChannelMonitor<ChanSigner>) {
- fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+impl<'a, ChanSigner: ChannelKeys, K: KeysInterface<ChanKeySigner = ChanSigner>> ReadableArgs<&'a K>
+ for (BlockHash, ChannelMonitor<ChanSigner>) {
+ fn read<R: ::std::io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
macro_rules! unwrap_obj {
($key: expr) => {
match $key {
let counterparty_payment_script = Readable::read(reader)?;
let shutdown_script = Readable::read(reader)?;
- let keys = Readable::read(reader)?;
+ let key_derivation_params = Readable::read(reader)?;
+ let holder_revocation_basepoint = Readable::read(reader)?;
// Technically this can fail and serialize fail a round-trip, but only for serialization of
// barely-init'd ChannelMonitors that we can't do anything with.
let outpoint = OutPoint {
return Err(DecodeError::InvalidValue);
}
}
- let onchain_tx_handler = Readable::read(reader)?;
+ let onchain_tx_handler = ReadableArgs::read(reader, keys_manager)?;
let lockdown_from_offchain = Readable::read(reader)?;
let holder_tx_signed = Readable::read(reader)?;
counterparty_payment_script,
shutdown_script,
- keys,
+ key_derivation_params,
+ holder_revocation_basepoint,
funding_info,
current_counterparty_commitment_txid,
prev_counterparty_commitment_txid,
// routine).
// TODO: We should remove Clone by instead requesting a new ChannelKeys copy when we create
// ChannelMonitors instead of expecting to clone the one out of the Channel into the monitors.
-pub trait ChannelKeys : Send+Clone {
+pub trait ChannelKeys : Send+Clone + Writeable {
/// Gets the per-commitment point for a specific commitment number
///
/// Note that the commitment number starts at (1 << 48) - 1 and counts backwards.
/// 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 `<Self::ChanKeySigner as Writeable>::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<Self::ChanKeySigner, DecodeError>;
}
#[derive(Clone)]
sha.input(b"Unique Secure Random Bytes Salt");
Sha256::from_engine(sha).into_inner()
}
+
+ fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::ChanKeySigner, DecodeError> {
+ InMemoryChannelKeys::read(&mut std::io::Cursor::new(reader))
+ }
}
extern crate bitcoin;
#[cfg(any(test, feature = "_test_utils"))] extern crate hex;
-#[cfg(any(test, feature = "_test_utils"))] extern crate regex;
+#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))] extern crate regex;
#[macro_use]
pub mod util;
use util::enforcing_trait_impls::EnforcingChannelKeys;
use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
use util::errors::APIError;
-use util::ser::Readable;
+use util::ser::{ReadableArgs, Writeable};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::Hash;
let monitors = nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap();
let monitor = monitors.get(&outpoint).unwrap();
let mut w = test_utils::TestVecWriter(Vec::new());
- monitor.serialize_for_disk(&mut w).unwrap();
+ monitor.write(&mut w).unwrap();
let new_monitor = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(
- &mut ::std::io::Cursor::new(&w.0)).unwrap().1;
+ &mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
assert!(new_monitor == *monitor);
let chain_mon = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister);
assert!(chain_mon.watch_channel(outpoint, new_monitor).is_ok());
use chain::transaction::{OutPoint, TransactionData};
use chain::keysinterface::{ChannelKeys, KeysInterface};
use util::transaction_utils;
-use util::ser::{Readable, Writeable, Writer};
+use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
use util::logger::Logger;
use util::errors::APIError;
use util::config::{UserConfig,ChannelConfig};
}
}
-impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
+impl<ChanSigner: ChannelKeys> Writeable for Channel<ChanSigner> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
// Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been
// called but include holding cell updates (and obviously we don't modify self).
self.latest_monitor_update_id.write(writer)?;
- self.holder_keys.write(writer)?;
+ let mut key_data = VecWriter(Vec::new());
+ self.holder_keys.write(&mut key_data)?;
+ assert!(key_data.0.len() < std::usize::MAX);
+ assert!(key_data.0.len() < std::u32::MAX as usize);
+ (key_data.0.len() as u32).write(writer)?;
+ writer.write_all(&key_data.0[..])?;
+
self.shutdown_pubkey.write(writer)?;
self.destination_script.write(writer)?;
}
}
-impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
- fn read<R : ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+const MAX_ALLOC_SIZE: usize = 64*1024;
+impl<'a, ChanSigner: ChannelKeys, K: Deref> ReadableArgs<&'a K> for Channel<ChanSigner>
+ where K::Target: KeysInterface<ChanKeySigner = ChanSigner> {
+ fn read<R : ::std::io::Read>(reader: &mut R, keys_source: &'a K) -> Result<Self, DecodeError> {
let _ver: u8 = Readable::read(reader)?;
let min_ver: u8 = Readable::read(reader)?;
if min_ver > SERIALIZATION_VERSION {
let latest_monitor_update_id = Readable::read(reader)?;
- let holder_keys = Readable::read(reader)?;
+ let keys_len: u32 = Readable::read(reader)?;
+ let mut keys_data = Vec::with_capacity(cmp::min(keys_len as usize, MAX_ALLOC_SIZE));
+ while keys_data.len() != keys_len as usize {
+ // Read 1KB at a time to avoid accidentally allocating 4GB on corrupted channel keys
+ let mut data = [0; 1024];
+ let read_slice = &mut data[0..cmp::min(1024, keys_len as usize - keys_data.len())];
+ reader.read_exact(read_slice)?;
+ keys_data.extend_from_slice(read_slice);
+ }
+ let holder_keys = keys_source.read_chan_signer(&keys_data)?;
+
let shutdown_pubkey = Readable::read(reader)?;
let destination_script = Readable::read(reader)?;
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};
self.chan_keys.clone()
}
fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
+ fn read_chan_signer(&self, _data: &[u8]) -> Result<Self::ChanKeySigner, DecodeError> { panic!(); }
}
fn public_from_secret_hex(secp_ctx: &Secp256k1<All>, hex: &str) -> PublicKey {
}
}
-impl<ChanSigner: ChannelKeys + Writeable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelManager<ChanSigner, M, T, K, F, L>
+impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelManager<ChanSigner, M, T, K, F, L>
where M::Target: chain::Watch<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
L::Target: Logger,
{
/// The keys provider which will give us relevant keys. Some keys will be loaded during
- /// deserialization.
+ /// deserialization and KeysInterface::read_chan_signer will be used to read per-Channel
+ /// signing data.
pub keys_manager: K,
/// The fee_estimator for use in the ChannelManager in the future.
// Implement ReadableArgs for an Arc'd ChannelManager to make it a bit easier to work with the
// SipmleArcChannelManager type:
-impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
+impl<'a, ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
ReadableArgs<ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F, L>> for (BlockHash, Arc<ChannelManager<ChanSigner, M, T, K, F, L>>)
where M::Target: chain::Watch<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
}
}
-impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
+impl<'a, ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
ReadableArgs<ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F, L>> for (BlockHash, ChannelManager<ChanSigner, M, T, K, F, L>)
where M::Target: chain::Watch<Keys=ChanSigner>,
T::Target: BroadcasterInterface,
let mut by_id = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
let mut short_to_id = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
for _ in 0..channel_count {
- let mut channel: Channel<ChanSigner> = Readable::read(reader)?;
+ let mut channel: Channel<ChanSigner> = Channel::read(reader, &args.keys_manager)?;
if channel.last_block_connected != Default::default() && channel.last_block_connected != last_block_hash {
return Err(DecodeError::InvalidValue);
}
use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
use util::enforcing_trait_impls::EnforcingChannelKeys;
use util::test_utils;
-use util::test_utils::TestChainMonitor;
+use util::test_utils::{TestChainMonitor, OnlyReadsKeysInterface};
use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
use util::errors::APIError;
use util::config::UserConfig;
let old_monitors = self.chain_monitor.chain_monitor.monitors.lock().unwrap();
for (_, old_monitor) in old_monitors.iter() {
let mut w = test_utils::TestVecWriter(Vec::new());
- old_monitor.serialize_for_disk(&mut w).unwrap();
+ old_monitor.write(&mut w).unwrap();
let (_, deserialized_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(
- &mut ::std::io::Cursor::new(&w.0)).unwrap();
+ &mut ::std::io::Cursor::new(&w.0), &OnlyReadsKeysInterface {}).unwrap();
deserialized_monitors.push(deserialized_monitor);
}
}
use util::{byte_utils, test_utils};
use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
use util::errors::APIError;
-use util::ser::{Writeable, ReadableArgs, Readable};
+use util::ser::{Writeable, ReadableArgs};
use util::config::UserConfig;
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
let nodes_0_serialized = nodes[0].node.encode();
let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
- nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.serialize_for_disk(&mut chan_0_monitor_serialized).unwrap();
+ nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write(&mut chan_0_monitor_serialized).unwrap();
logger = test_utils::TestLogger::new();
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
persister = test_utils::TestPersister::new();
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister);
nodes[0].chain_monitor = &new_chain_monitor;
+ keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
- let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut chan_0_monitor_read).unwrap();
+ let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(
+ &mut chan_0_monitor_read, &keys_manager).unwrap();
assert!(chan_0_monitor_read.is_empty());
let mut nodes_0_read = &nodes_0_serialized[..];
let config = UserConfig::default();
- keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
let (_, nodes_0_deserialized_tmp) = {
let mut channel_monitors = HashMap::new();
channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
// Start the de/seriailization process mid-channel creation to check that the channel manager will hold onto events that are serialized
let nodes_0_serialized = nodes[0].node.encode();
let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
- nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.serialize_for_disk(&mut chan_0_monitor_serialized).unwrap();
+ nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write(&mut chan_0_monitor_serialized).unwrap();
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
logger = test_utils::TestLogger::new();
persister = test_utils::TestPersister::new();
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister);
+ keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
nodes[0].chain_monitor = &new_chain_monitor;
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
- let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut chan_0_monitor_read).unwrap();
+ let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(
+ &mut chan_0_monitor_read, &keys_manager).unwrap();
assert!(chan_0_monitor_read.is_empty());
let mut nodes_0_read = &nodes_0_serialized[..];
let config = UserConfig::default();
- keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
let (_, nodes_0_deserialized_tmp) = {
let mut channel_monitors = HashMap::new();
channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
let nodes_0_serialized = nodes[0].node.encode();
let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
- nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.serialize_for_disk(&mut chan_0_monitor_serialized).unwrap();
+ nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write(&mut chan_0_monitor_serialized).unwrap();
logger = test_utils::TestLogger::new();
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
persister = test_utils::TestPersister::new();
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister);
+ keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
nodes[0].chain_monitor = &new_chain_monitor;
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
- let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut chan_0_monitor_read).unwrap();
+ let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(
+ &mut chan_0_monitor_read, &keys_manager).unwrap();
assert!(chan_0_monitor_read.is_empty());
let mut nodes_0_read = &nodes_0_serialized[..];
- keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
let (_, nodes_0_deserialized_tmp) = {
let mut channel_monitors = HashMap::new();
channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
let mut node_0_stale_monitors_serialized = Vec::new();
for monitor in nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter() {
let mut writer = test_utils::TestVecWriter(Vec::new());
- monitor.1.serialize_for_disk(&mut writer).unwrap();
+ monitor.1.write(&mut writer).unwrap();
node_0_stale_monitors_serialized.push(writer.0);
}
let mut node_0_monitors_serialized = Vec::new();
for monitor in nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter() {
let mut writer = test_utils::TestVecWriter(Vec::new());
- monitor.1.serialize_for_disk(&mut writer).unwrap();
+ monitor.1.write(&mut writer).unwrap();
node_0_monitors_serialized.push(writer.0);
}
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister);
nodes[0].chain_monitor = &new_chain_monitor;
+ keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
+
let mut node_0_stale_monitors = Vec::new();
for serialized in node_0_stale_monitors_serialized.iter() {
let mut read = &serialized[..];
- let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut read).unwrap();
+ let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut read, &keys_manager).unwrap();
assert!(read.is_empty());
node_0_stale_monitors.push(monitor);
}
let mut node_0_monitors = Vec::new();
for serialized in node_0_monitors_serialized.iter() {
let mut read = &serialized[..];
- let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut read).unwrap();
+ let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut read, &keys_manager).unwrap();
assert!(read.is_empty());
node_0_monitors.push(monitor);
}
- keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
-
let mut nodes_0_read = &nodes_0_serialized[..];
if let Err(msgs::DecodeError::InvalidValue) =
<(BlockHash, ChannelManager<EnforcingChannelKeys, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
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<KeysInterface<ChanKeySigner = EnforcingChannelKeys>> = 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())); },
// Cache node A state before any channel update
let previous_node_state = nodes[0].node.encode();
let mut previous_chain_monitor_state = test_utils::TestVecWriter(Vec::new());
- nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.serialize_for_disk(&mut previous_chain_monitor_state).unwrap();
+ nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write(&mut previous_chain_monitor_state).unwrap();
send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
// Restore node A from previous state
logger = test_utils::TestLogger::with_id(format!("node {}", 0));
- let mut chain_monitor = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut ::std::io::Cursor::new(previous_chain_monitor_state.0)).unwrap().1;
+ keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
+ let mut chain_monitor = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut ::std::io::Cursor::new(previous_chain_monitor_state.0), &keys_manager).unwrap().1;
chain_source = test_utils::TestChainSource::new(Network::Testnet);
tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())};
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
- keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
persister = test_utils::TestPersister::new();
monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &tx_broadcaster, &logger, &fee_estimator, &persister);
node_state_0 = {
let monitors = nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap();
let monitor = monitors.get(&outpoint).unwrap();
let mut w = test_utils::TestVecWriter(Vec::new());
- monitor.serialize_for_disk(&mut w).unwrap();
+ monitor.write(&mut w).unwrap();
let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::read(
- &mut ::std::io::Cursor::new(&w.0)).unwrap().1;
+ &mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
assert!(new_monitor == *monitor);
let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister);
assert!(watchtower.watch_channel(outpoint, new_monitor).is_ok());
let monitors = nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap();
let monitor = monitors.get(&outpoint).unwrap();
let mut w = test_utils::TestVecWriter(Vec::new());
- monitor.serialize_for_disk(&mut w).unwrap();
+ monitor.write(&mut w).unwrap();
let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::read(
- &mut ::std::io::Cursor::new(&w.0)).unwrap().1;
+ &mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
assert!(new_monitor == *monitor);
let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister);
assert!(watchtower.watch_channel(outpoint, new_monitor).is_ok());
let monitors = nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap();
let monitor = monitors.get(&outpoint).unwrap();
let mut w = test_utils::TestVecWriter(Vec::new());
- monitor.serialize_for_disk(&mut w).unwrap();
+ monitor.write(&mut w).unwrap();
let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::read(
- &mut ::std::io::Cursor::new(&w.0)).unwrap().1;
+ &mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
assert!(new_monitor == *monitor);
let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister);
assert!(watchtower.watch_channel(outpoint, new_monitor).is_ok());
use ln::chan_utils::{TxCreationKeys, ChannelTransactionParameters, HolderCommitmentTransaction};
use chain::chaininterface::{FeeEstimator, BroadcasterInterface, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT};
use chain::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER, InputMaterial, ClaimRequest};
-use chain::keysinterface::ChannelKeys;
+use chain::keysinterface::{ChannelKeys, KeysInterface};
use util::logger::Logger;
-use util::ser::{Readable, Writer, Writeable};
+use util::ser::{Readable, ReadableArgs, Writer, Writeable, VecWriter};
use util::byte_utils;
use std::collections::{HashMap, hash_map};
secp_ctx: Secp256k1<secp256k1::All>,
}
-impl<ChanSigner: ChannelKeys + Writeable> OnchainTxHandler<ChanSigner> {
+impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
self.destination_script.write(writer)?;
self.holder_commitment.write(writer)?;
self.prev_holder_commitment.write(writer)?;
self.prev_holder_htlc_sigs.write(writer)?;
- self.key_storage.write(writer)?;
self.channel_transaction_parameters.write(writer)?;
+ let mut key_data = VecWriter(Vec::new());
+ self.key_storage.write(&mut key_data)?;
+ assert!(key_data.0.len() < std::usize::MAX);
+ assert!(key_data.0.len() < std::u32::MAX as usize);
+ (key_data.0.len() as u32).write(writer)?;
+ writer.write_all(&key_data.0[..])?;
+
writer.write_all(&byte_utils::be64_to_array(self.pending_claim_requests.len() as u64))?;
for (ref ancestor_claim_txid, claim_tx_data) in self.pending_claim_requests.iter() {
ancestor_claim_txid.write(writer)?;
}
}
-impl<ChanSigner: ChannelKeys + Readable> Readable for OnchainTxHandler<ChanSigner> {
- fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler<K::ChanKeySigner> {
+ fn read<R: ::std::io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
let destination_script = Readable::read(reader)?;
let holder_commitment = Readable::read(reader)?;
let prev_holder_commitment = Readable::read(reader)?;
let prev_holder_htlc_sigs = Readable::read(reader)?;
- let key_storage = Readable::read(reader)?;
let channel_parameters = Readable::read(reader)?;
+ let keys_len: u32 = Readable::read(reader)?;
+ let mut keys_data = Vec::with_capacity(cmp::min(keys_len as usize, MAX_ALLOC_SIZE));
+ while keys_data.len() != keys_len as usize {
+ // Read 1KB at a time to avoid accidentally allocating 4GB on corrupted channel keys
+ let mut data = [0; 1024];
+ let read_slice = &mut data[0..cmp::min(1024, keys_len as usize - keys_data.len())];
+ reader.read_exact(read_slice)?;
+ keys_data.extend_from_slice(read_slice);
+ }
+ let key_storage = keys_manager.read_chan_signer(&keys_data)?;
+
let pending_claim_requests_len: u64 = Readable::read(reader)?;
let mut pending_claim_requests = HashMap::with_capacity(cmp::min(pending_claim_requests_len as usize, MAX_ALLOC_SIZE / 128));
for _ in 0..pending_claim_requests_len {
pub mod logger;
pub mod config;
-#[cfg(any(test, feature = "_test_utils"))]
+#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
pub mod test_utils;
/// impls of traits that add exra enforcement on the way they're called. Useful for detecting state
use util::enforcing_trait_impls::EnforcingChannelKeys;
use util::events;
use util::logger::{Logger, Level, Record};
-use util::ser::{Readable, Writer, Writeable};
+use util::ser::{Readable, ReadableArgs, Writer, Writeable};
use bitcoin::blockdata::constants::genesis_block;
use bitcoin::blockdata::transaction::{Transaction, TxOut};
}
}
+pub struct OnlyReadsKeysInterface {}
+impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
+ type ChanKeySigner = EnforcingChannelKeys;
+
+ fn get_node_secret(&self) -> SecretKey { unreachable!(); }
+ fn get_destination_script(&self) -> Script { unreachable!(); }
+ fn get_shutdown_pubkey(&self) -> PublicKey { unreachable!(); }
+ fn get_channel_keys(&self, _inbound: bool, _channel_value_satoshis: u64) -> EnforcingChannelKeys { unreachable!(); }
+ fn get_secure_random_bytes(&self) -> [u8; 32] { unreachable!(); }
+
+ fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::ChanKeySigner, msgs::DecodeError> {
+ EnforcingChannelKeys::read(&mut std::io::Cursor::new(reader))
+ }
+}
+
pub struct TestChainMonitor<'a> {
pub added_monitors: Mutex<Vec<(OutPoint, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>>,
pub latest_monitor_update_id: Mutex<HashMap<[u8; 32], (OutPoint, u64)>>,
// At every point where we get a monitor update, we should be able to send a useful monitor
// to a watchtower and disk...
let mut w = TestVecWriter(Vec::new());
- monitor.serialize_for_disk(&mut w).unwrap();
+ monitor.write(&mut w).unwrap();
let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::read(
- &mut ::std::io::Cursor::new(&w.0)).unwrap().1;
+ &mut ::std::io::Cursor::new(&w.0), &OnlyReadsKeysInterface {}).unwrap().1;
assert!(new_monitor == monitor);
self.latest_monitor_update_id.lock().unwrap().insert(funding_txo.to_channel_id(), (funding_txo, monitor.get_latest_update_id()));
self.added_monitors.lock().unwrap().push((funding_txo, monitor));
let monitors = self.chain_monitor.monitors.lock().unwrap();
let monitor = monitors.get(&funding_txo).unwrap();
w.0.clear();
- monitor.serialize_for_disk(&mut w).unwrap();
+ monitor.write(&mut w).unwrap();
let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::read(
- &mut ::std::io::Cursor::new(&w.0)).unwrap().1;
+ &mut ::std::io::Cursor::new(&w.0), &OnlyReadsKeysInterface {}).unwrap().1;
assert!(new_monitor == *monitor);
self.added_monitors.lock().unwrap().push((funding_txo, new_monitor));
}
self.backing.get_secure_random_bytes()
}
+
+ fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::ChanKeySigner, msgs::DecodeError> {
+ EnforcingChannelKeys::read(&mut std::io::Cursor::new(reader))
+ }
}
impl TestKeysInterface {