Parallelizing EVM With Sei | Jayendra (Jay) Jog - Sei

ETHDenver 2024 · February 2024 · 19:40

Jayendra Jog discusses parallelizing the EVM on Sei in this ETHDenver 2024 talk, covering how the chain executes independent transactions concurrently instead of processing them strictly in sequence. The discussion covers the technical work of detecting which transactions can safely run in parallel without conflicting over the same state. It's presented as an approach to raising throughput for EVM-compatible chains without abandoning EVM compatibility.

Speakers

Topics

From ETHDenver 2024, hosted by ETH Denver.

Transcript

All right, GMGM everyone. Let's go ahead and get started. So, my name is Jay. I'm a co-founder over at SE Labs and we are building the first paralyzed EVM. And today I wanted to take some time to talk about both what we're building um and also go over some of the hot takes that our team has that might be a little bit controversial especially at Eat Denver. So let's go ahead and get started. Um so over the past couple of years there's one thesis that we have started to develop which is that the EVM is here to stay. 87% of crypto developers currently work on the EVM. So essentially everyone that's

cryptonative is an EVM developer and if you basically ask them about moving to a new execution environment let's say cosm or any of these other execution environments there's typically a lot of hesitation and this comes from two major components. Uh the first is it's a pretty big security risk. If you're comfortable with solidity and you know the internals for how the EVM work um it's pretty risky to go to a new execution environment. let's say write a smart contract in Rust. Um one small bug can result in your entire project getting drained. So it's super intimidating to go to a new execution environment. Um on top of that uh there's also this idea of Ethereum

alignment and a lot of devs feel kind of icky. It kind of goes against their values um if they move away from the EVM. And this is fundamentally because the EVM is not just a tech stack. At its at its core, the EVM is an ecosystem. It's not just the technology, but it's also all of the builders that are there, all the tooling that's been created, all the mind share that surround it, all the research that's there. Um, and because of that, we fundamentally believe that the EVM is not going anywhere. Definitely not in the near future. Most likely not in the medium or long-term future as well. The question then becomes, what is the current limitation of the EVM? like what is the biggest issue with the EVM? Um I'll make the argument that the biggest issue with the

EVM right now is throughput or more specifically lack of throughput. Um so throughput is the general idea for like how much you're able how many transactions or like how much work you're able to process per unit of time. And if you look at Ethereum L1, if you look at roll-ups that are built on top of Ethereum, they're not really able to get more than 50 transactions per second um that they're able to process. So, what does this mean from the user experience and the developer experience? Well, from the user experience, this means that you have to pay ridiculous gas fees. Um, for example, I'm sure a lot of you have been doing stuff on Ethereum recently. If you're trying to do stuff on the L1, if it's 100 GU for uh gas fees, like you're going to be spending a shitload of money on gas. And

I mean, look, no one wants to pay that kind of gas. That ends up resulting in most of the human population, honestly, just being excluded from participating on chain. And that's definitely not the world that we anticipate um having happen onchain in the future. Um the other issue is it also becomes much more restrictive for developers. Um as a developer, if you're constrained to a 50TPS environment, then it becomes much more difficult for you to build the kind of applications that you would see um in web 2 or in traditional finance. And it forces you to make use of antiatterns to be able to get stuff just working on the EVM. Um, one example of this would be automated market makers. Like automated market makers, they do not exist in traditional finance. And the reason that

they've started to become so popular, the biggest reason that they're popular on chain is because they fit the limitations um of what the EVM really allows you to do. So there's a ton of limitations that come with this low throughput. Um, so then the question is how do you actually solve for this? Uh, and that's when parallelization comes in. So if you look at the landscape for EVM based chains right now, they're essentially all single threaded. So if you have a 100 transactions that come in, you'll need to process every single one of them one by one. And this is super simple from an engineering standpoint to implement, but it's not performant. It's extremely inefficient and it does not take advantage of modern hardware. Um half of you are on your phones right now, those of you that are on your phones, um these are multiple

these machines have multiple cores. they're able to process multiple work streams simultaneously. And if you have singlethreaded uh single threaded execution environments, you're not really making the best use of the hardware that you have at your disposal. So when you paralyze the EVM, it unlocks greater throughput and that helps enable lower gas fees in a much bigger design space for developers. And that's kind of the inspiration for SEV2. Uh there's a ton of different things that we've gone that we've ended up doing as part of SEV2. We support the EVM. We've added in optimistic paralization. We've created a new database layer and we also have twin turbo consensus that I'll go over briefly as well. Um so if you look at how parallelization can be supported on chain right now. There's basically two ways the teams have done it. Um approach

number one is by having developers define dependencies. This is kind of the approach that you see with Salana. When a transaction submitted all of the dependencies need to be passed along. Um the second approach is by having the chain itself figure out what the dependencies are. So this ends up leading to a much better developer experience, but then it adds complexity to the chain because the chain needs to figure out how to actually do this. But if you are able to have the chain figure out what the dependencies are, that is a better end state to get to because it makes the developer experience much much better. Um, and that's exactly what we've decided to do with say we make use of optimistic parallelization. And a super high level idea here is you try to run things all in parallel initially.

Then there will be conflicts for transactions that are touching the same state and then you rerun those. Um the nice thing though is when you start rerunning transactions for a second time onward, all of the state that they're touching has largely already been pulled into memory. So it ends up being much more performant because you don't really need to worry about um needing to read from disk. So with this approach, we've been able to start paralyzing the VM. There is one downside though to parallelization and that is state bloat. So state is the data um that needs to persist um to be able to process any new transactions that are coming in and to also be able to um generate state routes. And at a super high level what state consists of would be two kind of

broader ideas. Um one would be account balances. So like I have 10 say you have 20 say um it also has smart contract state. So let's say that there's like a unis swap smart contract. Um what are the actual liquidity pools that are there? What are the tokens that have been deposited? Um all that stuff need to be persisted on full nodes and it needs to be data that is stored on chain. The more throughput you have aka the more transactions that are processed the more state that actually gets created and this is something you then need to account for. And when you have more state the result of that is it leads to first of all more state storage that you need to manage. Like if there's 10 terabytes of state then most consumer hardware is not going to be able to like just automatically support that. You

need to start upgrading your hardware. Then that leads to more centraliz centralizing forces because then you have people that are forced to run custom hardware to be able to run a full node and that that leads to issues. So you need to be mindful about how much state gets created. Um and then the second thing is state sync. So when you start to run a new node, let's say that you want to start running like a validator for the network, you need to import all the states to be able to start processing new transactions that are coming in. there's 10 terabytes of data that you need to import. That takes a lot of time. That could take on the order of hours, days, potentially even longer. And that has pretty significant impacts on the network as well. So you you definitely want to be mindful about

how to account for state storage, how to account for state sync. Um so to help with that, we introduced the idea of SADB. So DB essentially has two major components. Um the first is a memory mapped IBL tree and the second is async writes to disk. Um the way that the memory mapped IVL tree works is it has three files that are there on disk and you take the entire tree, you split it up and then you put it into these three files. This is different than the approach that AV1 had where the entire tree itself was just stored on disk. And when you store the entire tree, there's a lot of extraneous metadata that needs to get stored. Um one example of this would be if you have an intermediate node that doesn't actually have a key

value pair. Guess what? There's data that needs to be allocated for storing these key value pairs. If you have a child node which is at the bottom of the tree that doesn't have a left child or right hash, guess what? You still need to store uh something for the left hash and right hash. And that ends up leading to a ton of unnecessary metadata that you're just tracking. When you have this these three files that are stored on disk as part of this memory map file system, um you're able to avoid all that extraneous metadata, which helps you get a 60% reduction in the state size, which is massive. Like that is a huge improvement on the amount of data um that you actually need to persist. And when you have less data, that also improves state sync times because suddenly if you have like 40 only 40% of

the amount of data that needs to be imported, then it makes it easier to import that data. Additionally, if you have three separate files that you're writing to, um, then you're able to paralyze rights to these three separate files. So that allows you to get roughly a 12x improvement in state sync times as well. So that that that's massive for helping prevent state float uh state bloat. The other benefit of DB um comes from async writes to disk. So what happens with SDB is you have all this data that's stored in this memory mapped IVL tree which is these three files on disk. Then you pull as much data as you can into memory. Ideally the entire IVL tree will be able to live in memory. If not there's uh subsets of data that you can pull into memory. And once you pull this data into memory then you're able

to uh generate the state route in memory itself. So typically in order to finish block execution you need to import uh this state route or you need to have some kind of state route that'll be uh used as part of like the block header. And in the case of say like if you're able to have state uh state root generation happen in memory that makes it much much easier for you to just kind of uh terminate um block processing at that time and then you can asynchronously write to a write ahead log and then also asynchronously actually write the data to disk. Uh so this approach helps lead to a 287x increase or improvement in commit times because you no longer need to actually wait for uh commit to happen to disk.

You can just have it um be in memory and then afterwards once it's done on the write ahead log then you have disaster recovery. So it makes it much more efficient from that side and that helps really improve the overall performance of the entire chain. Um the other thing that we're continuing to use which is there from CV1 already uh is twin turbo consensus. So twin turbo consensus is se's novel consensus mechanism. Um and this allows us to get 390 millisecond time to finality which makes it I mean currently it is the fastest chain that is out there on mainet right now. And this will continue to be the case for SEV2. Um and this has single slot finality with an internationally distributed validator set. And the two big unlocks that we had over here to get to this um is

optimistic block processing and intelligent block propagation. So the way that optimistic block processing works is kind of highlighted in this diagram over here where normally what you would have is there's a block proposer who proposes a block. Other people in the network they receive the block and then from there they have two rounds of voting a prevote step a pre-commit step and then afterwards they actually start to process the block. Um that is very inefficient though because as a validator like you receive the block and then afterwards you don't do anything with the block for these two voting steps which is completely unnecessary. Um so the idea behind optimistic block processing is that as soon as you receive the block you can start concurrently voting on the block

while also uh starting to process the block. And if you process the block then you can update a candidate state instead of updating whatever the canonical state should be. If the block ends up getting approved by the network, then you can commit whatever that candidate state is. If the block is rejected by the network, um then afterwards you can just discard the candidate state and there's not really any harm that's done. So with this approach, you're able to get like significantly improved time to finality. Uh the other idea that we introduced was intelligent block propagation. Uh the way that things normally work before is that there'd be some uh block producer whose needs to send both a block proposal message along with the entire block of like let's say a thousand different transactions across the

network for a validator to start voting they need to receive all thousand transactions even if all thousand of them are already in their local meool because there's already a P2P layer where these meool transa where these transactions are gossiped. Um so the current unlock with intelligent block propagation is what if you let validators try to construct a block locally before they start to uh wait to receive the block across the network. And what ends up happening is the block producer will just give a block proposal message which will be an ordered list of transaction hashes. Then validators will receive this ordered list of transaction hashes. Then they can start looking at their own mempool try to construct the block locally. If they have everything, which actually does end up being the case a lot of the time, um then they're just able to process a block

immediately. Otherwise, if they don't have it, then they're able to wait to receive all the contents um across the network. So, from both of these approaches, we've been able to observe 390 mcond finality, which is I mean, that is the fastest that you can have uh that I guess any network has um in terms of finality at the moment. Cool. So, that's kind of where we're at right now, I would say. I also wanted to go over some of the more controversial ideas that we have um as kind of just based off uh debates that we've been having or like ideas that folks have been kind of sharing about today. So the first idea that we wanted to go over is we don't think it's a good idea to blindly focus on the number of validators. And I think especially at E Denver, this might be something that

goes against what a lot of people believe in. But if you think about validators, like what how do you actually incentivize people to run validators? Well, there needs to be some kind of mechanism in place that whatever the validator costs are, so this would be the cost of the hardware, operational cost, opportunity cost, um, all of that is made up through some mechanism. This could be from foundation grants as you see in some ecosystems. It could be from whatever the transaction fees are plus potential me redistribution plus whatever inflation for the network is. But it's expensive to run validators. And if you have a 100,000 validators, then you need to you're the network basically is paying the cost for these 100,000 validators to remain operational. Otherwise, people will stop running them. So it ends up being very expensive. And most of the time, it's

just like you're just redoing the same work. Like if you have 100,000 validators, there's a thousand transactions in a block. All 100,000 of these validators are literally rerunning those same transactions. And that is I mean it works, but it's not necessarily the most efficient thing to be doing. So if what you care about is decentralization, trustlessness, and verifiability, I'd make the argument that it's better to have a smaller sufficiently decentralized validator set um where people are then able to consume zero knowledge proofs of whatever state transitions happen um to be able to verify whatever state of the chain they want using some kind of flight client.

So what this could look like, one approach would be um there's a like block producers or other participants in the network um they're asynchronously creating zero knowledge proofs and then light clients like you might just be running a light client locally. This could be something that is just part of metam mask. Um you would receive a zk proof and then from there you're able to just verify uh the state of the network without needing to run a validator without needing to run a full node. So it allows you to have a smaller validator set size which makes the network more sustainable. It allows these validators to be potentially more performant machines and it also allows people to have verifiability um and trustlessness of the network. So I think that's a model that a lot of chains are going to move to towards in the future.

Um it's also interesting because a lot of the more recent launches that have happened for L1's like within the past few years almost all of them have had smaller validator sets and I think a lot of them are going to move in this direction as well. Um the second idea that I want to go over um is that valids aren't full L2s. I think that there's a lot of folks that kind of view validiums as like the best of everything where you're able to get external DA while also kind of being Ethereum aligned in a way. Um, but if you're using a Volidium, then you're getting the minimum of the security between whatever the settlement layer is and the DA layer. So if your settlement layer is Ethereum, if your DA layer is Celestia, then you're essentially getting the uh economic or you're getting the security of the DA

layer and not getting full Ethereum security. So you're not really a full Ethereum L2 at that point. You're closer to being like a sovereign rollup or closer to being an L1 than you are a true rollup. And I mean we kind of created this diagram to go over that but rollups are the only things that are getting settlement and DA from Ethereum. If you're not really getting um DA from Ethereum then you're not going to be fully Ethereum secured and it's not really a true L2 in that case. Um, one of the other things that we've started seeing is that there's a lot of focus on uh trying to improve discreets maybe from things such as like asynchronous IO. Um, and I would make the argument that instead of I mean you can definitely try to improve disc

reads, but I think there's going to be more gains that happen from trying to encourage in-memory access as much as possible versus trying to focus on disc reads because at the end of the day it's going to be impossible to get around discreets entirely and there is going to be an overhead that comes to reading from disk. Um, and it's better to set up your mechanisms in a way to encourage in-memory access as much as possible. So, LRU caches do this implicitly like if you have data that some transaction is touching and then this data results like if this data gets cached then future transactions that touch that same state um they can make use of that data.

So that is like one example of a very easy way to um encourage inmemory reads. Uh another example that I think is going to start becoming more common with multi-dimensional markets in the future is different gas pricing based off of whether you're doing in-memory reads or if you're doing disc reads. So if you're doing in-memory reads then you will ideally have some uh lower gas fee that you need to pay and you'll get penalized if you do disc reads and I think there's very deterministic ways of doing this as well. For example, you could have like priority state where people have some kind of auction to bid on priority state. Um and then from there there's this priority state that is going to most likely get cash. Um and then from there you're able to just ensure that you're getting as much in-memory access as possible. So I definitely think this

is going to be something that um you'll see start happening in the next year or two from different chains that are considering multi-dimensional fe. Um the last idea that I'm going to bring up is that async rights right now are underexplored. Um we observed a 287x speed up with uh for commit times and the reason that happened is because state root generation happens in memory um and then you're able to move on and kind of have the rest of the writes happen asynchronously. And I think this is an idea that overall has been underexplored and it can definitely result in much much better performance and there's ways to ensure like if you use a write ahead log and you have like um things getting written to disk afterwards there's ways to ensure that there's like disaster recovery in place

as well. Um so it's very easy for the network to be reliable overall. Um so yeah I mean I think there's a ton of cool stuff um that is going to be explored from say side and yeah that's it from my side. Thanks y'all. [applause]