- self.context.holder_signer.validate_counterparty_revocation(
- self.context.cur_counterparty_commitment_transaction_number + 1,
- &secret
- ).map_err(|_| ChannelError::Close("Failed to validate revocation from peer".to_owned()))?;
-
- self.context.commitment_secrets.provide_secret(self.context.cur_counterparty_commitment_transaction_number + 1, msg.per_commitment_secret)
- .map_err(|_| ChannelError::Close("Previous secrets did not match new one".to_owned()))?;
- self.context.latest_monitor_update_id += 1;
- let mut monitor_update = ChannelMonitorUpdate {
- update_id: self.context.latest_monitor_update_id,
- updates: vec![ChannelMonitorUpdateStep::CommitmentSecret {
- idx: self.context.cur_counterparty_commitment_transaction_number + 1,
- secret: msg.per_commitment_secret,
- }],
- };
-
- // Update state now that we've passed all the can-fail calls...
- // (note that we may still fail to generate the new commitment_signed message, but that's
- // OK, we step the channel here and *then* if the new generation fails we can fail the
- // channel based on that, but stepping stuff here should be safe either way.
- self.context.channel_state &= !(ChannelState::AwaitingRemoteRevoke as u32);
- self.context.sent_message_awaiting_response = None;
- self.context.counterparty_prev_commitment_point = self.context.counterparty_cur_commitment_point;
- self.context.counterparty_cur_commitment_point = Some(msg.next_per_commitment_point);
- self.context.cur_counterparty_commitment_transaction_number -= 1;
-
- if self.context.announcement_sigs_state == AnnouncementSigsState::Committed {
- self.context.announcement_sigs_state = AnnouncementSigsState::PeerReceived;
- }
-
- log_trace!(logger, "Updating HTLCs on receipt of RAA in channel {}...", log_bytes!(self.context.channel_id()));
- let mut to_forward_infos = Vec::new();
- let mut revoked_htlcs = Vec::new();
- let mut finalized_claimed_htlcs = Vec::new();
- let mut update_fail_htlcs = Vec::new();
- let mut update_fail_malformed_htlcs = Vec::new();
- let mut require_commitment = false;
- let mut value_to_self_msat_diff: i64 = 0;
-
- {
- // Take references explicitly so that we can hold multiple references to self.context.
- let pending_inbound_htlcs: &mut Vec<_> = &mut self.context.pending_inbound_htlcs;
- let pending_outbound_htlcs: &mut Vec<_> = &mut self.context.pending_outbound_htlcs;
-
- // We really shouldnt have two passes here, but retain gives a non-mutable ref (Rust bug)
- pending_inbound_htlcs.retain(|htlc| {
- if let &InboundHTLCState::LocalRemoved(ref reason) = &htlc.state {
- log_trace!(logger, " ...removing inbound LocalRemoved {}", log_bytes!(htlc.payment_hash.0));
- if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
- value_to_self_msat_diff += htlc.amount_msat as i64;
- }
- false
- } else { true }
- });
- pending_outbound_htlcs.retain(|htlc| {
- if let &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref outcome) = &htlc.state {
- log_trace!(logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}", log_bytes!(htlc.payment_hash.0));
- if let OutboundHTLCOutcome::Failure(reason) = outcome.clone() { // We really want take() here, but, again, non-mut ref :(
- revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
- } else {
- finalized_claimed_htlcs.push(htlc.source.clone());
- // They fulfilled, so we sent them money
- value_to_self_msat_diff -= htlc.amount_msat as i64;
- }
- false
- } else { true }
- });
- for htlc in pending_inbound_htlcs.iter_mut() {
- let swap = if let &InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) = &htlc.state {
- true
- } else if let &InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) = &htlc.state {
- true
- } else { false };
- if swap {
- let mut state = InboundHTLCState::Committed;
- mem::swap(&mut state, &mut htlc.state);
-
- if let InboundHTLCState::AwaitingRemoteRevokeToAnnounce(forward_info) = state {
- log_trace!(logger, " ...promoting inbound AwaitingRemoteRevokeToAnnounce {} to AwaitingAnnouncedRemoteRevoke", log_bytes!(htlc.payment_hash.0));
- htlc.state = InboundHTLCState::AwaitingAnnouncedRemoteRevoke(forward_info);
- require_commitment = true;
- } else if let InboundHTLCState::AwaitingAnnouncedRemoteRevoke(forward_info) = state {
- match forward_info {
- PendingHTLCStatus::Fail(fail_msg) => {
- log_trace!(logger, " ...promoting inbound AwaitingAnnouncedRemoteRevoke {} to LocalRemoved due to PendingHTLCStatus indicating failure", log_bytes!(htlc.payment_hash.0));
- require_commitment = true;
- match fail_msg {
- HTLCFailureMsg::Relay(msg) => {
- htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(msg.reason.clone()));
- update_fail_htlcs.push(msg)
- },
- HTLCFailureMsg::Malformed(msg) => {
- htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailMalformed((msg.sha256_of_onion, msg.failure_code)));
- update_fail_malformed_htlcs.push(msg)
- },
- }
- },
- PendingHTLCStatus::Forward(forward_info) => {
- log_trace!(logger, " ...promoting inbound AwaitingAnnouncedRemoteRevoke {} to Committed", log_bytes!(htlc.payment_hash.0));
- to_forward_infos.push((forward_info, htlc.htlc_id));
- htlc.state = InboundHTLCState::Committed;
- }
- }
- }
- }
- }
- for htlc in pending_outbound_htlcs.iter_mut() {
- if let OutboundHTLCState::LocalAnnounced(_) = htlc.state {
- log_trace!(logger, " ...promoting outbound LocalAnnounced {} to Committed", log_bytes!(htlc.payment_hash.0));
- htlc.state = OutboundHTLCState::Committed;
- }
- if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut outcome) = &mut htlc.state {
- log_trace!(logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", log_bytes!(htlc.payment_hash.0));
- // Grab the preimage, if it exists, instead of cloning
- let mut reason = OutboundHTLCOutcome::Success(None);
- mem::swap(outcome, &mut reason);
- htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(reason);
- require_commitment = true;
- }
- }
- }
- self.context.value_to_self_msat = (self.context.value_to_self_msat as i64 + value_to_self_msat_diff) as u64;
-
- if let Some((feerate, update_state)) = self.context.pending_update_fee {
- match update_state {
- FeeUpdateState::Outbound => {
- debug_assert!(self.context.is_outbound());
- log_trace!(logger, " ...promoting outbound fee update {} to Committed", feerate);
- self.context.feerate_per_kw = feerate;
- self.context.pending_update_fee = None;
- },
- FeeUpdateState::RemoteAnnounced => { debug_assert!(!self.context.is_outbound()); },
- FeeUpdateState::AwaitingRemoteRevokeToAnnounce => {
- debug_assert!(!self.context.is_outbound());
- log_trace!(logger, " ...promoting inbound AwaitingRemoteRevokeToAnnounce fee update {} to Committed", feerate);
- require_commitment = true;
- self.context.feerate_per_kw = feerate;
- self.context.pending_update_fee = None;
- },
- }