+ /// Gets the funding transaction outpoint of the channel this ChannelMonitor is monitoring for.
+ pub fn get_funding_txo(&self) -> Option<OutPoint> {
+ match self.funding_txo {
+ Some((outpoint, _)) => Some(outpoint),
+ None => None
+ }
+ }
+
+ /// Gets the sets of all outpoints which this ChannelMonitor expects to hear about spends of.
+ /// Generally useful when deserializing as during normal operation the return values of
+ /// block_connected are sufficient to ensure all relevant outpoints are being monitored (note
+ /// that the get_funding_txo outpoint and transaction must also be monitored for!).
+ pub fn get_monitored_outpoints(&self) -> Vec<(Sha256dHash, u32, &Script)> {
+ let mut res = Vec::with_capacity(self.remote_commitment_txn_on_chain.len() * 2);
+ for (ref txid, &(_, ref outputs)) in self.remote_commitment_txn_on_chain.iter() {
+ for (idx, output) in outputs.iter().enumerate() {
+ res.push(((*txid).clone(), idx as u32, output));
+ }
+ }
+ res
+ }
+
+ /// Serializes into a vec, with various modes for the exposed pub fns
+ fn write<W: Writer>(&self, writer: &mut W, for_local_storage: bool) -> Result<(), ::std::io::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])?;
+ writer.write_all(&[MIN_SERIALIZATION_VERSION; 1])?;
+
+ match &self.funding_txo {
+ &Some((ref outpoint, ref script)) => {
+ writer.write_all(&outpoint.txid[..])?;
+ writer.write_all(&byte_utils::be16_to_array(outpoint.index))?;
+ script.write(writer)?;
+ },
+ &None => {
+ // We haven't even been initialized...not sure why anyone is serializing us, but
+ // not much to give them.
+ return Ok(());
+ },
+ }
+
+ // Set in initial Channel-object creation, so should always be set by now:
+ U48(self.commitment_transaction_number_obscure_factor).write(writer)?;
+
+ match self.key_storage {
+ KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key, ref delayed_payment_base_key, ref prev_latest_per_commitment_point, ref latest_per_commitment_point } => {
+ writer.write_all(&[0; 1])?;
+ writer.write_all(&revocation_base_key[..])?;
+ writer.write_all(&htlc_base_key[..])?;
+ writer.write_all(&delayed_payment_base_key[..])?;
+ if let Some(ref prev_latest_per_commitment_point) = *prev_latest_per_commitment_point {
+ writer.write_all(&[1; 1])?;
+ writer.write_all(&prev_latest_per_commitment_point.serialize())?;
+ } else {
+ writer.write_all(&[0; 1])?;
+ }
+ if let Some(ref latest_per_commitment_point) = *latest_per_commitment_point {
+ writer.write_all(&[1; 1])?;
+ writer.write_all(&latest_per_commitment_point.serialize())?;
+ } else {
+ writer.write_all(&[0; 1])?;
+ }
+
+ },
+ KeyStorage::SigsMode { .. } => unimplemented!(),
+ }
+
+ writer.write_all(&self.their_htlc_base_key.as_ref().unwrap().serialize())?;
+ writer.write_all(&self.their_delayed_payment_base_key.as_ref().unwrap().serialize())?;
+
+ match self.their_cur_revocation_points {
+ Some((idx, pubkey, second_option)) => {
+ writer.write_all(&byte_utils::be48_to_array(idx))?;
+ writer.write_all(&pubkey.serialize())?;
+ match second_option {
+ Some(second_pubkey) => {
+ writer.write_all(&second_pubkey.serialize())?;
+ },
+ None => {
+ writer.write_all(&[0; 33])?;
+ },
+ }
+ },
+ None => {
+ writer.write_all(&byte_utils::be48_to_array(0))?;
+ },
+ }
+
+ writer.write_all(&byte_utils::be16_to_array(self.our_to_self_delay))?;
+ writer.write_all(&byte_utils::be16_to_array(self.their_to_self_delay.unwrap()))?;
+
+ for &(ref secret, ref idx) in self.old_secrets.iter() {
+ writer.write_all(secret)?;
+ writer.write_all(&byte_utils::be64_to_array(*idx))?;
+ }
+
+ macro_rules! serialize_htlc_in_commitment {
+ ($htlc_output: expr) => {
+ writer.write_all(&[$htlc_output.offered as u8; 1])?;
+ writer.write_all(&byte_utils::be64_to_array($htlc_output.amount_msat))?;
+ writer.write_all(&byte_utils::be32_to_array($htlc_output.cltv_expiry))?;
+ writer.write_all(&$htlc_output.payment_hash)?;
+ writer.write_all(&byte_utils::be32_to_array($htlc_output.transaction_output_index))?;
+ }
+ }
+
+ writer.write_all(&byte_utils::be64_to_array(self.remote_claimable_outpoints.len() as u64))?;
+ for (ref txid, ref htlc_outputs) in self.remote_claimable_outpoints.iter() {
+ writer.write_all(&txid[..])?;
+ writer.write_all(&byte_utils::be64_to_array(htlc_outputs.len() as u64))?;
+ for htlc_output in htlc_outputs.iter() {
+ serialize_htlc_in_commitment!(htlc_output);
+ }
+ }
+
+ writer.write_all(&byte_utils::be64_to_array(self.remote_commitment_txn_on_chain.len() as u64))?;
+ for (ref txid, &(commitment_number, ref txouts)) in self.remote_commitment_txn_on_chain.iter() {
+ writer.write_all(&txid[..])?;
+ writer.write_all(&byte_utils::be48_to_array(commitment_number))?;
+ (txouts.len() as u64).write(writer)?;
+ for script in txouts.iter() {
+ script.write(writer)?;
+ }
+ }
+
+ if for_local_storage {
+ writer.write_all(&byte_utils::be64_to_array(self.remote_hash_commitment_number.len() as u64))?;
+ for (ref payment_hash, commitment_number) in self.remote_hash_commitment_number.iter() {
+ writer.write_all(*payment_hash)?;
+ writer.write_all(&byte_utils::be48_to_array(*commitment_number))?;
+ }
+ } else {
+ writer.write_all(&byte_utils::be64_to_array(0))?;
+ }
+
+ macro_rules! serialize_local_tx {
+ ($local_tx: expr) => {
+ if let Err(e) = $local_tx.tx.consensus_encode(&mut serialize::RawEncoder::new(WriterWriteAdaptor(writer))) {
+ match e {
+ serialize::Error::Io(e) => return Err(e),
+ _ => panic!("local tx must have been well-formed!"),
+ }
+ }
+
+ writer.write_all(&$local_tx.revocation_key.serialize())?;
+ writer.write_all(&$local_tx.a_htlc_key.serialize())?;
+ writer.write_all(&$local_tx.b_htlc_key.serialize())?;
+ writer.write_all(&$local_tx.delayed_payment_key.serialize())?;
+
+ writer.write_all(&byte_utils::be64_to_array($local_tx.feerate_per_kw))?;
+ writer.write_all(&byte_utils::be64_to_array($local_tx.htlc_outputs.len() as u64))?;
+ for &(ref htlc_output, ref their_sig, ref our_sig) in $local_tx.htlc_outputs.iter() {
+ serialize_htlc_in_commitment!(htlc_output);
+ writer.write_all(&their_sig.serialize_compact(&self.secp_ctx))?;
+ writer.write_all(&our_sig.serialize_compact(&self.secp_ctx))?;
+ }
+ }
+ }
+
+ if let Some(ref prev_local_tx) = self.prev_local_signed_commitment_tx {
+ writer.write_all(&[1; 1])?;
+ serialize_local_tx!(prev_local_tx);
+ } else {
+ writer.write_all(&[0; 1])?;
+ }
+
+ if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx {
+ writer.write_all(&[1; 1])?;
+ serialize_local_tx!(cur_local_tx);
+ } else {
+ writer.write_all(&[0; 1])?;
+ }
+
+ if for_local_storage {
+ writer.write_all(&byte_utils::be48_to_array(self.current_remote_commitment_number))?;
+ } else {
+ writer.write_all(&byte_utils::be48_to_array(0))?;
+ }
+
+ writer.write_all(&byte_utils::be64_to_array(self.payment_preimages.len() as u64))?;
+ for payment_preimage in self.payment_preimages.values() {
+ writer.write_all(payment_preimage)?;
+ }
+
+ self.last_block_hash.write(writer)?;
+ self.destination_script.write(writer)?;
+
+ Ok(())
+ }
+
+ /// 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 not just starting at the same height but starting at the highest
+ /// common block that appears on your best chain as well as on the chain which contains the
+ /// last block hash returned) upon deserializing the object!
+ pub fn write_for_disk<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+ self.write(writer, true)
+ }
+
+ /// Encodes this monitor into the given writer, suitable for sending to a remote watchtower
+ ///
+ /// 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 not just starting at the same height but starting at the highest
+ /// common block that appears on your best chain as well as on the chain which contains the
+ /// last block hash returned) upon deserializing the object!
+ pub fn write_for_watchtower<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+ self.write(writer, false)