 So welcome to the workshop. It's going to be quite hands-on if you so I was wondering how many people have Laptops and they're kind of ready to follow on Yeah, okay, so maybe I'll do it live as well And if you want to follow along that'd be great and do it yourself. That'd be that'd be good So the topic of the talk is to look into what an L2 transaction is in the context of arbitram So there are a range of different L2's but the one we'll use today is arbitram and L2 transactions will differ between those but some of the concepts will be passed between them So, yes, there's some differences some similarities. We'll go into some of those and I'll first give a bit of an introduction about What a roll-up is and that's what I mean by L2 in this in this context And then we'll go into the workshop itself okay, so at a very high level a roll-up is a Sidechain there's another blockchain But it's connected to some sort of base chain by a validating bridge and if you want to read more about this There's a paper by Patty you sat in the back of a room over there So you can get more information there And this is a kind of rough overview of how it works So you've got one blockchain at the top, which is the roll-up You've got the main blockchain at the bottom which in this case would be Ethereum and they're both progressing via state transitions New blocks are being made there's a bridge contract on the base chain on Ethereum and Periodically an operator will take the state of the roll-up of the roll-up chain and they'll paste it into that bridge contract That once it's in that bridge contract it can be checked So in an optimistic roll-up case, there's a fraud proofs that are used for checking that state And in the case of a ZK roll-up, it's just a ZK proof But the other crucial thing is that green blob that I've put inside the the bridge contract and that's data That's associated with the state transition So you on the on the roll-up You need a like a minimum amount of data to be able to recompute the state transitions that are occurring on the on the roll-up So in the case of optimistic roll-ups, that's going to be the transaction data itself and yeah, just continues in the same way and This would be the case where some data is put on chain the fraud proof is checked and it's found to be invalid Yeah So this is a kind of rough life cycle of a L2 transaction. So a user would create a transaction They'd submit it to a sequencer who would then be collecting these transactions into a batch When the sequencer has got enough transactions, they'll compress this batch using some standard compression algorithm in Arbitrum's case. This is broadly And then they submit the batch to Ethereum. So that's this green blob is that batch there Yeah, and another kind of difference between L1 L2 transactions is gas so as I've mentioned L1 turns out L2 transactions need to be submitted at some point to the L1 and someone's got to pay for that so eventually that's going to be the user and That that cost is associated with the call data that is required that is consumed by the transaction on L1 and is priced at the price of L1 gas Then there's L2 gas, which is basically the same as L1 gas the same gas that you know on Ethereum But it's at the price of L2, right? So this is just the execution of the transaction that's occurring on L2 So you pay first to put the transaction on L1 and then to put the trend and then to execute it on L2 So there's these two different costs and we'll kind of go into that in this workshop Yeah, so this is the URL. So if you go to this GitHub repo and you can Start following down the the set of instructions. So there's a set of prerequisites that include tools like foundry jq and broadly itself and You can start following the steps yourself Or you can watch me do it as I go Yeah Okay, yeah, so I've included some useful links at the top there's some RPCs there to connect to both arbitram and to Ethereum and just some other stuff some general information if you want to read more about like L1 L2 gas and Some of the ways in which arbitram works that are relevant to this talk Yeah, so these are the prerequisites Gets just there so you can clone this repo itself. We've got curl for making some requests foundry for using cast cast as a kind of tool for helping you format ABI style Functions for calling calling the JSON RPC JQ just for formatting some JSON and broadly which is the compression algorithm that's used in arbitram Yeah, so there's there's a quick setup stage. I've already done this I'll paste this in Yeah, just check those are there Okay, so the first step is that we're gonna send a transaction on L2 so I've already sent a transaction which you can use if you want In your example, or you'll feel free to like Use your own like metamask connect to arbitram and send them like a transaction on main net at the moment They're reasonably cheap I think so should cost you only a few cents to do that if you want to but this transaction hash if we look at it on on Arbiscan This is a USDC transfer basically, so this is just transferring some tokens And that's the this is what we'll look into today Yeah, so I'll set that environment variable And also feel free to like if you've got any questions at any stages as I'm walking through this Just stop me put your hand up. We don't have to get through all of this today So just you know, let's talk about it and if you've got questions, you know, just put your hand up at any time Yeah so first we'll kind of grab a transaction receipt receipt for that and There's two interesting things in this transaction receipt that you might not be used to when Looking at L2 compared with L1 transactions. So this is this L1 block number, which is The block number that the L2 sees of L1 so it's a kind of like L the L1 is it's reading the state from L1 occasionally and One of those bits of state is the L1 block number. You can access this as part of the arbitram EVM and Then the other thing is this gas that it used for L1 and that's what we're gonna look into So this is the amount of gas that was spent to send this traction transaction and get it recorded on L1 So we're gonna store that in a variable. Oh Yeah, and I'll just echo that out so you can see like roughly what it is. So it's like 236,000 gas so That seems like a lot when you think about just what it's doing is storing just a bit of data on the L1 But the reason why it seems like a lot is because this is in units of L2 gas So this is this has been scaled for what it would be if it was on L2 And that's just to make the accounting a little bit easier inside the inside of arbitram So this amount we need to find out what the ratio between the L2 gas and the L1 gas was at the time this transaction was sent to then try and really figure out how much L1 gas was used and From there we can start to figure out as well like how many bytes of data it might have consumed So Store some of these variables as well Okay. Yeah, so as I mentioned, we need to find out this ratio of L2 to L1 gas so the the roll-up is is Estimating at any one at any point in time what it thinks the L1 gas price is and It's a little bit more complicated than just reading the L1 base V Because there's a time lag between when the sequencer Processes a transaction and when it submits it on to the L1 So it does some kind of estimating and it moves moves its price up and down depending on how accurate it's been in the past To try and make sure that it keeps even And so there's this L1 get L1 base V function, which is what was really used by the The arbitram virtual machine to Well by arbitram sorry to to figure out what L1 gas prices it should charge and There's a bit more docs here if you're interested in reading about like exactly how that works And maybe we should go a bit more into that because I realize we're running quite quickly on time Because I guess I thought everybody would be following along and there'd be lots of problems, but I'm a skilled pro at this So it's going quite quickly Yeah, so one interesting thing that happens with that with that estimation is that Because because the sequencer is having to try and figure out what the price will be when it submits to L2 It's kind of a it ends up wanting to overcharge to not get out of pocket itself So arbitram has a slightly different mechanism there where The sequencer is rewarded later for exactly how much they spent and There's a kind of a pool that sits on L2 and the pool starts quite full and then the difference between what it was awarded and what it estimated in the first place is then reduced from the pool or added to the pool if it overcharged and Then this is you this difference between what the pool target should be and what it actually is It's taken as a factor into the future estimate of what the L1 gas price should be So the sequencer never ends up out of pocket. They always get exactly what they paid But there is some mild fluctuation between what users pay now and what users pay in the future So some users now might receive slightly less than what they like get a slightly better gas price than what they expected Some might get a slightly worse one, but overall it's quite quite close to the average quite close to what you should be getting Yeah, okay, so we'll call that pre-compile at At the block heights so that for this we need an archive node And we're gonna call the the pre-compile at the block heights when this transaction was sent on L2 and Then we'll see what the estimate was at that time Yeah, absolutely. Yeah, so So you want to know what the what the estimate was at the time that the transaction was sent So you need to know what the state of the the node was at that time and for that you need an archive node a Full node wouldn't be able to do this. Yeah second Exactly. Yeah, I think I think full nodes do keep some recent Historical states. I can't remember exactly how but probably not a week's worth Yeah, so you so to do this kind of thing that we're doing now You would need an archive node, but this isn't something that you might normally want to do This is just kind of like let's go look at some of the analytics. It's not part of like you don't need it to To send transactions or things like that and there are ways to get estimates for what these values are before you send your Transaction as well, so you know what you're gonna spend you don't have to wait and inspect it afterwards if you want to Yeah, I think there was someone Yeah, okay, thanks. Yeah It's not it's not a snapshot. It's just well, yeah, okay You you need you need to know what the state was at that time because this is stored in state This L1 base V estimate so at a different block height The L1 base V estimate will be different and we want to know what it was when this transaction was sent Yeah, so the see the sequencer has to pay some costs to put this data on chain And it wants to get refunded for that So this is this estimate is is is in the system It's under like you might say it's on the consensus of the of the L2 and the sequencer is forced to use this value And it's estimate. Yeah, well, the the currency is the same So they but it's both if is the unit of accounts here on both of them Yeah But the gas prices are different and they're moving and this is just a way to try and estimate that movement of gas on L1 Okay, so let's make This score Yeah, so this was an estimate of the base V at the time the L1 base V estimates, which is about Eight quay it looks like so that's what it thinks it was at the time And we'll store that in a variable So as I mentioned, we want to work out this ratio so that we can scale the L1 gas used in from L2 gas units Into L1 gas units so that starts to make sense to us again So we also need to know what the L2 base V was at that time And this we can do by just fetching the block at that height and looking at the base V in it Which is not point one quay. So our picture has like a minimum L2 gas price, which is not point one quay if it if Congestion happens then it will go above that but generally it just sits here if it's not if it's not Being used heavily at the time. Okay, so we'll store that as well And now that we have these two ratios we I mean these two these two Gas prices we can use them to calculate the ratio. So Have I stored this already? Yeah, that was above Yeah, so there's the actual amount of L1 gas that we used at the time, which is a bit more what we kind of expected and if we divide Why did we expect that? No a bit more like not more than it's it's like what we expected. Yeah Yes Yeah, it's a really great question. So you we do compression over a full batch rather than individual transactions Which does leave you with this problem, right? How do I know what? My transaction how many bytes it will use in the compressed batch rather than in in the other amount So what we do is we it's very hard to figure that out and do it fairly because it also depends on ordering and things like this. So What we what we do is we compress your individual transaction when we give you an estimate for it And so if your individual transaction is more compressible, you'll get a better you'll get a better estimate for it And you'll you'll be charged less But that still isn't quite the perfect scenario, but that's the kind of like halfway house that we've arrived at Yeah, okay, and so each unit of each byte of data on our one consumes around Consumes 16 gas if it's a non-zero bytes. So As an estimate we can say that This consumed around like 180 bytes of data So we can Then actually go and take a look and see if that's kind of what it did consume So to do that well RLP encode the transaction. I've got an error in my scripts there. I think This a a BCC doesn't look right. I was doing a bit of debugging Yeah, so this script what it does is a high level at a high level is just it it requests Transaction receipts takes the bits out of it, which are important for RL for for a natural transaction RLP encodes it and just spits out the result with the zero to prefix Which is type two transaction So if we do that again, oh Not sure why that's oh, yeah, thanks. There we go. Thanks for you. Yeah. Okay, and if we count those bytes Let me see it's about the same. So we spoke before about Yep So again, it's all right come quite here So RLP is just the format of the transaction that ethereum accepts and then we'll include RLP encoded transactions Into a big batch and the batch will then be compressed with a compression algorithm. So RLP isn't compression. It's just it's just serialization you don't need to you Yeah, because what what you so what runs under the state transition is the full decompression So when what you're when you've done the Ford for proof You're bisecting on the parts of the state transition So if the decompression is within that state transition then yeah, you'll be able to decompress You don't you don't need an implementation of the decompression on L1 You need it on L2 and you need to include it in the state transition. Yeah. Yeah, so let's try and explore the batch there's a Function on another one of the pre-compiles that you can find an arbitrem to find the batch containing a specific block Which is this one. So we store the block number earlier and we'll use that to look up the batch These pre-compiles by the way are they're kind of like the way in which arbitrem customizes itself Compared to Ethereum. So it needs to do some special things like this And they've been added as pre-compiles. So they can be found at like different addresses That you can find at the top of the files. Yeah, so he's cast again. This is a little bit longer. Oh, yeah, there it is. So 974 was the batch number. I don't know why I printed some rubbish, but oh, yeah, it's because I copied the there we go Yeah, it takes a little bit longer that one because we're doing oh, no, that one's not the longer one. Okay This one might be a bit longer So given the batch number we need to find the transaction That submitted it and we need to look at the call data that was in that transaction because that'll be the batch so we need to find the transaction and We do this just by looking up the logs that emitted this specific batch number Yeah So this is the transaction ID. So if we go to ethoscan, this is an L1 transaction ID This is the batch itself. And if we scroll down and look at Oh So it calls this function add sequencer L2 batch from origin And if we look at the original, this is all the batch data So it's a large amount of data being submitted in one go. We can even look at this function in the code So this is the contracts Which is called the sequencer inbox and it's where this sequencer submits these batches And this is the batch data itself. So we're gonna try and grab that data and decode it and the way that The way that variable size Arguments in in Yeah, in the EVM are encoded is at the end and we've been there as a placeholder for them inserted at this point So we'll find this data at the end of the at the arguments list And given these all fixed size arguments We can know the exact position in them in that in that input Which is Well, first we'll download it actually yeah Yeah, which is 458 is the is the position and we'll put it into a file So if we open So this is the raw batch data that we downloaded Raw is compressed exactly. Yeah, so so yeah This is pulled straight out of the call data and this is what the sequencer inputted so it's compressed Yes, exactly exactly great question and we'll explore that in step five. Yeah Yeah, so If we open the file, we can see that it begins with this zero zero at the start and this is not part of the compression This is just a Type of the data So there are some different instantiations of arbitram one is called arbitram one and another is called arbitram Nova and they Handled data in different ways. So arbitram one does this compression. It stores all the data on Ethereum Arbitram Nova doesn't it stores its data with an external party that external those external parties sign that they've received it And they put that signature along with like commitments that data on chain And this zero zero here just tells us that the type of this data is Roll-up data. It's arbitram one data So we want to remove that before we do the compression Do the decompression sorry So we we take those off and put it into another file and then we just remove those those front two zeros and then this is the The commands to decompress the batch So first I'm going to convert it from hex into binary Then I'm going to use broadly decompression and then I'm going to convert it back into hex and put it in a file Yeah, and it outputs this Warning because there's some zero bytes at the end which aren't actually relevant to the The compression but get added because of 30 like 256 by words Okay So if we look at that this is the actual batch data and We can look at the size differences now between the compressed and the decompressed So we've got this one, which is the Wait, what was it which one? compressed which is 198 bytes and then we've got the decompressed one which is 715 so you can see the difference in the ratio there and the the effectiveness of the compression Yeah, yes Exactly. Yeah, you you The if the shared structure between different transactions, then they're going to be included into this compression and improve it. Yeah this is a bit of The compression isn't actually this good because this if we look at this batch data It can it includes a lot of zeros and zeros Are charged at a different Amount in in gas in the EVM they charge that four by I think four bytes for four gas per byte rather than 16 for non non-zero bytes and The compressed batch will be almost no zeros in it There'll be it'll be much more like a tenth of them on zeros, right rather than 16. Sorry Yeah Yeah So it's it's not quite as good as it's showing here, but it's still quite good you can work it out by like Doing some more complex analysis, but we won't do that here Yes, we've compared those and then the last thing to do is that our transaction should be in that uncompressed batch So we'll go and try and find that so if we echo the The RLP, I think I had it in raw. Maybe let's see where I had it Yeah, I did have an RLP. Oh a TLP everyone So this is our transaction if we go into the batch and There it is So along with a load of other transactions Yeah, and that's basically it for the workshop. So if you've got any more questions, yeah Yeah, you can you can do that yourself as a Developer so that on our trim. There's a registry where you can register address against an index and then you can substitute them and our trim will know that you've done that and it will then Switch them back out when it comes to execute and in that way the sequence will charge you less for your gas Yeah, yeah, because when when you're compressing The addresses in in a batch then it does a lot of that for you anyway, like so it The two yeah, it's one one was like a legacy system where we would do that We'll allow users to do this themselves and now like the whole holistic batch way achieves a better result. Yeah Do you had a second question? Yeah Can everybody hear the questions by the way or should I repeat them? Yeah, sorry. Yeah No, there's not so like optimism use said look I think and we went for broadly The reason was is because we did some analysis of different compression algorithms and we found that probably performed best And I guess they did a similar sort of thing and chose that look for their own reasons Yeah, I don't know I don't know how important it is to standardize this specific part of the roll-ups because it's It's something that users shouldn't really be interacting with Generally, I think that's the most important part to standardize But yeah, it would be interesting to to see why they chose those that as well. Yeah, sorry I didn't repeat the question. Yeah, he asked if there would be If there's any efforts to standardize this compression algorithm, yeah I'll be to across different L2s Yeah Yes, yeah So there's an address registry that you can use you you register an address against an index and then that will be used When up on execution you substitute your indexes into your transaction and then there will be De-substituted from the registry upon execution to reduce the amount of call data that even goes into the batch itself. Yeah It should be So we used to have it in our docs We've just recently rebump them and I'm struggling to find it but we did used to have it there Do you know where it might be to get your friend of address registry? So we've got our address table here, which is the Yeah, so this is like a bit of documentation But I'm sure we had some more documentation about actually how to use this contract and pre-compile them we Okay, maybe we can do this afterwards as well. Yeah. Yeah Yeah, so the compression the broadly compression was part of nitro. Exactly. Yeah, it was one of the major parts that Reduced the cost Previously we didn't compress at them. Yeah. Yeah, so the question was why the hard-coded minimum base fee I think that's partly just to avoid like us Getting loads of state bloat early on for very cheap price Given that we may expect users to come on board onto the platform and the gas price not to always sit there It would be good to not the future not to be burdened by that kind of legacy behavior. Yeah Yeah Yeah Yes, the question was the execution occurs on layer two. So what's happening on layer one? What are we putting there? Yeah, you you just store the data such that there's an there's enough data there so that anyone who's observing aetherium Can recompute the same trains state transitions that are occurring on L2 and that's important so that anybody can Can take part in a fraud proof? Game yeah, yeah, we have two ways of doing it so that I'll open up that contract again The question was In the in the contract Do you need to admit all of the data that the batch data in an event in an event or can it just be in the call data of the transaction? Yeah So there's that we have two functions for that one is submitting it from origin and in this case we know that the That is being sent from the transaction origin and therefore we know that the call data is going to look like this So if we know that then the L2 can reliably grab data out of the call data if the sequencer is You know going via some other contract or it's not coming from the transaction origin then we emit the full batch data in an event so in production this So this is here if if it were needed, but in production is way more expensive. So it's never used Where do we not need what sorry? Yeah, so to clarify on what we're doing here. We're emitting a sequence number And so what the L2 node will do is it will say okay? I've got a new sequence number. I'll go Look up the the transaction related to that sequence number. I'll look inside the call data I'll find the batch basically the same process of we as we've just done and all of that all doing all of that It's part of that state transition function. So it's all yeah, yeah Yeah Yes execution happens on layer 2. Yeah And state is on layer 2 as well. Yes, so I missed a bit you said there was Yeah No, so the question is this does the execution also take place on layer 1 as well as on layer 2 and No, it doesn't we just put enough data such that anyone who's reading the Ethereum can then go away and recompute themselves what would have happened and take part in this fraud proof game Correct Exactly. Yeah. Yeah, you need so so yeah to if you want to know what the state of the L2 chain is You need to replay the history of the chain in the same way that you would replay the history of L1 to figure out what the state of L1 is Yeah, so the question is it's kind of I find out states about a specific address Without recomputing the full state on L2 and the answer is no so the state only exists on L2 And that's only where you can make questions about the state. Yeah Yeah, so the question is can you sort of game the system? Take advantage of this of this Minor fluctuations in L2 gas price to try and achieve a better price for yourself and the answer is yes. Yeah, you can Yeah, so I think that's that the question that comes down to a little bit around your security assumptions so In order for the state to in order for you to be confident of Ethereum state You want a wide range of people to run full nodes such that if an invalid state transition occurs a Large number of people can get together and form consensus that that was an invalid state transition That should be a rejected fork and we shouldn't ignore it But with a roll-up this there's a slightly different Safety assumption, which is that if any single one person Notices that there's an invalid state transition and that one person can enforce that the state transition is is correct So it's you don't need a large number of people necessarily You know, it's a kind of one of many one of n security assumption Rather than like an n of m and so this means that maybe you can afford to have less people actually running the L2 nodes Yeah, and and then so have maybe slightly more beefy machines Yes Yeah, we can go into it. Yeah, sure So the question is is like how how in practice the fraud proofs work Okay. Yeah, so two parties take place in a fraud proof game to figure out which of them has chosen the correct state and Then one of them wins which is what you what you're asking about and at that point that state is that the losing state Is rejected more people can challenge the winning state if they want to but the losing state is rejected whoever chose to Take part to defend that side of the state lose some stake because you have to put it stake to defend a state and the if no one if no one comes to challenge the winning state Then that will be accepted as the correct state and you'll go on from there No, the L2 doesn't deal to do so if you're running an L2 node You've got your if you think about a fork occurring on Ethereum You've got some people that choose different rules for their node That doesn't mean that you need to stop running your node with what you see as the correct rules And the same kind of happens on L2 I can run my node and I can see which of those two is Going is going to win the challenge because only one of them is correct And I know which one is correct so I can continue to accept transactions validate them We can continue to process them in that time what you can't do during that period is withdraw funds from the system So if withdrawals are paused whilst this fraud-proof game is taking place because Ethereum itself doesn't know which of those two states is going to be correct So the funds stay in the system while it's happening, but we can still progress the state as an as an external viewer. Yeah I'm not sure I fully understand the question Yeah, so the question is this like if two two states are in violation of each other as people defending either side What is that what are we actually challenging where what's the state transition that we're challenging? Is it the pre is it from the previous state to the current state or is it further back and the answer is it's just the previous assertion? Yeah, so the question is do the fraud proofs take place in the solidity contract and yes They do but the way they the way they work is that there is a bisection game that the two parties play We don't want to execute the full state transition again So instead we try to decide which part of the state transition we disagree on So we take the state transition we bisect it into many parts We allow the other person to choose which part they disagree with and which part they agree with and so you always you have You're reducing the size of the state transition always keeping a point that you have both agree on and always keeping a point That you both disagree on and making that smaller and smaller and smaller until you get down to a single opcode and then you execute that single opcode Yes So it's the question that's within a single state transition They disagree about multiple things or is it that there are multiple people disagreeing about one? Okay, so if there's two two parties, but they disagree about multiple things Then I'll just be the first disagreement that matters because that's all you need To to slash the person out of the system and remove their their state from the system Yes So I think your question I think is what happens if someone includes an invalid transaction in in the batch or So so the Arbitrum virtual machine will know what to do if someone gives in an invalid transaction It will ignore it basically So you can then choose to run a different Arbitrum virtual machine that would do something weird with that And then we would end up at different states and we would like challenge each other over over the result of that But just including an invalid transaction in the batch isn't enough to like confuse An honest validate that something weird has happened or that they've got the wrong state or anything like that There are rules about what to do for every byte that you see in that batch Yeah, I think sorry, there's one at the back first story How long do we have left These are great questions though. So the question is sorry Yeah, so The question is Given that During a fraud proof game with draws are paused Isn't there an attack you can do on the system to delay and cause problems for everyone else by just Creating a challenge and what is the cost of that of creating that challenge? And the answer is dependent upon how high the stake is set So that's Yeah, if you have a very high amount of stake then it becomes very costly for you to cause this delay Pardon The the amount of status steak is set by the system So for in order for you to take part in a challenge, you need to put up a certain amount of stake Yeah, so the moment the validator list is whitelisted So it's not open to the public. So the whatever amount value in there is is not really meaningful, but We're working quite hard on trying to make that open and when it is open I can say that it will be quite expensive Yeah Yes So there's a separate so the question is is what if the sequencer is malicious tries to cause an invalid state transition? Is that the right and what happens when someone challenges? So there's there's a separation in the system between sequencing transactions and Generate executing those transactions to create a state to update states So the sequencer has no power over what state will be update what the state will be based on what it puts there The node software does so if the sequencer puts rubbish there the node software like Honest node software will recognize it as rubbish if the sequencer Puts valid stuff there then they will process it as valid stuff But the sequencer is all it's doing is putting data onto the chain They don't enforce in any way what the state should be that's a result of that data Those are the validator nodes that decide that Yeah, so given just some data that arrives People running validator nodes need to decide what the result of that data would be Yeah, so kind of answer the question Yeah, and the nodes will know what to do when they receive that so there'd be strict rules about everything that the batch contains Exactly so the question is is like what can this what powers does the sequencer have in the system and the sequencer can choose ordering of things inside that batch But they can't Manipulate what the output of those transactions will be yeah, so you don't you don't trust them in any way for the security of the system The sequencer is necessary for liveness of the system to get transactions moving Fred's like waving his hand over there Yeah, so At the moment there aren't right so the moment we trust the sequencer to pave well if they don't then Do we won't be able to use the system properly The funds will still be safe that are in there and there's a secondary backup system which normal users can use So you don't have to go by the sequencer if you don't want to be you don't get the benefits of compression But you can send your transaction yourself Or you can find another someone willing to compress stuff for you and put it into Into the system for you, but they they won't fundamentally the sequencer is the one who chooses the ordering and you won't be able to do that We have like a wait a time period where if the sequencer is not actually doing its job at all It's not updating things or it's not including these what we call delayed messages, which are user sent messages via the L1 Then after a time period you can force those through regardless of the sequencer So that's the kind of backstop if you need to exit the system and the sequencer is not allowing you to send transactions Yeah, but it's not really the validators that are involved in that. It's more the users who say, okay I don't like the system anymore. It's not working for me and I want to just force my way out of it. Yeah Yes, yeah, so that that comes back to your your Your node software, right? So if you if you can see that This state is correct. Then if oh, sorry. Yeah. Yeah, so the The question was it's like what how does finality work in the system given that after a fraud proof a certain state will be rejected So the answer is if you are following that invalid state, then you will basically see a real probably quite a deep real But if you were running on a software, you won't see and you won't see any problems. Basically, you won't see any difference There'll be no change Yeah, but you can but that does bring into question what the finality of a transaction is in in there And as you as you pointed out you could get this deep reorg So it depends whether you're running software depends like whether you're running node software or not You might want to wait just until that week period is up all challenges are over and then just be like, okay Now it's definitely fine. Yeah Yeah, any more questions The question is is there an easy API that I can use to see if there are if the challenges are complete And the answer is that you can look in the smart contracts So you the smart contracts are created and destroyed when challenges exist So you can see in the smart contracts all the challenges that are taking place at any one time Yes Yes, it will if you if you are if you think that if you if your node software has a bug in it or you've done something malicious with your node software then You'll be following what will know will not be the canonical chain eventually and so you'll see Results that will not never happen or or may happen in a different way. The transactions will still be replayed So you all the transactions are on L1 So anyone who wants to run on a software can know what the final state will be but if if you're running some it sort of like Mutated software or something like that then yeah You after one week's time you may find that all of that state that you thought existed didn't and you're actually on this other chain the question is like The question is what what happens to me when that challenge ends and and I Realized that I was following the wrong chain. Is that the question? Yeah, the challenge ends No one decides to dispute this state transition Basically, everyone in the world is agreeing on this state transition at this point if they didn't and they would start challenging it Okay, I've got a wrap up now, but thanks very much for the great questions and