SSZ Transactions Breakout

SSZ Breakout · 15 Feb 2023 · 42:09

SSZ Transactions Breakout, held on 15 February 2023. These calls cover using SSZ, the serialization format Ethereum's consensus layer uses, in more places across the protocol, including transactions and the Engine API.

Topics

From SSZ Breakout, hosted by Ethereum Foundation.

Transcript

okay um so SSD breakout room um I think high level the thing we need to figure out here is how do we move forward uh how do we move forward with this yeah and and basically uh you know do we want and and when I guess we do it if uh we decide to move to SSD yeah I don't know Ethan do you want to maybe take a minute or two and like sort of recap both your proposal and vitalics and we can go from there

sure so this all um started kind of by me and vitalik at the same time roughly uh sorry okay um so we both started um to push for moving towards Merkel Patricia trees in the execution block header to SSC um vitalik made this post that I just linked where he essentially um discusses a way how to achieve this by

creating a SSC Union that has on one end um a selector that tells you what type the transaction originally had and on the other Branch it has a specific type depending on whether it's a 48441559-2930 or a legacy transaction and um that essentially gives you the full design space but it may be challenging to use because these trees are mainly used by light clients on for example smart contract on a different

chain an iot device or yeah some some zero knowledge circuit and for these they don't really tend to care about those specific encoding details they just want to know whether a transaction was sent to a specific contract and whether it was successful and that's why I explored an alternative approach and that's currently eip6404 where instead of using the union I created a super type that's the same way how it's done on Json RPC they have

a general transaction type that can be used to represent any transaction and the advantage here is that regardless of what type it originally was you can access it using the same data structure so I also um created this drawing here where I have the union based approach on the right side and the normalized transaction on the left side just so that we can visually see how how the different transaction types would be represented in both italics and mine approach and this is essentially

the point that we want to discuss whether we want to use a approach based on unions or whether we want to use an approach based on this generalized or normalized transaction thank you yeah I guess does anyone want to sort of make a case strongly for one approach or the other and we can sort of go from there I think the uh the main part of uh my

kid like the main part of my case for unions like it's just the Asia instinctive arguments that it feels more natural like doing it without like doing it with one super object just feels like it's using a functionality for something other than what that function and that functionality is that meant to be used for right because uh like if there are transactions that do have a different types then or if there are objects that have different types and that's just what unions are for and if we try to put everything into one object like it feels like we're shoehorning one thing into a design that's uh in like a design that's really not very well suited for it and

the risk from this sort of stuff is that you know there are unknown unknowns and in the future especially as we're transaction types get added there's a risk that like it might even become more confusing of uh you know what what's actually going on in a in a transaction and I mean like which field should be Asia or like how to keep um changing the scheme to accommodate a larger number of set of things in the future uh so like I'm willing to be convinced towards something closer than like I don't feel you know extremely strongly about this but it just uh like it just feels like it unions are by

defaults the right way to do it and I'm not convinced that some like fairly Niche use cases involving generalized indices are quite like are quite enough to be decisive to push us in the in the other direction especially when um you know the same field in the in a in different types of transactions could possibly even end up having different meetings I think I can make an opposite case which is basically that the union is a more complex construct because it has this open-ended

um property to it where you can keep adding types right and I think that actually works against us in some ways like adding a new transaction type is in I'd call it an extreme option in the sense that we've been at this for five years now and and like we should be getting closer to where we want to be in terms of transactions and at the same time inventing new ones has a big cost for for the whole Community right we're seeing that now with Legacy transactions like we're never ever going to be getting rid of them actually right so because of Hardware wallets because of all kinds of

issues and smart contracts so kind of feel the extends like sure we could be designing for a future where we create lots of transaction types but is that an objective if it's not then the single type is is kind of simple it's very Compact and easy to reason about like from also from an implementation point of view because you remove one form of dynamism and you also remove this case where in your current code you kind of

have to guard against the union taking a branch that you don't understand I think that's fair um as though I think like the thing that's just worth keeping in mind is that uh well so from a compact this point of view actually this is my probably my more substantive objection right the issue is that if you have a union then the type specific overhead is just going to be an extra four bytes but if you have this uh structure where you have one transaction type and it just has a bunch of fields and the average transaction is only using half of the fields then

um that means that we Asia need like you would need to like add an extra 20 bytes into the SSD representation and adjust to a spec like independently specified that all of the different fields are missing um it doesn't affect the network format um it is only for the transactions route transactions wrote In The Block header where the transactions would have to be normalized um but of course um if you would uh later on create a new devp2p that for example uses the normalized types for purpose of

exchanging um the transactions as they are included into a block maybe you could use the SSC format there as well and then I agree that there could be this overhead of maybe an extra 20 bytes or so for um but only for the transactions that do not use all the fields and right now yeah sorry I should but like the average transaction that you is going to use far from all Fields right um currently the average transaction I guess is a 1559 transaction and the overheads for that one would be the extra zero to specify the number of

blob study tests and the list um like the an extra four bytes to indicate the offset of this probe version hashes field so it's an extra eight bytes to represent a 1559 transaction in SSC with this hmm um one other I'm actually can you just remind me one concrete kind of very specific case um so how do um free like eip1559 like Legacy transactions get represented in terms of the gas price and the base fee like where does the facts that they are

pre-1559 yeah get represented in the structure there is a um TX type field that um okay remember still Regional encoding so you can still um recover the original encoding you can recover the originally signed got it and recover the ID got it okay actually I think I am having a TX type definitely makes a decoding cleaner and on the serialization stuff like to be clear like I don't consider my own argument uh necessarily decisive there right because uh like we have compression and voices where data is expensive like Roll-Ups are going to use

compression anyway um and uh you know you can easily custom compress away like you know 20 bytes of uh nothing if that appears all the time in a transaction so I guess I just want to say that I also tend to fall in the union camps or a handful of reasons one I think is very similar as vitalik said to how we think about the transactions even with this unified transaction type we still have the concept of many different types of transactions and yes there are places where we end up normalizing the

transaction into a single message that movie goes through the evm but there are you know a lot of times where we have to deal with transactions on an individual basis dealing with the Legacy transactions and 1559 transactions in the mempool is slightly different just because there is no you know priority fee for legacy transactions we have to make concessions for that we're having discussions about 4844 transactions and whether they should have blobs whether they should not be allowed to not have blobs how to deal with the pool there so I think that we have this situation where we're already dealing with transactions independently of each other and the unified transaction doesn't get away

from that we still have many functions and types related to it that we have to determine okay if it's this type then I calculate the signature in this way Etc so I think for that reason just from a mental bottle it doesn't make as much sense to have the normalized transaction then I also think that the main reason we seem to want this normalized transaction is to have static General indices for all of the values of a transaction and I don't even know if that's a good commitment that we can make because the reality is we don't know what the next five or ten years are going to lead us to and it's very likely that we need to change the transaction

type again we don't necessarily want to do it but I don't think that we can reasonably make the commitments to the community that this General index is not going to change in the future and so if we can't make that commitment then we need you know one to to not have this unified transaction type because we don't get the value that it's trying to provide and two we need to provide another mechanism for getting General indices so we eventually need to have some sort of pre-compile or op code that says I want to access I want the general index for this type and this Fork that that's something that I think needs to exist and I think that's the right way to get General unders is not making a commitment that the general indices won't change well one thing is that

we've kind of avoided the union time because it does represent this complexity where it actually over generalizes because if we do assume that you know we might add one or two transaction types the union is is absolutely Overkill right because it allows for and like forces us developers to think about an infinite number of new transaction types that might appear in in it and at the same time when we do create new transaction types um it's true we might get more wild with them if we have unions but then we also don't we

we don't have to think as much about the existing transactions which means that we're sending a signal to the community basically that you know anything can happen here and like the example I would bring up is like Intel processors which like from 80 86 you know from from 40 years ago they kind of still work um the instruction set is fine like and I think part of their success has been this fantastic record of backwards compatibility and if we now say that all right you know infinite amount of transaction types don't worry guys um that that doesn't

tell a story of ossification or anything or it tells a rather a story of like expecting anything and and if that's what we want indeed like if we want to design for this like uh thousand transaction type the world and then then then then the union makes a lot of sense but it does also create this complexity in the code today and that's how we didn't use it right it's a good point hey give me an I think one thing that might like one thing that we could do is uh go through the same exercise we went through with EOS where we realized that like wait the past we take actually does depend on having like understanding the exact or

at least a probable structure of what changes we're likely to do in the future so here like what future transaction types are we even likely to introduce and I think my answer for this is I can think of a few right so one is uh transaction new transaction types for contract Creations uh so like a transaction being able to directly make a create two possibly something specific to elf code um because of how eof is going to try to ban introspection and so you need to do some more specific stuff um a third would be age transaction type that's designed around account abstraction whenever we get to um like a transforming uh 4337 from

being a nurse in ERC into something that's more enshrined and we need an actual transaction site for user operations um as yeah aside from that um four would be yeah if we go even further on a multi-dimensional gas right so if for example we go and full one and add four dimensions of gas where one is computation and other is witness size a third might be yeah you know data and you know fourth might be like you know storage then transactions might have to have four gas prices and uh maybe yeah maybe four priority fees um and uh something like that right so those are

like how many use cases is that like about four I I don't know if we can think of any more right so I don't know maybe that maybe that can help understand like like what what we're concretely trying to build what future we're currently trying to build around do people have in Asia other future transaction types have in mind I could imagine uh yeah go I guess I just wanted to point out that we can think of it on multiple layers of abstraction as an Ethan is pointing out also on the chat this uh 6404 is only about calculating the transaction root and what representation used for that and we definitely have different representations for

for networking for example for the early acid transactions right we could have different representation I don't know for for Block storing in blocks we could have different representation for engine API it probably doesn't make sense to have that many a different representations but yeah we can think of this as different potential problems and have a solution tailored to to that problem uh still we probably don't want to have too many of those Solutions because it's yeah I I wanted to add one potential use

case which I'm not quite sure about but um a kind of um zcash like transaction where we don't actually reveal some of the information that I think might be a major upheaval but um it's certainly a case that maybe stresses this theory of not wanting to change transactions too much well that one is uh fascinating right because like like that gets into it feels similar to uh erc4337 aggregation where we start talking about like oh you know instead of having a signature for every transaction where we're going to talk about one merged signature for for all the transactions and because like

that's the way to save space and if we start doing like base layer ZK for privacy then oh you know we're going to start getting into similar kinds of collective stuff so I want like I think there's a chance that that stuff can be pushed into existing Frameworks but there's also a chance that it is going to look different foreign something else well I totally support this idea that there should be a kind of pre-compiled header for a contract for giving you generalized instances according to the fork this is unfortunately not applicable in other blockchains where kind of things like Marco proofs or other commitment proofs

may be used over the SSD types of ethereum speaking of Miracle proofs actually one thing to keep in mind is that that I think we should start thinking about early is that eventually the Asia hash function is probably going to be changed from uh 256 to you know maybe Poseidon maybe RC uh something that's more Stark friendly as uh ethereum at some points in the future is going to redesign itself around like or re-optimize itself around the the snark world and so one other topic that is maybe relevant here maybe relevant in

the context and I definitely relevant in the context of figuring out how to use your proof uh Merkle proof says like how it's like what we need to do to make that happen right like does that mean that we need to make a pre-compile for like would we commit to SSD forever and we just make a pre-compile for like here is whatever the current SSD hash function is and does that mean doing uh other things uh to answer that I actually have one which one one more idea so basically we could just you know leave the union for later we could always introduce layer over whatever we decide now that includes whatever we decide now as you

know one of the Union types so that when we do indeed have a change that you know is expensive for whatever reason we we deal with it then because like that even plays well with the tree structure in general a bit uglier maybe but but like that's one option if we if we don't feel strongly right now I don't think it's kind of irreversible we just call whatever we come up with now in the Legacy Legacy transaction I'm not sure what's the best way forward

here it's a mess yes yeah can we flip a coin or something I don't know if the next hash yeah even yeah I mean just want to highlight this from the chat so this interface these transactions route um I just want to double check whether this assumption is correct as part of the core ethereum we treat it more or less in an Opark way there is a way how we create it that's a standardized by spec But ultimately the only ones who really care about what is part of these transactions route are

consumers they right now use the Json RPC API or the evm pre-compiled if they are consumers on ethereum itself but what we are trying to create here is a way so they can validate that the answer that they are getting is actually correct um so I mean if you are already live on top of ethereum as a smart contract you don't need to validate because you can just ask the evm hey give me this transaction value if that's important um but if it's a smart contract on a different blockchain if it is a small wallet like metamask that tries to validate hey is this transaction amount

um or if it's an iot device those are the consumers of these transactions Rule and that was my main [Music] motivation there to make it as as easily possible as easy to consume as possible I mean all these transaction types they exist the normalized transaction does not seem to restrict any future transaction types um beside them just having to find a representation in both the Json RPC and transactions root 3 so yeah maybe there are other users of

transactions but I like my current assumption is it's just those essentially I mean I don't really understand what you mean by consumers or just the user transactions rude like are users the only are consumers the only users of the state route are users the only or consumers the only users of the receipts route or uncles like I think they're they are used for both consensus validation and by users yeah I mean this this vertical discussion for the state route

I mean primarily that that the reason there is to make it more parallelizable to update as well so which is a service to user in the end for receipts root transactions route yeah sure I mean that they are used in consensus to agree on things as well that's true I guess I'm just like wondering what is what is the specific thing that you're trying to point out by saying that consumers care about the transactions root oh that's that's just that um those light clients that are not really part

of the core protocol they live outside but either we put the complexity on them by making it more General than necessary with the union or we can try at least to cut the complexity and contain it within the core so that at least they don't have to deal with any of these like Legacy types yeah I mean there's just a lot of things to think about here but I don't think that there's that much of a difference between having a unified transaction

object and a union I mean we're talking about one additional level of the the try and if we have if we have the union then the transactions already have static General indices for the different values it's just that you have to determine which type you're interacting with so um it's a now one thing that might help I think concretify things here is that do you have a list of uh or could you come up with a list of use cases for why someone would want generalized index proofs of uh particular values like just to get a feel for um you know both the

scope of the issue and uh you know to what extent like some of those uh specific use cases actually would be served by the different approaches um I don't have them prepared right now but I could uh I could work on them but would have to be the next call so to say or in the channel yeah I mean or over the next couple of days like uh as I said like I'm not sure we need a call on it like as I said like I'm not like I'm not dead set on uh unions in a way that I would feel like really sad that um you know they would come I just think it's uh you know one of those irreversible Choice says that I want to send you a bit of exploring to make sure that we yes that we set on the right one

uh but uh you know you you think if you come up with use cases and I'm happy to you know take a look I'm also happy to try to think of some myself okay we'll I will prepare um this three that I like I can prepare an iot a wallet and maybe with sahari's helper CK use case so that we can explore how they would um behave one other thing I think is kind of strange about the unified type is that we only have a fixed number of additional fields that we can add

right now with the PDFs that you generated I think that's five additional fields that we could add so that sort of sets a bound on what we can change without modifying the general indices I was thinking about um extending SSC containers so that you can specify a maximum capacity so you can maybe say it's like 64 or 128 and it will just zero extend until there the same way how the lists work okay so yeah there is a limit but you can

make it large enough to fit the design space one question I have is um how critical is it that we make this decision for like Cancun my my understanding is that it is and that we don't want to ship 4844 um with like a transaction type that like in the fork after we end up sort of overriding um but is that like correct or is it you know possible that you know we ship 4844

with the current design but then um you know in the forecast or not we decide to change it um I'm trying to get you know if we are sort of making this you know quote-unquote irreversible decision you know is this something we need to figure out in like the next month or two or is this something you potentially have a year to think about I personally think it would be a shame to ship 4844 with some idea about how SSE is going to be integrated into the execution layer and then have a pretty big change in that in a

later Fork so I would really like to have a pretty clear idea of how we're going to do this migration now or in the near future yeah does anyone disagree with that okay so I guess this probably implies in the next month or so we should try and like a line honest spec especially if it affects you know

refactoring old transaction types and yeah does that seem like realistic to people I'll take I'll take the silence as no objections then yeah in terms of next steps is it in looking at some of the potential use cases you mentioned um sharing that with the folks here and making your decision off of those use cases or is there something else that um

we should be sort of investigating in the next month or so there was also the way how transactions are hashed but I guess it's sort of is this what Roberto is bringing you up in the in the chat so like the hash conditions concerns no um it's it's not really the I mean the hash correlations between shot 256 and ketchak I I guess they are not really uh like a maybe a theoretical thing but I don't see any risk there personally talk to a couple

cryptographers but I'm talking about um whether like how we want to derive the um signature of a transaction because you need to find a like hashtag transaction in a way and then you sign that hash and you kind of need to put the transaction type in there you need to put the fact in that it is a transaction that you are signing and not a regular message and maybe something that tells you by the way this is the type 5 of the ethereum spec and not the time 5 of The binance Chain so that it doesn't conflict with each other so that's another open thing

uh related to SSC in some way because in vitalik's proposal you can at least have the transaction ID be the part of the SSC tree which is not possible in the normalized case so I need this additional transaction hash field but um yeah it's it's another it's sort of related but also kinda isn't not sure okay and I guess yeah I I feel like I don't know in terms

of next steps eaten um do you have the bandwidth in the next couple weeks to like look into those things and potentially update your EIP to sort of all right there it is yeah look into uh those different edge cases and probably make sense to have another conversation about this in I don't know maybe two weeks and then assuming like we're happy with that we we uh you know we update your EIP and and go forward for that with that

yeah sounds good I mean just uh providing collecting and providing those use cases maybe someone else has another use case that they want to try um implementing them with the normalized TX implementing them with the Union just to see how how they differ from each other I think that's the best way to decide on these I think this image already helps a lot that I um prepare Justice graphic that shows you how exactly do those types differ but yeah having some code would be even better two weeks sounds good for me yeah okay and let's just I can I can

schedule another one of these breakouts like literally two weeks from now at the and then tomorrow on Awkward devs we can tell you know people who maybe are not here that this is happening and like they should pay attention in the next two weeks if they want to get involved yeah does that make sense yeah I think so and also regarding the net timeline eip4844 um forces execution to implement SSC anyway so I think uh regardless of whether this will be a union or a normalized transaction it should not

risk delaying um get released too much it's just transaction root computation um cool anything else people wanted to cover I think maybe one thing to think a little bit about is where are we going in terms of the peer-to-peer propagation of this information I know that a lot of the these things are still represented in the 27-18 manner but I don't think that for the long term we really want to have a bunch of different

serialization formats or transactions it doesn't sound nice to serialize transaction for the try in a certain way serialize it on the disk a certain way serialize it over a wire a certain way so it might be useful to think about these proposals and the context of what if this is what's going over the wire to piers so for the Legacy like for the main pool I don't think you can change those too

much from 27 18 because um you always have this use case where someone signed a transaction puts it in a box maybe for legacy or whatever inheritance someone else will later broadcast it um I mean you can wrap it I guess but the serialization in that specific rlp format uh probably still needs to be supported in some way either on Json RPC or on the main pool topics even but yeah I don't think it needs to be supported outside the signing hash like we could today totally move the El peer-to-peer stack to SSD and if you have that ROP

transaction in a box it should be a function to convert it from ROP to the SSC format right um also for the transaction ID but um yeah sure how would about that I mean it kind of has this problem that you need to upgrade the network in a coordinated way because regardless of its I mean if it's a union and you add another case to the union um it may and no longer be the case that you can still load the previous specs format

for example if so if a field changes from variable length to fixed length or vice versa it can make them incompatible but yeah sure sure I will think about this network yeah if it's possible to change the network to SSC as well here cool okay anything else okay thanks everyone then um yeah let's

continue to chat on the type transaction Channel and um yeah have another one of these calls two weeks from now thanks Tim thanks all yeah