Fault Proofs on Optimism with Cannon

ETHCC 6 · July 2023 · 17:55

Joshua Gutow explains Cannon's design, implementation and development status as a fault-proof protocol for Optimism. The speaker describes an interactive protocol for challenging deterministic computations.

Speakers

Topics

From ETHCC 6, hosted by Ethereum France.

Transcript

[Music] foreign [Music] good afternoon everyone my name is Joshua guto and I work at op Labs as a software engineer today I'm going to talk about fault proofs on optimism kind of give a high level overview of all the different components uh run some brief examples just kind of give an update on where we're at cool so today's agenda we're going to go through the three main components of our fault proof system the fault proof program Canon which is our fault proof VM the dispute game which kind of ties us together then I'm going to do some brief slides maybe better viewed later on Canon running canon in the Challenger

so we've started to be able to run some of these components and into brief information on how to stay up to date with all the work that we've been doing cool so the fault proof program um so this is the thing that you actually have a dispute about and we're going to be talking about the op program which is kind of the first fault proof program but we'll actually talk about some of the Gen ways any program not quite anyone any program but lots of programs could be kind of quote unquote fault proof programs so generically to be able to do a fault proof over kind of a program you need to have some requirements so this program needs to be deterministic it needs to be seated from information that only exists on out one

um and so kind of like with the L1 block hash op code then you can kind of get access to every single previous block hash you can get access to all the historical state but you need to kind of seed it from this hash so if there's like an oracle update on chain you can pull that in but it has to come through that update um and then we also have kind of in the op program because it's an L2 chain we feed in the ll2 block hash but that's from kind of finalized information on L1 and then so kind of going through like uh this history in this provenance is you can fetch arbitrary information by hash

as long as you're like kind of fine with it via the proofs then when you have this program it's kind of emulated and then we have a host for it cool so let's talk about the specific op program so what it does is it takes the derivation package from the op node and so this is what goes from L1 blocks to L2 block bodies so that's like transactions uh and kind of the list of transactions to be executed and then we pull in the L2 execution from op GIF and that's kind of those block bodies to the final L2 state so it kind of pulls everything all together and kind of wrap around already existing code so whenever we make a change in op node or though P Geth it automatically gets pulled in

um and then we kind of go through ethereum's pre-existing proof system probably one of the few users of it but it's all there and nice and then there's kind of technicality around what it actually does which is verifying the output root as correct or not um so it's a slight difference from the op node program which just kind of executes blocks but that makes it fit in with the proof system and then lastly there's this fun trick that kind of hinted it is a block by number lookup you can't actually do in this environment because you don't really have a proof on it but you can kind of convert it into a block by hash lookup by walking back the chain

so there's a couple sneaky things like that where we have to intercept calls and term one type of column into another cool so that's the fault proof program that runs inside Canon and so let's go through a high level overview of the fault proof VM and Canon so Canon is a bunch of things kind of wrapped up in one it's a mips interpreter and we kind of have an on-chin version and we have an off-chain version um the on-chain version kind of has to have all these State it's deterministic so it needs to have state and it doesn't touch the network the off-chain version you can run it in a mode similar to on-chain but there's also a mode where it fetches pre-images so if you inside the op program you say I need this L1

block to grab all the transactions from it it does a look up by hash and that's the block body is the pre-image for the block hash so it needs to go fetch that data from an L1 RPC somewhere um and then kind of there's this off chain component of Step generation and then this last on chain component is only ever actually executing a single mips instruction so it's not executing the entire history of the program just this one cheap instruction um and so what it is it's go code that runs an evm that's your uh gath on L1 emulating a mips machine that's your contract running compiled go code that runs an evm that's your L2 gath and so you could go recurse this more and more

if you wanted to cool so that's a high level overview now let's talk about a single instruction step this is the core of Canon which is all of like the individual instructions of your program so every program is composed up of billions of very simple instructions so like adding two numbers together shifting a number loading something from memory writing something to memory and so this is just example um we're adding the contents of registers one and two and then storing them into two we have our step number which is kind of where it is in this trace and then our program counter is kind of what the next instruction should be and then we have our registers

um and this is actually kind of what happens on chain is we have contracts that does the single instruction um then kind of off chain we have to do all of these instructions basically because you're several gigahertz processor is doing several billion instructions per second um and so over the entire course of the program we have this huge instruction Trace so the instruction Trace is just all of these steps combined together and then what we do is we go get that information at specific points and we do a buy section over this instruction Trace that's kind of the core of the dispute game and what lets us scale uh really easily is because we can have a very long instruction Trace but have a

relatively small kind of number of rounds on chain and so we're not doing all this computation on chain cool so that's kind of the instruction trace and Canon so we have these two components we go from our fault proof program to Canon we have the instruction trace and then we have to do the bisection game on chain and kind of figure out like what's actually true or not um so kind of the high level setup of the game is that there's a output proposer which says okay I think the end state of the L2 system is this and then the dispute game kind of says I think that's wrong and so you can initialize it with a commitment to the very last state of that Trace

um kind of like say Canon has said this is true or not um and then that's kind of the Tracer disputing over and then there's also kind of a fixed depth uh to this game which actually means you kind of have a fixed instructional length that's kind of side note then you have to do some padding um there's a little bit of details but that's kind of the initial setup so now we actually play the game and we kind of have this set of rules that we go through uh to kind of do this by section so we if we kind of say every claim disagrees with its parents we and so that means every kind of all the even levels agree with each other and then all the odd levels agree with each other and then we kind of either go left in

this Choice which is attacking or we go right in this Trace which we call it's offending based on whether we agree with the claim value and so we're trying to bisect uh to the instruction point where the Divergence in the traces happened so kind of example of this is like if someone thinks one thing thing happened and someone else thinks another thing happened where is the first instruction where those diverged yeah the news claim is doing this narrowing so let's kind of quickly go through this example so we're going to have two traces A B C D E F G H and abcda e x y z so those are just stand letters are just stand-ins for hashes so

well the top one's going to be green and the bottom one's going to be blue I'm going to go through kind of each claim and what that looks like so kind of Z is the initial claim uh put out on chain then green attacks with d kind of narrowing it then you defend with X again narrowing it and doing this bisection then we attacked e again and so we're kind of this final state right the letters or hashes are right next to each other so we're going to ask is e to x a valid State transition and the answer is no and so kind of for the dispute resolution games we're just going to add on this extra client so this is kind of what we do is like we have these countering claims and at this

very last thing this step that's your single instruction on Canon you load in the pre-state and you say did the post state that we're going to did that actually is that valid or not time cool and so then with this resolution is we have all of these claims We've ran our Canon so then we actually have to kind of go back up and say are we do we agree with a root claim or not and so we kind of have this rule we find the leftmost contested claim and then we assume that it's true the leftmost claim really pops up when there's like multiple actors playing this game because that's kind of allowed and then

we assume it's true because otherwise it would have been countered and if there's no uncontested claims because like we said we hey a step failed then we default to the roots being true and then this step is really only about like for this final Leaf claim and has slightly more complicated rules so that's kind of a brief overview of the dispute game and how we kind of tie it back up to the root cool so now we have all these components we compile the core derivation function the op program to Maps which is now our fault proof program we generate the instruction chases with our fault proof VM we bisect it with the dispute game we run this single instructions app with Canon and then we can keep a removed

outputs depending on the results so with this we can remove outputs that are invalid or if there's a malicious actor who's trying to remove a valid output or state commitment we can say no this is actually correct and we're going to leave it cool um yeah we can tie it all together and then there's kind of one last critical thing um which is very exciting for me and as kind of we go down this modularity road map uh with kind of the OB stack is we can work with different clients or different fault proof VMS even right so right now we're working just with the op node and op GIF which kind of get imported to op program and it's just Canon but with OP ref and some other

kind of potential rust uh op clients you can take rust and then you can compile it to Canon so now you have two uh two different fall approved systems two different clients and it's very easy to kind of interchange it we're not changing the dispute game we're not changing Canon it just kind of works the other thing is now you can create a new fault proof VM so we have kind of some ideas in the works there's kind of both kind of with a different type of VM as well as doing like potentially some ZK so there's this risk zero idea floating around or Sierra the team kind of thinking about some ideas with like let's do a risk

Vive ZK evm and so now you have a ZK ebn that plugs into that last step and then kind of it all bubbles up so the modularity is a very big component of this cool so that way I have all the components let's start running them um so this is a very long thing that I don't expect you all to get exactly this moment but you can go into the mono repo Canon folder um and kind of start playing around with it already and here it's working on Gurley and it's creating some State outputs and some State commitments every 100 steps and it's only doing 400 but you can run it much much longer um and then kind of on the op Challenger

which is the component that plays the dispute game that we just worked you just go into the open Challenger folder and kind of create the game and then you can run two different copies of the agents kind of attacking each other and then there's a way to visualize it at the end cool so that's kind of where we're at currently um now let's talk about some ways to keep up to date with everything so the two places kind of the have the most digestible information is our Dev blog and our opylabs Twitter um we're talking a lot about this um and we're going to have more information coming up coming out about the dispute game and that's kind of as we get to more Milestones that's kind of

where those be announced and if you're really interested in the technical details uh everything is in public on Twitter or on GitHub so github.com ethereum Dash optimism optimism that's our primary repository that's where Canon is that's where the Challenger is that's where our fault game contracts is we're working in public so I want to follow along and want to help out we're always happy cool so that's kind of a high level overview of fault proofs I'm Joshua I'm at OPI Labs I we're close to time but if anyone has any questions I'm happy to answer them [Applause] thank you for the talk

um I just wondered how do you store um how do you manage to store the layer two states do you use pre-compiles or how do you do this are kind of inside Canon yes um so you have to call out to an archive node and we basically do when we're doing the execution we do an MPT proof against the state and that gets loaded into a pre-image um so during the the time that the transaction can be replayed from where from an archive nodes like optimism there are two nodes you

you take the this data I don't know yeah so initial that's yeah all the transactions are on L1 we have the transaction data and then we're simulating it and then we call out into state that makes sense I can also try and explain it afterwards okay okay right there thank you hi hello thank you uh if I understood correctly this is like a strong optimization of the dispute game itself but I thought that this would not be like um mandatory since fault proof should be

should appear quite rarely so nobody should actually submit uh faulty blocks because of the incentive game behind it yep so it was was it really a need to optimize it that much or is it to prevent the denial of service attacks maybe uh and in terms of like doing the bisection yes I mean going instead of just you know like um disputing the whole block and saying yeah execute it completely again because I believe this block is yes that is a necessary optimization um there's some tricky things with if you do that Lo loading the data for that block becomes really tricky it becomes very

gas intensive um and kind of without without doing the bisection architecture uh becomes so difficult to do a good fault proof and keep it up to date um that it's basically like kind of not worth doing okay okay great thank you description thank you everybody [Applause] [Music] foreign [Music]