 I'm going to talk about the Pala consensus protocol. This is joint work with the Hilbert Chen and Rafa Alpas. So in Chinese, Pili Pala is the sound of thunder. It also means fast, furious, and streamlined. OK. So I will begin by explaining the problem I'm trying to solve. So in all these cryptocurrency systems, the core abstraction is called state-to-machine replication, also referred to as blockchain or consensus. So in the rest of the talk, these terms are used interchangeably. We have a set of decentralized nodes. And these nodes are trying to reach agreement on ever-growing, linearly-ordered log of transactions. OK. There are two important security properties that we care about, namely consistency and liveness. Consistency says that all of the honest nodes must agree on the same log. So it could be your log is a little faster than mine because the network has delayed. But nonetheless, at the end of the day, we have to all agree. Lifeness says that whenever I want to buy coffee, the transaction will appear in all of the honest nodes logs very quickly. It's not like I want to wait forever for my coffee. OK. Now, initially, the problem may seem somewhat boring. So what's so exciting about building a linearly-ordered log? Well, indeed, if all of these nodes were honest and they correctly followed the protocol, the problem would have been trivial. But what's challenging about it is when some of these nodes can be corrupt. And these corrupt nodes can behave arbitrarily and deviate arbitrarily from the protocol. And even in such adversarial conditions, we want to make sure that the remaining honest nodes must nonetheless satisfy these security properties. So in the rest of the talk, we are always going to assume that less than 1 third of the nodes are corrupt. OK. So I will tell you a very simple consensus protocol that satisfies these two properties, consistency and liveness. And to begin with, I will first explain somewhat of a strongman scheme, a protocol that's very natural. It works by single-rounder voting. This is actually Thunders' fast-path consensus protocol, the previous version. If you are not familiar with Thunders' protocol, it doesn't matter because the entire talk is going to be self-contained. OK. So let's start with this very simple voting-based protocol. And before I talk about the protocol, I will very quickly explain the block formats we are going to assume throughout the talk. So in the talk, we are going to assume every block contains the parent hash. Basically, it's a cryptographic digest of the entire prefix of the chain. It has an epoch number. So we are going to assume every epoch is one second. And whenever honest nodes send a message, the message is going to get delivered in, let's say, a quarter of the second. So in one epoch, you can have four round trips. For simplicity, in this talk, I'm just going to assume the synchronous model. Basically, every honest message will get delivered very quickly. But at the end of the talk, I will mention, it's actually very easy to extend the approach to partially synchronous setting, too. OK. So now, of course, the block is going to contain the transactions you want to confirm. So very simple. OK, to make it more fun, this is the scenario we are going to work with. Vitalik acts as the proposer, and everyone else is a voter. So some of these nodes can be corrupt. Like in this case, Loki is corrupt. And the proposer can also be corrupt. So here's how a very natural protocol would work. Step number one, the proposer makes a proposal. The proposal contains a block. And the block is tagged with the epoch number, indicating the current epoch. OK. Now, when the voters receive the proposal, they are going to vote on the proposal. And in this case, Vitalik proposed an orange block. So if you are honest, you are going to vote on exactly the proposal you have received. So almost everyone casts an orange vote, except for Loki. Loki is corrupt. And instead of voting honestly, he voted for two blue blocks. OK, so now we have voted. What do we do next? We basically wait. We wait until we collect enough votes on the same block. And when there are enough votes on the same block, we have high enough confidence that we can confirm that block. So what is enough? In this talk, I'm going to assume votes from two-thirds the committee is considered enough. And in fact, if we have two-thirds votes, we are going to call that a notarization. OK, so a very important thing to remember about this protocol is that all of the honest notes are going to vote uniquely in every epoch. This means that in every epoch, I'm going to wait until I hear the first proposal from the proposer. I'm going to vote on that proposal and only that proposal. I'm not going to vote on anything else. So this invariant is very important for consistency. And in fact, given this invariant, I can give you a very simple consistency proof. OK, so imagine let's fix an epoch. OK, so imagine for this epoch, the blue block obtained notarization and the orange block obtained notarization too. And what I want to prove is that the blue block must be the same as the orange block. And remember, as I said in the beginning, we are going to assume less than one-third nodes are corrupt. OK, so how does the proof work? If you look at the blue set and orange set, and remember, there are only n nodes in total, right? So it must be the case that the intersection contains at least one-third n nodes. And now, because the adversary controls less than one-third, this means there must be an honest node in this intersection. OK, now remember what I said about honest nodes, right? They are going to vote uniquely. And if this honest guy in the intersection voted for both the blue and the orange, there is only one explanation, right? Basically, the blue block must be the same as orange. OK, so this establishes the fact that with this very simple protocol, for every epoch, only one block can get nodarization. OK, and another thing to note is that this consistency proof doesn't rely on the proposal being honest. The only thing it relies on is the fact that honest nodes vote uniquely. OK, so with this in mind, let's take a step back and think about this very simple protocol, right? As I said, we are going to assume two-thirds of the nodes are honest and online. And when the proposer is honest, life is all good, we have both consistency and liveness. Consistency, I've just proved to you, liveness is also simple because if the proposer is honest, he's going to propose the same thing to everyone. And because two-thirds of the nodes are honest, soon enough you are going to collect enough votes and you'll make progress. So when the proposer is corrupt, what happens? In this case, we still have consistency because as I argued, the consistency proof doesn't rely on proposer being honest, right? But we don't have liveness because the proposer can just crash and fail to propose anything or maybe he can propose different things to different people and everyone will end up voting on a different block. And no block will gain nodarization in this case. So OK, so now if you look at this picture, we have three out of the four properties. And the only thing we need to fix is the liveness issue when the proposer is corrupt. And if we can fix that, we can get a full consensus protocol. OK, before I talk about Pala, I want to quickly mention the approach that's used by the previous version of the Thunder protocol, right? In the previous version of the Thunder protocol, the idea is that we have the fast path and the slow chain. The slow chain is basically think of it as Ethereum as Bitcoin, but it can also be a proof of stake slow chain, right? So on the fast path, we run this voting-based protocol, like I just explained. But when the proposer crashes and the fast path doesn't have liveness, we will fall back to the slow chain. And we use the slow chain to resolve the problem and to re-elect the next proposer. And then you can re-boostrap the fast path. OK, so this is a very simple and powerful idea. One drawback is that if you use this approach to fall back to the slow chain to fix the proposer, then the proposer switch is going to take about 10 minutes. If, let's say, we use Ethereum as a slow chain. And that's rather slow. And one implication of this is that if we want the proposer to be decentralized on the fast path, it's kind of impossible because every time we switch the proposer, it's going to cause interruption for 10 minutes. And that's not going to be OK. OK, so what we want is a mechanism to allow us to rotate the proposer on the fast path in a seamless manner. And that's what I'm going to talk about. I'm going to talk about the PALA protocol. PALA is Thunder's new fast path consensus protocol. It's actually a full-fledged consensus. It gives you both consistency and liveness. And in fact, you can just run PALA in a standalone fashion even without the slow chain. And one question you might want to ask is, since now PALA itself is a full-fledged consensus protocol, do we still need a slow chain? And the answer is, it still makes sense to have a slow chain because the slow chain is a multi-centralized backing. You can have decentralized monitoring of the fast path through the slow chain. And whenever under these extraordinary circumstances, let's say maybe the entire committee can be corrupt, in these cases you can still use the slow chain to recover. OK, so again, if you are not familiar with Thunder's current approach, it doesn't matter because the protocol I'm going to explain, as I said, is self-contained and the full-fledged consensus protocol in itself. OK, so since we are going to talk about proposal rotation, the most challenging case is if every block can allow a new proposal. And that's what we are going to stick to in this talk. We are going to assume a very simple round robbing policy. In epoch I, node I is the proposal. So if we can solve this extreme case, then the other cases are simpler. Like for instance, you can have a stability favoring policy where you only switch the proposal when the current one doesn't work. OK, but this is what we are going to stick to in this talk. OK, so let's kind of quickly recap the fast path, the one-round voting protocol we mentioned, right? And let's try to work the proposal rotation into this protocol. So as I said, the protocol goes by epochs. In every epoch, we are going to do the following, very natural. If I'm the proposer of this epoch, I will take my freshest, notarized chain, and I will propose the next block extending the freshest, notarized chain. So very natural. When people receive the proposal, they are going to vote. As I explained earlier, everyone votes uniquely in each epoch. But I'm also going to assume that when people vote on the block, they are going to check that the parent chain has been notarized. Because if the block extends from an invalid parent, you shouldn't vote on that block. OK, so the protocol goes by proposed vote. Proposed vote, very simple. Of course, it doesn't quite work yet. And what I'm going to do next is to describe the problems with this protocol and introduce two very simple fixes to this very simple protocol. And then the resulting protocol would be actually provably correct. OK, well, the nice thing is that this very simple protocol already works in an ideal world when everyone is honest. If everyone is honest, what you should expect is that as the epochs go by, these blocks get notarized one by one, and nothing will be skipped, and things are all good. But when some of these people can't be corrupt, so by the way, I forgot to mention, I'm just going to assume the committee itself will act as the proposer. I'm not going to distinguish the committee and the proposer anymore. Because the proposer is by rotation. Now, when some of these notes are corrupt, then you're running to these somewhat tricky problems. And I will use this as a running example to illustrate the problems and to introduce the two simple fixes. So let's look at this scenario. So imagine this is a notarized chain that I see during the protocol. What are the problems here? One problem is that the block number two is being skipped. There is no block number two. And another problem is that the fifth block is extending from three and not extending from four. So this actually creates a fork. What I really want to talk about is the second problem. But let me just very quickly explain the first one. So how can block two be skipped? So if proposer two is corrupt, let's say he just crashes and he didn't make any proposal. I mean, of course, no epoch two block will get notarized. So what we don't want is for a single bad guy to kill liveness. And we can do this if we just basically, we're just going to allow skipping. In a notarized chain, the epoch numbers don't have to be consecutive. You can skip. OK. But this skipping behavior kind of introduces the second problem, which is what I want to focus on. In this case, you may ask, why does the block number five extend from three and not from four? OK. So let's think about it. One very natural explanation is that perhaps the proposer five is corrupt. Although he sees block four notarized, he tries to undo block four by extending from a previous block. OK. And that's not going to be OK. And in fact, in the extreme case, if I'm malicious, I can extend from a very, very ancient block from the past. And that's not going to be OK, right? So the fix is actually very natural. This was the protocol we had earlier. And I'm just going to add an additional rule to the voting to say whenever I vote for a block, I will make sure that the parent chain is fresh enough. If this proposed block is extending from something way, way, way back in the past, I'm going to refuse to vote on it. So technically, we have to specify what it means to be fresh enough. And the most natural strongman kind of idea is to say I will compare the parent block with the freshest notarized chain I've seen so far. And I want that the parent block be at least as fresh. So this almost works, but not quite so, because one thing is that the proposal was made, let's say, half a second ago. And if I'm comparing the proposal with my current freshest notarized chain, that's kind of unfair to the proposal because a lot can have happened during that half second. I could have seen new notarized blocks during that half second. So what the protocol actually does is to have a slightly relaxed condition. Instead of comparing with the present myself, I'm going to compare the parent block with myself, but a second ago. So a second is like a parameter. It actually captures attention between consistency and life-ness. And the actual proof to show that this parameter works is it needs a little bit more work. But for the talk, I'm going to ask you to take my word for it. If you set this to be one second, it'll all work. OK, so that's the first fix. And we are almost there. We just need one additional minor fix. OK, and I'm going to use exactly the same scenario, same question, to motivate the second fix. So remember what we asked is, why does the block number 5 extend from 3 and not 4? And earlier we said, perhaps the proposal 5 is correct. Now I'm going to ask you to erase everything from your mind, forget about everything I explained, and let's start from scratch. Here's another possible explanation. It actually could be the case that proposal 5 is honest, and it is proposal 4 who is corrupt. And this scenario can also happen when proposal 4 is the bad guy. And how can it happen? Here's the concrete attack. So let's say Loki is our proposal 4. He proposes two blocks in epoch 4, the blue block to the blue guys, and the red block to the red guys. Now we have six people on the committee, so you need like four votes to have a nodarization, right? In this case, if you collect all of the honest notes votes, it's not enough to make a nodarization for either the blue or the red block, because we have three for blue and two for red. But remember that the corrupt guy also has a vote. Now if the corrupt guy votes for blue, he can have a nodarization for the blue block. And the bad thing here is that the corrupt guy is the only guy who knows a nodarization for blue. And no one else has seen a nodarization for blue yet, right? So now he can play it to his advantage. In particular, he can time the release. He can, let's say, release the last vote to a subset of the notes first. So some of the people will see nodarization for this block first before others see it. OK, so concretely, OK, so this is the only guy who knows a nodarization for the blue block. So concretely, he's going to exploit this advantage in the following way. So at some instant, the bad guy chooses one victim, in this case, Spider-Man. And he's going to tell Spider-Man a nodarization for the fourth block. OK, but at the same instant, everyone else hasn't seen a nodarization for four yet. They've only seen nodarization for the prefix up to three. So now what's going to happen is that these guys are going to vote for the block five. And because the fifth proposer is honest, and he hasn't seen a nodarization for four yet, so he's going to build this block from three, and then this block can get a nodarization in this very instant. OK, so what is problematic about this scenario? The problem here is that, suppose, at the instant when Spider-Man sees nodarization for four, if he hastily confirms block four, then he's in trouble, because at the end of the time, he'll live to discover that, in fact, this other fork survived to the end of time, and four is abandoned, right? So he risks inconsistency with the rest of the nodes at the end of time. OK, so what do we do now? Well, the moral of the story is that, like perhaps I shouldn't confirm a block the moment I see the nodarization. For me to confirm a block, not only do I want to see a nodarization for the block, I also want to note that many other people have seen a nodarization for the block, too. So I want like a higher degree of confidence. OK, so now to implement this idea, the question we have to answer is, how do I know that many other people have seen the nodarization, right? I know when I see the nodarization, but how can I tell that you guys have seen the nodarization, too? In fact, we can do this also very simply. So imagine we have two consecutive blocks, in this case, three and four, and I've seen both of them nodarize. So remember, the honest notes are only going to vote for block four if they have seen nodarization for three, right? I must see the nodarization for the parent before I vote for the block. So this means by voting for four, I'm also attesting to the fact that I've seen nodarization for three in epoch four. So whenever I see this pattern, two consecutive blocks get both getting nodarized, I can draw the conclusion that many honest people must have seen a nodarization for three in their epoch four. Not only have they seen the nodarization, they see it very fast, they see it in epoch four. So this is very nice, because for any future block, many people have seen nodarization for three very quickly, they're going to insist on the prefix ending at three, being included in any future chain. And that's how the block is going to stick around and not be lost, right? So for instance, in epoch five or any future epoch, if anyone makes a proposal, this proposal must include the prefix ending at three, otherwise people are just going to refuse to vote on it, right? Remember, people check that the parent block must be fresh enough when they cast the vote. Okay. So essentially, this motivates the second very simple fix, and all we need to do is to add the following modification to finalization, right? So remember, in Bitcoin, whenever we see a chain, we don't confirm the whole chain, we chop off the trailing six blocks. The trailing six blocks are not stable yet. And here it's a little bit similar, except that we don't chop off six blocks, right? Whenever I see a nodarized chain, and let's say the nodarized chain ends at a streak of consecutively nodarized blocks. So basically everything except the last block is final. So if at any time I see a nodarized chain ending at a streak of consecutively nodarized blocks, I only have to chop off the last one, and then the prefix is nodarized, but the prefix is final. Okay. So that's basically it. And just to quickly recap, the protocol is very simple. You go by proposed vote, proposed vote, and you need to check a couple of things when you vote. And then this very simple proposed vote-based protocol combined with this finalization rule actually gives you a provably correct consensus protocol. And I'm not going to go through the proof and to quickly conclude. In this talk, I talked about a synchronous protocol that tolerates one-third corruptions, right? For thunder's new fast path consensus, it's not too difficult to extend this protocol to the partially synchronous setting. And as I said, the protocol is extremely simple. It's like almost the most natural protocol combined with a carefully thought-out finalization rule. And what's cool about this protocol is every block requires only a single round of voting to confirm. I'm just going to... Okay. So let me just quickly conclude. Try out our test net, and also thunder is currently hiring, and we have all sorts of positions including executive-level positions like CMO and COO. And contact me if you are interested. Thanks.