]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Fix reconnect message order on remote updates while waiting on RAA
authorMatt Corallo <git@bluematt.me>
Thu, 18 Oct 2018 02:13:31 +0000 (22:13 -0400)
committerMatt Corallo <git@bluematt.me>
Tue, 23 Oct 2018 19:26:11 +0000 (15:26 -0400)
src/ln/channel.rs

index c53cf2520d6c79a29e5d4144ebb5124e7776a99d..992807493e8d78b05b5649423df602055f96f332 100644 (file)
@@ -296,6 +296,12 @@ pub(super) struct Channel {
        cur_local_commitment_transaction_number: u64,
        cur_remote_commitment_transaction_number: u64,
        value_to_self_msat: u64, // Excluding all pending_htlcs, excluding fees
+       /// Upon receipt of a channel_reestablish we have to figure out whether to send a
+       /// revoke_and_ack first or a commitment update first. Generally, we prefer to send
+       /// revoke_and_ack first, but if we had a pending commitment update of our own waiting on a
+       /// remote revoke when we received the latest commitment update from the remote we have to make
+       /// sure that commitment update gets resent first.
+       received_commitment_while_awaiting_raa: bool,
        pending_inbound_htlcs: Vec<InboundHTLCOutput>,
        pending_outbound_htlcs: Vec<OutboundHTLCOutput>,
        holding_cell_htlc_updates: Vec<HTLCUpdateAwaitingACK>,
@@ -492,6 +498,8 @@ impl Channel {
                        cur_local_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
                        cur_remote_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
                        value_to_self_msat: channel_value_satoshis * 1000 - push_msat,
+                       received_commitment_while_awaiting_raa: false,
+
                        pending_inbound_htlcs: Vec::new(),
                        pending_outbound_htlcs: Vec::new(),
                        holding_cell_htlc_updates: Vec::new(),
@@ -647,6 +655,8 @@ impl Channel {
                        cur_local_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
                        cur_remote_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
                        value_to_self_msat: msg.push_msat,
+                       received_commitment_while_awaiting_raa: false,
+
                        pending_inbound_htlcs: Vec::new(),
                        pending_outbound_htlcs: Vec::new(),
                        holding_cell_htlc_updates: Vec::new(),
@@ -1696,6 +1706,7 @@ impl Channel {
 
                self.cur_local_commitment_transaction_number -= 1;
                self.last_local_commitment_txn = new_local_commitment_txn;
+               self.received_commitment_while_awaiting_raa = (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) != 0;
 
                let (our_commitment_signed, monitor_update) = if need_our_commitment && (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 {
                        // If we're AwaitingRemoteRevoke we can't send a new commitment here, but that's ok -
@@ -1831,6 +1842,7 @@ impl Channel {
                self.their_prev_commitment_point = self.their_cur_commitment_point;
                self.their_cur_commitment_point = Some(msg.next_per_commitment_point);
                self.cur_remote_commitment_transaction_number -= 1;
+               self.received_commitment_while_awaiting_raa = false;
 
                let mut to_forward_infos = Vec::new();
                let mut revoked_htlcs = Vec::new();
@@ -2120,7 +2132,11 @@ impl Channel {
                        })
                } else { None };
 
-               let order = RAACommitmentOrder::RevokeAndACKFirst;
+               let order = if self.received_commitment_while_awaiting_raa {
+                       RAACommitmentOrder::CommitmentFirst
+               } else {
+                       RAACommitmentOrder::RevokeAndACKFirst
+               };
 
                if msg.next_local_commitment_number == our_next_remote_commitment_number {
                        if required_revoke.is_some() {