Monad: Accelerating Ethereum Execution - TOKEN2049 Dubai 2024
TOKEN2049·Wed, Oct 9, 2024, 12:00 AM
Transcript
all right hi my name is keone Han I'm the co-founder of monad I'm going to be giving you a really fast lightning talk just to give some information about what we do in monad to accelerate evm execution all right so what is monad mon monad is a new evm layer one offering both performance and portability we offer over 10,000 TPS of throughput AKA a billion gas per second 1 second block times and 1 second finality monad also offers full bite code evm compatibility so that any evm app can be redeployed on monad without any changes why is this important this is important because we want both decentralization and performance monad has hundreds of nodes in consensus so hundreds of nodes producing ultimately contributing to block production and minimal Hardware requirements specifically 32 gigs of RAM um and it's really it's important to have really low Hardware requirements so that anyone can run a node and have access to the full State and be able to consult the exact state of the world at any given time all right so I'm going to talk about three major Concepts here the first is asynchron execution the second one is parallel execution and the third one is monad DB enabling parallel State access so first of all asynchronous execution just to give a little bit of background blockchains mostly have interleaved execution um and apologies for the the legibility here but and execution consensus and execution are interleaved and what this means is that because consensus is quite expensive it takes up most of the block time therefore execution can only be a small portion of that time so just to take ethereum for example ethereum has 12C block times but in practice the actual execution budget is only 100 milliseconds so this is crazy because that's literally only 1% of the total block time um and I always like to think of it similar to how people say that you only use 10% of your brain what if you use 100% of your brain think about how much how much hard you could be how much more you could do and the reason that this execution budget is so small is because consensus in execution are inter Leed and consensus is taking up most of that time all right so here's a simple schematic execution is the dark block and consensus is kind of the light block um and you could see just an example of a couple of blocks preceding one after the other and here's another schematic which is kind of showing the same thing but through time asynchronous execution is the idea of moving execution out of the hot path and only doing consensus so basically having all these nodes agreeing on the official ordering of transactions without executing and then after consensus completes then two things can happen in parallel in separate swim Lanes the first is consensus over the next block and the second thing is execution over that list of transactions that we've just agreed upon so kind of now the schematic looks a little bit like this and I've just updated that other schematic that we have so initially when we look at this it doesn't really look that different we're not getting that much more out of it it's you know we've reversed the order so now execution happens after consensus and consensus on the next block can proceed while execution is proceeding but the important thing to note here is that now that we've changed the architecture we can actually expand that dark blue block execution parti and have a much larger execution budget so yeah just to summarize asynchronous execution is the concept of running execution post consensus while consensus on the next block is proceeding um there's a couple of smaller finer details that we need to cover in order to make this possible um so in particular every node is Computing that is executing that same set of transactions in parallel independently so we have to do some special checks later to make sure that they all got the same result and then note also that the nodes are coming to consensus with a slightly delayed view of state so we need to do some special stuff to make sure that um we're always safe um but in general this change is a massive Improvement for the overall throughput of the system because we have so much more time to execute all right the second thing to talk about is parallel execution um so just to emphasize in ethereum trans actions are linearly ordered and they're serially executed in most systems and the goal is to still have transactions be linearly ordered but do something smarter so that we can get to the end state of that long list of transactions um get to that same end State as if we'd executed serially while doing something smarter um and so parallel execution is actually a very simple algorithm um there there's some fancy names like optimis concurrency control or software trans actional memory but I think the thing I want everyone to know is that the actual algorithm is something that is just very intuitive that we all kind of intuitively understand I'll walk through it right now just doing the intuitive thing so basically um really fast optimistic parallel execution is the idea of running many transactions in parallel as if they were starting from the same starting point and generating a bunch of pending results and each of those pending results is a list of the inputs and outputs for that transaction um and so we generate a bunch of pending results all at the same time while running a bunch of transactions in parallel and then we step through those pending results in the original order of the transactions and for each pending result we look at the inputs and if those inputs are unchanged since the point when they were executed we just commit that pending result and if they've change then we go reexecute so I think maybe to give to help understand this a little bit better want to do a really simple example so imagine that you know we have five transactions so just the serial way would just be doing them one after another all in the same core and the smarter thing is to run them on separate cores and as soon as a core frees up then start you know doing another transaction so we generate some pending results from this algorithm and so let's take an example let's say that the first let's say there's five transactions that we'll focus actually three transactions we'll focus on so the first one is me sending Alice 100 usdc the second one is Kobe minting an nft something totally unrelated to my usdc and then the third one is me sending Bob 100 usdc so we run these three transactions in parallel oh and sorry one thing I should have said before is that say that the starting state is that I have a th000 usdc and Bob and Alice both have zero usdc in their account okay so we'll go through this example so in parallel execution what happens is we run all these transactions in parallel um and you can see that we actually get some bad results so in particular you look at transaction one's pending result um it starts with an input of me at a th and ends with me at 900 which is correct but then if you look at transaction three's pending result it also started with me at a th000 and ends with me at 900 which is of course wrong so but we generate these pending results and we're going to sort of deal with any conf a little bit later um so we'll step through these pending results the first one which starts with me at a00 goes to me at 900 and starts with Alice at zero and goes to Alice at 100 this is totally fine we can accept this one the second one is totally unrelated stuff so this is fine we can accept this one and the third one is bad because it had a bad input relative to what our new view of the state of the world is which is 900 usdc for me so we need to go reschedule this work um you know we're just going to go and reexecute transaction 3 on whatever the most free core is and the thing emphasize here is that this re-execution is actually very cheap because the store the state that was needed for this transaction is already in memory and almost all of the execution costs are actually just reading state from um from SSD so because the state is in memory it's very fast to reexecute okay so when we reexecute now the input is me at 900 and the output is me at 800 so this is now correct so now we can accept this and then just keep moving onward so just to emphasize um that's the end of the example by the way like that's literally all that this algorithm is it's not anything crazy it's just the intuitive thing so just to emphasize running many transactions in parallel generating pending results keeping track of the inputs and outputs for each one committing them in the same order that they were originally defined in and re-executing if we needed and just to emphasize every single transaction in this algorithm will end up getting executed at most twice like once during the parallel run and then maybe once if it needs to be re executed all right so the most common question that we actually get with respect to this algorithm is what happens if there's a whole bunch of transactions that all have sort of like serially dependent state so for example if I send a 100 transactions of me sending usdc to different people then clearly these are all going to be serially dependent so we're going to have to reexecute transaction 2 through 100 again um and so it's actually not a big deal and the reason why this is NBD is because the first execution is pulling those state dependencies from SSD into cach and then once we do that then all of the other executions are going to be quite cheap the second execution is fast because the state is cached um so you can think of optimistic parallel execution as two phases where the first one is running many transactions in parallel this is slow but it's in parallels we're doing many many transactions worth of work pulling many transaction worth of State in um and then the second stage is fast because we already have all the dependencies in cash so all this is dependent on one very CR problem which is that we need to be able to pull a lot of state from the SSD in parallel during that parallel stage so this is actually a perfect perfect transition for the third and final part of monad that I want to talk about which is parallel State access so I'm going to pause here for a second because I feel like I've given a lot you know sort of like a wall of information i' just stop and think for a second about the world that we live in and how advanced Hardware is now like we all know that gpus are incredibly powerful they've enabled like a revolution in terms of machine learning the same thing is actually true in terms of ssds ssds are extremely powerful um and they're very cheap you can buy a 2 terb SSD with really high um iops so high number of I IO operations per second about a million eye operations per second for about $200 it's really cheap basically you can think of ssds as being big cheap sources of storage that actually are a bottle with a really big wide bottleneck um so there's a lot of bandwidth to ssds the only problem is you need software that can actually take advantage of this really wide bottleneck it's really important to saturate that wide bottleneck that's out there and the problem is that in ethereum clients right now they really don't use this bottleneck well at all um I I should say neck of the bottle rather than the bottleneck actually because it sounds like a a blocker so ethereum lives in a Merkel Patricia tree and then that Merle Patricia Tree in most clients is embedded inside of another database in the case of go ethereum it's level DB or Pebble DB um and then both of those databases actually use another tree structure under the hood so for those of you who are familiar with the Merkel Patricia tree you know that you know there's like data that's stored at the bottom of the tree in leaf nodes and to Traverse to any of those nodes you have to Traverse all the way through the tree and the problem is that because each of those nodes is stored in another tree structure under the hood there's like a second look up into a tree that's happening for each no that you visit so you're kind of doing like a quadratic amount of work to navigate down to one node this is suboptimal this data structure is embedded in another data structure um and so this means that there's a lot of sequential lookups um I believe that to look up one value inside a Merkel tree that's stored inside of level DB or Pebble DB um it's about 50 sequential operations it's 50 sequential operations just to go get that one value and so you can imagine that this means that it's really slow to access data from the SSD in a normal ethereum client so how did we solve this problem we introduced a custom database called monad DB um this is a custom state store that stores Merkel Patricia Tree natively on SSD this avoids this read amplification problem um that I mentioned before where we're kind of like doing a quadratic lookup um instead we're just directly navigating to a node in the Merkel Tree in addition we have support for ASN IO using iur ring um and we also bypass the file system for additional improvements just in general this is a really efficient way to access data and that allows many transactions running in parallel to all read from the database effectively in parallel thus enabling parallel execution to be performant all right so just to give a recap monad is a highperformance evm layer one um and the reason why this is important is because enables decentralization plus performance anyone should be able to run a monad node with minimal Ram requirements it doesn't rely on a lot of memory because of monad DB which is allowing the SSD to be utilized much more efficiently and monad is able to accomplish this through these couple of architectural software improvements rather than relying on Hardware so lastly I just wanted to say a couple of words on why this matters this matters because all of us here understand the transformative power of decentralized currency and decentralized applications but we need to actually scale those to hundreds of millions of users so if you think about you know just doing some very simple math 100 million daily active users doing TR 10 transactions per user per day is a billion transactions per day I always like to talk in transactions per day because I think you can reason more clearly from more of like a traditional Tech perspective Ive um yeah 100 million daus is like not crazy that's not a crazy level of adoption but that would correspond a billion transactions per day which is 10,000 TPS so you know all of our our goals here I think at the conference is to see the adoption of cryptocurrency more widely help crypto apps eat the world and we need better infrastructure in order to Able in order to be able to do that um thanks so much guys appreciate it
Automatic transcript — names and jargon may be misspelled.