Breaking the I/O Bottleneck for Blockchains with Small Authentication Large Trie

ETHBoston 2025 · 12 Sept 2025 · 20:07

Lei Yang of MegaETH presents Small Authentication, Large Trie, a hybrid data structure for authenticated storage and state commitments. He explains how replacing sparse lower trie layers with hash-table buckets can reduce random disk access and improve memory efficiency in blockchain systems.

Speakers

Topics

From ETHBoston 2025, hosted by ETHBoston.

Transcript

All right. Um, yeah, thanks for the for the  introduction. It's very nice to be uh to be back at MIT to talk about some uh researchy stuff we uh  just uh uh produced at Mega ETH. Um, by the way, Mega ETH is a um super fast Ethereum rollup  uh layer 2. Um, so the the core like feature is what we call real-timeness. ically um we want  to mimic the the level of VA 2 performance like um sub millisecond transaction latency and up  to 10,000 transactions per second in terms of throughput. Um but this talk I think is kind of  standalone. It's not really just about mega. It's a primitive that would be very useful for for  whatever um blockchain that still hopes to get some what we call state commitments. ically um  Merkel try roots um state roots in Ethereum or

this um Merkel commitment of all the unspent uh  UTXOs in Bitcoin. to this kind of stuff. Um yeah, so it's a it's a very long title. Um I'll just  shorten it to small authentication large try. This is what this is the name of the data of the data  structure that we developed and it's also kind of the the sense of the protocol of the of the of  the scheme. Basically you want to capture a large amount of data with a very small authenticating  uh authentication structure. So um so first um what is a um authentication structure? what is the  the primitive that we're working on. So we call it um the authenticated key value storage and yeah  I think people in uh in different communities like cryptographers they they call it um like  authenticated database I think system people

they call it um authenticated key value storage.  So basically it's it's just a mergry right. So you have a bunch of key value pairs for example your  um your account balances in Ethereum or um your your unspent UTXOs in Bitcoin whatever right you  but you want to capture um so for example Alice has $10 and um you want to compute a commitment  think of it as a as a hash um of these key value pairs of these individual elements of information  and um the commitment is useful because um you can generate a proof very efficiently and also  verify the proof very efficiently then that some particular um key value pair or some particular  like data element belongs to the commitment in

the sense that say I tell you that uh the current  state of Ethereum is captured by this commitment 0x that beef and then I can very succinctly prove  to you that my my balance for example I'm Alice my balance is $10 with just a very short amount of  data. So this is why why it's useful, right? It's basically what uh Merkel try uh allows you to do  and um yes so these kind of data structures they also allow you to update those uh state elements.  For example, Alice balance increased by uh by $10 and you can accordingly increase the commitment  to to reflect what's the the current state.

So why why why is this interesting, right? It's  interesting because it's by far the most important performance bottleneck on Ethereum or or any like  similar blockchain that still hopes to uh to uh to produce a up-to-date state commitment in real  time. So what I'm showing here is um um the like throughput or I should say the the amount of time  for you to um process a bunch of um historical Ethereum transa historical Ethereum blocks from  the Ethereum mainet on a machine with a relatively uh recent version of Wrath the currently um  leading edge um state u sorry Ethereum execution client. So basically what you're doing is you are  rerunning those Ethereum blocks updating the state

roots and also doing other things in real time  and uh then we're measuring the amount of time it takes for you to finish the process. So the  time is basically a metric for how performant this process is and uh by the way we also vary the  amount of memory available to the server just to test different scenarios. So here the green bar  the green section of the bars is the amount of time taken by those um reexecution processes  to update and maintain the state roots or to update and maintain the state commitments of those  authenticated uh key stoages. So you can find you can see that in um the ideal case where we have  like virtually an infinite amount of memory for you to use um maintaining the commitment takes  five times seven six amount of time than it took

um the process to actually run the transactions.  So basically you execute a transaction that you spend almost six times longer to u do all the  maintenance work on the state commitments which is arguably not useful work if you only care  about like transaction TPS right and um the issue worsens to nine almost 10x uh when you have  a limited amount of memory which is usually the uh the realistic case so um it's pretty tough  because sorry um yes it's pretty tough because um that basically says Hey, I want to build a really  fast blockchain and uh I it basically says that um if we uh don't worry about this um authenticated  key value storage, if we don't worry about like updating the commitment, then um it seems that  the best we can do is to remove the the purple

section and the the the blue section and at most  we kind of get a 10% improvement because we're not addressing the like the elephant in the room.  So this is really an very uh important problem and the reason that Merkel position tries or the  standard uh state authentication like uh key value storage used by Ethereum or most uh blockchains  is because they generate a ton of um random disk ios when you try to update them. So what you see  here is each node in um this Merkel Patricia try data structure is the hash of its children. So um  and also um the tree is structured in the sense that if you follow the path so each edge in the  path each edge in the tree has a u like a label a

segment of your key or of your address associated  with it. So if you go from the root and uh if you traverse the path that reconstructs your say your  wallet address then that's how that's basically the the list of nodes the list of internal nodes  that you have out that you have to update when you update your uh when you update your key. So  basically when you update your key you you have to kind of propagate all the changes back to the root  because they are all hashes. You you touch it you have to touch all the all the nodes in the middle.  Um and uh this generates a ton of um random disk ios and uh worse still it's sequential. So you  cannot even like do it at first and uh um and then hope to do all the remaining updates in  parallel. It's impossible. You have to do it

sequentially and it kills performance on more than  an SSD which has a ton of IOPS or IO's per second when you do them in parallel but not too much  when you do them in sequence in a sequential way. Um so this is why um Merkel position tries or the  like the state-of-the-art um or at least like the status quo data structures are not very ideal when  it comes to um speeding up updates or speeding speeding up like updates to commitments. Um but um  they also have some nice properties. For example, they are what we call historical history  independent in the sense that the state root is a pure function. pure function meaning  that there's nothing else like involved in the computation but of the actual state elements that  you want to capture like the account balances also

um Merkel partition tries are easy to maintain  um in the sense that it does not really burn a lot of CPUs or or memory or disk space or a  lot of bandwidth so um the wish list for us is to keep the nice properties of Merkel petition  tries but try to minimize the disio because this is what makes like updating state rules 10x slower  than executing transactions on Ethereum. Um so a crazy idea here is hey can we store the entire try  the entire merric try or whatever data structure in unreasonable amount of memory because if we can  fit everything in the memory then there's not like there's no bottleneck from like the sequential  dis IO's right we kind of skip you kind of get

around this um IO random IO issue um altogether  um so to to see if that is actually feasible able um there's a very important metric which is the  amount of data you have to store for um per state element you want to commit to in the sense so  we have heard of this um state bloat issue right Ethereum state is keep keeps expanding and it's  going to say 10x in the next say three years and uh with that it seems that the try the size  of the state uh commitment data structure the size of the um authenticated key value storage  will also expand 10 by 10x and at some point you cannot fit it in the main memory anymore. For now  it's possible. It's about say 100 gigabytes but

uh very soon it it may not be possible anymore.  So the the key metric we we optimize here is that we want to commit to an everexpanding a large  amount of um state elements or accounts or UTXOs with a relatively small like auxiliary data data  structure. the authenticated key value storage. We want to minimize the amvertised cost of this  authenticated key value storage data structure per state element that we uh commit to. So let's take  a look at how um Ethereum Merco Patricia try a fares. So in this case um record patricia try has  um about 16 exactly 16 uh children per node and um the number of levels in this data structure or  how large or how tall this data structure will be

is roughly the number of nodes or the number of  um state elements you capture divided by um yeah divided by uh your your depth sorry your your your  width uh which is r Sorry, I think there's some uh formatting issue. Um but basically in the ideal  case actually to capture say 1.5 billion uh keys or 1.5 billion addresses you only need about 3.2  gigabytes which seems nice but again this is the ideal case. in the realistic case because um there  is something which we call sparsity in Merkel producer choice that makes the actual like um that  makes the actual data size of Merkel petric much larger than this ideal case. So um in particular  we found that when you go deeper and deeper into

this Merkel Patricia try um there are fewer nodes  or each node has fewer children and um when a node has less than 16 which is the optimal the maximum  number of children it has it can like capture a smaller number of children right by definition.  And because each node is like managing a smaller number of children, if you ultimately want to  handle the same number of um accounts or um nodes in the bottom layer, you have to add more nodes in  the in the in the in the middle because like yeah, it's because each node has less children, right?  Each node is managing a fewer each node is not doing each internal node is not doing its best um  capturing the hashes of its children. So you have

to use more of them and uh that in that expands  that kind of inflates the the number of internal nodes and uh um yeah the the size of the tree  just expands and here is some theory and some um experimental data. So the the the points are  from our experiments and the curve is derived by some theory and um the optimal case is the  uh the black curve which is on the bottom and uh the realistic case is the the green curve  here. Um and you can see that there's almost a um eight times difference from optimality to  um to the reality. And um yeah in Ethereum's current size 1.5 billion uh keys you need almost  17 gigabytes to fit all those internal nodes.

It's just internal nodes. So um there has always  been a proposal of say um vertical tries where the essense is basically you expand the like  the width of the tree to make it fatter but um um shallower and in theory that should help  you um reducing the the number of internal nodes but it seems that because of the same issue  because of the sparity the the like like the the effective is limited and from the optimality  which is the black curve vertical tries Um, basically 256 array radics tries they they don't  do so well either. And uh we can even that and we even proved in theory that even if you just keep  expanding like the width of the tree to make it to compact it to make it even shallower and shallower  um you only achieve so much. So um the purple

curve is the uh the average case at different  arity or at different like width of the tree and uh the vertical bar the the y-axis is the uh  the size of the um data structure divided by the number of keys basically the per key per account  overhead when you want to authenticate them. Um this reduction stops at some point even if you  keep increasing the arity and the trend actually goes and just goes horizontally where um the uh  optimal case which is to use a complete perfect um balanced tree um you get the the like you keep  getting um effectiveness as you increase the so it just says that just blindly expanding the width  of the tree does not really help. So um the so

what we have uh learned so far is that we want to  minimize the disk IO when you um uh like commit to and when you update the state state commitments  of your blockchain. And um the idea to circumvent this random disio issue is to fit the entire  authentication data structure in the main memory. And um the key metric we optimize for is to reduce  the amount of overhead in terms of bytes per um state element committed or per address or  per key um to a minimum. And the challenge here is that you've just blindly follow the like what  traditional um algorithm or data structure people tell you which is to expand the width of the tree  you hit a block which is sparsity and that kind

of limits how much you gain from uh from these  protocols from these schemes. So what we did is we found that actually there is a trick that can take  which are not elaborate. Um but basically what we learned was that a perfect data structure  should be heterogeneous in the sense that um you should divide your data structure into two  parts. want a static main try which is complete. Basically what computer scientists are hoping  for um in the sense that all the nodes inside this static main try is complete and has all the  children it it should have um filled with and then you replace the bottom layer which is plagued  by sparity with hashts. Hashts are nice because

um they deal with sparity very gracefully. they  they don't really like expand in number of layers. you just you just resize the you just resize the  hashts and um um it can accommodate a different number of um elements fit inside um without  really incurring extra extra work basically that's the way I would I would summarize and um so  this is basically our um data structure we have a um main um try which is complete and uh shallow um  no no spaces being left no space has been wasted because it's complete. It's it only covers the the  top layers which is not plagued by sparity. And um yes and um then we have the buckets which are  hash tables instead of sub trees. Um these

layers usually in um regular in normal trees in  normal MPTs they are plagued by sparity but but yeah hashts are are immune to that and um you just  like fuse them together you get a very nice data structure. I will um skip through the process  of using this data structure but you ultimately get a very nice data structure that outperforms  Merkel Patricia tric or any form any variant of it um by uh almost um 16x. So here again I'm showing  the reality with Merkel Patricia choice which is the blue curve um the purple curve which is  Merkel choice in theory and the optimality um which is complete trees which is the like the  dream of every computer scientist but if you look

at our data structure which we call ST um it kind  of approximates it approaches the optimality when the number of keys is large enough and here it's  about um 10 billion ion. Um so basically in the in the case where we actually care about which is  about 10 billion um accounts um you and also going going from that beyond um we approach what you  can do um optimally with those um authenticated key value storage data structures. Um yes and  we uh did a bunch of we yeah we actually took an implementation in our test net and we did a  bunch of uh tests and uh it shows that um the new data structure completely um gets us around  this random disk io um bottleneck and the IO

bottleneck is no longer a an issue for us and u it  has slightly increased computation cost compared to Merkel partic but it's manageable and uh it's  paralyzable. So if you just throw more CPU cores, which is very easy to do, relatively easy to  do, um you get to higher throughput. And um we also compared it with um a few other um recent  works on solving the same problem. QMDB from um I think layer zero and noomt I think from  solving labs. Um and we found that our performance um is better than theirs um at a cost of  slightly again increased CPU consumption, but again CPUs are cheap. disk IO is very hard to  scale. So this is kind of the approach that we're taking and um yes so um short on time so I'll just  pause here. Um it's been live since day one of me

testn net um this March and uh we're going to  ship it in mainet very soon. [Applause] Yeah. Um if there's a Q&A session I can take a few  questions uh on the stage or offline. Yeah. Uhhuh. Oh, I didn't say what date  uh we are shipping, but yeah, it's a nice question. Very, very soon. Yeah. Thank you.