Ethereum Execution Layer Specifications (EELS)
Devcon 7 SEA·Tue, Nov 12, 2024, 09:47 AM · 20:54
Speaker
An introduction and walk-through of the executable specifications for the Ethereum Execution Layer. Github (https://github.com/ethereum/execution-specs) EELS is an implementation of the EVM in Python that has been optimised for readability. A great tool for EIP authors looking to prototype new ideas on the EVM, it is easy to understand as well as update with new features.
Transcript
So I'm going to be doing the rest of the talk in English. I'm Guru. I work on the EELS team at the Ethereum Foundation, and I'm really excited to be here and talk to you a little bit about EELS, what we're all about and what we do, where we fit in the larger ecosystem broader picture. So I'll start with what EELS is. EELS stands for the Ethereum Execution Layer Specifications, which means simple enough, we specify the execution layer.
But what does it mean to specify the execution layer? There are all these different aspects to the execution layer, different components to it. And what do we mean by specifying the execution layer? We focus solely on basically the core of the execution layer, which is basically the state transition function, the EVM. And when we talk about the state transition function, what I mean is there are a couple of very important questions that we focus on.
Let's say I have a blockchain and I'm looking to add a new block to the end of this chain. There are two important questions that EELS tries to answer, answer very precisely. First one is if this new block that I'm trying to add, is it a valid block at all? The second question that we are trying to answer is, let's say it is a valid block, and I add this block to the end of this chain. How does that operation change the state of the chain?
So those are the two basic questions that EELS tries to answer, and like I said, tries to answer very precisely. Some of the other aspects of the EL is not something we really look at. We don't look at reorgs, networking, transaction pool, and so on. So those are not focused on when we talk about ELs. And that's our GitHub repository, in case you're interested.
I'll give you a QR code at the end of the presentation that you can scan. When we talked about specifying the execution layer, we do this in Python. As you can see on the screenshot on the right, you have a screenshot of the state transition function. There are a few things that you'll already notice in the screenshot. It is executable.
It's written in Python, which means you get all of the nice things that you have when you have executable specs. You can kind of isolate components, run components individually, see how they function, try to see the inputs and outputs, all that nice stuff. One of the things that we've done while building EELS is that we have tried to focus heavily on optimizing for readability. That means we want the code to be very readable. We want it to be easy to update.
And this is important when I talk a little bit about why we are doing EELS. This readability aspect of EELS is going to be extremely important and has some interesting consequences. And when we also talk about Optimize for Readability, we also mean it's extensively documented. We have taken a lot of effort to document every single component, every single function that's there in EELS, what it does, and kind of speak a little bit more of that. And we have tried to, I mentioned earlier that we have written this in Python, but that is true to the extent, to an extent, but we have not used all the advanced aspects of Python as well.
Again, coming back to the readability aspect, because we have tried to keep it as close to pseudocode as possible so that it's not something that's, like, super focused on Python developers. We want everyone to be able to read this. We want everyone to be able to update it. So we have tried to keep the code as close to pseudocode as possible, which is, again, important when we speak about the broader aims that EELS has. Because of these reasons, it's a great playground for prototyping new EIPs.
It's something that we have as a focus. We want new EIPs to be prototyped in EELS, and the readability aspect, the ease of updating, the ease of reading, ease of understanding plays a huge role there. The question then is, next question is, why do we need ELs at all? If I were to answer that question, I would like to first look at the EL development cycle that goes on right now. So the execution layer, how new things are added to the execution layer.
So typically, when I. So the execution layer, how new things are added to the execution layer. So typically when I talk about the development cycle, these are the two ends of that cycle where on the one hand you have research. Research is basically come up with new ideas that they would like to see in Ethereum, new features that they would like to see. They come up with new EIPs.
EIPs are Ethereum improvement proposals. And on the other end of the spectrum is basically the client developers who take these EIPs, update the clients to reflect these changes, and do it in a super optimized way so that it can run in a production level kind of an environment. There it is heavily optimized for performance. Now, with this kind of a framework, there are a few implications that this kind of a framework will have on the EL development cycle. So now let's say you are an EIP author who's proposing a new change.
With this kind of a system, there will be a few implications for you. One of the first ones is you will have to update your EIP in one of the clients yourself. Now, like I just mentioned, these clients are production-level softwares. These are not very simple softwares to work with. And there are a lot of moving parts to them.
So someone who's not intimately familiar with the software code base might find it a bit of a step to kind of go and implement their EIPs in a production level client. A second implication or a second thing that you can do if you are an EIP author, is you can wait for a client dev to pick this up, pick up your EIP, and implement it in their client. But as I think all of you know, client devs are extremely busy. They have limited bandwidth. Their bandwidth is extremely precious.
And so unless the broader community is kind of considering your EIP very seriously, it's unlikely that a client will pick up your EIP and implement it in the clients. A third implication that this kind of a development cycle has is you might end up with different EIPs being added to different clients. For example, recently we had for the Prague, there was discussion around including EOF and 7702 within Prague. And it turned out EOF was implemented on EVM1 and 7702 was first implemented on EthereumJS. So if we are to talk about EIPs and try to kind of find out how EIPs might interact with each other, what are the different side effects, and if they're on multiple different clients, it's a bit of a challenge.
You have to wait for it to be implemented all in one place, and then you can kind of answer some of those questions about interactions. So you will have the EIPs scattered in different clients with this kind of architecture. Because maybe I should mention that when I talk about client implementations, we are talking about multiple different clients. So in a post-EELS world, we are looking to move to something slightly different from this. What we are trying to do is this.
And a quick shout out to the EAST team. EAST is basically the testing team, and they generate the tests. And I think they have a talk and workshop tomorrow. I would highly recommend you guys check them out, check the talk out tomorrow. But for the purposes of this talk, all you will need to know is EAST is a package that kind of takes a working EVM implementation and spits out tests.
It generates tests for you. So that knowledge is enough for the purposes of this talk. So what we are looking for is to move to something like this where the researchers come and implement their EIPs in EELS, which should be extremely easy because it's, like I said earlier, we have optimized for readability and for writing new code, for updating. So this should be very easy, even if the EIP author is unfamiliar with the client code. And EELS is very focused to the state transition function, so there's not a lot of clutter in the EELS code.
And then EELS talks to EAST, generates the tests, and the clients, even before they implement their first line of code, have all the tests that they need ready to go. So basically, before they write their first line of code, they have all the tests ready. So there's benefits on both ends of the spectrum. The researchers have an easy way to play around with stuff, iterate on their ideas, and see what are some of the weird edge cases that might come up and so on. And the client does just have to focus on optimizing their implementation.
They don't have to worry about tests being there. So EELS and EAST together will take care of that scenario. Okay. Just to summarize some of the advantages of using ELLs. Faster iteration cycle.
Researchers playing around with ELLs and, yeah, on the other side, the client is having all the tests ready. With it being a playground, it can throw light on some of the weird edge cases that might come up. So if you were to write a EIP document in Word or in some kind of plain English, it is sometimes going to be a little bit difficult to kind of imagine all the weird edge cases that might come up. Whereas if you're implementing it somewhere, it's more likely that you will encounter something will come up to the surface that you had not considered. It's a one-stop shop for EIP prototyping, which means all the EIPs that we are considering for subsequent updates are in one place.
We can answer multiple questions regarding how EIPs interact with each other and what are some of the side effects and those kinds of things. And the last thing is, this also means that the EIP authors get to leverage all the tools that EELS has developed. We have developed a lot of tools to make writing EIP simpler. We have a lot of code analysis tools, linting tools, test filling tools, and these become accessible to the EIP author right out of the box. So it's extremely beneficial.
And we are also closely integrated with EAST. EAST is also written in Python, so there's more scope for closer integration when it comes to EELS and EAST. And finally, you have us, the members of the EELS team, who are ready to support you in case you need any help writing the EIPs or in case you need any help regarding EELS. Where are we right now in terms of our roadmap? We have implemented all folks up to and including Prague.
So Prague is still not live on mainnet, but we have all the EIPs ready to go. We have implemented them all. We have a working implementation of EOF. A fully functional version of EOF is available, which is, I think, currently being considered for the next fork. It is right now the default test filler for EAST.
So if you were to go to EAST and try to fill the tests, EELS would be the EVM implementation that it uses to fill the tests. And finally, the last two points. So we consume all the current tests as well. And the other thing is we have verified all the mainnet blocks using EELS. This is for us to give an additional level of confidence that whatever we have implemented so far, everything until and including Prague is accurate.
So we have verified mainnet blocks up until Cancun so far, but we are quickly progressing towards the tip of the chain. And this is where we would like to go in the roadmap that I showed you earlier, why we need EELS. We want to be the first ones to have all the EIP implementations and all the updates to EIP subsequently. So in the post-EELS world, this is one of our main objectives. We would like to develop more tools for EIP authors.
Our entire thing is to make development and prototyping of EIP simpler. So we would like to build more tooling for EIP authors. We would also want to integrate into the EIP simpler. So we would like to build more tooling for EIP authors. We would also want to integrate into the EIP process.
There are currently discussions going on around how we kind of enforce this, whether we make it a mandatory part of the EIP process or how. I mean, there are discussions going on on this. This is something we would like to integrate in the EIP process largely. And finally, we would like to also participate in DevNets. When something is being developed and there are DevNets that are live, we would want to be able to have the capacity to verify the chain.
Finally, how can you use EELS? Like I mentioned, this is our repository on GitHub, Ethereum Execution Specs. It supports Python 3, 10, and above. I'd like to talk a little bit about our repository structure and the folder structure. So the folks that are live on mainnet are in the master branch, so that is the stable branch.
So right now this is everything up until Cancun. And the folks that are under development are in their own branch. This is the nomenclature that we use. Folks Prague is the current development fork, and each EIP within Prague is maintained in its own branch separately. So if you were trying to add a PR, you would create a new EIP branch for your EIP.
And this is kind of what the folder structure looks like. The source Ethereum is basically what houses all the specs. And one thing that if you notice, there's a separate folder for each hard fork on the execution layer. For example, Homestead is basically an entire copy of Frontier plus the additional forks that were meant for Homestead and so on. The next fork is basically Homestead plus the next EIPs.
Now this is a deliberate choice that we have made. It's not so great from a perspective of code duplication, but it's great when it comes to readability. I've mentioned this a few times already. Readability has been a big focus of ours. So you can just go to one of the folders, for example, Istanbul, and that folder will tell you exactly how the entirety of Istanbul fork works.
So there's no clutter with different forks. So you can just go to a particular hard fork and understand entirely how that hard fork works. So this means there are no conditionals. So if you go to a real client, you'll have all these conditionals. If Shanghai do this, if Cancun do this, and so on and so forth, there's no such thing here because of this choice that we have made.
There's no clutter in the code, so you can look at each code, each hard fork individually. It's extremely easy to read. But also in a scenario like this, one might legitimately ask the question, how do I track the updates that happen in each fork? So that's an important question. There are a lot of scenarios where you want to answer questions like, oh, what happened in London?
What happened in Berlin? And so on. For that, we have a custom diffing tool. And if you look at the screenshot on the right, that's a screenshot of what was the difference between the two hard forks that I've highlighted here, Muir Glacier and Istanbul. So what changed between Istanbul and Muir Glacier?
And if you look at the diffing tool, diffing tool is, again, it renders the diffs in HTML on GitHub pages. And if you look at it, it tells you all that happened between Istanbul and Möyreglacier is that we pushed the difficulty bomb. So, yeah. So you can look at the diffs between any consecutive folks this way and have your questions answered. Yeah, this is a team right now.
So it's me, Sam, and Peter. Peter's I think in the audience. Sam could not make it to DevCon this year, so shout out to both of them. Finally, how can you contribute? Like any other good open source project, we welcome all kinds of contributions from documentation to any kind of pull requests that you might want to create, any kind of issues that you might want to work on on our repository.
But there are two specific ones that I would like to particularly highlight. If you are working on a project that uses an EVM backend, we would love to see if you can integrate EELS into your project and see how easy or difficult that entire process was. We would love to hear from you how that was so that we can kind of improve anything that we have not considered so far. And same with if you're an EIP author, we would love for you to implement your EIP on EELS, and again, we'd love to hear back from you any kind of thing that was difficult or easy, anything that we can improve, any kind of feedback, extremely appreciated. Yeah, that's all I had to say.
This QR code takes you to our GitHub repository, and in case there are any questions, I'd be happy to take them. Thank you. Thank you, Guru. So we have one question, and again, the QR code, if you want to get a question in, just throw that up there. But we will start off with this one.
How do you write a code that is able to test EL behavior, which would require CL input, like a specific engine API call? Do you also have to implement CL changes? No, we don't implement CL changes. We take, so there's tools that we can, we use the T8n tool for this purpose. And the T8n tool can take the inputs from the CL.
For example, I think we are already doing this in Shanghai with withdrawals. So we take the withdrawals as an input. We don't do any kind of checks on them. So that's something that we assume the input that we've gotten is basically what it is, and then try to run the EL block, assuming that as the input that we've gotten is basically what it is and then try to run the EL block assuming that as the input. Thank you.
And how do you use slash import block states when validating an existing block? Do you mean I'm trying to understand? We import it as JSON. So if you have all the block parameters in a JSON file, we can import it that way. I'm trying to understand if that's what this question is meant to ask, or if not...
If it was your question, quickly put a follow-up. Yeah, I think... That was the question. Oh, okay. That was the question.
Okay. Perfect. We got it. Well, thank you, I think. That was the question.
Okay, we got it. Well, thank you, thank you. If we have no more questions, we'll wrap it up there. Let's give Guru a huge round of applause. Thank you so much.
Automatic transcript — names and jargon may be misspelled.