Skip to content

Instantly share code, notes, and snippets.

@fiatjaf
Last active March 3, 2020 12:52
Show Gist options
  • Save fiatjaf/712a8651dff5908d139dc62ea4dfd551 to your computer and use it in GitHub Desktop.
Save fiatjaf/712a8651dff5908d139dc62ea4dfd551 to your computer and use it in GitHub Desktop.
lightning network improved
HTLCs below the dust limit are not possible, because they're uneconomical.
So currently whenever a payment below the dust limit is to be made Lightning peers adjust their commitment transactions to pay that amount as fees in case the channel is closed. That's a form of reserving that amount and incentivizing peers to resolve the payment, either successfully (in case it goes to the receiving node's balance) or not (it then goes back to the sender's balance).
SOLUTION
I didn't think too much about if it is possible to do what I think can be done in the current implementation on Lightning channels, but in the context of Eltoo it seems possible.
Eltoo channels have UPDATE transactions that can be published to the blockchain and SETTLEMENT transactions that spend them (after a relative time) to each peer. The barebones script for UPDATE transactions is something like (copied from the paper, because I don't understand these things):
OP_IF
# to spend from a settlement transaction (presigned)
10 OP_CSV
2 As,i Bs,i 2 OP_CHECKMULTISIGVERIFY
OP_ELSE
# to spend from a future update transaction
<Si+1> OP_CHECKLOCKTIMEVERIFY
2 Au Bu 2 OP_CHECKMULTISIGVERIFY
OP_ENDIF
During a payment of 1 satoshi it could be updated to something like (I'll probably get this thing completely wrong):
OP_HASH256 <payment_hash> OP_EQUAL
OP_IF
# for B to spend from settlement transaction 1 in case the payment went through
# and they have a preimage
10 OP_CSV
2 As,i1 Bs,i1 2 OP_CHECKMULTISIGVERIFY
OP_ELSE
OP_IF
# for A to spend from settlement transaction 2 in case the payment didn't went through
# and the other peer is uncooperative
<now + 1day> OP_CHECKLOCKTIMEVERIFY
2 As,i2 Bs,i2 2 OP_CHECKMULTISIGVERIFY
OP_ELSE
# to spend from a future update transaction
<Si+1> OP_CHECKLOCKTIMEVERIFY
2 Au Bu 2 OP_CHECKMULTISIGVERIFY
OP_ENDIF
OP_ENDIF
Then peers would have two presigned SETTLEMENT transactions, 1 and 2 (with different signature pairs, as badly shown in the script). On SETTLEMENT 1, funds are, say, 999sat for A and 1001sat for B, while on SETTLEMENT 2 funds are 1000sat for A and 1000sat for B.
As soon as B gets the preimage from the next peer in the route it can give it to A and them can sign a new UPDATE transaction that replaces the above gimmick with something simpler without hashes involved.
If the preimage doesn't come in viable time, peers can agree to make a new UPDATE transaction anyway. Otherwise A will have to close the channel, which may be bad, but B wasn't a good peer anyway.
2019-04-30
Display the source blob
Display the rendered blob
Raw
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="761px" height="634px" viewBox="-0.5 -0.5 761 634" content="&lt;mxfile host=&quot;www.draw.io&quot; modified=&quot;2020-03-01T01:59:32.569Z&quot; agent=&quot;Mozilla/5.0 (X11; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0&quot; etag=&quot;KWte8fitWDSIJ6wgaFo0&quot; version=&quot;12.7.9&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;0KdIDNT6uhnKyzJYLgkn&quot; name=&quot;Page-1&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><path d="M 70 362 L 70 407 L 83.63 407" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 88.88 407 L 81.88 410.5 L 83.63 407 L 81.88 403.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="70" cy="322" rx="40" ry="40" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 322px; margin-left: 31px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">NORMAL UPDATE</div></div></div></foreignObject><text x="70" y="326" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">NORMAL UPDATE</text></switch></g><ellipse cx="430" cy="322" rx="40" ry="40" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 322px; margin-left: 391px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">HASHLOCKED UPDATE</div></div></div></foreignObject><text x="430" y="326" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">HASHLOCKED UP...</text></switch></g><ellipse cx="250" cy="322" rx="40" ry="40" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 322px; margin-left: 211px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">RESCUE UPDATE</div></div></div></foreignObject><text x="250" y="326" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">RESCUE UPDATE</text></switch></g><rect x="90" y="382" width="50" height="50" rx="25" ry="25" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 44px; height: 1px; padding-top: 407px; margin-left: 93px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">SETTLE</div></div></div></foreignObject><text x="115" y="411" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">SETTLE</text></switch></g><path d="M 430 362 L 430 407 L 443.63 407" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 448.88 407 L 441.88 410.5 L 443.63 407 L 441.88 403.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="450" y="382" width="50" height="50" rx="25" ry="25" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 44px; height: 1px; padding-top: 407px; margin-left: 453px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">SETTLE</div></div></div></foreignObject><text x="475" y="411" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">SETTLE</text></switch></g><path d="M 250 362 L 250 407 L 263.63 407" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 268.88 407 L 261.88 410.5 L 263.63 407 L 261.88 403.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="270" y="382" width="50" height="50" rx="25" ry="25" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 44px; height: 1px; padding-top: 407px; margin-left: 273px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">SETTLE</div></div></div></foreignObject><text x="295" y="411" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">SETTLE</text></switch></g><ellipse cx="610" cy="322" rx="40" ry="40" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 322px; margin-left: 571px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>NORMAL</div><div>UPDATE</div></div></div></div></foreignObject><text x="610" y="326" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">NORMAL...</text></switch></g><path d="M 610 362 L 610 407 L 623.63 407" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 628.88 407 L 621.88 410.5 L 623.63 407 L 621.88 403.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="630" y="382" width="50" height="50" rx="25" ry="25" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 44px; height: 1px; padding-top: 407px; margin-left: 633px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">SETTLE</div></div></div></foreignObject><text x="655" y="411" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">SETTLE</text></switch></g><rect x="30" y="212" width="80" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 78px; height: 1px; padding-top: 222px; margin-left: 32px;"><div style="box-sizing: border-box; font-size: 0; text-align: left; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div align="left">Initial channel state.</div></div></div></div></foreignObject><text x="32" y="226" fill="#000000" font-family="Helvetica" font-size="12px">Initial chann...</text></switch></g><rect x="380" y="172" width="110" height="60" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 108px; height: 1px; padding-top: 202px; margin-left: 382px;"><div style="box-sizing: border-box; font-size: 0; text-align: left; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div align="left">This update can only be spent with the preimage of the payment that is being sent through the channel.</div></div></div></div></foreignObject><text x="382" y="206" fill="#000000" font-family="Helvetica" font-size="12px">This update can on...</text></switch></g><rect x="180" y="172" width="151.25" height="80" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 149px; height: 1px; padding-top: 212px; margin-left: 182px;"><div style="box-sizing: border-box; font-size: 0; text-align: left; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>This is used to close the channel if the payment is delayed for &lt;payment_delay&gt; blocks.</div></div></div></div></foreignObject><text x="182" y="216" fill="#000000" font-family="Helvetica" font-size="12px">This is used to close the...</text></switch></g><rect x="555" y="182" width="110" height="60" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 108px; height: 1px; padding-top: 212px; margin-left: 557px;"><div style="box-sizing: border-box; font-size: 0; text-align: left; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">After the payment is resolved a new Update is created by the two parties.</div></div></div></foreignObject><text x="557" y="216" fill="#000000" font-family="Helvetica" font-size="12px">After the payment...</text></switch></g><rect x="77.5" y="482" width="75" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 73px; height: 1px; padding-top: 492px; margin-left: 79px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>balance:</div><div>1000 -- 1000</div></div></div></div></foreignObject><text x="115" y="496" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">balance:...</text></switch></g><rect x="437.5" y="482" width="75" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 73px; height: 1px; padding-top: 492px; margin-left: 439px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>balance:</div><div>912 -- 1088</div></div></div></div></foreignObject><text x="475" y="496" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">balance:...</text></switch></g><rect x="257.5" y="482" width="75" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 73px; height: 1px; padding-top: 492px; margin-left: 259px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>balance:</div><div>1000 -- 1000</div></div></div></div></foreignObject><text x="295" y="496" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">balance:...</text></switch></g><rect x="617.5" y="482" width="75" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 73px; height: 1px; padding-top: 492px; margin-left: 619px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>balance:</div><div>912 -- 1088</div></div></div></div></foreignObject><text x="655" y="496" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">balance:...</text></switch></g><rect x="63.75" y="532" width="102.5" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 101px; height: 1px; padding-top: 547px; margin-left: 66px;"><div style="box-sizing: border-box; font-size: 0; text-align: left; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div align="left">Channel balance starts with 1000 for each.<br /></div></div></div></div></foreignObject><text x="66" y="551" fill="#000000" font-family="Helvetica" font-size="12px">Channel balance s...</text></switch></g><rect x="418.75" y="532" width="136.25" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 134px; height: 1px; padding-top: 547px; margin-left: 421px;"><div style="box-sizing: border-box; font-size: 0; text-align: left; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>If receiver has the preimage but sender is unresponsive, the channel is closed with the updated balance.</div></div></div></div></foreignObject><text x="421" y="551" fill="#000000" font-family="Helvetica" font-size="12px">If receiver has the pre...</text></switch></g><rect x="243.75" y="552" width="136.25" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 134px; height: 1px; padding-top: 567px; margin-left: 246px;"><div style="box-sizing: border-box; font-size: 0; text-align: left; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">If the payment doesn't complete in time and the receiver side is unresponsive the sender side can close the channel with the previous balance.</div></div></div></foreignObject><text x="246" y="571" fill="#000000" font-family="Helvetica" font-size="12px">If the payment doesn't...</text></switch></g><rect x="600" y="522" width="136.25" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 134px; height: 1px; padding-top: 537px; margin-left: 602px;"><div style="box-sizing: border-box; font-size: 0; text-align: left; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">The payment was completed. A new update is generated.</div></div></div></foreignObject><text x="602" y="541" fill="#000000" font-family="Helvetica" font-size="12px">The payment was complet...</text></switch></g><rect x="77.5" y="442" width="82.5" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 81px; height: 1px; padding-top: 452px; margin-left: 79px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nSequence 10</div></div></div></foreignObject><text x="119" y="456" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">nSequence 10</text></switch></g><rect x="433.75" y="442" width="82.5" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 81px; height: 1px; padding-top: 452px; margin-left: 435px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nSequence 10</div></div></div></foreignObject><text x="475" y="456" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">nSequence 10</text></switch></g><rect x="613.75" y="442" width="82.5" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 81px; height: 1px; padding-top: 452px; margin-left: 615px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nSequence 10</div></div></div></foreignObject><text x="655" y="456" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">nSequence 10</text></switch></g><rect x="190" y="442" width="220" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 452px; margin-left: 191px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nLocktime &lt;current_block&gt; + &lt;payment_delay&gt;</div></div></div></foreignObject><text x="300" y="456" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">nLocktime &lt;current_block&gt; + &lt;payment...</text></switch></g><rect x="30" y="262" width="82.5" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 81px; height: 1px; padding-top: 272px; margin-left: 31px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nLocktime 1</div></div></div></foreignObject><text x="71" y="276" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">nLocktime 1</text></switch></g><rect x="210" y="262" width="82.5" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 81px; height: 1px; padding-top: 272px; margin-left: 211px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>nLocktime 2</div></div></div></div></foreignObject><text x="251" y="276" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">nLocktime 2</text></switch></g><rect x="387.5" y="262" width="82.5" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 81px; height: 1px; padding-top: 272px; margin-left: 389px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>nLocktime 3<br /></div></div></div></div></foreignObject><text x="429" y="276" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">nLocktime 3&#xa;</text></switch></g><rect x="567.5" y="262" width="82.5" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 81px; height: 1px; padding-top: 272px; margin-left: 569px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>nLocktime 4<br /></div></div></div></div></foreignObject><text x="609" y="276" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">nLocktime 4&#xa;</text></switch></g><path d="M 480 132 L 540 132 Q 550 132 550 142 L 550 632" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><rect x="240" y="122" width="240" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 238px; height: 1px; padding-top: 132px; margin-left: 241px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">These are only used in case of disagreeent.</div></div></div></foreignObject><text x="360" y="136" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">These are only used in case of disagreee...</text></switch></g><path d="M 550 632 L 180 632 Q 170 632 170 622 L 170 142 Q 170 132 180 132 L 240 132" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><rect x="0" y="2" width="760" height="110" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 758px; height: 1px; padding-top: 57px; margin-left: 2px;"><div style="box-sizing: border-box; font-size: 0; text-align: left; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div align="left">Instead of making linear UPDATE transactions that resolve to settlement transactions that may contain a bundle of in-flight HTLCs, we instead issue a HASHLOCKED UPDATE, i.e., an UPDATE transaction that can only be spent when the corresponding preimage arrives and a corresponding RESCUE UPDATE. In the normal channel operation these are superseded by a new UPDATE transaction after a payment is completed. However in case of disagreement one of the two special UPDATEs is used to close the channel.</div><div align="left"><br /></div><div align="left">This design reduces the cost of sending payments through a channel in case of onchain settlement and makes it unnecessary to have trusted "fake" HTLCs that pay to miners instead of to each peer and don't provide reliable proof-of-payments. However, it only allows for one payment to be in-flight at each time in a channel.<br /></div></div></div></div></foreignObject><text x="2" y="61" fill="#000000" font-family="Helvetica" font-size="12px">Instead of making linear UPDATE transactions that resolve to settlement transactions that may contain a bundle of in-flight HT...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://desk.draw.io/support/solutions/articles/16000042487" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>

Lightning Network: reclaiming the original vision

The title is a joke because I have no idea of what was the original vision, but this at least corresponds to some vision from someone (me).

Description

In the current Lightning Network it's not safe to send or relay small payments because the cost of settling these payments onchain in case of failure is too big.

The way the current design solves this is that according to node preferences, whenever a payment below some threshold is sent through a channel the commitment transaction is adjusted to pay that amount as fees in case the channel is closed. That's a form of reserving that amount and incentivizing peers to resolve the payment, either successfully (in case it goes to the receiving node's balance) or not (it then goes back to the sender's balance).

Since onchain fees are expected to rise (and rise they must if Bitcoin is to continue working) then the above can become a problem as most or all Lightning transactions are deemed uneconomical and sent not through real HTLCs redeemable onchain but just as fake HTLCs which are just fees to miners.

Against the argument that such a construction is not trustless it has been argued that a channel is a valuable entity that both peers wouldn't want to close just to make the other party lose money, with which I agree. Problem

The Lightning Network resembles a lot the idea of sending payments through mutual credit networks, an idea that has been tried many times in the past starting with Ryan Fugger's Ripple (before he sold the name to the Ripple shitcoin) but never worked out because no one has came up with a way to solve the decentralized commit problem (and embarrassingly people keep reviving the idea without acknowledging this issue which was already stated in the old Ripple documents).

In short, the problem is that the payment is done in parts, A pays B, B pays C, C pays D and so on (or in the reverse order), but if one of the payments fails or is delayed the entire thing is left half-committed, in an undecided state, and there's not even a way to know when peers should safely say a payment has failed or it's still pending.

Like Lightning, these networks work with payments going through routes passing through channels and altering the balances of these channels. However Lightning does two things these mutual credit networks don't do:

  1. It isn't based on credit or trust. Instead, the balances are based on money deposited upfront
  2. It solves the decentralized commit problem with HTLCs that can be redeemed the Bitcoin blockchain with clear timeouts and exposing (or not, depending on who redeemed) preimages that work as proofs of payment and can be used by the remaining pending hops in a route

However, if the Lightning Network suddenly starts working without real HTLCs then the second advantage doesn't hold anymore, we will be living in a world of undecided transactions with no proof-of-payment.

For example: if D gets a payment proposal from C it then releases a proof-of-payment. At that point, before sending an updated commit transaction to D, C can stop answering D but still use the proof-of-payment to resolve the payment it has pending from B and B can do the same with A, so A will have a proof-of-payment but D won't be received anything.

If following the current Lightning spec, D will then proceed to close his channel with C to redeem the HTLC onchain – however there's no real HTLC to be redeemed, the C–D channel will be closed for no reason – or rather for the reason that C was a terrible peer anyway, but that's not the way the network was supposed to work (there's a claim a payment network could work this way, but then it would be another iteration of mutual credit networks and not Lightning anymore).

Solution

The solution is to make payments in Lightning atomic and conditional, with proof-of-payment, but without increasing the onchain overhead by a lot.

The idea is that each payment in-flight would conditionally alter the final balance instead of add a new output and require a new transaction to be redeemed. The final balance is still a single transaction that closes the channel.

This way there's no incentive at all to skip adding the relevant conditions and fulfillments to each channel. Lightning keeps its two basic promises: trustlessness through a fair split of predeposited coins (minus fees) and a decentralized commit enforced by hashlocks.

A prototype of how this can be implemented on Eltoo is shown here: https://gist.github.com/fiatjaf/712a8651dff5908d139dc62ea4dfd551#file-hashlocked-updates-eltoo-svg


2020-02-29

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment