New Ethereum talks, every Monday. The week's conference uploads by event, in your inbox.

Loading player…

Sszb: A High Performance SSZ Implementation in Rust by Ghilia Weldesselasie | Devcon SEA

DevconTue, Oct 7, 2025, 12:00 AM

This talk goes over my EPF project for the SSZ ecosystem: - a benchmarking suite for the various rust SSZ implementations in the ecosystem to properly evaluate performance and point developers to which library they should use. - a high performance ssz implementation that's faster than existing libraries in the ecosystem Speaker(s): Ghilia Weldesselasie Skill level: Intermediate Track: [CLS] EPF Day Keywords: Core, Protocol Follow us: https://twitter.com/efdevcon, https://twitter.com/ethereum, https://warpcast.com/devcon Learn more about devcon: https://www.devcon.org/ Learn more about ethereum: https://ethereum.org/ Visit the https://archive.devcon.org/ to gain access to the entire library of Devcon talks with the ease of filtering, playlists, personalized suggestions, decentralized access on Swarm, IPFS and more. Devcon is the Ethereum conference for developers, researchers, thinkers, and makers. Devcon SEA was held in Bangkok, Thailand on Nov 12 - Nov 15, 2024. Devcon is organized and presented by the Ethereum Foundation. To find out more, please visit https://ethereum.foundation/

Transcript

Um, hello. My name is Giliam. I'm here to present my work on SSZ a high performance SSZ implementation in Rust as well as my work on SSZ Arena a benchmarking suite for the crates in the Rust ecosystem. Um, my motivation for working on this project was uh having a chance to work on optimizing an existing project uh which I haven't done before and so I learned a lot in doing this as well as um seeing what kind of gains were possible in something like SSZ. It's not a real bottleneck in uh clients today.

It's still a a fairly simple task but I was curious about what kind of losses were present over a long period of time uh if without a an optimized implementation and so I thought this work was uh very uh appropriate for the fellowship because it's I guess lower priority for client teams but still work that needs to be done. So um I'm briefly going to going to talk about what serialization is in SSZ and go over the SSZ ecosystem as well as my work on the benchmarking suite and the implementation finally talking about performance and next steps. So zooming past these first few slides, serialization is a process of transforming a data structure into a common format that uh the different clients can agree on. Which is uh important for consensus. Uh normally, data structures can't be transmitted as is because of different in-memory representations and such.

SSZ is the serialization scheme on Ethereum 2 meant to replace RLP on the execution layer. Uh it has a few improvements like uh schemas which are a must-have in a performance system. And merklization is the process in which we generate a short uh digest of the state um while allowing for updates without rehashing the entire state. Uh this is useful to generate small proofs of uh the contents inside a beacon block for light clients that don't want to hold too much state data. So, uh there are a few SSZ implementations uh in the ecosystem, mainly in Go.

Uh fast SSZ is uh most popular one and used in geth today, although Peter also has an implementation out. Uh in Rust specifically, there's Sigma Prime's uh Ethereum SSZ, Grandine's crate, which isn't public and is only used internally, and Alex Stokes's crate SSZ RS. Uh for the first half of the fellowship, I worked on a benchmarking seat to evaluate how these libraries perform against each other. Uh most of these crates have tests on consensus spec tests, uh but there's no real way to see how they perform on real data like beacon blocks and beacon states. Uh So, I worked on a uh library or not library, a project called SSZ Arena, which uh benchmarks the different crates in the ecosystem.

And so, it evaluates it on more controlled test cases like lists of uh integers and validators, validator structs, and also evaluates it on blockchain data like beacon blocks and beacon state that I obtained from a uh beacon chain checkpoint. So, I leverage criterion for the this benchmark suite, which gives us handy reports, but I also use uh another uh benchmarking library called uh Divan, which handily gives us allocation stats, so you can see how much memory is being allocated during these uh encoding and decoding runs. And so, this this gives us a robust way to measure performance. Now, onto the second half of my work in the fellowship, working on my own implementation. So, how does one optimize SSZ?

Optimizing this uh serialization scheme and benchmarking is kind of tricky because most the real bottleneck or um most of the optimization in encoding decoding is simply using a more optimal data structure. There's a lot of techniques you can do to optimize this. You can lay out your data in memory. So, uh it's aligned to the word boundaries. And the other uh techniques like zero copy deserialization where you can simply cast your bytes into your type.

That's only really possible when you have control of the end of underlying data structures. Um which I did not have for this project. And there's a lot of reasons why you might not want to just rewrite your types with serialization in mind. Um Sigma prime particular has done a lot of good work with their uh Millhouse crate, which um allows for faster uh s- sparse updates of beacon state. And so, it doesn't really make sense to just change your type that create just to speed up serialization.

It's better to just think about how to work with uh the types we have. And so, being constrained by the inability to change the underlying data structure, I opted to minimize intermediate allocations. And so, another a second bottleneck in serialization is how much memory are you allocating in between steps to serialize and deserialize. And so, here's how I went about my implementation. SSZ has has two main differences.

It uh uses the buff and buff mute traits. This is an abstraction over uh buffer types, so it encapsulates both vectors and slices. And has the added benefit of abstracting offset accounting, which greatly simplifies the implementation. So, for context, you can outright define how to encode and decode certain types, but the SSZ B package also provides a macro for automatically generating implementations for container types, which are like structs. Um And so, generating this these implementations is a hassle.

We um provide a way to do this automatically, and the implementation for it is very simple, thanks to the buff mute traits. And second, we avoid a lot of intermediate state during the encoding process and minimize any needed allocations during the decoding steps. Uh this reduces the number and size of memory allocations needed to perform serialization, which is another dominant cost, as I mentioned before. Um Peter's go implementation uh SSZ implementation does this, and Grandine was also another big inspiration. Although, to note, Grandine only works with slices.

Uh the benefit of using buff and buff mute is being able to use vectors and any other buffer implementation you want to provide, as long as you implement the trait. Which not quite sure how it's going to be used just yet, but could be handy. And it performs pretty well, so I tested this on beacon block decoding and encoding, it's pretty pretty fast on the the decoding part. If you'll consult the graph, I'm not quite sure how visible it is, but um it's clocking in at around 129 milli- uh microseconds on the decoding part versus 3 milliseconds um in Ethereum SSZ. And while the differences aren't as drastic for uh all types, we're getting uh there's similar levels of performance um around 85% uh encoding speed up and 95 decoding speed up on the beacon blocks.

Uh um So, that that was for the beacon blocks. There's still some changes to be made, some fixes to be made for uh beacon state encoding and decoding. I know that uh I there's a bug in the implementation. I know where it is. I'm going to go fix it, but I only found it like 2 hours ago, so uh didn't really have time to fix that today.

Uh as for next steps, I want to ship a uh support for merklization and Merkle proofs with generalized indices. This is needed to have a full-fledged SSZ implementation. My focus for this fellowship was on performance of encoding decoding, and so I left this for after the cohort. Additionally, I'd like to support uh a new trait I call SSZ check, which provides uh early input validation for to check that a an input conforms to a certain type. This would be useful if you want to reject malformed inputs earlier instead of having a full decoding step in the hot path of your application.

Uh And then after that, stable release. I want to gear up for write a stable release adding usage docs and cleaning up anything that needs to be uh polished in the library. And then once that's done, I want to work on something I find interesting, but I'm not sure if other projects would want to use this, but I think it'd be cool to have support for partial encoding and uh decoding. For example, for large objects like beacon state, fully decoding can be very expensive. And so, partial decoding would drastically speed things up, especially if you only need a subfield of your beacon state.

And uh re-encoding and rehashing would work similarly. Again, with the Sigma Prime's Millhouse implementation, they're already implementing their types with uh sparse updates in mind. And I think uh SSC could use uh some similar ideas with regards to sparse updates. I'm a little over time. Uh I want to thank my uh mentor, Michael Sproul from Sigma Prime, who did uh most of the work, I believe, on uh Ethereum SSC.

He's not at Devcon, uh I think. Um but if you're watching this, thank you. And I also want to thank uh Josh and Mario for um providing the opportunity. I learned a lot through the cohort. And uh I'm glad I got the chance to do this work.

Um any questions? That's all for me. Yeah. All right. Any questions about the SSD library?

Is it ready for clients to switch over to? Uh not right away. Probably after stable release. I forgot to mention also that there's no unsafe code in this, so it's uh Michael told me not to use that. Yeah.

Um Coming soon. Yep, coming soon. All right, one more time for Gilia.

Automatic transcript — names and jargon may be misspelled.