- LocalSignedTx {
- txid: tx.txid(),
- tx, revocation_key, a_htlc_key, b_htlc_key, delayed_payment_key, feerate_per_kw, htlc_outputs
- }
- }
- }
- }
-
- let prev_local_signed_commitment_tx = match read_bytes!(1)[0] {
- 0 => None,
- 1 => {
- Some(read_local_tx!())
- },
- _ => return None,
- };
-
- let current_local_signed_commitment_tx = match read_bytes!(1)[0] {
- 0 => None,
- 1 => {
- Some(read_local_tx!())
- },
- _ => return None,
- };
-
- let payment_preimages_len = byte_utils::slice_to_be64(read_bytes!(8));
- if payment_preimages_len > data.len() as u64 / 32 { return None; }
- let mut payment_preimages = HashMap::with_capacity(payment_preimages_len as usize);
- let mut sha = Sha256::new();
- for _ in 0..payment_preimages_len {
- let mut preimage = [0; 32];
- preimage[..].copy_from_slice(read_bytes!(32));
- sha.reset();
- sha.input(&preimage);
- let mut hash = [0; 32];
- sha.result(&mut hash);
- if let Some(_) = payment_preimages.insert(hash, preimage) {
- return None;
- }
- }
-
- let destination_script_len = byte_utils::slice_to_be64(read_bytes!(8));
- let destination_script = Script::from(read_bytes!(destination_script_len).to_vec());
-
- Some(ChannelMonitor {
- funding_txo,
- commitment_transaction_number_obscure_factor,
-
- key_storage,
- delayed_payment_base_key,
- their_htlc_base_key,
- their_cur_revocation_points,
-
- our_to_self_delay,
- their_to_self_delay,
-
- old_secrets,
- remote_claimable_outpoints,
- remote_commitment_txn_on_chain: Mutex::new(remote_commitment_txn_on_chain),
- remote_hash_commitment_number,
-
- prev_local_signed_commitment_tx,
- current_local_signed_commitment_tx,
-
- payment_preimages,
-
- destination_script,
- secp_ctx,
- })
- }
-
- //TODO: Functions to serialize/deserialize (with different forms depending on which information
- //we want to leave out (eg funding_txo, etc).
-
- /// Can only fail if idx is < get_min_seen_secret
- pub fn get_secret(&self, idx: u64) -> Result<[u8; 32], HandleError> {
- for i in 0..self.old_secrets.len() {
- if (idx & (!((1 << i) - 1))) == self.old_secrets[i].1 {
- return Ok(ChannelMonitor::derive_secret(self.old_secrets[i].0, i as u8, idx))
- }
- }
- assert!(idx < self.get_min_seen_secret());
- Err(HandleError{err: "idx too low", msg: None})
- }
-
- pub fn get_min_seen_secret(&self) -> u64 {
- //TODO This can be optimized?
- let mut min = 1 << 48;
- for &(_, idx) in self.old_secrets.iter() {
- if idx < min {
- min = idx;
- }
- }
- min
- }
-
- /// Attempts to claim a remote commitment transaction's outputs using the revocation key and
- /// data in remote_claimable_outpoints. Will directly claim any HTLC outputs which expire at a
- /// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for
- /// HTLC-Success/HTLC-Timeout transactions, and claim them using the revocation key (if
- /// applicable) as well.
- fn check_spend_remote_transaction(&self, tx: &Transaction, height: u32) -> Vec<Transaction> {
- // Most secp and related errors trying to create keys means we have no hope of constructing
- // a spend transaction...so we return no transactions to broadcast
- let mut txn_to_broadcast = Vec::new();
- macro_rules! ignore_error {
- ( $thing : expr ) => {
- match $thing {
- Ok(a) => a,
- Err(_) => return txn_to_broadcast
- }
- };
- }
-
- let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers!
- let per_commitment_option = self.remote_claimable_outpoints.get(&commitment_txid);
-
- let commitment_number = 0xffffffffffff - ((((tx.input[0].sequence as u64 & 0xffffff) << 3*8) | (tx.lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor);
- if commitment_number >= self.get_min_seen_secret() {
- let secret = self.get_secret(commitment_number).unwrap();
- let per_commitment_key = ignore_error!(SecretKey::from_slice(&self.secp_ctx, &secret));
- let (revocation_pubkey, b_htlc_key) = match self.key_storage {
- KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key } => {
- let per_commitment_point = ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key));
- (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key)))),
- ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &htlc_base_key)))))
- },
- KeyStorage::SigsMode { ref revocation_base_key, ref htlc_base_key, .. } => {
- let per_commitment_point = ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key));
- (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &revocation_base_key)),
- ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &htlc_base_key)))
- },
- };
- let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key)), &self.delayed_payment_base_key));
- let a_htlc_key = match self.their_htlc_base_key {
- None => return txn_to_broadcast,
- Some(their_htlc_base_key) => ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key)), &their_htlc_base_key)),
- };
-
- let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key);
- let revokeable_p2wsh = revokeable_redeemscript.to_v0_p2wsh();
-
- let mut total_value = 0;
- let mut values = Vec::new();
- let mut inputs = Vec::new();
- let mut htlc_idxs = Vec::new();
-
- for (idx, outp) in tx.output.iter().enumerate() {
- if outp.script_pubkey == revokeable_p2wsh {
- inputs.push(TxIn {
- prev_hash: commitment_txid,
- prev_index: idx as u32,
- script_sig: Script::new(),
- sequence: 0xfffffffd,
- witness: Vec::new(),
- });
- htlc_idxs.push(None);
- values.push(outp.value);
- total_value += outp.value;
- break; // There can only be one of these