 I'd like to introduce our next speaker by just saying that he is going to be speaking on Casper. And there are many different approaches to Casper, proof of stake. And because I really wanted to give Vlad his MFIR Special Introduction, I think we should all chant Casper, Casper, Casper, Casper, Casper, Casper. Come on up, Vlad. Woo! Super dumb. OK, great. I'm mic'd up already. White clicker. All right. Let's just test the clicker. Great. All right. All right. Are we ready to go? Time's rolling. OK, time to go. So I'm going to present to you basically my research on correct-by-construction Casper, which I've done over the last few months with a lot of help and guidance from Greg Meredith. I can't see him right now with all the glaring lights, but I thought I'd give him a shout out right away. So I'm going to cover some background knowledge about consensus protocols. And then I'm going to talk about and cover my research for Casper. And then I'll kind of relate it to the previous literature and talk about future work. So there's a lot to get through. I'm going to do it really fast. So here's my little table of contents. Who cares, right? So what are consensus protocols? Consensus protocols basically are something that nodes are used to make the same decision about something. This is the kind of traditional definition of consensus protocols that really has this concept of decision at its core. And having consensus basically means that we have the protocol in a state where all of the protocol following nodes are guaranteed to make the same decision. And basically, these protocol following nodes are the protocols called safe. If when they make a decision, they will always make the same decision. It's called live if it's definitely the case that they will make a decision eventually in some kind of finite amount of time. Like you can guarantee, like prove, that they will make a decision. So those are some basic concepts of liveness and safety. So let's review them quickly again. So safety is the property that when nodes decide, they all decide the same thing. Liveness is the property that nodes will eventually decide. Asynchronous networks are basically this topic in consensus protocols that is not really related to asynchronous calls and asynchronous computing. It just has to do with the fact that we don't have timing assumptions on the network, which basically means that communications can arrive in any causally consistent order. Any order where if a message B that is causally, is caused by a message A, can't arrive before message A. That's the only kind of ordering that's imposed on network messages is the ordering that's imposed by the causation of the protocol state updates. And usually with asynchronous networks, we assume that the message just arrive eventually. But we can't ever say in what order. So asynchronous consensus is kind of difficult. And we kind of know this because of this FLP impossibility result, which says that in an asynchronous network, you can't actually be live and safe in the presence of one fault or more. Basically, if any of these communications can fail, you can kind of show that in an asynchronous network, you can't be both guaranteed that everyone will make the same decision and that we'll be able to make a decision in a finite amount of time. And the reason for this, we're going to see through the course of this talk. But this kind of gets at the point that asynchronous consensus is really challenging because the lack of network assumptions makes it really hard for us to justify why the protocol would move forward from a state where we don't know what to decide to a state where we would know how to decide. There needs to be some messages that flow for that to happen. But if some messages might not actually make it, then we can show that actually we can't prove that there's a guarantee that in a finite amount of time this kind of decision will be made safely. And now we can just talk a little bit about Byzantine faults. You've probably heard of Byzantine fault tolerance. It's all the rage these days. Basically, normally what we say is that any node that isn't following the protocol is Byzantine. And we normally also say that nodes behave in arbitrary ways. We also have results that basically kind of also say that this is kind of hard stuff. Those are like limits to what can be done. Normally there's like two results. One of them is that in an asynchronous network, you can't have more than a third Byzantine fault tolerance where you have safety, where we have this property that if nodes decide, they will all decide the same thing. And we have a similar result for synchronous networks where you can't tolerate half the nodes being faulty and also have all the nodes that are following the protocol be guaranteed to make the same decision. So I'm kind of just asking you to accept this at this point because we've got to go and get to the rest of the presentation. So now I'm going to describe basically this is like correct by construction approach that I've been taking for my CASPER research, especially in the last couple of months. Basically there's like an outline, and then I'm going to describe my data structures and give some definitions, and then give the correct by construction binary decision thing. One thing I should have mentioned at the top of the talk is that the title of my talk is slightly different than advertised. So what I'm really going to be presenting is a correct by construction asynchronous CASPER protocol that agrees on a bit. So like it agrees on like zero or one. And it's going to be Byzantine fault tolerant and correct by construction. So no network assumptions. We can tolerate like Byzantine behavior, but we only agree on a bit. And still I think that's worth presenting. So basically, so here's kind of the approach that I'm taking. Rather than thinking about the safety of decisions, I'm going to just think about estimates, right? So estimates are these things that kind of are sometimes defined in some consensus protocols, but are always defined really in like the blockchain world. An estimate is like a non-finalized decision. It's like a proposal for a decision. When we talk about traditional consensus protocols, all of the decisions that we're talking about are like what we call in blockchain world finality, like finalized decisions that will never get reverted, where these nodes like commit to this value and will never, ever, ever change their minds. Because that's what the protocol says, and that's the definition of consensus. Oh my God, we're running out of time. So we use estimates. And they mean finality. So basically, we're going to define a notion of safety on estimates. And basically what we're going to do is try to, and we're going to construct an adversary, which will try to change an estimate for a particular node with a particular view who has an estimate. In order, and if that adversary succeeds, then that estimate will be unsafe because in that particular network context, for example, it's possible for that estimate to change. And basically, the reason why we're doing this is because an estimate is kind of a very personal thing, whereas the safety of an estimate, meaning like oh my estimate can't change, is much easier to determine on a local view than the safety of a consensus protocol, which has to do with the decisions that different nodes make across the network. And so I think it's just easier to reason about. So, and if we have this result, which I'm going to show that we do, or I may, I'll show somewhere that we do, for even if I don't show you today, that if nodes calculate that their estimates are safe, then they both will have the same estimate. So, and this is actually going to guarantee our correct decision rule. Basically nodes are going to calculate if their estimate is safe, and if it's safe, then they can decide. And that's going to be the correct by construction approach, where the decisions are all going to be the same, i.e. we're going to have safety, because the only time when people are going to decide is after they've run this ideal adversary and saw that their estimate can't be changed. And if my estimate can't be changed, then it's cool for me to make this decision because I know that it'll be fine. So, now let's go into the real formal model and the more technical part of the talk. So, basically, this is the main data structure that we're going to be dealing with. These bets are, they have three things, an estimate, a justification, and a sender. The estimate is basically a bit in this case, because we're just doing binary consensus. The justification is a set of bets or the empty set, and the sender is like, you know, a validator. So validators are some fixed set, they have weights, the weights have this tie-breaking property, which means that any two subsets of the validators have different weights so that I don't get ties, are an annoying edge case. So, we have this other data structure called a view, and a view is just a set of bets. So we have bets, which have estimates, justifications, which are sets of bets, and senders, we have weights on the validators, names for the validators, and views. And these are all of the data structures that we will use to define everything that I'm gonna talk about for the course of this talk. And that everything that's defined in the correct by construction approach. And it's worth noting that the bet structure is a dag, and you can represent it kind of like this, where I'm gonna line up validators, right? So the number on the node is the estimate of the bet, the edges correspond to which bets are in the justification, and the kind of vertical alignment along these letters corresponds to which validator made that bet. Here, validator one made two bets, one with estimate zero, one with estimate one, validator two, similarly, and they've got all these justifications pointing everywhere. It's great. So now we're gonna start going some definitions, where we're just gonna define a whole bunch of stuff that we're used to talking about sometimes. Sometimes there could be new stuff in terms of this data structure that we just have, that I just defined, and which basically is the model that everything is gonna sit on. So a bet is the dependency of another bet if it's in the justification or if it's in the dependency of anything in the justification. So the recursive definition, but there's a really pretty picture. The red bet is in the dependency of the blue bets. Basically because it is upstream from them in these arrows. So equivocation is something that we sometimes talk about in consensus protocols. I have a formal definition here of what it means for two bets to be in equivocation. Basically they have the same sender, they're not the same bet, and neither of them are the dependency of the other. So basically they represent kind of a bet made with the justification that ignored the fact that they previously had made a bet. There's no way to make two bets and have neither of them be in the justification of the other without kind of intentionally leaving out something that you knew, because you can't be ignorant of the fact that you made a bet, really. So here are some examples of equivocations. The colored bets are equivocations. The two red ones and the two blue ones, they don't include each other in their dependencies. There's no arrow saying that the one knows about the zero or that the one up there knows about the other one. So these are equivocations. And equivocations correspond to something important when we talk about Byzantine faults and kind of our ideal adversary. So the latest bet is another definition. Basically because we have this dependency relation, it kind of defines like a causally after. What we can also have is like from a particular view, we can say, oh, these certain bets are the latest. Here, some drawings, right? These bets, they don't have any nodes with an arrow pointing out. So there's no arrows pointing out of these bets into another bet from the same balader. So those two bets on the left are the latest nodes, latest bets from Validator 1. Note that they're an equivocation of Validator 2, Validator 3 also have some latest bets there. It kind of has an intuitive thing, right? It's like the latest bet that we've observed from them. And we have these little arrows to help us find the way. So in the bet is invalid if the estimate of the bet is not the maximum weight estimate given the view and their justification. So the justification is a set of bets. It's got a view and it's got some latest bets in there and you can wait, you know, every Validator has a weight, every Validator has a latest bet, and I'm gonna say, okay, look, if these Validators have an estimate one and the latest bet, those Validators have an estimate of zero, but these ones have more weight, then like my bet, having all that stuff and justification would only be valid if my estimate was one. Basically, we're running like a majority kind of election here when we have only valid bets around. People are always gonna choose the maximum weight estimates. So then we have this definition of Byzantine Validator. So this is something where normally people would define Byzantine Validator, oh, it doesn't follow the protocol, but here what we're gonna do is define, our goal is to define everything in terms of the data structure that we set out initially, right? We haven't even said what the protocol is exactly. So it's saying that it's not part of the protocol, doesn't really make sense, and we wanna make it correct by construction Byzantine fault tolerance, so we can't really use the definition of, oh, if you're not following the protocol, then you're Byzantine because we haven't even constructed the protocol yet, right? So what we're gonna say is that knows our Byzantine if they either produce an invalid bet or equivocate. And this is great because in terms of our little data structure, then either you're a sequential node that's always producing valid bets, or you've done some craziness, and you're lying basically, you're telling some node one thing, telling another node the other thing, or you're producing invalid bets. And those are coming we can identify in our bet structure and it's bad, right? And I lied about my definitions of invalid error. You actually have to exclude the Byzantine nodes in your calculation here. So if a node has two latest bets, you just drop their weight to zero. If a node made an invalid bet, you drop their weight to zero. Here are some invalid bets that are just not majority estimates given the weights that were observed below. I'm just gonna power through because we've got a lot to cover. So basically an estimate is safe in a view. Basically if there is no possible future of the view, which means like additions of bets to that view where the estimate is changed in a particular context. In this case, we're just talking about an asynchronous network. So an estimate is safe in an asynchronous network if no matter what valid bets you added, no matter what communications occur, the majority estimate just won't change. So all possible futures of this state of the protocol in just only asynchronous conditions, like any causally consistent sequence of message passing is cool. There is, the estimate is the same. There is no possible future where the estimate is different than it's safe. But this is kind of not a constructive definition, so that won't do for our correct by construction kind of thing. What we need to do instead is calculate safety by producing this adversary that tries to kind of make the network condition happen that changes the estimate. So here's an example of an adversary that shows this bet from validator to three to validator two in order to induce validator two to produce a new bet, because now validator two sees a different max weight estimate and that changes the overall mass weight estimate that we see from the view as a whole. So like that first view is like not safe. And basically we have a slight issue when we're trying to calculate this adversary because we have side effects. So what we're gonna do is actually have a lower bound and ignore the side effects basically because the side effects, if they help the attacker, the attacker can go with and if they don't the attacker will ignore. So this attacker is kind of stronger than normal. So if this attacker fails, then definitely your thing is safe. So basically the way that to do the construction for the ideal attacker for an asynchronous network is basically to only allow bets that don't have the victim estimate in there to travel and only allow bets that don't have the victim estimate there to be made. So the adversary just like stops all bets that disagree with his estimate from traveling across the network. And like that's the kind of ideal network adversary for an asynchronous network. And then the decision rule in the asynchronous network is oh once I calculate that my estimate can't change under this ideal adversary, I decide. And that's correct by construction because there's no way for two nodes in the same, in the network to disagree about whether there's a possible future of that network where they have different estimates because they're both modeling the asynchronous network is a little bit of a subtle argument basically because if they have different estimate then one of them has to be later than the other which meant that the first one has to have a possible future that changes it to one of the estimates to the other. But we're really running out of time. So with equivocation, we also do this thing where only the bets with the wrong estimate fly around but you also get some additional flexibility about where you can add bets because you don't only have to add them in on the end, latest bets, right? You can add bets anywhere because like equivocating validators are crazy. They just add bets wherever, right? So but it's like the same type of idea where like if we're safe in that equivocating environment then like we decide okay, we can stop and it's like a correct by construction decision function of like when to stop participating in the consensus i.e. when to make this final decision, right? So this is very related to like finality in that whole discussion, right? So I'm gonna try to quickly relate this to existing research. Basically the only stuff that I've talked about here has been exposed kind of safety measure where we don't actually look though we didn't talk about liveness at all and so we don't violate FLP and possibility at all we have Byzantine fault tolerance and safety in a synchronicity, we don't have liveness, that's great. And basically we can see why we don't have liveness because like if we don't, so like if we don't have safety at a particular point then we cannot prove that we will advance to a point where we do have safety in the context of this adversary because that adversary by the virtue of the fact that we said we don't have safety is able to change our estimate and therefore we can't actually become safe from a position where we aren't safe in a way that's provable and so like we haven't violated FLP at all. So basically it was cool that we did it only this exposed measurement of safety rather than reasoning about liveness at all because they're not usually what happens. So like there exists views in this exposed world where you have extremely high levels of fault tolerance where like all the one node could be faulty and your estimate still won't change because like any of these faults will be detected by everyone and those weights of those nodes will drop to zero but so it's very, very safe but there's like no way to actually get to that point if all nodes but one are Byzantine because they'll presumably not participate in the network behavior that was required to create that kind of system. So it's not live. We don't actually have a guarantee that we'll get there from a point where we don't have it to this like point where we're safe. So I think it provides kind of an interesting view into Byzantine fault tolerance in general and I hope we can extend this research into liveness and also define everything in terms of the same data structure, right? Because these bets being passed around really do basically map exactly onto the kinds of restraints on the network that we normally have. So we have a whole bunch of future work, right? So what I just said, liveness, I want to make a conservative attacker that minimizes the amount of equivocation that needs to happen by weight. This will improve the computational complexity of stopping in a Byzantine fault context. We need to move from because it's on a bit so because it's on the EVM, we need to do validator rotation. We need to add economics so we can run it in public and we need to do complexity and performance optimization and basically improve the theory, the specifications, the documentation, the implementation. By the way, I do have an implementation of the correct by construction thing. I mean, mostly I have the ideal adversary implemented in Python for equivocating faults. So that's cool in any asynchronous network. My time is almost up and my slides are done. Thanks for listening. Excellent, thank you, lad. Good job.