mirror of
https://github.com/lnbook/lnbook
synced 2024-11-15 00:15:05 +00:00
621 lines
48 KiB
Plaintext
621 lines
48 KiB
Plaintext
[[routing]]
|
|
== Routing on a Network of pass:[<span class="keep-together">Payment Channels</span>]
|
|
|
|
((("routing", id="ix_08_routing_htlcs-asciidoc0", range="startofrange")))In this chapter we will finally unpack how payment channels can be connected to form a network of payment channels via a process called _routing_. Specifically, we will look at the first part of the routing layer, the "Atomic and trustless multihop contracts" protocol. This is highlighted by an outline in the protocol suite, shown in <<LN_protocol_routing_highlight>>.
|
|
|
|
[[LN_protocol_routing_highlight]]
|
|
.Atomic payment routing in the Lightning protocol suite
|
|
image::images/mtln_0801.png["Atomic payment routing in the Lightning protocol suite"]
|
|
|
|
=== Routing a Payment
|
|
|
|
((("routing","routing a payment")))In this section we will examine routing from the perspective of Dina, a gamer who receives donations from her fans while she streams her game sessions.
|
|
|
|
The innovation of routed payment channels allows Dina to receive tips without maintaining a separate channel with every one of her fans who want to tip her.
|
|
As long as there exists a path of well-funded channels from that viewer to Dina, she will be able to receive payment from that fan.
|
|
|
|
In <<dina_routing_diagram>> we see a possible network layout created by various payment channels between Lightning nodes. Everyone in this diagram can send Dina a payment by constructing a path. Imagine that Fan 4 wants to send Dina a payment. Do you see the path that could allow that to happen? Fan 4 could route a payment to Dina via Fan 3, Bob, and Chan. Similarly, Alice could route a payment to Dina via Bob and Chan.
|
|
|
|
[[dina_routing_diagram]]
|
|
.Fans connected (in)directly to Dina on the Lightning Network
|
|
image::images/mtln_0802.png["Fans connected (in)directly to Dina on the Lightning Network"]
|
|
|
|
((("routing nodes")))The nodes along the path from the fan to Dina are intermediaries called _routing nodes_ in the context of routing a payment. There is no functional difference between the routing nodes and the nodes operated by Dina's fans. Any Lightning node is capable of routing payments across its payment channels.
|
|
|
|
Importantly, the routing nodes are unable to steal the funds while routing a payment from a fan to Dina.
|
|
Furthermore, routing nodes cannot lose money while participating in the routing process.
|
|
Routing nodes can charge a routing fee for acting as an intermediary, although they don't have to and may choose to route payments for free.
|
|
|
|
Another important detail is that due to the use of onion routing, intermediary nodes are only explicitly aware of the one node preceding them and the one node following them in the route.
|
|
They will not necessarily know who is the sender and recipient of the payment.
|
|
This enables fans to use intermediary nodes to pay Dina, without leaking private information and without risking theft.
|
|
|
|
This process of connecting a series of payment channels with end-to-end security, and the incentive structure for nodes to _forward_ payments, is one of the key innovations of the Lightning Network.
|
|
|
|
In this chapter, we'll dive into the mechanism of routing in the Lightning Network, detailing the precise manner in which payments flow through the network. First, we will clarify the concept of routing and compare it to that of pathfinding, because these are often confused and used interchangeably. Next, we will construct the fairness protocol: an atomic, trustless, multihop protocol used to route payments. To demonstrate how this fairness protocol works, we will be using a physical equivalent of transferring gold coins between four people. Finally, we will look at the atomic, trustless, multihop protocol implementation currently used in the Lightning Network, which is called a hash time-locked contract (HTLC).
|
|
|
|
=== Routing Versus Pathfinding
|
|
|
|
((("pathfinding","routing versus")))((("routing","pathfinding versus")))It's important to note that we separate the concept of _routing_ from the concept of _pathfinding_. These two concepts are often confused, and the term _routing_ is often used to describe both concepts. Let's remove the ambiguity before we proceed any further.
|
|
|
|
Pathfinding, which is covered in <<path_finding>>, is the process of finding and choosing a contiguous path made of payment channels that connects sender A to recipient B. The sender of a payment does the pathfinding by examining the _channel graph_ that they have assembled from channel announcements gossiped by other nodes.
|
|
|
|
Routing refers to the series of interactions across the network that attempt to forward a payment from some point A to another point B, across the path previously selected by pathfinding. Routing is the active process of sending a payment on a path, which involves the cooperation of all the intermediary nodes along that path.
|
|
|
|
An important rule of thumb is that it's possible for a _path_ to exist between Alice and Bob (perhaps even more than one), yet there may not be an active _route_ on which to send the payment. One example is the scenario in which all the nodes connecting Alice and Bob are currently offline. In this example, one can examine the channel graph and connect a series of payment channels from Alice to Bob, hence a _path_ exists. However, because the intermediary nodes are offline, the payment cannot be sent and so no _route_ exists.
|
|
|
|
=== Creating a Network of Payment Channels
|
|
|
|
((("routing","creating a network of payment channels")))Before we dive into the concept of an atomic trustless multihop payment, let's work through an example.
|
|
Let's return to Alice who, in previous chapters, purchased a coffee from Bob with whom she has an open channel.
|
|
Now Alice is watching a live stream from Dina, the gamer, and wants to send Dina a tip of 50,000 satoshis via the Lightning Network. But Alice has no direct channel with Dina. What can Alice do?
|
|
|
|
Alice could open a direct channel with Dina; however, that would require liquidity and on-chain fees which could be more than the value of the tip itself. Instead, Alice can use her existing open channels to send a tip to Dina _without_ the need to open a channel directly with Dina. This is possible, as long as there exists some path of channels from Alice to Dina with sufficient capacity to route the tip.
|
|
|
|
As you can see in <<routing_network>>, Alice has an open channel with Bob, the coffee shop owner. Bob, in turn, has an open channel with the software developer Chan who helps him with the point of sale system he uses in his coffee shop. Chan is also the owner of a large software company which develops the game that Dina plays, and they already have an open channel which Dina uses to pay for the game's license and in-game items.
|
|
|
|
[[routing_network]]
|
|
.A network of payment channels between Alice and Dina
|
|
image::images/mtln_0803.png["A network of payment channels between Alice and Dina"]
|
|
|
|
It's possible to trace a _path_ from Alice to Dina that uses Bob and Chan as intermediary routing nodes.
|
|
Alice can then craft a _route_ from this outlined path and use it to send a tip of a few thousand satoshis to Dina, with the payment being _forwarded_ by Bob and Chan.
|
|
Essentially, Alice will pay Bob, who will pay Chan, who will pay Dina. No direct channel from Alice to Dina is required.
|
|
|
|
The main challenge is to do this in a way that prevents Bob and Chan from stealing the money that Alice wants delivered to Dina.
|
|
|
|
=== A Physical Example of "Routing"
|
|
|
|
((("routing","real-world physical example", id="ix_08_routing_htlcs-asciidoc1", range="startofrange")))To understand how the Lightning Network protects the payment while being routed, we can compare it to an example of routing physical payments with gold coins in the real world.
|
|
|
|
Assume Alice wants to give 10 gold coins to Dina, but does not have direct access to Dina. However, Alice knows Bob, who knows Chan, who knows Dina, so she decides to ask Bob and Chan for help. This is shown in <<alice_dina_routing_1>>.
|
|
|
|
[[alice_dina_routing_1]]
|
|
.Alice wants to pay Dina 10 gold coins
|
|
image::images/mtln_0804.png[]
|
|
|
|
Alice can pay Bob to pay Chan to pay Dina, but how does she make sure that Bob or Chan don't run off with the coins after receiving them?
|
|
In the physical world, contracts could be used for safely carrying out a series of payments.
|
|
|
|
Alice could negotiate a contract with Bob, which reads:
|
|
|
|
____
|
|
_I, Alice, will give you, Bob, 10 gold coins if you pass them on to Chan._
|
|
____
|
|
|
|
While this contract is nice in the abstract, in the real world, Alice runs the risk that Bob might breach the contract and hope not to get caught.
|
|
Even if Bob is caught and prosecuted, Alice faces the risk that he might be bankrupt and be unable to return her 10 gold coins.
|
|
Assuming these issues are magically solved, it's still unclear how to leverage such a contract to achieve our desired outcome: getting the coins delivered to Dina.
|
|
|
|
Let's improve our contract to incorporate these considerations:
|
|
|
|
____
|
|
_I, Alice, will reimburse you, Bob, with 10 gold coins if you can prove to me (for example, via a receipt) that you have delivered 10 gold coins to Chan._
|
|
____
|
|
|
|
You might ask yourself why should Bob sign such a contract.
|
|
He has to pay Chan but ultimately gets nothing out of the exchange, and he runs the risk that Alice might not reimburse him. Bob could offer Chan a similar contract to pay Dina, but similarly Chan has no reason to accept it either.
|
|
|
|
Even putting aside the risk, Bob and Chan must _already_ have 10 gold coins to send; otherwise, they wouldn't be able to participate in the contract.
|
|
|
|
Thus Bob and Chan face both risk and opportunity cost for agreeing to this contract, and they would need to be compensated to accept it.
|
|
|
|
Alice can then make this attractive to both Bob and Chan by offering them fees of one gold coin each, if they transmit her payment to Dina.
|
|
|
|
The contract would then read:
|
|
|
|
____
|
|
_I, Alice, will reimburse you, Bob, with 12 gold coins if you can prove to me (for example, via a receipt) that you have delivered 11 gold coins to Chan._
|
|
____
|
|
|
|
Alice now promises Bob 12 gold coins. There are 10 to be delivered to Dina and 2 for the fees. She promises 12 to Bob if he can prove that he has forwarded 11 to Chan.
|
|
The difference of one gold coin is the fee that Bob will earn for helping out with this particular payment. In <<alice_dina_routing_2>> we see how this arrangement would get 10 gold coins to Dina via Bob and Chan.
|
|
|
|
[[alice_dina_routing_2]]
|
|
.Alice pays Bob, Bob pays Chan, Chan pays Dina
|
|
image::images/mtln_0805.png[]
|
|
|
|
Because there is still the issue of trust and the risk that either Alice or Bob won't honor the contract, all parties decide to use an escrow service.
|
|
At the start of the exchange, Alice could "lock up" these 12 gold coins in escrow that will only be paid to Bob once he proves that he's paid 11 gold coins to Chan.
|
|
|
|
This escrow service is an idealized one, which does not introduce other risks (e.g., counterparty risk). Later we will see how we can replace the escrow with a Bitcoin smart contract. Let's assume for now that everyone trusts this escrow service.
|
|
|
|
In the Lightning Network, the receipt (proof of payment) could take the form of a secret that only Dina knows.
|
|
In practice, this secret would be a random number that is large enough to prevent others from guessing it (typically a _very, very_ large number, encoded using 256 bits!).
|
|
|
|
Dina generates this secret value +R+ from a random number generator.
|
|
|
|
The secret could then be committed to the contract by including the SHA-256 hash of the secret in the contract itself, as follows:
|
|
|
|
++++
|
|
<ul class="simplelist">
|
|
<li><em>H</em> = SHA-256(<em>R</em>)</li>
|
|
</ul>
|
|
++++
|
|
|
|
((("payment hash")))((("payment secret (preimage)")))((("preimage (payment secret)")))We call this hash of the payment's secret the _payment hash_.
|
|
The secret that "unlocks" the payment is called the _payment secret_.
|
|
|
|
For now, we keep things simple and assume that Dina's secret is simply the text line: `Dinas secret`. This secret message is called the _payment secret_ or _payment preimage_.
|
|
|
|
To "commit" to this secret, Dina computes the SHA-256 hash, which when encoded in hexadecimal, can be displayed as follows:
|
|
|
|
----
|
|
0575965b3b44be51e8057d551c4016d83cb1fba9ea8d6e986447ba33fe69f6b3
|
|
----
|
|
|
|
To facilitate Alice's payment, Dina will create the payment secret and the payment hash, and send the payment hash to Alice. In <<alice_dina_routing_3>> we see that Dina sends the payment hash to Alice via some external channel (dashed line), such as an email or text message.
|
|
|
|
[[alice_dina_routing_3]]
|
|
.Dina sends the hashed secret to Alice
|
|
image::images/mtln_0806.png["Dina sends the hashed secret to Alice"]
|
|
|
|
Alice doesn't know the secret, but she can rewrite her contract to use the hash of the secret as a proof of payment:
|
|
|
|
____
|
|
_I, Alice, will reimburse you, Bob, with 12 gold coins if you can show me a valid message that hashes to:`057596`....
|
|
You can acquire this message by setting up a similar contract with Chan who has to set up a similar contract with Dina.
|
|
To assure you that you will be reimbursed, I will provide the 12 gold coins to a trusted escrow before you set up your next contract._
|
|
____
|
|
|
|
This new contract now protects Alice from Bob not forwarding to Chan, protects Bob from not being reimbursed by Alice, and ensures that there will be proof that Dina was ultimately paid via the hash of Dina's secret.
|
|
|
|
After Bob and Alice agree to the contract, and Bob receives the message from the escrow that Alice has deposited the 12 gold coins, Bob can now negotiate a similar contract with Chan.
|
|
|
|
Note that since Bob is taking a service fee of 1 coin, he will only forward 11 gold coins to Chan once Chan shows proof that he has paid Dina.
|
|
Similarly, Chan will also demand a fee and will expect to receive 11 gold coins once he has proved that he has paid Dina the promised 10 gold coins.
|
|
|
|
Bob's contract with Chan will read:
|
|
|
|
____
|
|
_I, Bob, will reimburse you, Chan, with 11 gold coins if you can show me a valid message that hashes to:`057596`....
|
|
You can acquire this message by setting up a similar contract with Dina.
|
|
To assure you that you will be reimbursed, I will provide the 11 gold coins to a trusted escrow before you set up your next contract._
|
|
____
|
|
|
|
Once Chan gets the message from the escrow that Bob has deposited the 11 gold coins, Chan sets up a similar contract with Dina:
|
|
|
|
____
|
|
_I, Chan, will reimburse you, Dina, with 10 gold coins if you can show me a valid message that hashes to:`057596`....
|
|
To assure you that you will be reimbursed after revealing the secret, I will provide the 10 gold coins to a trusted escrow._
|
|
____
|
|
|
|
Everything is now in place.
|
|
Alice has a contract with Bob and has placed 12 gold coins in escrow.
|
|
Bob has a contract with Chan and has placed 11 gold coins in escrow.
|
|
Chan has a contract with Dina and has placed 10 gold coins in escrow.
|
|
It is now up to Dina to reveal the secret, which is the preimage to the hash she has established as proof of payment.
|
|
|
|
Dina now sends +Dinas secret+ to Chan.
|
|
|
|
Chan checks that +Dinas secret+ hashes to +057596+.... Chan now has proof of payment and so instructs the escrow service to release the 10 gold coins to Dina.
|
|
|
|
Chan now provides the secret to Bob. Bob checks it and instructs the escrow service to release the 11 gold coins to Chan.
|
|
|
|
Bob now provides the secret to Alice.
|
|
Alice checks it and instructs the escrow to release 12 gold coins to Bob.
|
|
|
|
All the contracts are now settled.
|
|
Alice has paid a total of 12 gold coins, 1 of which was received by Bob, 1 of which was received by Chan, and 10 of which were received by Dina.
|
|
With a chain of contracts like this in place, Bob and Chan could not run away with the money because they deposited it in escrow first.
|
|
|
|
However, one issue still remains.
|
|
If Dina refused to release her secret preimage, then Chan, Bob, and Alice would all have their coins stuck in escrow but wouldn't be reimbursed.
|
|
And similarly if anyone else along the chain failed to pass on the secret, the same thing would happen.
|
|
So while no one can steal money from Alice, everyone would still have their money stuck in escrow permanently.
|
|
|
|
Luckily, this can be resolved by adding a deadline to the contract.
|
|
|
|
We could amend the contract so that if it is not fulfilled by a certain deadline, then the contract expires and the escrow service returns the money to the person who made the original deposit.
|
|
We call this deadline a _timelock_.
|
|
|
|
The deposit is locked with the escrow service for a certain amount of time and is eventually released even if no proof of payment was provided.
|
|
|
|
To factor this in, the contract between Alice and Bob is once again amended with a new clause:
|
|
|
|
____
|
|
_Bob has 24 hours to show the secret after the contract was signed.
|
|
If Bob does not provide the secret by this time, Alice's deposit will be refunded by the escrow service and the contract becomes invalid._
|
|
____
|
|
|
|
Bob, of course, now has to make sure he receives the proof of payment within 24 hours.
|
|
Even if he successfully pays Chan, if he receives the proof of payment later than 24 hours, he will not be reimbursed. To remove that risk, Bob must give Chan an even shorter deadline.
|
|
|
|
In turn, Bob will alter his contract with Chan as follows:
|
|
|
|
____
|
|
_Chan has 22 hours to show the secret after the contract was signed.
|
|
If he does not provide the secret by this time, Bob's deposit will be refunded by the escrow service and the contract becomes invalid._
|
|
____
|
|
|
|
As you might have guessed, Chan will also alter his contract with Dina:
|
|
|
|
____
|
|
_Dina has 20 hours to show the secret after the contract was signed.
|
|
If she does not provide the secret by this time, Chan's deposit will be refunded by the escrow service and the contract becomes invalid._
|
|
____
|
|
|
|
With such a chain of contracts we can ensure that, after 24 hours, the payment will successfully go from Alice to Bob to Chan to Dina, or it will fail and everyone will be refunded.
|
|
Either the contract fails or succeeds, there's no middle ground.
|
|
|
|
In the context of the Lightning Network, we call this "all or nothing" property _atomicity_.
|
|
|
|
As long as the escrow is trustworthy and faithfully performs its duty, no party will have their coins stolen in the process.
|
|
|
|
The precondition to this _route_ working at all is that all parties in the path have enough money to satisfy the required series of deposits.
|
|
|
|
While this seems like a minor detail, we will see later in this chapter that this requirement is actually one of the more difficult issues for LN nodes.
|
|
It becomes progressively more difficult as the size of the payment increases.
|
|
Furthermore, the parties cannot use their money while it is locked in escrow.
|
|
|
|
Thus, users forwarding payments face an opportunity cost for locking the money, which is ultimately reimbursed through routing fees, as we saw in the preceding example.
|
|
|
|
Now that we've seen a physical payment routing example, we will see how this can be implemented on the Bitcoin blockchain, without any need for third-party escrow. To do this we will be setting up the contracts between the participants using Bitcoin Script. We replace the third-party escrow with _smart contracts_ that implement a fairness protocol. Let's break that concept down and implement it!(((range="endofrange", startref="ix_08_routing_htlcs-asciidoc1")))
|
|
|
|
=== Fairness Protocol
|
|
|
|
((("fairness protocol","routing and")))((("routing","fairness protocol")))As we saw in the first chapter of this book, the innovation of Bitcoin is the ability to use cryptographic primitives to implement a fairness protocol that substitutes trust in third parties (intermediaries) with a trusted protocol.
|
|
|
|
In our gold coin example, we needed an escrow service to prevent any one of the parties from reneging on their obligations. The innovation of cryptographic fairness protocols allows us to replace the escrow service with a protocol.
|
|
|
|
((("fairness protocol","properties")))The properties of the fairness protocol we want to create are:
|
|
|
|
Trustless operation:: The participants in a routed payment do not need to trust each other, or any intermediary or third party. Instead, they trust the protocol to protect them from cheating.
|
|
|
|
Atomicity:: Either the payment is fully executed, or it fails and everyone is refunded. There is no possibility of an intermediary collecting a routed payment and not forwarding it to the next hop. Thus, the intermediaries can't cheat or steal.
|
|
|
|
Multihop:: The security of the system extends end to end for payments routed through multiple payment channels, just as it is for a payment between the two ends of a single payment channel.
|
|
|
|
An optional, additional property is the ability to split payments into multiple parts while maintaining atomicity for the entire payment. These are called _multipart payments_ (_MPP_) and are explored further in <<mpp>>.
|
|
|
|
==== Implementing Atomic Trustless Multihop Payments
|
|
|
|
((("fairness protocol","implementing atomic trustless multihop payments")))((("routing","implementing atomic trustless multihop payments")))Bitcoin Script is flexible enough that there are dozens of ways to implement a fairness protocol that has the properties of atomicity, trustless operation, and multihop security. Choosing a specific implementation is dependent on certain trade-offs among privacy, efficiency, and complexity.
|
|
|
|
((("hash time-locked contracts (HTLCs)","fairness protocol")))The fairness protocol for routing used in the Lightning Network today is called a hash time-locked contract (HTLC). HTLCs use a hash preimage as the secret that unlocks a payment, as we saw in the gold coin example in this chapter. The recipient of a payment generates a random secret number and calculates its hash. The hash becomes the condition of payment, and once the secret is revealed, all the participants can redeem their incoming payments. HTLCs offer atomicity, trustless operation, and multihop security.
|
|
|
|
((("Point Time-Locked Contract (PTLC)")))((("PTLC (Point Time-Locked Contract)")))Another proposed mechanism for implementing routing is a _Point Time-Locked Contract_ (_PTLC_). PTLCs also achieve atomicity, trustless operation, and multihop security, but do so with increased efficiency and better privacy. Efficient implementation of PTLCs depends on a new digital signature algorithm called _Schnorr signatures_, which is expected to be activated in Bitcoin in 2021.
|
|
|
|
=== Revisiting the Tipping Example
|
|
|
|
((("routing","real-world physical example")))Let's revisit our example from the first part of this chapter. Alice wants to tip Dina with a Lightning payment. Let's say Alice wants to send Dina 50,000 satoshis as a tip.
|
|
|
|
For Alice to pay Dina, Alice will need Dina's node to generate a Lightning invoice. We will discuss this in more detail in <<invoices>>. For now, let's assume that Dina has a website that can produce a Lightning invoice for tips.
|
|
|
|
[TIP]
|
|
====
|
|
Lightning payments can be sent without an invoice using a feature called _keysend_, which we will discuss in more detail in <<keysend>>. For now, we will explain the simpler payment flow using an invoice.
|
|
====
|
|
|
|
Alice visits Dina's site, enters the amount of 50,000 satoshis in a form, and in response, Dina's Lightning node generates a payment request for 50,000 satoshis in the form of a Lightning invoice. This interaction takes place over the web and outside the Lightning Network, as shown in <<alice_dina_invoice_1>>.
|
|
|
|
[[alice_dina_invoice_1]]
|
|
.Alice requests an invoice from Dina's website
|
|
image::images/mtln_0807.png["Alice requests an invoice from Dina's website"]
|
|
|
|
As we saw in previous examples, we assume that Alice does not have a direct payment channel to Dina. Instead, Alice has a channel to Bob, Bob has a channel to Chan, and Chan has a channel to Dina. To pay Dina, Alice must find a path that connects her to Dina. We will discuss that step in more detail in <<path_finding>>. For now, let's assume that Alice is able to gather information about available channels and sees that there is a path from her to Dina, via Bob and Chan.
|
|
|
|
[NOTE]
|
|
====
|
|
Remember how Bob and Chan might expect a small compensation for routing the payment through their nodes? Alice wants to pay Dina 50,000 satoshis, but as you will see in the following sections she will send Bob 50,200 satoshis. The extra 200 satoshis will pay Bob and Chan 100 satoshis each, as a routing fee.
|
|
====
|
|
|
|
Now, Alice's node can construct a Lightning payment. In the next few sections, we will see how Alice's node constructs an HTLC to pay Dina and how that HTLC is forwarded along the path from Alice to Dina.
|
|
|
|
|
|
==== On-Chain Versus Off-Chain Settlement of HTLCs
|
|
|
|
((("hash time-locked contracts (HTLCs)","on-chain versus off-chain settlement of")))((("off-chain settlement, on-chain payment versus")))((("on-chain payment","off-chain settlement versus")))((("routing","on-chain versus off-chain settlement of HTLCs")))The purpose of the Lightning Network is to enable _off-chain_ transactions that are trusted just the same as on-chain transactions because no one can cheat. The reason no one can cheat is because at any time, any of the participants can take their off-chain transactions on-chain. Each off-chain transaction is ready to be submitted to the Bitcoin blockchain at any time. Thus, the Bitcoin blockchain acts as a dispute-resolution and final settlement mechanism if necessary.
|
|
|
|
The mere fact that any transaction can be taken on-chain at any time is precisely the reason that all those transactions can be kept off-chain. If you know you have recourse, you can continue to cooperate with the other participants and avoid the need for on-chain settlement and extra fees.
|
|
|
|
In all the examples that follow, we will assume that any of these transactions can be made on-chain at any time. The participants will choose to keep them off-chain, but there is no difference in the functionality of the system other than the higher fees and delay imposed by on-chain mining of the transactions. The example works the same if all the transactions are on-chain or off-chain.
|
|
|
|
[[htlcs]]
|
|
=== Hash Time-Locked Contracts
|
|
|
|
((("hash time-locked contracts (HTLCs)","mechanism of operation", id="ix_08_routing_htlcs-asciidoc2", range="startofrange")))((("routing","hash time-locked contracts mechanism of operation", id="ix_08_routing_htlcs-asciidoc3", range="startofrange")))In this section we explain how HTLCs work.
|
|
|
|
The first part of an HTLC is the _hash_. This refers to the use of a cryptographic hash algorithm to commit to a randomly generated secret. Knowledge of the secret allows redemption of the payment. The cryptographic hash function guarantees that while it's infeasible for anyone to guess the secret preimage, it's easy for anyone to verify the hash, and there's only one possible preimage that resolves the payment condition.
|
|
|
|
In <<alice_dina_invoice_2>> we see Alice getting a Lightning invoice from Dina. Inside that invoice ((("payment hash")))Dina has encoded a _payment hash_, which is the cryptographic hash of a secret that Dina's node produced. ((("payment secret (preimage)")))((("preimage (payment secret)")))Dina's secret is called the _payment preimage_. The payment hash acts as an identifier that can be used to route the payment to Dina. The payment preimage acts as a receipt and proof of payment once the payment is complete.
|
|
|
|
[[alice_dina_invoice_2]]
|
|
.Alice gets a payment hash from Dina
|
|
image::images/mtln_0808.png["Alice gets a payment hash from Dina"]
|
|
|
|
In the Lightning Network, Dina's payment preimage won't be a phrase like +Dinas secret+ but a random number generated by Dina's node. Let's call that random number _R_.
|
|
|
|
Dina's node will calculate a cryptographic hash of _R_, such that:
|
|
|
|
++++
|
|
<ul class="simplelist">
|
|
<li><em>H</em> = SHA-256(<em>R</em>)</li>
|
|
</ul>
|
|
++++
|
|
|
|
In this equation, _H_ is the hash, or _payment hash_ and _R_ is the secret or _payment preimage_.
|
|
|
|
The use of a cryptographic hash function is one element that guarantees _trustless operation_. The payment intermediaries do not need to trust each other because they know that no one can guess the secret or fake it.
|
|
|
|
==== HTLCs in Bitcoin Script
|
|
|
|
((("Bitcoin script","HTLCs in")))((("hash time-locked contracts (HTLCs)","Bitcoin Script and")))In our gold coin example, Alice had a contract enforced by escrow like this:
|
|
|
|
____
|
|
_Alice will reimburse Bob with 12 gold coins if you can show a valid message that hashes to:_ +0575...f6b3+. _Bob has 24 hours to show the secret after the contract was signed. If Bob does not provide the secret by this time, Alice's deposit will be refunded by the escrow service and the contract becomes invalid._
|
|
____
|
|
|
|
[role="pagebreak-before"]
|
|
Let's see how we would implement this as an HTLC in Bitcoin Script. In <<received_htlc>> we see an HTLC Bitcoin Script as currently used in the Lightning Network. You can find this definition in https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#offered-htlc-outputs[BOLT #3, Transactions].
|
|
|
|
[[received_htlc]]
|
|
.HTLC implemented in Bitcoin Script (BOLT #3)
|
|
[source,text,linenums]
|
|
====
|
|
----
|
|
# To remote node with revocation key
|
|
OP_DUP OP_HASH160 <RIPEMD160(SHA256(revocationpubkey))> OP_EQUAL
|
|
OP_IF
|
|
OP_CHECKSIG
|
|
OP_ELSE
|
|
<remote_htlcpubkey> OP_SWAP OP_SIZE 32 OP_EQUAL
|
|
OP_IF
|
|
# To local node via HTLC-success transaction.
|
|
OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
|
|
2 OP_SWAP <local_htlcpubkey> 2 OP_CHECKMULTISIG
|
|
OP_ELSE
|
|
# To remote node after timeout.
|
|
OP_DROP <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
|
|
OP_CHECKSIG
|
|
OP_ENDIF
|
|
OP_ENDIF
|
|
----
|
|
====
|
|
|
|
Wow, that looks complicated! Don't worry though, we will take it one step at a time and simplify it.
|
|
|
|
The Bitcoin Script currently used in the Lightning Network is quite complex because it is optimized for on-chain space efficiency, which makes it very compact but difficult to read.
|
|
|
|
In the following sections, we will focus on the main elements of the script and present simplified scripts that are slightly different from what is actually used in Lightning.
|
|
|
|
The main part of the HTLC is in line 10 of <<received_htlc>>. Let's build it up from scratch!
|
|
|
|
==== Payment Preimage and Hash Verification
|
|
|
|
((("hash time-locked contracts (HTLCs)","payment preimage and hash verification")))((("hash verification")))((("payment secret (preimage)")))((("preimage (payment secret)")))The core of an HTLC is the hash, where payment can be made if the recipient knows the payment preimage. Alice locks the payment to a specific payment hash, and Bob has to present a payment preimage to claim the funds. The Bitcoin system can verify that Bob's payment preimage is correct by hashing it and comparing the result to the payment hash that Alice used to lock the funds.
|
|
|
|
This part of an HTLC can be implemented in Bitcoin Script as follows:
|
|
|
|
----
|
|
OP_SHA256 <H> OP_EQUAL
|
|
----
|
|
|
|
Alice can create a transaction output that pays, 50,200 satoshi with a locking script above, replacing `<H>` with the hash value +0575...f6b3+ provided by Dina. Then, Alice can sign this transaction and offer it to Bob:
|
|
|
|
.Alice's offers a 50,200 satoshi HTLC to Bob
|
|
----
|
|
OP_SHA256 0575...f6b3 OP_EQUAL
|
|
----
|
|
|
|
Bob can't spend this HTLC until he knows Dina's secret, so spending the HTLC is conditional on Bob's fulfillment of the payment all the way to Dina.
|
|
|
|
Once Bob has Dina's secret, Bob can spend this output with an unlocking script containing the secret preimage value _R_.
|
|
|
|
The unlocking script combined with the locking script would produce:
|
|
|
|
----
|
|
<R> OP_SHA256 <H> OP_EQUAL
|
|
----
|
|
|
|
The Bitcoin Script engine would evaluate this script as follows:
|
|
|
|
1. +R+ is pushed to the stack.
|
|
2. The `OP_SHA256` operator takes the value +R+ off the stack and hashes it, pushing the result +H~R~+ to the stack.
|
|
3. +H+ is pushed to the stack.
|
|
4. The `OP_EQUAL` operator compares +H+ and +H~R~+. If they are equal, the result is +TRUE+, the script is complete, and the payment is verified.
|
|
|
|
==== Extending HTLCs from Alice to Dina
|
|
|
|
((("hash time-locked contracts (HTLCs)","extending across a network")))Alice will now extend the HTLC across the network so that it reaches Dina.
|
|
|
|
In <<alice_dina_htlc_1>>, we see the HTLC propagated across the network from Alice to Dina. Alice has given Bob an HTLC for 50,200 satoshi. Bob can now create an HTLC for 50,100 satoshi and give it to Chan.
|
|
|
|
Bob knows that Chan can't redeem Bob's HTLC without broadcasting the secret, at which point Bob can also use the secret to redeem Alice's HTLC. This is a really important point because it ensures end-to-end _atomicity_ of the HTLC. To spend the HTLC, one needs to reveal the secret, which then makes it possible for others to spend their HTLC also. Either all the HTLCs are spendable, or none of the HTLCs are spendable: atomicity!
|
|
|
|
Because Alice's HTLC is 100 satoshi more than the HTLC Bob gave to Chan, Bob will earn 100 satoshi as a routing fee if this payment completes.
|
|
|
|
Bob isn't taking a risk and isn't trusting Alice or Chan. Instead, Bob is trusting that a signed transaction together with the secret will be redeemable on the Bitcoin blockchain.
|
|
|
|
[[alice_dina_htlc_1]]
|
|
.Propagating the HTLC across the network
|
|
image::images/mtln_0809.png["Propagating the HTLC across the network"]
|
|
|
|
Similarly, Chan can extend a 50,000 HTLC to Dina. He isn't risking anything or trusting Bob or Dina. To redeem the HTLC, Dina would have to broadcast the secret, which Chan could use to redeem Bob's HTLC. Chan would also earn 100 satoshis as a routing fee.
|
|
|
|
==== Back-Propagating the Secret
|
|
|
|
((("hash time-locked contracts (HTLCs)","back-propagating the secret", id="ix_08_routing_htlcs-asciidoc4", range="startofrange")))Once Dina receives a 50,000 HTLC from Chan, she can now get paid. Dina could simply commit this HTLC on-chain and spend it by revealing the secret in the spending transaction. Or, instead, Dina can update the channel balance with Chan by giving him the secret. There's no reason to incur a transaction fee and go on-chain. So, instead, Dina sends the secret to Chan, and they agree to update their channel balances to reflect a 50,000 satoshi Lightning payment to Dina. In <<alice_dina_htlc_redeem_1>> we see Dina giving the secret to Chan, thereby fulfilling the HTLC.
|
|
|
|
[[alice_dina_htlc_redeem_1]]
|
|
.Dina settles Chan's HTLC off-chain
|
|
image::images/mtln_0810.png["Dina settles Chan's HTLC off-chain"]
|
|
|
|
Notice that Dina's channel balance goes from 50,000 satoshi to 100,000 satoshi. Chan's channel balance is reduced from 200,000 satoshi to 150,000 satoshi. The channel capacity hasn't changed, but 50,000 has moved from Chan's side of the channel to Dina's side of the channel.
|
|
|
|
Chan now has the secret and has paid Dina 50,000 satoshi. He can do this without any risk, because the secret allows Chan to redeem the 50,100 HTLC from Bob. Chan has the option to commit that HTLC on-chain and spend it by revealing the secret on the Bitcoin blockchain. But, like Dina, he'd rather avoid transaction fees. So instead, he sends the secret to Bob so they can update their channel balances to reflect a 50,100 satoshi Lightning payment from Bob to Chan. In <<alice_dina_htlc_redeem_2>> we see Chan sending the secret to Bob and receiving a payment in return.
|
|
|
|
[[alice_dina_htlc_redeem_2]]
|
|
.Chan settles Bob's HTLC off-chain
|
|
image::images/mtln_0811.png["Chan settles Bob's HTLC off-chain"]
|
|
|
|
Chan has paid Dina 50,000 satoshi, and received 50,100 satoshi from Bob. So Chan has 100 satoshi more in his channel balances, which he earned as a routing fee.
|
|
|
|
Bob now has the secret too. He can use it to spend Alice's HTLC on-chain. Or, he can avoid transaction fees by settling the HTLC in the channel with Alice. In <<alice_dina_htlc_redeem_3>> we see that Bob sends the secret to Alice and they update the channel balance to reflect a 50,200 satoshi Lightning payment from Alice to Bob.
|
|
|
|
[[alice_dina_htlc_redeem_3]]
|
|
.Bob settles Alice's HTLC off-chain
|
|
image::images/mtln_0812.png["Bob settles Alice's HTLC off-chain"]
|
|
|
|
Bob has received 50,200 satoshi from Alice and paid 50,100 satoshi to Chan, so he has an extra 100 satoshi in his channel balances from routing fees.
|
|
|
|
Alice receives the secret and has settled the 50,200 satoshi HTLC. The secret can be used as a _receipt_ to prove that Dina got paid for that specific payment hash.
|
|
|
|
The final channel balances reflect Alice's payment to Dina and the routing fees paid at each hop, as shown in <<alice_dina_htlc_redeem_4>>.(((range="endofrange", startref="ix_08_routing_htlcs-asciidoc4")))
|
|
|
|
[[alice_dina_htlc_redeem_4]]
|
|
.Channel balances after the payment
|
|
image::images/mtln_0813.png["Channel balances after the payment"]
|
|
|
|
[[preventing_theft]]
|
|
==== Signature Binding: Preventing Theft of HTLCs
|
|
|
|
((("hash time-locked contracts (HTLCs)","signature binding to prevent theft of", id="ix_08_routing_htlcs-asciidoc5", range="startofrange")))((("signature binding", id="ix_08_routing_htlcs-asciidoc6", range="startofrange")))There's a catch. Did you notice it?
|
|
|
|
If Alice, Bob, and Chan create the HTLCs as shown in <<alice_dina_htlc_redeem_4>>, they face a small but not insignificant risk of loss. Any of those HTLCs can be redeemed (spent) by anyone who knows the secret. At first only Dina knows the secret. Dina is supposed to only spend the HTLC from Chan. But Dina could spend all three HTLCs at the same time, or even in a single spending transaction! After all, Dina knows the secret before anyone else. Similarly, once Chan knows the secret, he is only supposed to spend the HTLC offered by Bob. But what if Chan also spends Alice's offered HTLC?
|
|
|
|
This is not _trustless_! It fails the most important security feature. We need to fix this.
|
|
|
|
The HTLC script must have an additional condition that binds each HTLC to a specific recipient. We do this by requiring a digital signature that matches the public key of each recipient, thereby preventing anyone else from spending that HTLC. Since only the designated recipient has the ability to produce a digital signature matching that public key, only the designated recipient can spend that HTLC.
|
|
|
|
Let's look at the scripts again with this modification in mind. Alice's HTLC for Bob is modified to include Bob's public key and the +OP_CHECKSIG+ operator.
|
|
|
|
Here's the modified HTLC script:
|
|
|
|
----
|
|
OP_SHA256 <H> OP_EQUALVERIFY <Bob's Pub> OP_CHECKSIG
|
|
----
|
|
|
|
[TIP]
|
|
====
|
|
Notice that we also changed +OP_EQUAL+ to +OP_EQUALVERIFY+. When an operator has the suffix +VERIFY+, it does not return +TRUE+ or +FALSE+ on the stack. Instead, it _halts_ execution and fails the script if the result is false and continues without any stack output if it is true.
|
|
====
|
|
|
|
To redeem this HTLC, Bob has to present an unlocking script that includes a signature from Bob's private key as well as the secret payment preimage, like this:
|
|
|
|
----
|
|
<Bob's Signature> <R>
|
|
----
|
|
|
|
The unlocking and locking scripts are combined and evaluated by the scripting engine, as follows:
|
|
|
|
----
|
|
<Bob's Sig> <R> OP_SHA256 <H> OP_EQUALVERIFY <Bob's Pub> OP_CHECKSIG
|
|
----
|
|
|
|
1. +<Bob's Sig>+ is pushed to the stack.
|
|
2. +R+ is pushed to the stack.
|
|
3. +OP_SHA256+ pops and hashes +R+ from the top of the stack and pushes +H~R~+ to the stack.
|
|
4. +H+ is pushed to the stack.
|
|
5. +OP_EQUALVERIFY+ pops +H+ and +H~R~+ and compares them. If they are not the same, execution halts. Otherwise, we continue without output to the stack.
|
|
6. +<Bob's Pub>+ key is pushed to the stack.
|
|
7. +OP_CHECKSIG+ pops +<Bob's Sig>+ and +<Bob's Pub>+ and verifies the signature. The result (`TRUE/FALSE`) is pushed to the stack.
|
|
|
|
As you can see, this is slightly more complicated, but now we have fixed the HTLC and made sure only the intended recipient can spend it.(((range="endofrange", startref="ix_08_routing_htlcs-asciidoc6")))(((range="endofrange", startref="ix_08_routing_htlcs-asciidoc5")))
|
|
|
|
==== Hash Optimization
|
|
|
|
((("hash time-locked contracts (HTLCs)","hash optimization")))Let's look at the first part of the HTLC script so far:
|
|
|
|
----
|
|
OP_SHA256 <H> OP_EQUALVERIFY
|
|
----
|
|
|
|
If we look at this in the preceding symbolic representation, it looks like the +OP_+ operators take up the most space. But that's not the case. Bitcoin Script is encoded in binary, with each operator representing one byte. Meanwhile, the +<H>+ value we use as a placeholder for the payment hash is a 32-byte (256-bit) value. You can find a listing of all the Bitcoin Script operators and their binary and hex encoding in https://en.bitcoin.it/wiki/Script[Bitcoin Wiki: Script], or in https://github.com/bitcoinbook/bitcoinbook/blob/develop/appdx-scriptops.asciidoc[Appendix D, "Transaction Script Language Operators, Constants, and Symbols," in _Mastering Bitcoin_].
|
|
|
|
Represented in hexadecimal, our HTLC script would look like this:
|
|
|
|
----
|
|
a8 0575965b3b44be51e8057d551c4016d83cb1fba9ea8d6e986447ba33fe69f6b3 88
|
|
----
|
|
|
|
In hexadecimal encoding, +OP_SHA256+ is +a8+ and +OP_EQUALVERIFY+ is +88+. The total length of this script is 34 bytes, of which 32 bytes are the hash.
|
|
|
|
As we've mentioned previously, any participant in the Lightning Network should be able to take an off-chain transaction they hold and put it on-chain if they need to enforce their claim to funds. To take a transaction on-chain, they'd have to pay transaction fees to the miners, and these fees are proportional to the size, in bytes, of the transaction.
|
|
|
|
Therefore, we want to find ways to minimize the on-chain "weight" of transactions by optimizing the script as much as possible. One way to do that is to add another hash function on top of the SHA-256 algorithm, one that produces smaller hashes. The Bitcoin Script language provides the +OP_HASH160+ operator that "double hashes" a preimage: first the preimage is hashed with SHA-256, and then the resulting hash is hashed again with the RIPEMD160 hash algorithm. The hash resulting from RIPEMD160 is 160 bits or 20 bytes--much more compact. In Bitcoin Script this is a very common optimization that is used in many of the common address formats.
|
|
|
|
So, let's use that optimization instead. Our SHA-256 hash is +057596...69f6b3+. Putting that through another round of hashing with RIPEMD160 gives us the result:
|
|
|
|
----
|
|
R = "Dinas secret"
|
|
H256 = SHA256(R)
|
|
H256 = 0575965b3b44be51e8057d551c4016d83cb1fba9ea8d6e986447ba33fe69f6b3
|
|
H160 = RIPEMD160(H256)
|
|
H160 = 9e017f6767971ed7cea17f98528d5f5c0ccb2c71
|
|
----
|
|
|
|
Alice can calculate the RIPEMD160 hash of the payment hash that Dina provides and use the shorter hash in her HTLC, as can Bob and Chan!
|
|
|
|
[role="pagebreak-before"]
|
|
The "optimized" HTLC script would look like this:
|
|
|
|
----
|
|
OP_HASH160 <H160> OP_EQUALVERIFY
|
|
----
|
|
|
|
Encoded in hex, this is:
|
|
|
|
----
|
|
a9 9e017f6767971ed7cea17f98528d5f5c0ccb2c71 88
|
|
----
|
|
|
|
Where +OP_HASH160+ is +a9+ and +OP_EQUALVERIFY+ is +88+. This script is only 22 bytes long! We've saved 12 bytes from every transaction that redeems an HTLC on-chain.
|
|
|
|
With that optimization, you now see how we arrive at the HTLC script shown in line 10 of <<received_htlc>>:
|
|
|
|
----
|
|
...
|
|
# To local node via HTLC-success transaction.
|
|
OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY...
|
|
----
|
|
|
|
==== HTLC Cooperative and Timeout Failure
|
|
|
|
((("cooperative failure")))((("hash time-locked contracts (HTLCs)","cooperative/timeout failure")))((("timeout failure")))So far we looked at the "hash" part of HTLC and how it would work if everyone cooperated and was online at the time of payment.
|
|
|
|
What happens if someone goes offline or fails to cooperate? What happens if the payment cannot succeed?
|
|
|
|
We need to ensure a way to "fail gracefully," because occasional routing failures are inevitable. There are two ways to fail: cooperatively and with a time-locked refund.
|
|
|
|
Cooperative failure is relatively simple: the HTLC is unwound by every participant in the route, removing the HTLC output from their commitment transactions without changing the balance. We'll look at how that works in detail in <<channel_operation>>.
|
|
|
|
Let's look at how we can reverse an HTLC without the cooperation of one or more participants. We need to make sure that if one of the participants does not cooperate, the funds are not simply locked in the HTLC _forever_. This would give someone the opportunity to ransom the funds of another participant: "I'll leave your funds tied up forever if you don't pay me ransom."
|
|
|
|
To prevent this, every HTLC script includes a refund clause that is connected to a timelock. Remember our original escrow contract? "Bob has 24 hours to show the secret after the contract is signed. If Bob does not provide the secret by this time, Alice's deposit will be refunded."
|
|
|
|
The time-locked refund is an important part of the script that ensures _atomicity_, so that the entire end-to-end payment either succeeds or fails gracefully. There is no "half paid" state to worry about. If there is a failure, every participant can either unwind the HTLC cooperatively with their channel partner or put the time-locked refund transaction on-chain unilaterally to get their money back.
|
|
|
|
To implement this refund in Bitcoin Script, we use a special operator pass:[<code>O⁠P⁠_⁠C⁠H⁠E⁠C⁠K⁠L⁠O⁠C⁠K⁠T⁠I⁠M⁠E​V⁠E⁠R⁠I⁠F⁠Y</code>] also known +OP_CLTV+ for short. Here's the script, as seen previously in line 13 of <<received_htlc>>:
|
|
|
|
----
|
|
...
|
|
OP_DROP <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
|
|
OP_CHECKSIG
|
|
...
|
|
----
|
|
|
|
The +OP_CLTV+ operator takes an expiry time defined as the block height after which this transaction is valid. If the transaction timelock is not set the same as +<cltv_expiry>+, the evaluation of the script fails and the transaction is invalid. Otherwise, the script continues without any output to the stack. Remember, the +VERIFY+ suffix means this operator does not output +TRUE+ or +FALSE+ but instead either halts/fails or continues without stack output.
|
|
|
|
Essentially, the +OP_CLTV+ acts as a "gatekeeper" preventing the script from proceeding any further if the +<cltv_expiry>+ block height has not been reached on the Bitcoin blockchain.
|
|
|
|
The +OP_DROP+ operator simply drops the topmost item on the script stack. This is necessary in the beginning because there is a "leftover" item from the previous script lines. It is necessary _after_ +OP_CLTV+ to remove the +<cltv_expiry>+ item from the top of the stack because it is no longer necessary.
|
|
|
|
Finally, once the stack has been cleaned up, there should be a public key and signature left behind that +OP_CHECKSIG+ can verify. As we saw in <<preventing_theft>>, this is necessary to ensure that only the rightful owner of the funds can claim them, by binding this output to their public key and requiring a signature.
|
|
|
|
==== Decrementing Timelocks
|
|
|
|
((("hash time-locked contracts (HTLCs)","decrementing timelocks")))As the HTLCs are extended from Alice to Dina, the time-locked refund clause in each HTLC has a _different_ +cltv_expiry+ value. We will see this in more detail in <<onion_routing>>. But suffice it to say that to ensure an orderly unwinding of a payment that fails, each hop needs to wait a bit less for their refund. The difference between timelocks for each hop is called the +cltv_expiry_delta+, and is set by each node and advertised to the network, as we will see in <<gossip>>.
|
|
|
|
For example, Alice sets the refund timelock on the first HTLC to a block height of current + 500 blocks ("current" being the current block height). Bob would then set the timelock +cltv_expiry+ on the HTLC to Chan to current + 450 blocks. Chan would set the timelock to current + 400 blocks from the current block height. This way, Chan can get a refund on the HTLC he offered to Dina _before_ Bob gets a refund on the HTLC he offered to Chan. Bob can get a refund of the HTLC he offered to Chan before Alice can get a refund for the HTLC she offered to Bob. The decrementing timelock prevents race conditions and ensures the HTLC chain is unwound backward, from the destination toward the origin.(((range="endofrange", startref="ix_08_routing_htlcs-asciidoc3")))(((range="endofrange", startref="ix_08_routing_htlcs-asciidoc2")))
|
|
|
|
=== Conclusion
|
|
|
|
In this chapter we saw how Alice can pay Dina even if she doesn't have a direct payment channel. Alice can find a path that connects her to Dina and route a payment across several payment channels so that it reaches Dina.
|
|
|
|
To ensure that the payment is atomic and trustless across multiple hops, Alice must implement a fairness protocol in cooperation with all the intermediary nodes in the path. The fairness protocol is currently implemented as an HTLC, which commits funds to a payment hash derived from a secret payment preimage.
|
|
|
|
Each of the participants in the payment route can extend an HTLC to the next participant, without worrying about theft or stuck funds. The HTLC can be redeemed by revealing the secret payment preimage. Once an HTLC reaches Dina, she reveals the preimage, which flows backward, resolving all the HTLCs offered.
|
|
|
|
Finally, we saw how a time-locked refund clause completes the HTLC, ensuring that every participant can get a refund if the payment fails but for whatever reason one of the participants doesn't cooperate in unwinding the HTLCs. By always having the option to go on-chain for a refund, the HTLC achieves the fairness goal of atomicity and trustless operation.(((range="endofrange", startref="ix_08_routing_htlcs-asciidoc0")))
|