Home < Chaincode Labs < Chaincode Residency < The Update Layer

The Update Layer

Speakers: Rene Pickhardt

Date: June 26, 2019

Transcript By: Jonathan Gross

Tags: Lightning

Category: Residency

Media: https://youtu.be/SoFlRCNdqDg

Location: Chaincode Labs Lightning Residency 2019

Introduction

Maybe we had a wrong impression, you can ask, like in Christian’s talk, as many questions as you want while the presentation is there. So, it’s a small disclaimer just saying: these slides are part of a much larger slide set which is open-source and you find notes and, I think, we share slides in the Google Docs anyway.

The outline of the talk is, I’m going to talk about the construction of payment channels in Bitcoin. I start with a small motivation from HTTP and then I do the real channel construction, then I talk a little bit about the peer protocol for channel management without the HTLCs because HTLCs and what you have is something that is supposed to be in a later talk just from the structure how we are doing this. So we’re talking about the peer messages for opening a channel and I have a small word about Segwit and transaction malleability. And then I talk about three ways on how to close a channel.

Construction of Payment channels (RSMCs) (Chapter 1)

Let’s start with the construction of payment channels. So first of all why do we do this what is the purpose of a trustless bedirectional payment channel and the Lightning Network?

So first of all we want to be able to send payments between two partners and this should be done instantly. It’s basically instantly means it’s like updating a balance sheet. You heard the term of channel capacity and channel balance often when you talk about the Lightning Network. It should only be bound by network traffic over the Internet and not depend on other stuff, right, it should be as fast as possible. We don’t want to have a direct involvement of the blockchain in our payment channel, right, so as long as everybody plays by the rules we don’t involve the blockchain.

And then, we want to do it in a way that there’s no need for any partner to trust the other side. This morning we talked a little bit about trust and what I always like to say is in lightning we still trust somebody. Who do we trust in lightning? The blockchain, yes. I mean this is really where all the trust is being pushed to and mitigated to, right. So the Bitcoin blockchain and the Bitcoin network need to be trusted. But the Bitcoin network will only needs to be trusted in order to settle conflicts if they arise.

Then we don’t want to have high fees or overhead when sending payments within the channel. And the crucial part about these channels is that payments can go back and forth. As Christian mentioned, historically we already had single channels where we could send in one direction and then we need to close the channel and open a new one. And with these channels we can send money back and forth and this is really cool construction.

Of course we want to scale the usage of Bitcoin. I mean that’s like the higher goal or motivation why we are building this entire network anyway.

So yeah the question is that we’re trying mainly to resolve here is how can this technically be possible. And I should already mention there are other constructions. Christian, what is the other construction? I think eltoo.

A comparison with HTTP

As I promised let’s start with a small comparison with HTTP. As you all probably know HTTP is a request and response protocol, right. Which means you, the client or the browser, can make requests to some server and then the server gives you a response.

And according to the protocol a server cannot initiate a communication with you. If you open your browser, it will hardly happen that Facebook decides “oh I want to talk to you”, and they just load the Facebook page in your browser, right. You have to type in facebook.com and then you hit enter and then you start the conversation with them.

So my question is: how can a website, for example Twitter, give us a notifcation that some new data is there on their website? If you are on this website and your tweets appear, then you see a message there’s new tweets, you can load them, and you didn’t ask for it directly. Like, at least from your user experience that did not happen, right. And this is all happening over HTTP. So my response to this is that they do this by abusing the protocol. And it’s known as a server push along polling or these kinds of things, right. And if we look a little bit back in history, it took us about ten years to figure out how to do this stuff. But HTTP was invented in 1989-1990, around this time, and it was just in the early 2000s when people really started doing all this Ajax magic and these kinds of things, right. So many people already knew before that it could be done but it was not really implemented.

How does a HTTP server push work?

And I just want to review a little bit how does the HTTP server push work. So you load a web page, and then JavaScript secretly initiates another HTTP request with the web server. And the server looks if it has some information for the client. So for example, are there new tweets? And if there is information, yes you can respond: “here’s the information you requested”. The interesting case is if there is no data. Then usually, what you would expect is the HTTP request would finish and say “no there is no data for me”. But in our case, server push defers answering that request to some time in the future, right. It just keeps your TCP socket open, over which HTTP is running, and it waits to the future. And how long does it wait? Well if new information for the client is available or if the client opens a new page and can’t receive the response anymore, right, and in this case if something happens, or there is a heartbeat mechanism to reestablish the connection all the time. And then the answer comes. But from an end-user perspective, it really looks like the server has initiated conversation. Because on your web page, magically something appears. And because the end user usually doesn’t know the Ajax request is outstanding. You can read more about this on Wikipedia obviously: https://en.wikipedia.org/wiki/Push_technology.

Payment channels are constructed by deferring the publication or broadcast of some TXs to the future

The argument that I’m trying to make is that lightning uses the same idea of deferring something to the future, of not playing properly by the Bitcoin. So payment channels are constructed by deferring the publication or broadcast of some transaction to the future.

So Bitcoin obviously is not a request response protocol, it’s rather a broadcast gossip protocol. You have a Bitcoin transaction and once it’s done you broadcast it to everybody, and everybody can say yeah we reply to it and we mine it and do all that kind of stuff.

So the question here is: in lightning, what exactly is being deferred to the future. I’m pretty sure you all know this, right? What are we deferring to the future in lightning? Publication of transactions, yes. So transaction spending outputs, they are held back from being broadcast. We will look into the details in the remainder of the talk. So Later Transactions are purposely tried to be double spent. In lightning, we’re double spending transactions all the time. This is really what’s happening. Bad word, right? We’re trying to make Bitcoin in order to solve the double spending problem and all we’re trying not to use the blockchain or at least use it as little as possible and we’re double spending all the time. It’s a little bit delirious, but this is apparently how it works. And, I mean, obviously a transaction can only be spent once, at the end of the day, this is how the Bitcoin network helps us with consensus and making sure that the protocol works. And lightning or the lightning network protocol or the construction of payment channels, how I see it is to make sure that the correct double spend is, by the end of the day, being broadcast, right? So we have the transaction, we have hundreds or thousands of double spend, and the lightning network protocol is trying to make sure that the correct double spend is the one that is actually being mined.

So what I wanted to say is that Payment channels are to Bitcoin what HTTP Server Push is to HTTP. So it’s a non obvious use of the Bitcoin protocol. And it took us, like HTTP, a little while to figure out how to do this properly. I think we’re still, to some degree, trying to figure out and making it better

A payment channel is a 2-2 multisig Address together with some (smart?) contracts

So from a technical perspective, a payment channel is a two of two multisig address together with some smart contracts. I put smart in parentheses with a question mark because I’m not to fond of this term, but I think, at the end of the day, it is a smart contract. So two out of two multisig address means that the output script that spends this transaction requires two signatures in order to be able to spend this transaction.

And it is a form of a Pay to Script Hash in our case and this usually always looks something like this. So you have like serialized script and the hash of it, and you have the Opcode to check if it’s equal or not. And then the input script is: you have all the signatures and then what the script is like, then you have the serialized script.

And in case of a multisig you can basically – sorry I’m always hitting the wrong key here – you have the output script which is the same, but the input script really has the signatures in this way. So you have the check multisig Opcode.

The smart contract (RSMC)

In lightning, the smart contract is called the revocable sequence maturity contract. So we start with a 2-2 multisig wallet that has some funds. And this is something that we definitely see onchain, right? We discussed privacy before where we talked about what do we see onchain and what do we not see onchain. This is something we see onchain. We don’t necessarily know that this is a lightning funding transaction or a lightning wallet that is like backing this channel but we see it onchain.

The question to ask is: who owns these funds? So the channel partners do not share these two private keys with each other, right? Everybody just has one private key, right? So not a single person can access these funds right away, right? I always need to communicate with the other person in order to access these funds. And I would argue, depending on how we are spending these funds, this is how the funds are being owned. All right? So I have this multi signature wallet, there’s some funds on them, and I make a transaction, and in this transaction I’m saying, well 60% of the Bitcoin go to me and 40% of the Bitcoin go to you. And this is how we define ownership of the funds that are in this wallet, right? The transaction is defining the ownership.

So this particular transaction that defines ownership, we keep this secret if possible as long as possible. Basically we never want this to be public. And this will encode the balance, as I just explained, right? 60-40 or 50-50 or whatever. And this transaction is called a commitment transaction. I think you all heard that term before. And it has to be signed before publishing the funding transaction. The funding transaction is the one that sends Bitcoin to this 2-2 multisig wallet.

So some technical details. As I mentioned before, this funding transaction is heavily being double spent. Which on Bitcoin is impossible. We secure the funds with timelocks. This is what’s being used to make the smart contract really work in the way how we want it to work. And it allows for conditional hash timelock outputs that we use in routing. This is a later talk today, when we talk about those.

And yes, RSMC is the revocable sequence maturity contracts.

So I drew some pictures. I wanted to actually steal your lock but I have managed to actually find one and do it. So let’s just assume we have some output over here of 100 mBTC and controlled by Alice’s key. And Alice is in her funding transaction with the input script referring to this output. And is creating a new output that says everything goes back, maybe, to Alice’s & Bob’s key, which means it’s a 2-2 multisig wallet.

I make heavy use of colors in the following slides so I want to talk about the legend for these colors. So if something is wite, it means it is broadcast and mined, right? This transaction, technically, it could also be created. This was not broadcast and mined, but let’s assume this one has enough confirmations, it’s mined and broadcast, then it’s fairly safe to make this transaction and refer to this output. If the background of a transaction is grey, it means that it’s not broadcast yet. And if it’s green, later on, it means that we should broadcast this right now and we should really want to broadcast this one. And red has two meanings: either it means it should not be broadcast or it means it cannot be mined, meaning the outputs are already consumed, it would be a double spent if it would be mined, right? So these are the legends.

So what we do then when we have this funding transaction, we create a so-called commitment transaction. And the commitment transaction also has an input which is referring to the output of the funding transaction. And maybe Alice, when she was creating the channel, was already saying well Bob should already have some money, so she decides that a commitment transaction has two outputs: 70 mBTC go to Alice and 30 mBTC go back to Bob, right? And here I wrote it a last time that these transactions are all unpublished at this point.

Once we have signatures for the commitment transaction, this transaction (the funding transaction) can be published. Because now it’s safe for Alice to publish this one. She knows she can always get her amount of Bitcoin back because she already has a signed commitment transaction and she doesn’t need Bob at this point in order to do something. And for those who understand lightning a little bit better, I should say this as a disclaimer: this currently is just leading up to the final construction. There’s some slight or minor mistakes here, this would not completely work yet. But we are extending this example on the fly, just for those who already know the entire construction not to be confused. Are there questions so far?

So as I mentioned before, the commitment transaction is really encoding the balance of the payment channel, right? So the capacity is 100 mBTC and the balance is Alice has 70 mBTC and Bob has 30. And this transaction can be broadcast to the Bitcoin network at any point in time, which is really nice. So if Alice and Bob have a disagreement or somebody of these two people disappears, the other person can take this commitment transaction, broadcast it to the blockchain and say: “hey, this is how I want the world to look like”. And the funding transaction must use segWit outputs to prevent malleability. I will later, after the construction, talk a little bit more about malleability and why this is important. But I just want to mention it here already.

So now we create the second commitment transaction. Bob updates the channel balance, right? So if you look at this, this is exactly the picture as we had it before, but now we have the commitment transaction too coming to this. This one is also referring to the output of the multisig wallet. But now, Alice gets 80 mBTC and Bob gets 20 mBTC. What this means is that, effectively, Bob has sent 10 mBTC to Alice. Because before, Alice had 70, now Alice has 80. What’s the problem with this situation? Yeah, exactly, well, after Bob does this, Bob gets a decent meal from Alice, right? He had a great time, and then Bob decides to broadcast this commitment transaction. So if Bob does this, this one cannot be mined anymore, because this one is already mined. Both are public now, and, effectively, Bob has stolen 10mBTC from Alice. This is bad. This is something that should not happen, right? And as I mentioned before, in lightning, we’re trying to make sure in the protocol, by modifying these outputs a little bit, that this situation cannot occur.

So how do we do this? This is our goal. Make sure that as soon as we have this one and they are still unpublished, this one should or cannot be broadcast, for some reason. So we do this by modifying the output in the commitment transaction so that fraudulent publishing will punish the publisher. So we change this output a little bit and, so, for example, the punishment would be to give the silent party, the party that didn’t publish this, all the outputs that would go to the other party. The penalty mechanism that we know in the Lightning paper. So we do this by changing the output of the commitment transaction. Now I already did a slight modification of the commitment transaction. First of all it’s not called commitment transaction 1 anymore but it’s called commitment transaction 1b, because it’s Bob’s commitment transaction. Alice has her own version of commitment transaction, right? So we have two first commitment transactions. Well the version for Bob looks like this, that 70 mBTC still go to Alice, but these 30 mBTC are not sent directly to Bob anymore. They are sent to this output script which is called the revocable sequence maturity output. And here you can see the entire script. It’s a bit technical, it’s rather focused on this kind of like picture. Basically, if you look here, it has an if and an else, right, so this, well, either you are in the case where you have the revocable delivery, which means after a relative timelock, Bob can claim with his key the 30 mBTC, as he should be able to do because this is his funds. But, before this relative timelock has passed by, there is the breach remedy transaction, the breach remedy condition, in which this output can be claimed if there’s Bob’s & Alice’s revocation key, or the first revocation key. But every commitment transaction has their own revocation key later on, as you want to change them for every state. So these are the two possible ways of being able to spend this commitment transaction. If you look before, here, I refer to this as a double spending. And here in this picture, this is not a double spending, just to make sure that we’re talking about the same thing, because this is just a visual representation of this entire script, right? I mean this is just helping out to better understand what’s written here in the script code of Bitcoin script.

Alright, so, what does this help us to modify the output like this? Well, let’s assume that the commitment transaction gets published on the blockchain. Within the first 144 blocks, what can happen is only Alice is able to spend this output. Because Bob, with his key, he can’t do anything. There’s the timelock, right, that prevents Bob from actually spending this output, right? I mean the script is there but Bob, whith the new transaction, cannot use this output because the Bitcoin network will prohibit this. Alice, however, if she, for some reason, has Bob’s key, she could do this, and Bob does not have Alice’s key, right? And in the other situation, let’s assume Alice does not have Bob’s key. After 144 blocks, Bob is able to spend this output. So yeah, that’s the construction, basically.

[inaudible question from audience]

The thing is when you think about even more, actually, both of them should be white because this one is just a visualization of this script and this script is already white, right? I mean this entire script is onchain but the reason why I think I made it gray was that, actually, the transaction that is really spending this output does not have to be published at this point in time. So I should rather make it green in the sense of, like, he can do it, yeah.

OK, so now what happens if the channel state or the channel balance is being updated, right? So remember we have the first commitment transaction 1b and we have our contract, our revocable sequence maturity contract with it, and then we have our second commitment transaction in which bob has sent some money to Alice. So what I argue is that this transaction should not be published by Bob anymore. Why should Bob not do this? Yeah, he loses his funds, right? So, in order to lose his funds, Alice has to do something. She has to say “yeah I’m only signing this commitment transaction if you will share your revocation secret with me”, right? So, this commitment transaction is only publishable if it’s signed by Alice and Bob, and this will only happen if Alice has Bob’s revocation secret. And then, in this situation, the entire setting is safe. But because now, Bob is incentivized, if he needs to broadcast something to the Bitcoin network, to use this commitment transaction ; if he uses that one he has the fear of losing his funds. So let’s just make it explicit, let’s assume that this transaction is being published and mined. Obviously, this one cannot be mined anymore. It would be double spend off the funding transaction. But since Alice has a revocation key, she now should really go for the breach remedy condition, and she should try to collect the entire outputs. If she does not do this, by the way, Bob can, after the timelock, get his funds, right? This is the reason why lightning nodes need to be online, right? If the Lightning node goes offline for a certain amount of time, the timelock is gone. Let’s say Alice’s node is offline, then Bob would still get his funds and publish an old state. But that’s a gamble, right?

Some remarks on presented simplifications

So some remarks on the presented simplifications, because there were still some simplifications in this. In order to be able to ascribe blame both sides get their own commitment transactions. So, as you saw, I called the commitment transactions 1b 2b 3b for Bob, and basically in a symmetrical way there’s commitment transactions for Alice, only that the revocable sequence maturity contract now is for Alice’s output, right? So Alice’s output is timelocked there. And then, of course, if one of these commitment transactions is being broadcast, the other person sees ho yeah, it’s theirs and not mine. And also the revocation key is a different one.

Then, there are transactions for every channel update. So we have to go to the next one. I don’t know why I put the statement here, hum.

For every update of the commitment transactions, new revocation keys have to be created, right? They don’t use the same revocation key over and over again, right? Because then, after sharing their revocation key for the first time, obviously this would be a bad situation, right? Because then, for the next transaction, I could already guess the revocation key and already claim it, even though I should not have it. And, as we discussed before, there is this smart way of generating the revocation keys as a sha chain so you don’t need to store all the old revocation keys. It’s sufficient to only store a couple of revocation keys. Yeah, as I mentioned before, future breach remedy transactions, if the revocation keys were always the same, it could be spent right away, right? So we need old revocation keys.

The commitment transactions will have even more outputs, right? So we only saw two outputs in the commitment transaction, which was the timelocked output that goes to myself basically, which can be like taken away as a penalty and the output of the channel partner, but there’s also HTLCs that are additional outputs in the commitment transactions. And this talk will not talk too much about HTLCs because Fabrice is doing a talk about HTLCs afterwards. And then in the multihop talk, I will use them again to also show you how actually funds are being exchanged in one channel.

So yeah, there’s a small reading suggestion for a payment channel construction with less overhead, and that’s the eltoo paper. So a simple layer 2 protocol for Bitcoin. I think one of the authors is sitting here, trying to shill it all the time. And there’s also Lalu from Lightning Labs, who helps with it. On my blog, I wrote a summary on this: https://www.rene-pickhardt.de/index.html%3Fp=2116.html. There’s actually another very good summary by Lisa, she also wrote a summary on her blog. But even the paper is, I would say, pretty easy to read. So yeah, I don’t talk more about eltoo today.

Some remarks on dust outputs

Some remarks on dust outputs, because they are an issue. As you know, in Bitcoin, outputs must have certain amount, otherwise the fees will be higher to spend the output than the amount that is attached to the output, right? And then the blockchain could be spammed.

Dust limit depends on the script and is usually a few hundred satoshis, right? So the question is what’s happening if I make a lightning payment that is less than a few hundred satoshis. So let’s say I want to transfer one satoshi on the lightning network, how does that work?

So what we’re doing in lightning is if the outputs in the commitment transactions are below the dust limit, they will just be omitted. So then they don’t really exist. So in this situation, let’s assume we have this channel where we have 100 mBTC as a capacity and there’s 50 mBTC for you and 50 mBTC for me. Now I can easily transfer one Satoshi because I can reduce your output or I can reduce my output by 1 satoshi and increase your output by 1 satoshi. But if I initially funded this channel and I have all the funds on my side, I cannot really send 1 satoshi to you because then you would have an output that has 1 sat and this would be below the dust limit. So your output would be omitted right away. And when the output is omitted, it’s not getting back to me but it’s added to the fees that are being paid for the commitment transaction in case the transaction is going to be mined. So, while lightning implementations support these tiniest payments, those amounts cannot always be enforced onchain, and this makes these tiny payments, or routing tiny payments, might make you lose some funds, right? So some people call it custodial, to some degree, right, because you kind of trust the other node that at some point in time, when you make more updates, you eventually get an output that has maybe 100 sats or something like that. I think all implementations currently can be configured to not accept payments under certain amount if you want to avoid this kind of behavior.

Standard to_local witness script for commitment txs

So yeah, this is the standard to_local witness script for commitment txs.

Peer Protocol (BOLT 02)

Now, I want to talk a little bit more about the peer protocol, because as Christian already mentioned in the first talk today, is that the update layer is really happening in BOLT 02 and this is called the Peer Protocol.

Purpose of the Peer Protocol

So, the purpose of the Peer protocol is to establish a communication between two peers that are connected. And for the remainder of this talk, I assume there is a working authenticated and encrypted transport layer, which is called Noise_XK. So this is on top of a single TCP socket. So how will two nodes be actually able to maintain the revocable sequence maturity contract and the HTLCs, right? I mean that goes a little bit in your direction and part of this will already answer. Also how will onion packages being sent between peers, right? I think, this morning, somebody was a little bit surprised that the onion was part of a lightning message and that there was like double encryption basically, because the onion is encrypted, and then the lightning message is encrypted again. And then, we have the channel management and the operation of the channel, right? Which basically is like how do these two interact with each other. So, this means we have channel establishment, right? How do I actually open a channel, right? Because I only showed the cryptography so far but not on the communication level all of this is happening. And how do we close a channel? How is that actually working? And then, the normal operation. That’s really how we route payments, how we update an amount, and that’s being in the next talk.

Format of Lightning messages

So first of all, we have the format of lightning messages. So, we have a 2 byte field for the type, and then we have a variable length payload, which is at most, 2 to 16th minus 1 byte. And the format of the payload confirms to the type, right? So this is all specified in the bolts when you read about them. And even type messages must be specified and must not be sent otherwise. This is actually the second time where it’s okay to be odd rule applies, right? It’s not only for the features, but also for the messages. Because I was a bit confused before, when you mentioned it for the features. So, there’s also some logical groups of types, if you look at the BOLT specifications. So, the first 32 types are for setup and control of how peers are interacting with each other. I think if you pay close attention to Christian’s talk, there was type 16 that was in it and type 17 that was the error message, right? It was the base and control. And then there are the types up to 127, which is channel establishment and closure of channels, which I will talk a little bit about it right now. And then there is channel operation, including setup and settlement of HTLCs, which is in the second talk I give today. And then the even higher types are for the gossip protocol. I think we talk about the Casa protocol tomorrow.

Establishing a channel (Chapter 6a / BOLT 02)

So yeah, let’s talk about establishing a channel. How does this really work? So, this is the typical graphic that you often see, and these are names of lightning messages, right? So, there’s 2 peers, A and B, and they already have a connection, so they are peers, right? The key exchange with the noise XK protocol, this all works. As I said, assume that the transport is there. And then you have these messages: the open_channel message, the accept_channel message, the funding_created, funding_signed and funding_locked messages. And this is basically the workflow of how these messages are being sent to each other. And obviously, there’s some information attached to these messages, and we’re going to look at these a little bit closer now.

So yeah, these are the five messages. So let’s start with the open_channel message. The arrow here means that it goes from Alice to Bob, right? We saw this on this big picture, that Alice was on the left, Bob on the right. So, it’s type 32. It’s the first message in this block of messages and it starts with a 32 byte chain_hash. And the chain_hash is the hash of the Genesis block of this chain. It’s a very interesting property, I would say, that, when you open a channel, you specify on which blockchain you actually want to specify, this channel. We’re always talking about the Lightning Network as a solution to scale Bitcoin, but technically, I could already include a chain_hash of the litecoin network or the Genesis hash of the litecoin network blockchain. And then, this channel message and everything else would more or less go through, right? So, I can have channels on different chains. Then, I have a temporary_channel_id, because the final channel id is not determined yet so this is just some random data for the nodes to refer to this. I have the amount of satoshis that I want to bring to this channel. So this is the funding_satoshis. push_msat. So msat is always milli satoshi. As you know, in lightning, we calculate even a fraction up to one thousandth of satoshi, and this is how much I might already push to the other side of the channel, right? When I open a channel, I could already say: hey, the other party already gets some money with it. Then I can put in the dust_limit_satoshis. Then, the next field is the max_htlc_value_in_flight_msat. So, this means what is the maximum amount of payment that is being supposed to be routed on this channel, you know? Currently, it’s like hard fixed in lightning that it can’t be more than 4 million, I think. I think 40 million, right? So, but you could technically set here a different value and then, if both nodes agree to pursue on establishing the channel, you could already forward higher. And then the htlc_minimum_msat value, as I said before, like too small HTLCs might not make sense for you because, when the channel breaks, you might lose these outputs, because they are below the dust limit. So, you can also set this here. Then, there’s the to_self_delay, which is basically the amount of blocks you would wait in your revocable sequence maturity contract. Then the maximum amount of accepted HTLCs, right? So, maybe you don’t want to have like too large transactions being onchain, so you say I only want to allow 100 HTLCs on my channel concurrently at one moment, and, other than that, I don’t accept anymore. Your channel partner needs to know this. Then, you have the funding_pubkey, which is the address of the 2-2 multisig wallet that you are providing here. And then, you have some Basepoints for all the keys that are being used in lightning. So there’s the revocation basepoint, the payment basepoint, the delayed_payment basepoint and the HTLC basepoint, because all of these addresses are derived from their own basepoint. And the first_per_commitment basepoint. So, if you think about these, I mean it’s a very technical list of data, but if you think about all these values that we have there, it’s pretty much what you would assume when you see how lightning works, right? I mean the funding_satoshis makes sense, the hash_chain, and the rest is just like some configuration of the lightning channel, as it is. So, this is what Alice suggests to Bob and says “hey, I want to open the channel and this is my offer”.

So now, Bob will answer with the channel_accept message. And what you can see is that most of the data values are the same and, I think, the only difference that is here is the minimum_depth. Which means this is for how long the funding transaction should be confirmed before I make the channel operational with you, right? And all the other values, I mean it’s not the same data, right, the relocation basepoint and stuff, I mean, it’s obviously different, but it’s the same type of data that is being sent back, right? So, basically, these messages are very similar.

So then, you have the funding_created message, right? And I just put this here again as a reminder of our graphical view of how this looks like, right? We have the funding transaction, it’s not published yet, right, it’s still gray, unpublished. But once Alice decides she wants to open a channel, she sends this message over to Bob, Bob replies with the accept_channel message, Alice, it’s her turn again to create the funding_created message. So it still has a temporary_channel_id, which must be the same as in the open_channel message, right? She cannot just exchange this id now, then Bob would say “I don’t know what to do with this id, I did not agree to a channel with this temporary id”.

Then, there should be a funding transaction id, right? Even though the funding transaction is, at this stage, not supposed to be sent to the Bitcoin network, and Alice is also not sending over the funding transaction. She is sending the funding transaction id to Bob. Why does Bob need the funding transaction id? Yeah, so the commitment transaction is referring to the funding transaction, right? So he needs the transaction id to point to it. And again, the transaction has to be non malleable and must not be broadcast at this time.

Then, we have a funding transaction output index. So technically, I mean, when you looked at this diagram, there was only one output in the funding transaction, but technically, you could have several outputs and these several outputs could actually be outputs for different channels. So, it’s safer to say “hey, by the way, it’s really the first output that you’re trying to spend when you’re trying to spend a new commitment transaction”. So, the funding transaction output index is also sent over.

And then, of course, you need a signature. And this is a valid signature using the funding_pubkey for the initial commitment transaction. And if this one is not correct, the other party must fail the channel and say “yeah, you know, you’re sending me some data, but I cannot do anything with this”.

So, then, the funding_signed message is being sent back, right? So, this means we now have a commitment transaction over here which has the channel_id which is the funding_txid XOR the funding_output_index.

So then, there is a signature sent back for the first commitment transaction. So when I mean 2nd signature, this means this is the signature that Bob will use to sign Alice’s commitment transaction. Because, I mean, by the end of the day, when Alice opens the channel, she needs to have a commitment transaction that is safe to be broadcast, right? So, Bob already knows how the commitment transaction for Alice should look like because notice the basepoint at everything where the commitment transaction is being generated. So, Bob can basically create this commitment transaction and it needs two signatures and the signature from Bob is being sent over to Alice. And if it’s invalid, again, Alice will stop this operation and fail the channel. And of course, she must not broadcast the funding transaction because that would be a bad idea because now, the channel is funded, there is money at a multisignature wallet and Bob could blackmail her and say “hey, only if you give me that amount of Bitcoin to me, I will give you a signature”. And if valid, of course, she should broadcast the funding transaction.

OK, so, on transaction malleability and the need for segwit. I promised in the beginning I would talk about this little bit. So, after signatures for commitment transactions are exchanged, we have the funding_signed message. So we are here. The funding transaction is published by A, right? Because Alice now has the second signature. Her own signature, she can produce by herself, she doesn’t need any communication for this. So, let’s assume she publishes the funding transaction. So what B can do is B can catch this funding transaction, and if B malleates the transaction, it gets a new txid. And that is a bad thing because when the txid changes, then, of course, the commitment transaction that Alice has generated is pointing to nothing, right? And then, of course, your commitment transaction is not worth anything, right? So we really need this fact that the funding transaction cannot be altered any more. So what are the ways to malleate a transaction? So this could happen by swapping the S value of the signature or using a different encoding, I think. I have to admit, as I said before, I’m just one year in Bitcoin, so in some of the Bitcoin low-level stuff I’m not too strong. Or the sigScript could be also changed in order a little bit to executing the same, changing the transaction hash. So you can read about it obviously in the Bitcoin wiki. And then B can, as I mentioned before, try to publish the malleated version. And the commitment transaction refers to the old txid. So the txid of the funding transaction is malleated. The commitment transaction becomes worthless and B can blackmail. Stuff can be very ugly. This blackmail comes at no cost, right? Because, I am B, I’m accepting the channel_open message. And then at some point in time, I look at the blockchain, I’m faster in publishing the … Or maybe I’m a miner, I can like stuck this transaction and now I can do crazy stuff with it. So Segwit mitigates the possibility to malleate this transaction. That’s why we needed Segwit so badly. I think that the script in segwit could not be changed anymore.

So then, when we have this, we have the funding_locked message, all right? So after the funding is published and broadcasted, we have the channel_id, we have the next_per_commitment_point, right? So there’s this BOLT 03 with the key derivation that explains how all these keys are being derived in a pretty smart, but, I would say, technical way. And the next_per_commitment_point is shared so that for the next commitment transaction, they can already, like, create signatures. And future base points cannot be derived from old ones. But I think old ones can be derived from future ones, and that’s a pretty good thing. And the funding_locked message… [inaudible question from the audience] So, there are several base points, right? So you have, in the commitment transaction, you have the commitment base point. And the base points for these commitment transactions, they are all derived by an HD wallet, basically. But it’s also, basically, used in the sense of like a sha chain. So, you, basically, you do reverse order, which means that you can, when you know a commitment point, you can, from there, derive all the old ones, but you cannot derive the future ones. Which is nice because then you don’t have to store the old ones, if you, in case you need them anymore because you broke a transaction or something. So, yeah, the funding_locked message is necessary for the channel to become operational because you need the next commitment point. And the sender, it’s specified in the protocol, must wait until the minimum depth that the receiver of the channel was requiring, was achieved before sending this message.

[video cut]

The mutual close: [… ] Which means that you have to basically settle all HTLCs before you kind of like signal that you want to close a channel. You wait until all the HTLCs are settled. You don’t accept new HTLCs anymore and then you make this final transaction. And it’s also part of the BOLT 02 peer protocol, it’s written down how to do this specifically.

Then there’s the bad way of closing the channel, which is the unilateral clause, which happens if the protocol for example was breached or if somebody is just not there anymore. Because, then, you basically broadcast your commitment transaction. And you want to find situations where this message happens. Look in the BOLTs for the string “… MUST fail the channel”. Whenever you find the string, it still could happen that you do a collaborative close, but it’s not specified that if you must fail the channel, that you do it in the unilateral way. But, most of the time, the unilateral way is actually happening then. Because usually what led to the situation where you must fail the channel already when somebody’s not responding anymore, or something bad is happening. So, this is in the BOLTs where you find these cases where this is actually happening. And, it’s, by the way, quite frustrating when it happens, because your funds are timelocked, usually the fees are higher because, you know, in the commitment transaction, you’re just like guessing the fees that are in the future when you publish this transaction. Whereas, when you mutually close this channel, you can look at what are the fees right now. So this is really bad. But it could also be accidental because there’s hardware failure. Or the other side publishes the latest commitment transaction. It’s part of BOLT 05.

And then, there is the ugly way, which means that we use the revocation transaction. Somebody is maybe, deliberately, he tries to cheat, maybe not, maybe there’s just a software bug. I remember when I experienced such a software bug. I think you even have a better experience where you demonstrated [video cut].

So, let’s talk about the good way, the mutual close of closing a channel. And, as I said before, that’s always preferable to everybody. So, we have a similar picture here. We have shutdown messages, we have closing_signed messages. And the funny thing is: the closing_signed message could occur quite frequently, right? It’s not one exchange of these messages, but it could happen again and again and again. And so, it might converge at some point in time. I think there’s some mechanism for you that it will converge. So, it excludes the timelock of the funds. You make just a spend and you say: this amount goes to you, this amount goes to me, and once we publish this transaction, we’re happy it just goes out. So, partners can spend these funds directly. The fee can be negotiated while the closing takes place, right? And this potentially saves a lot of fees, right? Because you can basically look what the fee levels are. The only problem is: if your fee estimation of both nodes is different, right? Because you might use different implementations, and then you have different understanding of the world. And two messages are included. The shutdown message to signal the intend. So, basically, what I do is, I send a shutdown message saying “hey, I want to shutdown this channel”. And then Bob says “yep, I also I agree with you, right? Let’s shut down the channel”. If Bob doesn’t send this, then I will force close. Bob has no interest in doing this because, I mean, I only said I want to shut down the channel. So I’m daring or force closing. I think I even have it on the slide, so as I mentioned before with the converging.

Let’s look at the shutdown messages. But these messages are very easy. So, you have the channel_id, you have the len. And the len of the scriptpubkey that is being used. So, you can have different types of scripts for the closing transaction. You can either have P2PKH or a P2SH or witness public key hash. All these kinds of different script types are supported. And it must not be before the funding_created / funding_signed messages, right? So, you cannot close the channel too early. And it may be done before the funding_locked message, right? So, if the funding transaction is already published and maybe has one or two confirmations but the other person wants the channel not to be operational until there are six confirmations, you can already say “hey, I want to have a mutual close”. You may do that. And the important thing is once you send this shutdown message, you will not accept incoming HTLCs anymore. And that’s why you need to also reply with the shutdown message so that all parties do not accept and update HTLC messages. And, yeah, no future update messages will be accepted, per the gossip protocol. Because, I mean, it doesn’t make sense to accept an update protocol with new fee rates if the channel is not operational anymore.

So, then comes the closing_signed message. And if you look at it, it has the fee_satoshis and the signature, right? That’s why you need to have it back and forth because you need both signatures on both sides. And all HTLCs must be settled and cleared in the current commitment transaction, right? So you have to wait maybe before you start sending these closing_signed messages. So you send the shutdown message, you settle all the HTLCs. That might take a while. But then you can do it. And if the fees of one round of closing messages are equal, then you should sign and broadcast the closing transactions because you have consensus on the fees. And you can also close the connection, but you can still keep the peer connection alive. And otherwise, the fees should converge, right? So, must be strictly between the two fee values that are suggested. So, let’s say you suggest 5 sats, I suggest 50. Now, in the next step, we must get closer to each other, that at some point in time, we find the same amount.

OK, so, the bad way is the unilateral close. I think I speed this up a little bit because I think it’s quite clear what’s happening. So the most recent commitment transaction is pushed to the chain. The channel stops immediately to be operational, right? I mean, by sending any other channel operational messages back and forth, I mean, this thing is onchain now. Or at least, it’s in the mempool. And almost the exact channel state is seen onchain, right? So you see the balance and you see basically all fully committed HTLCs with the outputs that are higher than the dust limit. And then the HTLCs are spent with HTLC success transactions, all right? Or the HTLC timeout transactions, depending on whether the person who has this HTLC is able to provide the preimage or not. I can see all of this. So yeah, obviously watching services could help to do so. And if no claiming with the time lock, the breaching party can spend their outputs, right? This is the 24 hours Christian was talking about. And this case should obviously never occur.

So yeah, what can be seen by channel closes on chain?

So that depends on the type of close. And the channel state in the case of force close can be seen. In the mutual close, only the final balance can be seen. And the pending HTLC outputs can be seen only if they are not below the dust limit. And there might be a fight about HTLC sizes. I don’t know why this word is there, but there can be a fight obviously when you initiate the channel or about the dust limit. So nodes have an interest to be larger than the dust limit and the privacy aware people might want to be below the dust limit, right? So if I’m a routing node I will only route payments that are bigger than the dust limit. But if a person is very worry for their privacy, then they will want to see the payment hash, or the preimage later onchain, right, so they only want to make payments smaller than the dust limit. And this might be also gamed by some people.

Rational for Retransmission messages

There might be a rational for retransmission of messages. So, the communication transport is unreliable, right. So the noise program is on top of TCP and, I mean, I could just connect or not shutdown, right, so we don’t know that all messages once I sent them have really been arrived or are being replied. So at some point in time, I might have to retransmit communication messages. So I cannot assume, for example, that updates_add_htlc messages were received unless the commitment_signed message was received. And therefore, I might have to retransmit them again and again after a certain amount of time. Or I only store updates upon the receipt of commitment_signed transaction. And this ensures the retransmission after the channel reestablishment, right? So, when you make the connection again, you have to retransmit some of your data in this like channel protocol. So there is this channel_reestablish message that basically sends the current state of your channel to the other side, that basically says “hey, this is really where we are currently”. And in this way, you know where you are, that you can operate the channel from there on because you don’t know if the other messages have been arrived.

And yes, these are some resources and links.