SSZ Execution Blocks (EIP-7807) for Geth

Devcon 8 · 4 Nov 2026 · 13:18

Ethereum Protocol Fellow Vivek Singh Solanki presents a shared SSZ engine for Geth, replacing the four different hashing methods spread across the codebase. The talk covers encoding, merkleization, progressive types that keep proof positions stable across forks and compact proofs for SSZ execution blocks, then turns to plug-in API work for Besu.

Speakers

Topics

From Devcon 8, hosted by Ethereum Foundation.

Transcript

[music] And for EPF I've been working on SSG execution blocks that is EIP707 in along alongside this I've been also working on one project in Basu that is about designing the plug-in API. I'll talk about this in later slides. So let's talk about the SSD blocks first. So what SSD changes about a block like it's all about proofs right right now we take the header fields we RLB code them uh into one blob and cect that so that particular hash proves proves the whole block but it does not prove anything inside it so let's say you have to prove

a receipt either you have to completely re-execute it or or you have to tell the RPC provider so what uh the AIP707 changes is that it uh uh so every field in SSG container the every field becomes a leaf of a mercy tree. So it's easy to prove any particular leaf position with just few pro few few hundred bytes and since the types are progressive. So if let's say in a certain fog the positions uh the uh new elements have been added the position does not change and the thing like the positions remain stable. So the proof does not break right.

So when I started uh Jad was that has no SSD of its own. They were uh hashing SSD files like SSD thing through four different methods like they were using for error files they were using fast SSG for Litecoin they were using Zet and they handwritten mercury T for two beacon types with hardly positions and their own verifier. So like I'll take you through the journey like what I did first and what next. So I've divided the work into two parts. First was the handdrawn SSG engine which which is what we get and and the second part was the main EIP work that is about the block. So yeah, so first work was to get the serialization and merization thing like basically the decoding and encoding

part. Basically the serializing is about like converting the get types get types to the SSG and getting them back. And the merization part basically this is the way SSG gives value SSG gives identity to it value like you basically convert the bite into two bytes into 32 byt chunks and h them pair wise up as a binary tree and the root becomes the HT root. And then comes the progressive types uh that comes with the EIP 7916 uh which is our progressive list and EIP 7495 that is our progressive containers like uh the issue with uh the pig size list is that let's say if if you add few elements uh let's say in a new new fork

you add new few elements so the every position of the letter elements changes and every existing proofs break. So with uh with uh the progressive list uh it grows in the form of a sub tree in the size of 1 4 16 and 64 and so on. So let's say if the element three is taken at the second position it will be in the three for the lifetime like the existing proof will not break right. Then after this I went on building the general indices and single leaf proofs like I'll take example let's say you have to prove a leaf 11. I'll ask a full node for the leaf 11. So it will hand me over just the this is just his siblings.

So let's say I already have the root of the position one. So I can just hash that 11 and 10. I'll get the root five. I'll hash five and four. I get the root two. I'll hash two and three. I'll get the root of the uh uh t root. And if that it matches with the root that I already tr that means the received is inside the block. So it's easy to prove right. Uh then comes the block part which is the main EIP for this. Uh these are all the LT fields uh fields uh shown in the order. Out of this the three are progressive list and like right now the blog is a header and the body right in SSG we put the both into one SSG container and every field is a leaf of a

mercury tree and every list is also a separate mercury tree. So every position in lift as well has a part to the uh root of to the block hash of the to the root of like to the block hash uh up the way right so about testing uh it was done in three parts three parts first comes the official spec vectors that covers uh that has around 4600 cases which is about classic and progressive types and it covers projectile bit list all the stuff and I picked up few roots from argon work from Jack and someone some roots from breath as well and then then the at the bottom at the bottom is the

GL gon blocks like I've created some block from G on block producers and then I've used Python spec reference uh reference script to generate few roots and I've compared them uh to to see if the things are working right yeah like the current status uh I open the issue Then I got the review late from the get team. So initially Marius was interested but then the EIP was DFI so it was not included. So uh I've uh uh so the other the maintainers like Gary and let told key they'll not merge it and I asked Eton for the reviews right so what I've did

key I moved all the stuff into one upstream PR that is all the work that I have done and the many PRs uh are in my fork right now so let's talk the let's talk about the other project like this was the industry one I was focusing more on this this was in Basu Right. So, Basu has a plug-in API. So, the Basu thing is that uh you can extend it without forking it. So, uh the thing is the plug-in API is not something aside feature. The whole line is using the plug-in API for his work and it has it has a a lot of uh plugins that are completely built on the plug-in API and a lot of production uh uh plugins depend on API being good. But

over time the API has grown into a one single jar like it started in 2019 and it it has grown into a one single jar that is around 112 types and it has no like the documentation was not not proper. So we have decided to like after exploring a lot of open source project like we went through a lot of open source project that has uh that that has been maintaining their own plugins and their own plug-in API and then we decided to break down this particular jar into four feature modules like if I talk about the issues uh I have uh broken down down them into three parts first comes that every other plug-in

whether it is small or something like let's say I want to publish a matic It has to depend on the EVM because there was a leak or we have a just one particular jar. So EVM is you know there's the highest turn part of the codebase like it changes with every fork. So let's we cannot cannot uh like promise stability even to a small plug-in. Then second problem was that uh the life cycle was not designed in a way that you can know key at what particular phase what particular service is available. Let's say uh you ask a service at the registration phase but it is not completely completely initialized. Uh the bas will hand over the service to you but when you try to access the fields in it you'll get a

null null pointer. So like the plugins has to do a lot of uh checks and a lot of workound to go to solve all these problems. And the other issue was about versioning. Uh the plug-in API version is tightly coupled with Basu. Let's say you have some changes in basu and there are no change in the plug-in API and still there is a new release for the basu you have to bump the one for the plug-in API as well but the jar is completely bite to bite identical so it says nothing to the plug-in authors whether the changes are breaking or minary or it's just a patch so we have done the work into three phases basically the first one was breaking the the whole big plug-in API

jar into per modules leaving near the implementations. So as I took the example of the like RPC uh metric plug-in. So uh let's say if to publish a metric you just have to depend on the core and the RPC module and not be depending on the EVM stuff and the other jars. So you this promises the stability and don't you don't have to bump the versions uh with every new update in any other particular plug-in API plug-in API feature module API. So the issue was key this approach looks good on paper but what if it doesn't work out uh the way we are thinking in Basu. So uh we will have to introduce we

have to do all this work without breaking anything for the plug-in authors. So we decided that uh from the centralized plug-in API we'll move the types into smaller modules but we'll not change the package names. So the imports are import statements are exactly same and we'll keep exporting all the smaller smaller modules to the plug-in API. So the things are b identical for the plug-in authors like and to make to ensure that we does not slip uh we do we do not slip breaking changes to like through the human reviews. So we place the ICMP uh tool in place. It basically compares the jar before and after your changes. If the things are bite and source uh source identical uh the CI passes if

it's not you'll get a error and you have to fix it. So yeah for the life cycle the idea was key uh if a service comp is the service is available at a particular if a service compi compiles it should be available at a particular phase. So to make sure this uh we have done around seven refinements. So out of this the four four or five refinements are already merged. We are working on the two refinements. If I talk about this particular this is the biggest one like it's about key let's say if you're in a uh registration phase and you're trying to access a service if it's not available at the particular phase it will not compile. But before it used to

be like you'll get the service but it's an empty object of no use and you'll get null pointer exceptions. Yeah, like what the current state uh we have around 30 mer request merge pool requests around this project in the like they already merge on the main like 23 hours on the main and seven on the plug-in API refactor branch that we have been working on and I've opened a lot of issues because uh it has a lot of deferred work to be done after uh the whole series ends like what we have decided that we'll introduce all the breaking changes at once during So all those work uh is saved as deferred issue in BU repo to be done

after glaman and after this uh the next goals is to finish the life cycle series and the all the refinements and then we have to decide that we'll uh what versioning we'll use for the plug-in API whether it will be caliber or we have to change to sar versioning calver is more like calendar versioning you based on the year and the month you have been changing the plug-in API and sar is more like it show tells you whether it's a major change a minor change or it's a patchwork like thank you like thank you eon for the SSG SSG project and special thank to Fabio for the bas projects he's been a great

mentor so far yeah thank >> [applause] >> do. Okay, thank you so much VC. Yeah, awesome. Any questions, any thoughts, any comments? We have time. We are actually ahead of time this time. I can believe that. That's the first time it happened at EPF day. That's really awesome. Not really. Thanks for adearing to the time schedule. Uh folks, any thoughts? Any questions? Ethan, go ahead. Yeah. Um that's a question for the 787 SSC block headers. Um last year Tamagna tried this in Nimbus. Um and the spec

has evolved since like for example we got these progressive data types >> like but it still points to Electra. We have three list progressive list. >> Okay. So so you did this like based on the >> I got an error when I compared to the Python reference script. So I have to switch to Electra. >> Okay. Okay. Yeah. Yeah, that makes sense. >> Thank you. >> Thanks. [music]