From 42aa7f8e5af8ebbbe28ed3066ae6440a9a9eb98f Mon Sep 17 00:00:00 2001 From: Bitcoin Txoko <142011724+bitcointxoko@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:49:41 +0100 Subject: [PATCH] Update ln-07.md --- en/ln-07.md | 92 ++++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/en/ln-07.md b/en/ln-07.md index 91b8dd6..b37d40c 100644 --- a/en/ln-07.md +++ b/en/ln-07.md @@ -21,13 +21,13 @@ Here are some concepts and flows that we have covered previously in our series t #### Set up -Alice and Bob have successfully opened their channel. They have both seen that the funding transaction is confirmed and they have exchanged the channel_ready message with each other to indicate that they are ready to use the channel. The state of their asymmetric commitment transactions currently looks like this: +Alice and Bob have successfully opened their channel. They have both seen that the funding transaction is confirmed and they have exchanged the `channel_ready` message with each other to indicate that they are ready to use the channel. The state of their asymmetric commitment transactions currently looks like this: ![1-initial]() -Both commitment transactions spend the 2-of-2 multisig funding transaction output. Since it is a 2-of-2 multisig, spending from this output requires signatures from both peers. The signatures are represented by the two boxes at the top of the commitment transactions. You can see from the diagram that Alice's commitment transaction has a signature from Bob represented by the blue box; Bob has a signature from Alice for his commitment transaction represented by the green box. Each commitment transaction also has the to_local and to_remote outputs which pay the respective parties their current channel balance. Both Alice and Bob can sign their own commitment transactions at any time and broadcast it to the Bitcoin Network. This woul be a **force close**. +Both commitment transactions spend the 2-of-2 multisig funding transaction output. Since it is a 2-of-2 multisig, spending from this output requires signatures from both peers. The signatures are represented by the two boxes at the top of the commitment transactions. You can see from the diagram that Alice's commitment transaction has a signature from Bob represented by the blue box; Bob has a signature from Alice for his commitment transaction represented by the green box. Each commitment transaction also has the `to_local` and `to_remote` outputs which pay the respective parties their current channel balance. Both Alice and Bob can sign their own commitment transactions at any time and broadcast it to the Bitcoin Network. This woul be a **force close**. -For the sake of making the next few diagrams easier to follow, we will ignore the funding transactions as well as the to_local and to_remote outputs for a while since our initial focus will be on adding and removing HTLC outputs. So the above diagram is now simplified to this: +For the sake of making the next few diagrams easier to follow, we will ignore the funding transactions as well as the `to_local` and `to_remote` outputs for a while since our initial focus will be on adding and removing HTLC outputs. So the above diagram is now simplified to this: ![2-simplified]() @@ -41,7 +41,7 @@ Hint: if you like git, this is very much like a git workflow. Past commits are o #### Adding a HTLC -When either Alice or Bob want to send a payment, they would need to propose the inclusion of the HTLC to their channel peer. This is done with the update_add_htlc message: +When either Alice or Bob want to send a payment, they would need to propose the inclusion of the HTLC to their channel peer. This is done with the `update_add_htlc` message: ![update_add_htlc]() @@ -55,17 +55,17 @@ Here's a table for what each of the message fields mean: | cltv_expiry | the block height that the HTLC should expire at. | | onion_routing_packet and blinding_point | data that the HTLC recipient will use to determine where next to send the payment. | -There is a counterintuitive point to note here: the sender of this message does not yet put this update in their own staging area yet. This is because the update is still "pending on the receiver" because the sender has not yet received any acknowledgement from the receiver for the new update. Imagine this scenario: the sender sends an update and then immediately receives a commitment_signed message (more details on this later). In this case, there should be no ambiguity around which updates are included in the transaction being signed. Hopefully this will make more sense as we work through the example. +There is a counterintuitive point to note here: the sender of this message does not yet put this update in their own staging area yet. This is because the update is still "pending on the receiver" because the sender has not yet received any acknowledgement from the receiver for the new update. Imagine this scenario: the sender sends an update and then immediately receives a `commitment_signed` message (more details on this later). In this case, there should be no ambiguity around which updates are included in the transaction being signed. Hopefully this will make more sense as we work through the example. ##### Step1: Alice -> Bob: update_add_htlc(A1) -Let's say Alice sends Bob an update_add_htlc. Let's call this HTLC A1 because it's the first one Alice(A) is sending to Bob. If Bob is happy with all the fields in the messag, then he adds the HTLC to his staging area commitment transaction nad Alice marks the HTLC as pending on Bob's side but does not yet add it to her own staging commitment transaction. +Let's say Alice sends Bob an `update_add_htlc`. Let's call this HTLC A1 because it's the first one Alice(A) is sending to Bob. If Bob is happy with all the fields in the messag, then he adds the HTLC to his staging area commitment transaction nad Alice marks the HTLC as pending on Bob's side but does not yet add it to her own staging commitment transaction. ![add_a1]() -Note that neither side has actually committed to this HTLC yet so if Bob is a routing node for this payment, he should not yet send update_add_HTLC to the next hop on the route until A1 has been _irrevocably_ committed. An HTLC addition or removal is only considered irrevocably committed once both parties in the channel have committed to the commitment transaction with or without it. +Note that neither side has actually committed to this HTLC yet so if Bob is a routing node for this payment, he should not yet send `update_add_HTLC` to the next hop on the route until A1 has been _irrevocably_ committed. An HTLC addition or removal is only considered irrevocably committed once both parties in the channel have committed to the commitment transaction with or without it. -This is not shown on the simplified diagram, but in reality Alice's main output in Bob's staging commitment transaction (i.e. the to_remote output) will now have the value of the added HTLC subtracted (along with the fees to cover the extra output). If the HTLC ends up succeeding then this amount will be added to Bob's output and if it ends up failing, then it will be re-added to Alice's output. +This is not shown on the simplified diagram, but in reality Alice's main output in Bob's staging commitment transaction (i.e. the `to_remote` output) will now have the value of the added HTLC subtracted (along with the fees to cover the extra output). If the HTLC ends up succeeding then this amount will be added to Bob's output and if it ends up failing, then it will be re-added to Alice's output. ##### Step 2: Alice -> Bob: update_add_htlc(A2) @@ -81,7 +81,7 @@ Likewise, Bob can sugges a change, B1, to Alice: #### Committing to the current state -At some point, one the peers will want to make sure that the other peer has committed to the latest set of changes and revoke the previous valid state. The is done by sending the commitment_signed message: +At some point, one the peers will want to make sure that the other peer has committed to the latest set of changes and revoke the previous valid state. The is done by sending the `commitment_signed` message: ![commitment_signed]() @@ -101,7 +101,7 @@ Let's say that Alice sends this message to Bob. Bob will now have all the requir ![commit_sign_1]() -Notice that Alice knew that her signature would need to cover the A1 and A2 HTLCs. This is fine because the [underlying transport](https://github.com/lightning/bolts/blob/master/08-transport.md) is guaranteed to be reliable and ordered meaning that if Bob were to receive Alice's commitment_signed message then it means that he definitely received her update_add_htlc messages for A1 and A2. Alice and Bob both know that the signature should not cover the B1 HTLC since Alice has not sent an acknowledgement for it yet. +Notice that Alice knew that her signature would need to cover the A1 and A2 HTLCs. This is fine because the [underlying transport](https://github.com/lightning/bolts/blob/master/08-transport.md) is guaranteed to be reliable and ordered meaning that if Bob were to receive Alice's `commitment_signed` message then it means that he definitely received her `update_add_htlc` messages for A1 and A2. Alice and Bob both know that the signature should not cover the B1 HTLC since Alice has not sent an acknowledgement for it yet. Another thing to notice is that Bob now actually has two valid commitment transwactions since he has not yet revoked his previous state. However, he is incentivised to revoke his previous commitment transaction since the HTLCs on the new state are one of the folowing: - Payments to Bob himself meaning that he gains from committing to the new state. If he doesn't commit to the new state, then Alice won't either and so there would still exist a version of a commitment transaction that does not pay Bob his incoming funds. @@ -110,14 +110,14 @@ Another thing to notice is that Bob now actually has two valid commitment transw ##### Step 5: Bob -> Alice: revoke_and_ack -In response to Alice's commitment_signed, Bob sends the revoke_and_ack message: +In response to Alice's `commitment_signed`, Bob sends the `revoke_and_ack` message: ![revoke_and_ack]() -- The per_commitment_secret provides Alice with the information she needs to be able to spend any revocation path on Bob's previously valid state. See [revocation chapter] for more detail about how revocation works. -- The next_per_commitment_point gives Alice the information she needs in order to derive the revocation pubkey that will be used in Bob's next commitment transaction. +- The `per_commitment_secret` provides Alice with the information she needs to be able to spend any revocation path on Bob's previously valid state. See [revocation chapter] for more detail about how revocation works. +- The `next_per_commitment_point` gives Alice the information she needs in order to derive the revocation pubkey that will be used in Bob's next commitment transaction. -Once Alice receives this message, Bob's previous commitment transaction has successfully been revoked. Note that this message explicitly acknowledges the commitment_signed message sent by Alice and by extension, since message delivery is reliable and ordered, it also implicitly acknowledge the update_add_htlc messages that Alice sent for A1 and A2. Alice can therefore finally add A1 and A2 to her staging area commitment transaction since they are no longer pending on Bob's side: +Once Alice receives this message, Bob's previous commitment transaction has successfully been revoked. Note that this message explicitly acknowledges the `commitment_signed` message sent by Alice and by extension, since message delivery is reliable and ordered, it also implicitly acknowledge the `update_add_htlc` messages that Alice sent for A1 and A2. Alice can therefore finally add A1 and A2 to her staging area commitment transaction since they are no longer pending on Bob's side: ![8_revoke_1]() @@ -128,28 +128,28 @@ Now we can clean up the diagram a little: From the last diagram, notice that Alice's and Bob's latest commitment transactions are actually out of sync. This is fine since none of the updates have been irrevocably committed yet. That might seem hard to believe since the commitment transactions look so different so let's walk through the consequences of either of these transactions ending up on-chain from the perspective of both sides. - From Alice's perspective: - - if her commitment transaction were to be broadcast, she gets back her original to_local amount. - - if Bob's commitment transaction were to be broadcast, then Alice's offered HTLCs (such as A1 and A2) will be on-chain. For offered HTLCs, alice is sending sats _out_, meaning that her to_local would be lower. But, if Bob was a routing node for these HTLCs then he would not have forwarded them as they are not yet irrevocably committed meaning that he won't receive the pre-images required to claim these HTLCs and therefore Alice would be able to get her funds back via the timeout path. If Bob was the recipient of these HTLCs, then he would be able to produce the pre-image to claim the HTLCs, but then Alice would see the pre-image on-chain and would be able to claim the incoming HTLCs from their incoming channel and would thus have earned routing fees. + - if her commitment transaction were to be broadcast, she gets back her original `to_local` amount. + - if Bob's commitment transaction were to be broadcast, then Alice's offered HTLCs (such as A1 and A2) will be on-chain. For offered HTLCs, alice is sending sats _out_, meaning that her `to_local` would be lower. But, if Bob was a routing node for these HTLCs then he would not have forwarded them as they are not yet irrevocably committed meaning that he won't receive the pre-images required to claim these HTLCs and therefore Alice would be able to get her funds back via the timeout path. If Bob was the recipient of these HTLCs, then he would be able to produce the pre-image to claim the HTLCs, but then Alice would see the pre-image on-chain and would be able to claim the incoming HTLCs from their incoming channel and would thus have earned routing fees. - From Bob's perspective: - - if Alice's commitment transaction is broadcast, Bob gets back his funds via the to_remote output. + - if Alice's commitment transaction is broadcast, Bob gets back his funds via the `to_remote` output. - if Bob had to force close via his commitment transaction, then HTLCs offered to him (like A1 and A2) would be on-chain. If Bob was routing these HTLCs, then he would not have forwarded them on since they are not yet irrevocably committed. So he wouldn't be able to claim the success path but that is fine since the funds for these did not come out of his balance. If Bob waas the final destination for these, then he would be able to claim them via the success path. ##### Step 6: Alice -> Bob: update_add_htlc(A3) -We want to be very clear about the point that the commitment transactions can remain out of sync indefinitely and that Bob does not need to send commitment_signed just because Alice did. So, for the sake of another example, let's say that Alice at this point sends yet another HTLC, A3, to Bob: +We want to be very clear about the point that the commitment transactions can remain out of sync indefinitely and that Bob does not need to send `commitment_signed` just because Alice did. So, for the sake of another example, let's say that Alice at this point sends yet another HTLC, A3, to Bob: ![10_add_a3]() ##### Step 7: Bob -> Alice: commitment_signed -Bob wants to irrevocably commit some of the HTLCs so that he can forward them on, so he finally sends Alice a commitment_signed of his own. This will include his signature for Alice's staging-area commitment transaction along with all the signatures required from him for the second-level HTLC outputs. +Bob wants to irrevocably commit some of the HTLCs so that he can forward them on, so he finally sends Alice a `commitment_signed` of his own. This will include his signature for Alice's staging-area commitment transaction along with all the signatures required from him for the second-level HTLC outputs. ![11_commit_sign_2]() ##### Step 8: Alice -> Bob: revoke_and_ack -Just like Bob did previously, Alice responds to the commitment_signed with a revoke_and_ack in order to revoke her previous state. This also serves as an acknowledgement to Bob that Alice has received and committed to B1 and so Bob can now add B1 to his staging area commitment transaction. +Just like Bob did previously, Alice responds to the `commitment_signed` with a `revoke_and_ack` in order to revoke her previous state. This also serves as an acknowledgement to Bob that Alice has received and committed to B1 and so Bob can now add B1 to his staging area commitment transaction. ![12_revoke_2]() @@ -189,47 +189,47 @@ You probably get the idea of adding HTLCs now. But what about removing them? HTL ##### Step 12: Bob -> Alice: update_fulfill_htlc(A2) -In the best case scenario, a HTLC is removed because it is being fulfilled meaning that its pre-image is being passed back. This is done with the update_fulfilled_htlc message which looks like this: +In the best case scenario, a HTLC is removed because it is being fulfilled meaning that its pre-image is being passed back. This is done with the `update_fulfilled_htlc` message which looks like this: ![update_fulfill_htlc]() -In our example, Bob sends Alice the update_fulfill_htlc message for HTLC A2. This also demonstrates that HTLCs don't have to be removed in the same order they were added. +In our example, Bob sends Alice the `update_fulfill_htlc` message for HTLC A2. This also demonstrates that HTLCs don't have to be removed in the same order they were added. ![20_fulfill_a2]() -Notice that just like the updates for adding an HTLC, updates for removing an HTLC will also initially be pending on the receiver side until they have been acknowledged by a revoke_and_ack. So in our case, Alice removes A2 from her staging area transaction when she receives the update_fulfill_htlc (and allocates the HTLC amount to Bob's output) but Bob does not yet remove the HTLC from his staging area transaction. +Notice that just like the updates for adding an HTLC, updates for removing an HTLC will also initially be pending on the receiver side until they have been acknowledged by a `revoke_and_ack`. So in our case, Alice removes A2 from her staging area transaction when she receives the `update_fulfill_htlc` (and allocates the HTLC amount to Bob's output) but Bob does not yet remove the HTLC from his staging area transaction. Unlike other update messages, there is no need to wait for an HTLC removal to be irrevocably committed if you receive the pre-image for it. After all, you can immediately send the pre-image upstream in order to claim any HTLCs there. ##### Step 13: Bob -> Alice: update_fail_htlc(A1) -HTLCs can also be removed due to payment failures such as HTLCs timing out or if there was some sort of routing failure such as a specific channel on the path no longer existing, a hop's fee requirements not being met, a link not having sufficient balance, etc. Such failures are communicated with the update_fail_htlc message: +HTLCs can also be removed due to payment failures such as HTLCs timing out or if there was some sort of routing failure such as a specific channel on the path no longer existing, a hop's fee requirements not being met, a link not having sufficient balance, etc. Such failures are communicated with the `update_fail_htlc` message: ![update_fail_htlc]() The reason field is an encrypted blob for the sender of the payme3nt in order to inform them of the failure reason. -After Bob sends Alice the update_fail_htlc message for A1, the state looks as follows: +After Bob sends Alice the `update_fail_htlc` message for A1, the state looks as follows: ![21_fail_a1]() ##### Step 14: Bob -> Alice: update_fail_malformed_htlc(A3) -The final message that can be used to remove an HTLC is the update_fail_malformed_htlc message: +The final message that can be used to remove an HTLC is the `update_fail_malformed_htlc` message: ![update_fail_malformed_htlc]() -This message is sent if any hop on the payment route was unable to parse the onion_routing_packet it received in update_add_htlc. If Bob sends Alice this message for A3, then the state now looks like this: +This message is sent if any hop on the payment route was unable to parse the `onion_routing_packet` it received in `update_add_htlc`. If Bob sends Alice this message for A3, then the state now looks like this: ![22_fail_a3]() ##### Step 15: Alice -> Bob: update_fulfill_htlc(B1) -Alice also initiates the removal of B1 by sending an update_fulfill_htlc to Bob. +Alice also initiates the removal of B1 by sending an `update_fulfill_htlc` to Bob. ![23_fulfill_b1]() -Let's now clean up the HTLC removals by irrevocably committing them. This will require a few commitment_signed - revoke_and_ack flows: +Let's now clean up the HTLC removals by irrevocably committing them. This will require a few `commitment_signed` - `revoke_and_ack` flows: ##### Step 16: Bob -> Alice: commitment_signed @@ -261,33 +261,33 @@ The two valid states now look nice and clean again: ### Updating fees -There is one more update_* mesasge that we need to cover and that is the update_fee message. This message is used to update the fee-rate that the peers should use when constructing their commitment transactions. The original fee-rate is decided in the open-channel flow but if the average mempool fee-rate increases, the channel funder might decide to update the fee of the commitment transactions so that they have a better chance of getting confirmed in a timely manner in a force close situation. It could also be that when the channel was opened, a very high fee-rate was chosen and perhaps a lower fee-rate would be desired. +There is one more `update_*` mesasge that we need to cover and that is the `update_fee` message. This message is used to update the fee-rate that the peers should use when constructing their commitment transactions. The original fee-rate is decided in the open-channel flow but if the average mempool fee-rate increases, the channel funder might decide to update the fee of the commitment transactions so that they have a better chance of getting confirmed in a timely manner in a force close situation. It could also be that when the channel was opened, a very high fee-rate was chosen and perhaps a lower fee-rate would be desired. -This message follows similar rules to other update_* messages in that it must also be irrevocably committed before it takes effect. The only extra rule that applies to this message is that only the channel funder may send this message: +This message follows similar rules to other `update_*` messages in that it must also be irrevocably committed before it takes effect. The only extra rule that applies to this message is that only the channel funder may send this message: ![update_fee]() -Note that with anchor channels, the need to use the update_fee messaging is becoming less and less since nodes will be able to use CPFP on the force-close transaction if required. +Note that with anchor channels, the need to use the `update_fee` messaging is becoming less and less since nodes will be able to use CPFP on the force-close transaction if required. ### Message retransmission -Something that you may have picked up on in the add/remove HTLC flow is that explicit acknowledgements for the update_* messages is delayed until the commitment_signed/revoke_and_ack exchange. That is ok most of the time since we assume that the underlying transport between the two nodes (see [BOLT8]()) is ordered and reliable. However, if for some reason the connection between the two nodes needs to be re-established for some reason, there will be doubt regarding whether our peer has received the last message that we sent. This is where the channel_reestablish message comes in. Upon reconnection, before continuing with the noirmal operation flow, the peers will exchange this message to make sure they are on the same page and to determine which messages they possibly need to re-send to their peer. +Something that you may have picked up on in the add/remove HTLC flow is that explicit acknowledgements for the `update_*` messages is delayed until the `commitment_signed`/`revoke_and_ack exchange`. That is ok most of the time since we assume that the underlying transport between the two nodes (see [BOLT8]()) is ordered and reliable. However, if for some reason the connection between the two nodes needs to be re-established for some reason, there will be doubt regarding whether our peer has received the last message that we sent. This is where the `channel_reestablish` message comes in. Upon reconnection, before continuing with the noirmal operation flow, the peers will exchange this message to make sure they are on the same page and to determine which messages they possibly need to re-send to their peer. ![channel_reestablish]() -Each peer in the channel has their version of the commitment transaction and the two commitment transactions can be updated independently, meaning that the number of times that one side's commitment transaction state has been updated (through the commitment_signed and revoke_and_ack flow) could be completely different to that of the other side. +Each peer in the channel has their version of the commitment transaction and the two commitment transactions can be updated independently, meaning that the number of times that one side's commitment transaction state has been updated (through the `commitment_signed` and `revoke_and_ack` flow) could be completely different to that of the other side. -The next_commitment_number field in the channel_reestablish message allows us to communicate with our peer the next commitment_signed that we expect to receive from them. This way, they will know if we have perhaps missed a commitment_signed from them that they previously sent before the disconnection. In other words, next_commitment_number tells the remote peer what we see our latest committed state to be. +The `next_commitment_number` field in the `channel_reestablish` message allows us to communicate with our peer the next `commitment_signed` that we expect to receive from them. This way, they will know if we have perhaps missed a `commitment_signed` from them that they previously sent before the disconnection. In other words, `next_commitment_number` tells the remote peer what we see our latest committed state to be. -Similarly, next_revocation_number is the commitment number of the next revoke_and_ack that we expect to receive. In other words, this indicates to our peer which commitment number we think is their latest one. +Similarly, `next_revocation_number` is the commitment number of the next `revoke_and_ack` that we expect to receive. In other words, this indicates to our peer which commitment number we think is their latest one. -The your_last_per_commitment_secret is the last per-commitment secret received from the remote peer which will give the remote peer an idea of the state it has definitely revoked. +The `your_last_per_commitment_secret` is the last per-commitment secret received from the remote peer which will give the remote peer an idea of the state it has definitely revoked. -my_current_per_commitment_point is the commitment point of the local party on its last commitment transaction signed by the remote peer (in other words, the commitment transaction that has not yet been revoked). +`my_current_per_commitment_point` is the commitment point of the local party on its last commitment transaction signed by the remote peer (in other words, the commitment transaction that has not yet been revoked). -There are lots of checks that a node should do when receiving a channel_reestablish in order to make sure that all necessary updates are re-sent so that the channel can continue working as normal. There are also some checks that ensure that nodes are not tricked into revoking a state that should not yet be revoked or tricked into broadcasting a state that _has_ been revoked. If you are interested in the details around these checks, read [BOLT2](). +There are lots of checks that a node should do when receiving a `channel_reestablish` in order to make sure that all necessary updates are re-sent so that the channel can continue working as normal. There are also some checks that ensure that nodes are not tricked into revoking a state that should not yet be revoked or tricked into broadcasting a state that _has_ been revoked. If you are interested in the details around these checks, read [BOLT2](). -Note that when a connection re-establish happens, both sides must remove any uncommitted updates from their staging area. If we revisit the git analogy, they should use git stash when a reconnection occurs. This means that both sides will need to retransmit any update_* messages that were not yet committed on the other side's commitment transaction. +Note that when a connection re-establish happens, both sides must remove any uncommitted updates from their staging area. If we revisit the git analogy, they should use git stash when a reconnection occurs. This means that both sides will need to retransmit any `update_*` messages that were not yet committed on the other side's commitment transaction. ### Closing a channel cooperatively @@ -299,7 +299,7 @@ Bob has decided that it is time to cut ties and sends Alice the shutdown message ![shutdown]() -The shutdown message contains the scriptpubkey that Bob would like his final channel balance to be sent to in the closing transaction. Once Bob has sent this final message, he may no longer send any new update_add_htlc messages. He may only send HTLC removal and update_fee messages. When Alice receives this message from Bob, she must responde with her own shutdown message and may also no longer send any new update_add_htlc messages. Alice and Bob now need to wait until all remaining HTLCs have been cleared from both commitment transactions. Since the closing transaction will spend from the funding transaction and explicitly looks different from the commitment transactions, I'll re-introduce some of the details into the state diagram: +The shutdown message contains the scriptpubkey that Bob would like his final channel balance to be sent to in the closing transaction. Once Bob has sent this final message, he may no longer send any new `update_add_htlc` messages. He may only send HTLC removal and `update_fee` messages. When Alice receives this message from Bob, she must responde with her own shutdown message and may also no longer send any new `update_add_htlc` messages. Alice and Bob now need to wait until all remaining HTLCs have been cleared from both commitment transactions. Since the closing transaction will spend from the funding transaction and explicitly looks different from the commitment transactions, I'll re-introduce some of the details into the state diagram: ![1_initial_1]() @@ -307,29 +307,29 @@ Once all the HTLCs have been cleared, which in our example is already the case, ##### Step 23: Alice -> Bob: closing_signed -Alice will first choose a fee-rate that she thinks is appropriate for the closing transaction. She will then use that fee-rate to complete the construction of the closing transaction and sign it. She then sends the closing_signed message to Bob: +Alice will first choose a fee-rate that she thinks is appropriate for the closing transaction. She will then use that fee-rate to complete the construction of the closing transaction and sign it. She then sends the `closing_signed` message to Bob: ![closing_signed]() -The fee_satoshis field tells Bob the fee in satoshis that Alice used to construct the first closing transaction proposal. The signature contains Alice's signature for this proposal. She may optionally also include the min_fee_satoshis and max_fee_satoshis fields in order to let Bob know that if he disagrees with her proposed fee_satoshis, then he may send a counterproposal as long as his counterproposal lies between the provided minimum and maximum range. +The `fee_satoshis` field tells Bob the fee in satoshis that Alice used to construct the first closing transaction proposal. The signature contains Alice's signature for this proposal. She may optionally also include the `min_fee_satoshis` and max_fee_satoshis fields in order to let Bob know that if he disagrees with her proposed `fee_satoshis`, then he may send a counterproposal as long as his counterproposal lies between the provided minimum and maximum range. At this point, the channel state looks like this: ![32_closing_alice_prop]() -There are two valid commitment transactions that can be signed at any time by each party to perform a force close, and there is one closing transaction proposal using a fee-rate of x sats-per-byte. This closing transaction currently only has Alice's signature and so is not yet valid. +There are two valid commitment transactions that can be signed at any time by each party to perform a force close, and there is one closing transaction proposal using a fee-rate of `x` sats-per-byte. This closing transaction currently only has Alice's signature and so is not yet valid. If at this point, Bob is happy with Alice's proposal, he could go ahead and sign the closing transaction using the fee-rate proposed by Alice and could broadcast it and that would be the end of it. But for the sake of the example, let's say that Bob isn't quite happy just yet. ##### Step 24: Bob -> Alice: closing_signed -Bob may decide that the fee-rate that Alice used is too low. So he sends a counterproposal with a new fee rate, y sats-per-byte, along with his signature for this counterproposal. +Bob may decide that the fee-rate that Alice used is too low. So he sends a counterproposal with a new fee rate, `y` sats-per-byte, along with his signature for this counterproposal. ![33_closing_bob_prop]() ##### Step 25: Alice -> Bob: closing_signed -If Alice is happy with Bob's counterproposal, then she signs the closing transaction using the fee-rate suggested by Bob. She may then broadcast the transaction and call it a day. However, it is recommended in the spec that Alice send one more closing_signed message to Bob but this time with the fee_satoshis field set to y sat-per-byte along with her signature for the transaction. Both parties will now have both signatures required in order to broadcast the final closing transaction that uses the y sats-per-byte fee-rate. +If Alice is happy with Bob's counterproposal, then she signs the closing transaction using the fee-rate suggested by Bob. She may then broadcast the transaction and call it a day. However, it is recommended in the spec that Alice send one more `closing_signed` message to Bob but this time with the `fee_satoshis` field set to `y` sat-per-byte along with her signature for the transaction. Both parties will now have both signatures required in order to broadcast the final closing transaction that uses the `y` sats-per-byte fee-rate. ![34_closing_alice_agree]()