 Good morning, everyone. It's apparently very early for some people, but we kind of imagined it to be a continuation of the material magician session we had, I think, on the first day. But the focus for today would be EAPs related to EVM. So yeah, there's this possibility to take a mic and describe our pitch for EAP. You are interested in, and we can discuss and maybe ask questions from the audience. So if anyone wants to start, if not, I can take five minutes, 10 minutes to talk about EOF, like five EAP proposals we have drafted so far. So this is a slide for my lightning talk about EOF, but mostly what I wanted to have on the screen is the five EAPs we have. Two first are potentially scheduled for Shanghai, which means the next execution layer upgrade. A day defined the kind of the basic of the EOF structure. So EOF stands for EVM Objects Format and is a kind of our idea to structure the EVM programs in the way that kind of behave more predictable way. So we know where the data is in the program. We know the code is. And we can version programs, so that also gives us some additional backwards compatibility features. And on top of that, we can build additional features. And these three additional features are the next three EAPs on the list. So firstly, EOF allows us to define instructions in a bit different way. So we can have some immediate values, means the opcode can be followed by additional numbers. That means something to the instruction that will interpret the values following. That wasn't possible before because of the backwards compatibility of existing EVM. So in the current EVM, you can craft a program that will break if you interpret values following opcodes in a different way. So these static jumps are more efficient than current ones. And there's also easier to analyze from external tools and also from the code validation in the EVM itself. And additionally, the next one is EOF functions, which means we can additionally partition the EVM code into separate sections, meaning individual native functions in the EVM and the additional instruction that allows you to go between these partitions. And all combined with the static jumps and the functions, we can get rid of existing dynamic jumps in the EVM, which it should improve efficiency. And most importantly, we can get rid of jump disk analysis. So the jump disk analysis is a process that has to be performed before we can start even executing EVM programs currently. And the cost of doing that is proportional to the size of the code. And none of the cost of EVM execution actually reflects this analysis. And lastly, we can also put additional verification in the EOF format that will allow you to check statically before deploying the code if a function performs Stack Overflow or possibly Stack Underflow. And we can reject such programs. Such programs would be, by definition, a bit more restrictive than the current ones. So there are some tricks you can do in current EVM that would not be possible anymore. But I think most of the compilers that target CVM doesn't really exploit these properties. So that also brings some additional efficiencies, because you can kind of check for correctness at least in the terms of stack behavior during deploy time. And you don't have to repeat these checks later during execution. OK, so that's all I can say in five minutes about that. So yeah, I'm open to answer some questions. And also, if someone wants to join on stage and talk about some interesting EVM stuff, yeah. OK, I have been spending the week trying to better understand the EOF. And one question I have is, so I understand you have different versions of EOF that you can implement. But you can also add, there are additions to an EOF version that can be done without a version bump. Can you walk through what are the proposals of those fives and maybe others that you have? Which one require version bump, which one don't? And how would you think about deploying the whole thing over time? OK, so the first two basics of EOF will be introduced with version one. And remaining three additions will require the version bump. And this is kind of the question, how many features we want to pack into a single version. So originally, we kind of wanted to split that. And that's also the reason we have like five EAPs, not like a single one, because people freak out if the EAP is big enough. So we kind of split that into multiple pieces, which also brings some inefficiency in the design and all of that, because we need to update multiple documents. So just to be clear, so like 35, 40, 36, 70, obviously you're introducing EOF requires to be one. But then there's none in the list of like 4,200, 450, and the last one I can't see. But anyways, none in the last three can be added. So you could add all three together and make EOF be two. Yes, exactly. You can combine how many features you want. It's like up to kind of our capacity. Yeah, what do you define as a version? I mean, multiple versions bring some like new kind of complexity to the system we don't have so far. So currently, when we change something to EVM, it's mostly time based. So to some point, EVM works this way. And from some point, it works differently. So I think all the codes still have all of the versions, historic versions, and because people care about executing every instruction from the beginning, but you can imagine you can design a client that only kind of has like the recent two or something like that. So you can kind of scrap the code that is and like do the full sync, which means doesn't execute the transactions, just collects the state and goes on from that. I think nobody did so far this way, but it's possible. And like this EOF itself will like introduce kind of the new EVM that will run next to the legacy one, and they will be able to communicate within the single transaction, right? So you can have like legacy contract that calls the new one and the new one could all one and like nothing breaks on this level, but it will have kind of two parallel EVMs. And yeah, just to follow up. So like of the, say like the last three, are there any, say we were to split that in like two and one or like three hard forks, like are there any that don't require a version bump or do they each, as long as they're not shipped together all the time require a version bump? I think that the static relative jump doesn't require a version bump at all. So kind of the forward, what is the forward backward? No, the forward compatibility of EOF is that you can always drop new instruction into it without version bump. So whatever you add to the instruction can be like whatever of any complexity you can always do that because we make sure the op codes that are undefined currently are not used in the programs. So like we can, yeah, we can drop the static relative jumps like without version bump. But I'm kind of, I don't know. Like my feeling is like it's probably like better to pack as many features as we have capacity for. So we don't have multiple EOF versions later, right? What about the backwards compatibility of packing in new optional EOF format sections? Like if EOF functions was separate from the code section and provided data on top of it, same with the stack validation information, it was had a separate section number that would go on top of it. I mean, could those be done in a forward compatible way with it doesn't break things? Let me think. So far we didn't actually like think about this way, but maybe that would be the way to design it in the way we can actually drop this feature later without a version bump update. EOF functions requires separate code block, right? Yeah, yeah, but you can kind of, so the thing is you can like, when you have something mandatory, you can make it optional later, right? So because kind of the previous deployed contracts will have this thing there, but if it's optional, it's still fine. So maybe there's a way to have like single code section with the information that maybe later will enable like more code sections. So like single code section contract from before will still work. We'll just have a single function there. So maybe there's way to design it in there, like forward compatible the way, so we don't have to version bump. That's I think my idea I haven't really thought about before. Would adding a minor version in the EOF header be useful to indicate that I'm, I require these forward compatible changes, but I'm compatible with a backward compatible interpreter kind of like HDMI 1.1, 2.1. I'm not sure. I mean, like still like system, like all the contracts have to like do exactly like the same things. And like this not really like optional thing you can perform in the sense that all the clients have to behave the same way. So I'm not sure like they're actually that having like minor version will make any change, make any difference. So either behaves differently or not. So if it's like two versions numbers, I don't think that makes any difference. Okay. I mean, I guess I just thought that Slythik could always just pack into the data section today. Yeah, maybe like the functions, there's a way to do it. I think we will need to like take a look into this. And the last one probably not because it just adds additional requirements of the code structure. So the previous programs probably will not follow these. Do I understand correctly that the last AP doesn't require the version bump because it's just the change on the EVM side. So it's not E in the bytecode and you can do it whenever you want. No, the last one actually requires the version bump because it puts additional restriction rules on the code. So it means we want to make sure that when you load the EVM program from database and you see the version number, you know exactly what you can expect from the code. So if some rules are not there at the deploy time, it means that the program you load from that era will like have different structure and you can't rely on it anymore. Yeah, I got it. Thanks. So I'm fortunate I've been just come across the EOF but so I'm guessing that the intention of these changes is to make it easier to do static analysis on the EVM code, particularly computing predecessors to basic blocks, which is always a challenge with EVM at the moment. And doing static translation will become a lot easier. Like you mean like external tools or like all of the... Well, so I've got sort of three main use cases. So one is static and a symbolic execution, for example. Another is translation translated to x86. And another is doing static analysis of contracts to see if they're valid. So I imagine that all these things are gonna help out with that. So like I think our main goal about control flow changes is to just get rid of jammed this analysis and make it more efficient. But we kind of expect to be also like DOF programs to be much easier to be analyzed, but external tools. But I think we just need like actually inputs from you. Like you probably should like take a look and to see like if it helps or not, like how much it helps because that's not really like a area of our expertise. But yeah, we kind of expect it to be much easier to do it analysis externally. Yes, certainly static jumps will help enormously, but because of the predecessor problem essentially. We need to talk about distribution of this. Beautiful. So ARM has a zero register. There's a lot of registered machines out there. Push zero will also be quite convenient. Fuel also has taken the zero register from ARM in their virtual machine. The EVM currently has the gas counter and the program counter. And I think their registers when registers. No, this way. I thought you will start talking about push zero AP because this one on the list. So maybe you want to talk about it? No, okay. I have. So, okay, like let me start like from the back. There's like one AP that introduces like push zero instructions. I think this is what is kind of analogous to ARM and all of that. So it's just to like make sure like people don't use like kind of exotic way of like M size of that to push zero on the stack. So we just will delegate one instruction to do exactly this with the same gas cost of the kind of the hacks we currently have. And that's also scattered from Shanghai if you remember, right? Can anyone confirm that? Okay, what I think it is. And so that's one thing. Registers in EVM probably never. So this like EOF stuff looks already complex enough that I don't know like what is the time scale we can deploy it or maybe it's, it will never be deployed in a minute. But the thing is like it has kind of different structure. So we kind of designed the EVM loop interpreter loop differently but the instructions they operate on are kind of shared between legacy and the new one. And I think that's the current, current direction we're going with. Will nobody propose like radical changes? I think like radical change would be just to take some other EVM, like, I don't know, we try to do a assembly, maybe the fuel of the M and put it somewhere or L2 or whatever. I don't expect to see so drastic changes to EVM. It's kind of the same. It's kind of the same of as the question, like, why do we have 256 bit size words, right? And we, I probably there's also not like a not really option to short it, it's to something smaller. All right, one more question. Hey, so Greg Colvin's got his simple sub routines EIP as well. Could you explain how that is different than these? Yeah, I would sit down because. So those some, I'm sure I can give a full picture. So maybe someone would jump and help me, but I can start with that. It kind of wanted to introduce this sub routines, which are kind of analogous to what our functions are to existing EVM. So there was some technical issues. Like one is about having this immediate values in the extraction, which are not like fully backwards compatible. And secondly, it kind of doesn't really help with this analysis. So this was one, one, because for the simplicity, the jumps will still work the same and they can cross the sub routines easily. So you can use the new instructions to kind of form kind of the sub codes in the code, but jumps will like go whatever they want. And it doesn't really help with analysis outside of that. And it doesn't really help to do kind of fancy compilation by fancy compilation. I mean, you can take like sub routine and compile it to like native code and something and then use the system call stack to implement sub routine calls. But because there's possibility to like jump through over, like jump out of the sub routine and go somewhere else, that's really, that doesn't fit into this model. So, but I'm not sure that were the reason that the chain didn't went through. Maybe there was some other reasons. Yeah, I mean, he's updated that proposal again since it was last rejected. I don't know if you've seen those updates. Yeah, yeah. I kind of noticed, but yeah, I'm not sure this is like the, I mean, the AP is kind of being updated and I have really trouble to keep track like which version we're talking about right now. But I know there are some changes, but this is like still kind of something we should consider for future upgrades or not because I'm not sure like if that's candidate for anything. Hi, so I just have one question. Are there any technical barriers for implementing 3074? I'm really bad at numbers. Can you tell like which AP it is? Both cool. Oh, this one. No idea, honestly. Maybe someone can help. Okay, no, you're not helping. No, I don't know really. So I think like on the technical level, probably not so many. I think it's mostly like social level which is problematic or like this, like some way you can trick people to do something and there is no way back or, but I am not an expert on this one actually. So I don't think I can answer this. You got to be a dictator here. If you had to dream up in the store too, what would it be? Or say like you're not changing the existing memory. You just get to do memory from scratch. How would you go about it? But you mentioned a store, right? Oh, M store. Like it's in like just like, oh, we're doing memory differently here. Yeah. I mean, that's good question. So like we didn't put anything like any kind of draft but we have some thought about that. And there was some input from Vitalik as well recently about how to kind of model that. I think this like multiple dimensions you can try to kind of describe it. Like one is that current memory allows you to just just use whatever index you want. You will just pay more gas for it and that was kind of calculated. And so the memory automatically expands to the use. And that's a kind of different way of doing that. So you kind of have to explicitly inform the EVM upfront, like, okay, please allocate more memory for me. And if you use something that is outside of the allocation, it will just terminate execution, right? And the second one is the model that WebAssembly uses. Right? So you need to kind of allocate memory upfront and you can't use it if it's not allocated. And so this is like one way you can select from. I think at least Solidity was happy with this automatic allocation but I'm not sure I can confirm that. Is anyone from Solidity here? Okay, no. I mean, Solidity is kind of happy that like memory automatically expands to new indexes and you don't have to maintain the like know how much you did allocated or. So it would be fine to have the EVM when you have to kind of declare to EVM that you need more memory. That would be good or not? Yeah, so no, statically analyzing the maximum memory size is a challenging problem at the moment. And if there was something in the EOF to specify the maximum memory size, it would probably be quite useful. So, okay, yeah. So if I get it right, it would prefer the system when you have to kind of explicitly say how much memory you would use or something like that. It's not absolutely necessary because in, for instance, no, Solidity is extremely facile and very easy to analyze, but there are other contracts which don't. Okay, okay, got it. Yeah, so this is one aspect and like kind of we don't have a winner here so far. And like from EVM implementation, I would prefer to somehow lower the housekeeping of memory. So whenever you execute one of the memory instructions, like this like Mload, Mstore, like most of the time EVM spending just to calculating the cost, like if it's like new instruction, like if the index is not like absurdly huge or something like that and just like accessing the memory is like, this is nowhere on the profile, right? So I think like keeping the housekeeping lower maybe combining the explicit allocation and do the like cost by memory pages or something like that would just help. But we didn't prototype any of that so far. So they're kind of rough ideas. But you can do quite interesting stuff if you have memory pages in the EVM implementation. It's a very similar problem to the SPUs on the PlayStation 3, for example. You have sort of the minimum register size was 128 bits. So the EVM is extremely similar to the SPU on the PlayStation. And that was an interesting challenge as well. Okay. That means like PlayStation runs EVM around. PlayStation was a bit quicker. Definitely. I think everything is quicker than EVM, right? Also just declaring all my questions are the lowest, like they're the fullback ones. Anyone can interrupt and take priority. Oh, there's someone. Beautiful. Are there any hardware implementation of EVM or maybe FPGA, ASIC that you know of? And if there is what were their biggest hurdle aside from M store, I'm guessing because that's a pain that otherwise. I mean, ASIC on like memory access level or the storage access level? Yeah, I'm not sure I can help here, but I know like some people were experimenting with having like ASIC way of accessing storage. Oh, ASIC. Okay. Okay. Wow. So we had a project called EVM.Jet, which just was compiling EVM bytecode into, like say x86, like native code. And the performance was great, but the cost of compiling that was also big. So that's kind of the trade-off. And at some point we just scrap it. It's somewhere around, but I think you have a difficult time to decide like which contacts you want to compile to native code. If you don't have to. I, you might have misunderstood my question. Sorry, let me restate it. So has there been anyone implementing a physical hardware machine that executes EVM? So it's got nothing to do with JET, so sorry. Just purely you get an opcode, it decodes it, and then it executes the code and it's all in there. Yeah, what I wanted to do, okay, yeah. I kind of wanted to put it in perspective in the sense like that seems, at least to my opinion, that seems like more advanced because I don't know about this stuff at all, that like doing even JET compilation, which is already hard. It's like compilation is not hard, but it's like time consuming. So you have to just squeeze this. If you have hardware, yeah. I think even if you had a hardware like that, the gas cost nowhere reflects the performance of it, right? So I'm not sure how much you will save. You'll save like your machine computational time, but I think it would not improve the network unless there's like most of the people use it. But I don't know if anyone tried that. I'll be definitely interested for a project to see how it works. Greg Colvin has infamously said that the EVM is a gas counting machine that does computation as a side effect. Do you think there could be any benefits to reducing the precision or the fidelity in terms of like how gradual you're doing your gas accounting and so like paying for more gas things upfront or even say like the memory case would be one case where you pay for expansion or the escalation, like the curve that it follows isn't actually like a smooth perfectly smooth curve. Naturally, it sort of like has a flat region or like a sort of linear region. Then it goes like jumps up and then it jumps up again. Do you think more things like that could be fine in the long run or do you think we should be really good at counting really small units of gas? It I think depends a bit like what kind of instructions substitute you mean. I think for memory, we should like take a look like how to improve gas housekeeping for these. For like purely computational ones, I think it's not so big deal right now. So the one thing is that the instructions actually do quite a lot because they are like 256 bit precision. So this is not like single CPU instruction you're doing, right? It's like four plus loading. So it's like 20 instructions you do. Like your CPU will be doing for the single instruction. It depends what the instruction is but it's actually quite a lot. So you kind of can hide the latency of gas computation there. So kind of the CPU is doing the computation itself and also calculates gas. So the overhead of disabled gas calculation, it's not, I mean, if you have really efficient EVM implementation, it's can be like 7%, maybe 10%. So this is not like huge amount. And the same for the stack checks and all of that. But yeah, so I don't know what like for EVM, I would keep it as it is. I think it's not so bad. Definitely the simple gas tools will have but I wouldn't change it like to be some kind of different precision or whatever. But we also don't want like complicated gas tools that doesn't bring anything. So the memories are fortunately like example once more which means you just compute this like 32 bit chunks of memory, which like you need to do some additional computation to calculate the gas cost. If that would be provide, it would be simpler and the effect would be the same, right? So you don't want to over design it definitely but I think like in general, it's kind of, it's okay. No, for most basic blocks, you can calculate the gas costs upfront and just calculate it with whole basic block. And obviously things like a store and so on, the variable but for many basic blocks, you can pre-compute it. Yeah, you can do that. Like with one comment that it's like for the basic gas cost, some instruction have like basic cost and then like variadic gas cost depending on the arguments and something like that. Yeah, we did try that, like even the EVM implementation and it brings I think some performance but I think we kind of scrapped the idea. Because you need like additional analysis phase to like actually pre-calculate that and you have to. And so quick, like description how it was done in EVM one, it was like the old interpreter that was doing this and the analysis cost was really big and we kind of transitioned to like simple design but efficient design of EVM, which doesn't do that anymore and the new one is actually faster than the old one. But to be fair, the old one didn't get so much attention recently. So maybe there's some like performance you can gain from it but it won't be really big one if you have efficient EVM. So like simplicity wins so far. At least in like the client perspective, right? Yeah, so certainly my experience is the EVM is a tiny part of the cost of the whole system anyway. So which possibly answers the sort of why don't we have an FPGA EVM which would obviously be trivial to do. 11.53, otherwise known T store T load one by LSE years ago. Do you have any thoughts on that and specifically to the memory problem would that reduce some of these pressures on reforming memory because you've got this transient storage is not hitting disk, it's pretty cheap. How do you feel about 11.53? So I'm not sure if I'm on the same page with this one but does it have this same kind of like map map structure that this storage has, right? So yeah, like for me, the issue is that you have this like map structure there. So it's like, this is like chunk of memory. You actually have like hash map or like whatever the implementation is because as I remember it was like doing the same you have like unlimited number of 256 bit slots you can assign to. So the EVM has to kind of have a map of that which it can scrap at the end of the transaction, right? Do you want it in Shanghai? Like me personally, I don't know. It's like I'm kind of, kind of unaffected by that. So like how actually I visioned EVM is like this kind of below that. So I kind of mostly focus on the like single call. So the, this transient storage it's like problematic in the way that I have to kind of outsource it somewhere else. So like the client of like client has to provide some way some API to actually access it because like for my EVM at least, it's that I just start the EVM context on the when you enter the call and I ended there. So I don't have anything that lasts above that. So what, yeah, I'm kind of transitioning to like this the transaction level EVM execution. I think like the ultimate question is like usability of that. And like if there's like strong enough number of use cases that will, I have to make it like desired, right? And I think some people really push hard for it. I have a follow-up question on that. Do you think the cost of a TS of it? Do you want to? Okay, anyway, yeah, go ahead. Do you think the cost of all the potential cost of a T store would be that much lower than the S store? I mean, the basic one is kind of like 100, right? For the currently for the S store, like the minimum we can get if this is like access slot and something. No, I mean, yeah, maybe, yeah. What are the numbers in the disposal? I phrase like the number is short, but like do you think like in the machine would it really be that different? Like from my perspective, it's not any different to access S store because I'm kind of have a buffer of like this cache of this S store. And I'd like from like, yeah, from like the core EVM side, it's not much different. But I think it's like, so the difference is when you have to actually go to the database on this or not. And like this is guaranteed not to be the case. So we don't have to do any database lookup at all. So yeah, probably it should be cheaper, but I don't know how much. Yeah, do you think another alternative solution would be to just fix the pricing of S store and S load? I think historically we did fix the pricing of S store in every hard fork, right? Exactly. If you see there like S store implementation, that's like multiple lines of like different revisions of EVM. So I don't know, maybe we can't get it right. So we need a replacement for it. Yeah. I don't know how to fix it like more. It's already super complicated. So maybe that's an argument pro T load to store. Yeah, I can't be sure. I mean, I would be sure if there was like group that actually tried to fix the store. So it's competitive feature than the transit storage. But I think there's not such group so far. So maybe we just have to pick one option of one. So I don't know. How much easier would life be if the EVM was 64 bit? Or does it not really make much of a difference to your work? Maybe my colleagues can help me with that. We did experiment with full assembly. And for some use case that EVM is used for, it's really helps when it's this big word size. So all it's like balance calculations, all of this like fixed point arithmetic. It's really hard. If you need to emulate like bigger numbers in the smaller like this, like more like smaller, like 64 bit word size, it's really horrible. And when you have like simple design, like interpreter and stuff. So you need like to drop a lot of instructions to emulate that. And it was really bad on some workloads. So we can't confirm it's like the best word size, but for some use case, it's really helps.