EOF Implementers Call #25

EOF Implementers Call · 11 Oct 2023 · 1:50:40

EOF Implementers Call #25, held on 11 October 2023. The EVM Object Format, or EOF, is a proposed overhaul of how contract code is packaged and validated in the EVM. These calls bring client teams, compiler authors and spec writers together on implementation, testing and specs.

Topics

From EOF Implementers Call, hosted by Ethereum Foundation.

Transcript

this meeting is being recorded okay I'm not sure why it's recording too but it's being recorded um yeah for the maybe just for the recording we have been uh going through the out sending questions for uf1 and we are discussing the validation um so I guess we we actually decided for this now right yeah my concern about the Deep

validation I think I is not a concern because we validate this is for the sake of the recording um we basically validate each bite whether it's a header bite or a code validation bite or a data bite and when you're recurse in the subcontainers you skip over the whole bit of it and then you revalidate the interior which again falls in the category of evaluated once for header bite data bite or code validation so we're not really evaluating bytes more than once so it and any nesting dolls you get with the um deploying factories deploying factories deploying factories are costed for each expansion charge for each expansion so the computational cost matches the expected charge cost so there's no mismatch between the gas

charge and the effort expended so I'm not concerned anymore and I'm okay with subc container validation awesome yeah I think that the important piece is that we we have to write down any concerns we may have into the security considerations um just to Aid the review uh for for others because otherwise you know if they're going to have like the same concerns it's going to take longer to get onto the same page all right shall we move to the next

exing question uh which I think is create for right so this is my proposed change right now the cre for spec has written that it takes a stack argument that references an index in a transaction my concern is stuff like 4337 where you're taking what might be user operations that might contain these or might or might not or future transaction formats where they might be bundled together and you might lose your index location within your transaction um especially for taking you know know taking user operation and bundling them into a type two transaction would have that extra

field my proposal is instead of indexes we use hashes and we refer to the to the uh contracts by their hash so there's a bit of a cost overhead when you bring in the transaction you're going to have to Hash it but if it's ssz encoded it's probably going to be hashed anyway um and you refer to it by hash now one concern is you might um this might be more larger code might be a push 32 before the create for but if you're embedding the hash of a contract um and you're doing it for size then you should be using Create 3 and embedding it in the oof container um there might be some strange situations where you're um needing to do diamond pattern and all that and you want to log in the version

um but I think the more typical case is you're going to be passing in your contract hash via call data and it's not going to be in the code it's going to come exterior from the code so what you get on the stack is going to get call data or it's going to come from um maybe maybe long-term memory and that's where you're going to get the the contract to deploy so the size growth isn't going to be too much larger and um looking beyond the current situation of the evm on layer ones I think this opens up more design space for layer 2 EVMS where they might have especially ZK EVMS where they might have a small list of contracts they want to deploy and it's provided by the Layer Two outside of the

transactions and say well you can do Unis swaps and you can do pools and you can do Minecraft things and that's it and so you could refer those contracts by hashes when you deploy those there so you could refer to stuff outside of it so I VI create three as you're deploying it from within the container and create four is you're deploying from outside the evbm and using a hash to reference it where our first proposed implementation is that the hash comes from a transaction containing the data so that's that's my you know high level pitch for why create for should shift to hashes and we could accommodate hashes and indexes by putting in rules like if there's 31 Z bytes then treat it as an index we could accommodate both in this

as well if we need to yeah I would be against having uh having clever rules um I would rather just go for a hash or index and and initially I think I mean I was I was leaning towards the hash but initially only because that allows for like Block Level to duplication um but as you mentioned I completely forgot about the um um the user bace account abstraction I think that's the the main reason why I would be for the hashes because that simplifies um the Rel layers in any kind of building on that

level I guess the question is uh anyone strongly in favor of having indexes anyone somewhat in favor having clever option of indexes and hashes and I guess we're going to go

with hashes for now and see if anybody um anybody from orod defs comes up with some arguments against so the implication for the tooling would be like the creation transactions would have to include cash right in the call data yeah or it would be a push 32 um I guess there are some contracts where you just do index one and always deploy index one so that is the downside you'd have to pull it out of call data and put it on the stack instead of just pushing one so like the Creator contract exactly

yeah I mean we we could have yeah I I would I would try to avoid having any kind of uh flever rules like you know empty has having some EXT some specific behavior or anything like that so we would just change the input from index if we go back to that index would just become Hash Hash

salt Ox data up at the top comment line so you would just change the ABI of the contract I mean it's already set up at um 32 by intervals so it's not too much of a change fact it's probably you just change the text of nit code index to nit code hash and we're done there's no actual structural changes to this

yeah the contract will stay the same I guess all right yeah I would suggest we we go with the Hesh for now just so that we actually try it out because I guess nobody properly implemented it and and tried it in different

contexts um so yeah I would I would try it out with the hashes and um and come back if it if if we find any issues with right nobody against this proposal then uh I suggest we go to the next Point uh we're bidding unreachable sections and want to explain that yeah this is just seems logic since

we disallow unreachable code then sections that don't have any call F or jump F into them should be forbidden and I guess it was like an oversight from our site originally and we never got this into the spec so seems to be a good idea to me the only downside is like some tasting might be more complicated because you can't just create like I don't know 256 sections like two tested limits each one of them should be reachable and things like that yeah

I think it's fine because I think creating a test case to do Max sections won't be too hard every section just becomes jump f um next section number and then the last section becomes uh stop so I think it's a minor and I think it goes along with the theme of no dead code and I think that's an important thing to get yeah I don't think this is controversial it just falls under no dead code um you know it's just a section which is not reachable instead of a a basic block right all right I mean let's do it

unless um we find some issues along the way um and then we have this this section uh for changes which can be rolled out in a different stage um there just one feedback at least from within the Epsilon team I think where we have been mostly leaning towards is it would be nice to spec uh these out but probably we wouldn't push very hard to have optional up codes um just for the reason of um having too big of a scope um but specking out jump

fi and maybe the the create with external address could be useful for the for a point of um realizing if there's any any shortcoming or any issue elsewhere in the design um but I wouldn't push hard to actually have them in like the first stage or first roll out because the the scope is already like uh quite significant um by the way I don't know if I should have mentioned at the beginning of the call but I submitted poll requests um one for return data load and one for this exchange op code so return data load is already speced out if you want to so exchanges

the swap MN right yes and something interesting that uh Dano and me figured out is that um the addressable range is actually larger by a factor of two so like with one bite you can actually address 32 stack of items instead of just 16 yeah if you assume you're never swapping one because you existing swap set so it's one plus for the first and then you order them first and second then you encode the second one as a Delta from the first again offset by one you can get up to 32 for your maximum swap the downsides you can move it a maximum of 16 spaces on the stack but

sometimes that's what you would need so I think that also makes sure that there's no duplicate swap instructions like swap 76 isn't the same as swap 67 so yeah basically there's a bunch of duplicate swap instructions um swap one2 is the same as Swap 2 one and also swap 1 one is a noop so you can basically Dino's encoding is better because it doesn't waste space uh what what's the number for

exchange uh I just made a PLL request against the 663 IP they're they're all in the Discord chat but I can oh yeah 663 all right it makes sense to just put it in there since that's the successor to swap in that's more functional and dupen would remain posted the PO request in the chat let me link this into the discussion actually would it help for me to submit a poll request for jump

fi yes I would say so I'll try to do that uh today then yeah I think that one we we could actually try to get into the existing VIP right one because jump F I mean I was thinking about it excuse me and um usually instruction sets don't have this conditional call instruction but instruction sets also don't usually have jump F which is like a tail recursive call instruction um so I think under the logic that these are

specialized call off instructions it makes sense yeah jump FS 6206 yeah at some point we actually wanted to merge that back into uh the functions C IP but now it covers the non- returning aspect so yeah maybe it's better to have it separate um select jump fi could go into 6206 yeah I think we're on the same page that specking out uh cannot hurt um

because specking out would tell us if there's any any other issue or shortcoming as for um at the end of the day I probably would be willing to drop jump if I if that's needed to to to get the rest of the features in and probably the same yeah I I don't have like a strong opinion which swap or exchange version um should we have as long as we have at least okay do we actually have anything to

discuss with these uh I link the the IPS yeah charers is there any like um do you want to give like a short overview of R data load uh sure I mean it's basically exactly what you expect it's three gas uh yeah if you pull up the pull request um added a little bit of motivation for it and it's yeah there's the spec of

it it's three gas it takes the offset from the stack uh exceptional failure if there's an out of bounds and uh otherwise it just puts the r the word that it reads back onto the stack and the main reason for this because you do utilize an in Viper the fact that calls can um uh can write some of the return data right and you write like I don't know the first I mean how how much do you do

you write sorry so I guess this return data load is is uh for the fact that the old calls uh would write the return data as well right use the output buffer and then decode from the output buffer and then to restore that functionality we need to be able to treat uh return data kind of similarly to how we treat memory as a buffer and so return data load kind of replaces the usage of M load here and otherwise is there's something a little bit weird uh

when you need to so normally you just um let's see how do you put this so normally when you use a call you specify the output buffer which is like um offset and length and then the the the evm implementation will just truncate the return data if the colleag returns more than what's you know more than the buffer size that's given um but without that you have to do it in the evm so in order to copy return data into the output buffer you need some sequence of instructions to like calculate the minimum of the of the return data size

and and the allocated buffer size um and I wouldn't actually but Viper statically so you can't like really you you have to bound it statically instead of at run time or you want to B aesthetically so I think from I have two two two different comments um I think from solidity perspective if I remember correctly Daniel said he would be super happy with return data load just generally um because it's it's nicer um in a

counterpart to call Dat load um but for your specific situation and and also solidity has been complaining about it but I kind of wonder if and probably discussed this on the last call as well but kind of wonder that the the underlying problem is not the the lack of return data load but rather that return data copy is not zero petting because if it would then then you could just keep calling get without taking care of the Regal data size right no that's not really the issue so what is the main issue

then the issue is like what happens when you go to ABI decode the return data so let's take a very simple case where like the contractor returns a u 256 um so right now what you would do is you call and then you provide an output buffer which is like 32 bytes and then excuse me the return value is just what you get when you m load from that buffer um and then in the new thing you need need to call return data copy and then mload return data copy into some buffer

and then mload from there and when you go to return data copy into that buffer you need to um make sure at evm time that um the return data size uh fits into the basically what happens is that in order to ABI decode things you basically need a buffer so the first thing you go to do after calling some contract is copy stuff from Return data into a memory

buffer and if you have return data load then you don't need to do that copy yeah although this this last argument I mean right now you do designate some memory area right because you use the output output buffer option of the calls yes so I think that that part may not be like a the strong part of the argument um but I do have one question what happens when you try to return data load out of bam

is it returning zero no it does the same thing as um it's consistent with return copy so that's um step three here yeah this part I would definitely um discuss with so liting yeah and uh this is yeah this is kind of a a weird thing and we discussed this for a little while in the last call um but for now at least it helps ABI

decoding uh because um another thing you need to do when you Abid decode is like validate um you need to do certain offset validations and this kind of gives it to you for free the the outof bounds return data um Behavior so it basically allows you to not do return data it allows you to skip return data size checks actually um which I don't know if that's considered a trick or not

but and and then it's also sorry sorry say it again uh of course it's also consistent with return copy which is maybe the most important thing yeah but also return data copy is the the one tiny piece inconsistent with the rest of the evm right um and we discussed that last but do you do you have some some actual numbers and what kind of regressions you you get um without this I posted the evm snippet that's required it's like a 10 byte piece of code or something for

every call D I personally don't have strong arguments against having return data load but I do have concerns regarding semantics and that it's it's really hard actually find a good option because they yeah I mean there just so many different sides to it but I mean what is the upcode count at this

point uh do you mean the exceptional failure semantics yeah I think that it's actually best and most for f forward compatible future proof uh to make return data load and return data copy zero pad um which is maybe unintuitive and not the most popular opinion but um it makes it easier to pack return data but let me think about this because um call data and return data are priced very differently so maybe you want to do something like um call data is packed so it makes

sense to zero pad it but return data is never packed or something like this so maybe it makes sense for return data to not be packed and so we do charge the out of bounds thing but I mean that's a really weird thing that just comes from how call data and return data are priced differently fill all right Ju Just trying to fit in

the entire conversation is 60 minutes um so we discussed I think return data load to to some extent um The Exchange to some extent and there are two more points here regarding jump fi and I think what we discussed there and just to recap is that we are going to at least spec it out and see if if we run into any issues um by the way I think Andre's less restricted stack validation might work

to Andre it's uh you require you have strict stack validation on backwards jumps but not strict validation on forward jumps right yes something like [Music] that yeah I think that's actually fine because it prevents this uh unbounded thing happen happening when you have loops um but it does kind of what you want on forward jumps yeah exactly it kind of still disallows unbounded Loops but allows jumping into one forward location from different stick Huts yeah I think it's a really good

compromise actually because it's easy to reason about from uh from an implementers perspective uh I think I had a proposal before which removed the stack validation entirely which is like Pro produces some hard to reason about cases um but it also removes the relevant restrictions that uh compiler that as a compiler writer I'm concerned with so from the point of view of the compiler produces the desired effect and then from the point of view of the implementation it's not too complicated either

uh so what's the best sorry yeah I'm not familiar with the the stch validation changes here um yeah the reason jump f i was proposed is because the stack validation rules um are in some sense too strict so they require you to add all these branches in code that um just used um Jump by before um so there were two proposals right one is

Jump fi which rules u r jump I and jump F into one instruction and then the other idea is to loosen the stack validation rules and that's one of that that approach is there's one approach which Andre implemented and I think it's actually um what WM does uh which I remember reading somewhere but I couldn't find it which is they have strict validation on backwards jumps to prevent uh

unbounded loop things but uh less strict validation on forward jumps yeah can can one of you maybe explain the the difference because it's only just you know less strict uh what has been said so far what is the Restriction exactly what has been lifted restriction is the requirement to all jump just um for have to have the equal stack height for every path that

goes through this uh location so this is vipers concern and I think solidity head similar is that they want to jump into some helpers from different stack Heights not from constant stack H and this is not allowed in current stack validation you have to balance St before J Som yeah I mean that was also one of the reasons non- returning functions were kind of introduced would this loosening allow us

to to remove the non- returning functions maybe uh I guess this particular question maybe needs a bit more focused effort um probably it's not like sorry like a

blocker for tomorrow that the less strict validation would that also allow us to remove the non- returning function special case because those were also introduced because of Stack balancing reasons um but in terms of tomorrow I would probably argue that this one part question is something we can uh we can let slip uh I don't think there going to be like a blocker for tomorrow and specifying jump fi I mean Charles do you think you're going to get it done by

tomorrow yeah I yeah I can send over a draft uh and then it would be helpful if people look over it yeah I mean let let's maybe try to to see the implications but I don't think we're going to make a decision on this today um and I don't think it blocks the presentation of tomorrow right it seems like a bit of a detail uh but I think in terms of choosing which which direction to go I think is kind of important yeah I don't think you're in the position on this call to to make the decision um I don't think we have at least I I don't really have good enough

contacts um yeah the minimum we should yeah is also something we probably really want to get feedback from solidity so probably the best course of action is describing this um problem in detail and then the two different options we have in detail um yeah I would suggest that we we try to craft a the one page major experting test um the problem in the two options and then get feedback from at least solidity um and potentially I don't know pav has been like super involved with the stack validation but I'm not sure when he's going to be available but at

least solidity should should get feedback is anyone volunteering to write up I can try to write it up yes awesome yeah maybe come we can come back to it also on the next call just to finalize that okay should we briefly discuss this last Point um three a three with additional address no I don't think that's

important uh if we need to choose one thing to talk about uh can we talk about exchange a little bit Yeah I do want to set aside at least five minutes um which would be the last five minutes I'm not sure if people have a bit more time um but to discuss like uh tomorrow's presentation um I'm not sure Dan do you um Dan Char do you have five 10 more minutes I've got a lot of time yeah I have some time right um yeah let's let's discuss exchange

them um so originally I actually drafted two um the P request with two different exchange op codes uh but then Dan and me realized that um this single exchange op code gives access to 32 slots and so I just dropped the second exchange but we can add it if we want access to um 250 sorry 512 slots

how do you get 512 slots 256 I thought it's all we get with one immediate art uh two immediates two two bites of immediates oh yeah you're right okay if we use the exchange with the two by media got it yeah yeah statistics changes and plus

M and the the arguments are unsigned right right because if you're ordering any two items on this deck you can strictly order them one comes first one comes second the first one has to be within the first 16 bytes so you have zero ma to one since we have swap One n already set up so you would add one to the first value and then you would have the zero index you would add one because it's at least the one after and then add to the remainder so I think we actually get 34 bytes maybe or 35 bytes of depth but it's 32 is the easier one to sell logically um we can be precise later but

the point is with with the nibble approach there's no wasted swaps so if you swap 67 or 76 those would swap the same things so we do the encoding so it you know is first one and then Delta for second one so we get more distance out of those duplicate um combinations per se yeah so my original thing which was Swap n m uh actually more than half of the instructions are duplicates um so like swap uh one two and Swap 2 one are the same and then swap one one is also a noop and swap 22 is a noop and

S so it's like half plus um there's like some kind of Matrix right anyway a lot of them are duplicates so you can get a better idea so why don't you offset by 16 so n n starts at 16 um I think n could start at two I think we want to start it two instead of 16 because that gives us space if we need to get rid of the dupen 1 through 16 to use for other things with a minimum of disruption yeah and if we're going to do that then we should also make dupe and start with from 17 or whatever it

is well yeah but how you what I don't get and I haven't try fully how do you I mean this currently can only go to like 30 32 items how does it goes like deeper SW 3 yeah I think that's a good thing sorry I didn't get that uh I I think it's 33 if we start from yeah yeah I mean I started out by saying that you know with uh the the one bite immediate then we can address 33 items

or 32 or 33 items and then with two bytes we can address 52 items but you know yeah so I originally drafted it with exchange and exchange 2 but then uh 33 items felt like kind of enough so I dropped exchange two yeah I think solidity had like different problems they they wanted the they wanted the depth as opposed to swapping any any two items and for that I me this this won't be as useful right because the Swap and can go 255 I mean yeah I mean you can ask

them yeah I think it's the same as with jump fi this really has to be discussed with the with them as well so maybe maybe for the next goal we can actually properly uh arrange um to make sure that uh somebody from solidity comes on um but I think we should do this async um yeah in fact I'm going to send it to Daniel to see if if he can review this um this spr yeah because it's it's very different um

problems it's trying to solve right and it has different tradeoffs yeah I mean there's kind of similar and related problems but it is a tradeoff especially with respect to like code size versus number of op code like if op code slots weren't an issue then we would just add exchange too

all right yeah I'm not sure we can uh make make any more progress on this um on Exchange Mr Andre do you have any any opinion not really yeah we should ask solidity all right should we discuss these last um nice TOS on the bottom I'd like data section

optional the question is if it's zero do we require its absence or do we allow it to be set to zero and I mean we the issue with fiddly little rules we could say that um well I mean the data section has to be when you're using a subc container if the rule is that your data section needs to be the actual size of the final contract not much of the subc container then it doesn't ma then we're not going to rewrite the data we're expecting a fixed data size we're not going to rewrite it so that might get rid of the whole rewriting issue so if there's zero data then I think if that's if we're not going to change the data section SI

I think we not only make it optional but we prohibit data size zero in the header this all of course hinges on whether or not we rewrite the data section the data section size but I think this um this dite listed here pending data section maybe more than just depending them I mean that's

that's the problem with the compiler um the compiler wouldn't I mean it could choose to do so but it would likely just include um an empty or or short data section if it expects it to to fill up right but it's still a choice made by the compiler right so go ahead no what I meant here is we are so with this back where like the previous spec where data section uh declared in the header is the equals to its size and then weend and update the size

value in the header uh in case it was empty and then it becomes nonempty at return return contract point then it will be not just dep pend in data section but also insert the uh inser this header in the subc container header in certain data section head but this is like this is not a problem if we go with allowing truncated data sections then it's not a problem actually so it gets simpler then appendant is really just aend in the data SE yeah exactly but what I meant is the

problem of the compiler is that the compiler would know that it will want to append data so then it would prepare the deployment code to have the header this only really comes up as a problem if you do have um a create treate external address for the init code then then you may need to extend the headers right because but that's like another problem generally when you take unknown init code that you need to to check whether it it satisfies what you expected

I mean yeah of course a compiler can shoot Sho itself in the the foot with more optionality but I don't think it's it's a downside it's it's really after to the compiler still not sure I understand because like this what I meant is complexity of the implementation of a pending of the data section at return point oh you meaning the client right I

mean yeah I I guess the one option is that if if you're pending and there's no data section then that's a failure right and then there's no complexity I mean now we decided anyway to allow truncated data sections and then if you intend to append later you will declare its size already and it will not be empty it will not be an empty header maybe this is a stupid question but are

data only contracts allowed in E so no code sections no not all but you could trivialize it just have one code section it's just a stop bite um which would have the effect of or you know have the invalid instruction so you can't call it um the explicit invalid or the or the revert so you could get around it with minimum of header impact I know that's something that like the uh um the sore 2 people are going to want which is they either want EXT data copy or they want a way to get at it so they intend to put some data in these contracts like inscriptions I'm just wondering if some

of the same considerations apply here what if they're putting unknown what if they're putting links in that are longer than what's in the section I that might be it or variable that I mean that is the downside but I would expect they would deploy their data contracts via top level transaction to be honest actually what what is the the motivation

for making it optional it's just reduce the header size for contracts that don't use yeah it was made mandatory just for the ease of parsing at some point last year but then we added container sections which are optional and now we have data section mandatory but container section is optional and it's kind of inconsistent and the argument for Simplicity of paring doesn't stand anymore kind

yeah I guess container stuff is is uh it's a good point but but based on that logic if we if we want to support data contracts first class then we also want to make PR sections optional right that's the definition of data contracts non Cod section so it must be optional here yeah I guess what I mean is

uh you could you could argue for either of these options really um because you could say that the init the subcontainers case is the the special case of creation and and the others are regular contracts um but yeah I don't have a strong opinion um yeah as I said you could you could argue for any of these in in various different ways okay I I would opt for no change then leave it like now so make it mandatory with the create hash though you could still put in a stub that's the same and then have a variable amount of

data that comes after it my expectation is that's how the S St two people would would want to do it um so they'd have like a stub that has their interface to read the data and then their data structure you know the first B will be how long it is and segmenting and other info and then it's a variable length after that so I think a fix L contract might be of less utility for them because create for still has an auxiliary data option to put in it too um by the way one issue with relying on the S store contract to return data is that you kind of have to trust it um so it opens up things like

re-entrancy or the data contract not doing what you expect it to and this is actually some kind of issue with um that I I was trying to solve with the create three variant uh which is like yes you can call a this you know dedicated Factory contract which is supposed to deploy a contract for you but you have to transfer execution context and then it makes tracing more complicated too so like with the s store to returning data

contract now every time you want to do an X data copy you introduce kind of a trace a call into the trace which I I don't think it's necessarily consider like a showstopper but uh I think it is kind of a consideration yeah I do think um EXT code copy is going to be a better solution for the sor2 community um EXT data copy sorry not EXT copy so their code might be nothing more than um basically stopping payments and stopping any calls and throwing exceptions saying I'm I'm a data

contract please try again later yeah please please don't try again that should be um considered together with the create 3 variant because they're both kind of doing the same thing except just one is a call context and one is a create context but I mean as a compiler writer I have no uh opinion on whether the data section is optional or not I think it f

other way so when people are micro benchmarking it would be nice but how many tiny contracts are deployed um it's not only tiny contracts but if you look at um I mean at least for solidity if you look at um solidity contracts we have immutables gu that's like a cheap cheapest way to to store variable data you know right right which is why we need Aug data but also let's consider that any any any real contracts going to

be putting in it's metadata um it's hash it's the the trailer seore stuff anyway so not many contracts you're going to have zero true data I mean that's for solidity but the question is then for for Viper um Char do you think you're going to have like a large number of contracts not having I don't think that the overhead of the data section is that significant if

we're talking about code size uh one thing I do think is significant is the the size of the code section header because if I recall correctly it's like six bytes or something per sub routine uh which is a little bit significant if you have a lot of um internal methods but how could we encode the data so we have it for stack validation um I mean you can just choose a more compressed encoding for all the offsets and lengths I think so let's just leave the data

section required that'll solve it it's it's it's more effort than return to get consensus on it so let's just keep it as expect yeah yeah it's not a significant over but what is a significant overhead is the size of headers actually of size of headers uh the last point is adding one more build so should we maybe discuss it

first um Andro I'm not sure is it is it you who added that the ma you mean yes is that for code section or for the entire contract this is for code section this is a minor change in validation and so we allow Max stack height in the type section to mean not exact equal Max stack height but like upper bound uh so so for tests it's it simplifies life because you can put there just Max and then like any

uh code is valid with that uh otherwise like currently for testing you have to calculate also the stack height of the code you wrote the current validation is we do stack validation and calculate during that calculate maximum stack height and check that it that calculated St height equals the one

declared in the header and this proposed change would would check that calculated stack height is less than or equal the one declared in the so a lazy compiler could just say 100 and just be done with it yeah exactly and like it's useful to have lazy compilers in testing scenarios is this what um I think this

is what net does is that what they do in theirs I guess my question is is there precedent for this in other VMS because if there is then I'm cool with it I don't know I don't actually understand uh what the difference is from the current behavior isn't Max stock height uh just the total the upper bound of the number of stock items in the in the code section So currently it's not an upper

bound but exact value of Maximum stack height that code section May reach right it's where you have to bingo it or whether you just have to be less than the number when you run your calculations for compiler from the perspective of the compilers it's better to just be upper bound instead of match exactly um because right like d said you can just kind of be lazy uh so it affects call F in a way that this this value is used at call F validation or at run time maybe and so if you declare

like Max upper bond for each then you will have lower maximum call stack depth it is a foot gun but if we're talking about lazy compilers are probably not concerned about Max recursion I don't think is the problem I think the problem is more catching compiler bugs because it's a foot gun right yeah but the space this opens I think is some of the stuff that we were looking for to allow variable stck kites to come into terminal operations um I think that's why we were discussing this um so like you have that one function that is well actually this

this would have been in the inputs and outputs variable no that be inputs and outputs anyway I thought you were um I thought Charles you were talking about times where you want to have everyone share revert and you don't want to have to care about what the stack height is when you're going to throw a revert as long as the top five arguments have all the information you need and then you would go and you would revert it I thought that was the value that this would add uh I don't think they're directly related because this is just max height that happens in the called sub routine right it makes it like not a black box because you can call a sub routine

and then it can blow up the stack yeah it doesn't have to do with its inputs and outputs and like yeah so I mean like the lazy compiler approach is just make everything make Max tack height like always 1,000 or like 1,24 or something um Andre can you explain how it simplifies testing again so just currently when you write the test and you like make a container like like we do it mostly by hand you have to calculate also the codes codes Max stack height uh because validation requires it

to be equal the declared Max stack height in the header must be equal of real max stack height and like for if we with this proposal for testing we can be lazy and just put 1,24 in each test and then it's fine right I 25 because you only have one bite it's two bytes I think yeah it's bytes I think for the compiler it doesn't matter exactly but the strict validation is a little safer because it's kind of like a it's a little bit like a check some bit

right it ensures that the thing that we're declaring in the header is actually matching uh what we did when we analyzed the code before we output it yeah this might catch some bugs at compiler development time yeah exactly I mean yeah so if there's like a bug in the compiler just like the contract like just won't deploy it'll fail validation yeah and and in terms of the testing I

think there's actually a way you can cheat which is just to do the same thing which is like you calculate the the max stock height that happens in the in the sub routine and then paste that into the header I don't know if that's like an acceptable thing yeah yeah that's um should work probably too like if we pull pull the St validation algorithm into testing to yeah yeah I don't know how how circular that makes things right but um I don't think that that is any worse than putting 1024 in

AER but what if each um call frame had its own stack then it would be more

um the abstraction be less leaky um I think the interesting thing is like inside of a sub routine you can't access things that are outside of the call frame right so there's no uh um benefit I think to enforcing

the global sack restriction unless I'm misunderstanding yeah I think we have been 90 minutes into the call so maybe uh you know we less

fresh do you think about this yeah let's transition to the ACD strategy and we can pick this up next week um yeah maybe just a small intro we had a discussion in um Epsilon regarding this and our view was that um yeah we just want you to present the facts and and and basically show you know where we are and what is a reasonable

time frame um is if he if you just go in there with um uncertainty okay you know question one two three all of these are like still open uh we're just trying to figure out um then it suggests that this going to take forever uh so I think we have to be you know more confident in in in the presentation and we can only be confident if you're confident internally right that we we have like a good enough specification um yeah I think that's that's basically

the the short summary um I think you wanted to probably spend like 10 10 15 minutes stps get some slides um on explaining the different pieces we have um obviously it's not the I don't think we need to do like a a recap like a 50th recap of what the header format is of course but rather what kind of uh uh components we have in the in the design system um because we have so many different sets of instructions for different reasons um yeah I'm not sure any any other like

um any reflection to to what I said um I think those are good but I think you also probably need to start the discussion off with some of the bigger objections um one of them we need to be clear we're not replacing Legacy that eof is going to be parallel to Legacy and then that 90% of the code between Legacy and eof is reused between the two so we get rid of the concern that we're bringing an entirely separate system system in here and focus on that eof is just a container format um and then I think we should pitch the benefits and that we can break things that need to be broken and L of things we're going to break we're going to break gas observability can you say can you say

the I'm just trying to keep a note can you say like the the first piece again um um the first piece I would probably the about the Legacy and the container EX exactly so in a single sentence um eof is a container format that will operate alongside Legacy evm instructions um it uses 90% of the same code to execute the evaluation it just changes how we package the evm instructions so that way you know I

think one of the big objections is if we're going to rewrite evm top to bottom why don't we just bring in my favorite alternative execution framework so we make it clear what we're really changing is the packaging format and that it's mostly the same it's almost entirely the same except it's not right huh except it's not um accept it's well yeah except you still have message frames you still have op codes you still have storage you still have transing storage you still have memory the main things are all still there so I think the next point that we would want to make explains why we even

do this container format is that we're taking the opportunity in container format um to break rules that can't be broken without um a structural change um we're getting rid of code observability we're getting rid of gas observability we're allowing new OP codes with immediate arguments um those I think are the three big things that that we getting in there um had a list of other things we are breaking oh address address Bas expansion um maybe put a star there that we're not committed to that but if we're going to do it this is where we should do it and we can break fundamental issues in the container format that we just could not even address in the Legacy

format so I think that sets the table for need and then I think we can go into the overview of what are some of the features we're adding that this allows us to add like a code validation containers um how we're dealing with code observability yeah when I said it it changes everything it's yeah I think it's it's a good framing um but exactly like point to um I think it it goes against the the

notion of one you know it's just a container format but we have changed everything yeah but it's fine I think that one objection that might come up is like why not wasm or someone other VM because UF is significantly different enough from Legacy evm that people might be like why not just use some other honestly honestly I doubt that would come up because wasm doesn't doesn't fixes any of the the problems we have gas weaving's problem observability and any of these

any language that doesn't have a gas construct is going to be a hard cell because that's the halting problem solution yeah I mean stylist does this now right they have something which injects gas metering into wasm code yeah I mean ew wasm did the very same but ewm and stylus and uh the parity version of ewas and all of these things they they basically bring wasn't to where the evm is and doesn't do anything more than that yeah I'm I'm just saying that it's worth it to be prepared for that line of

question yeah I wouldn't I wouldn't be afraid of that to be honest because Wasim has been like uh healed up like several times on alls and I think the answer is simple so yeah I mean just see the answer is simple it doesn't actually solve the the main problems you're trying to solve um which is any of like the code and gas observability upgradeability Etc um but yeah that know you wanted to say something oh was about well I mean there's there's so many things you have to change to wasm anyway like getting rid of floating points um need a standardize gas weaving um that's been

rehashed and there's a reason it hasn't gotten larged traction because it's and the performance isn't that much better I think that was one of your um presentations in Osaka was to that effect that you know we tried to make it fast but we couldn't without doing strange things like moving math into pre-compile so yeah for for the use cases we have it's it doesn't bring as many benefits but it has basically zero over with what we do EF uh with the original version of EF the overlap would have been much bigger because it was much closer to um you know wasm and and

conceptually but after food and gas observability um changes uh we are in a very different uh area um but yeah Deno you I mean I was keeping notes and you get to the overview yeah do you have any I think I think that's the big I think those are the big things to expand on the overview

um I think this is the wrong crowd to pitch the um EVMS the Nexus of all uh smart contracts in the future because I think what I mean one thing we might want to bring up is you know what if there's eof2 and eof3 you know the first answer is we're going to try and break enough things that we don't have to do it for five to 10 years ideally never but with the structures that we have with code validation we can engage in transpilation we can take let's say eof2 we need to get rid of all the dupes and swaps um it's a fairly mechanical process to take e code in that E1 into this hypothetical eof2 and mechanically translate the code because of the code

validation so that's one advantage um you know this probably at the end of the presentation or maybe as a backup slide in case someone asks what happens with eof2 um we could translate eof1 to eof2 as needed in fact it's I think it's possible to take all eof1 code um barring size and gas equivalents and reverse compile it down to Legacy code um I think everything we do here um would be ugly but it could be done so we could still trans pilot into the equivalent bases so going forward there would be Legacy code maybe that would be shut down to new deployments on mainnet and one version of eof and if we upgrade

the ver version of eof we would have to have a a way to describe how you go from eof version one to two as part of your transition but that's 5 to 10 years down the road if we do it and the greater ecosystem pitch is what if there's layer twos that only ever use eof um you know this is great for zks because we do things like get rid of um Dynamic jumps um and some of the other code validation makes it friendlier for them um you know we could cross compile it into wum if we wanted to I mean that's nothing stopping you from Cross compiling your evm today in wasum um so and I think maybe an overview of the highle features like

containers um and what what each eof what what each EIP provides and how it fits in I think to present that it would be helpful to have like a working compiler implementation that proves that you can take euf and compile it to something else either uf2 or wasm or whatever it is yeah that that would make a compelling pitch this is why I think it belongs in a backup slide because I don't I'm not aware of any transpilers ready for that yet I

think as uh Greg covin has been pointing out for a long time you can't write a compiler for current EV Legacy evm and that's well a constant time compiler and that's where the code validation and stack validation comes in and the um Dynamic jumps it's easier to write compiler bombs for dynamic jumps the big thing is you could have the stack value for the jump come from call data and you have it could have it go into big old nest of arbitrary jump DS so the amount of compiler contortions

you have to do to that quickly escapes linear time so I think that's where Greg's main complaint is um and that's really fixed by code validation and static jumps which I think is what his 615 was trying to address yeah I mean even if you can write a compiler it's like significantly harder right as I think anybody who's worked on the evm kind of knows right well because what Greg wanted to do was to do just in time compilation where everything was just in time compiled straight into your local op code um but you know Java's known for a while that

there's some compiler things so Java's written in a mixed mode where you do mixed interpreted or mixed compiled and they go the extra milees like well you can make some assumptions like if you know this field never changes from zero you could just compile it in as if it's a constant and they do fancy things like if they detect the field changing they'll go and validate all that code and do interpret it I mean this is some highle stuff that Java does but the amount of you know risk to return I mean they're always finding ways to break the compiler in every release of every dot release someone's found some silly Corner case that does trange things yeah jvm stack validation spec like 160 Pages or something sure

is it's crazy long good way to frame it is like it improves maintainability of evm yeah that's one good way to phrase yeah I think the reason that I have to look at the spec again why some of those sections are like 160 is they go into detail for each and every op code and they also need to worry about backwards compatibility clear back to Java version one .1 or some really far out there requirement where they've changed the class file formats and they Define the

equality between each of the different formats so that's why I think the strategy of one eof would solve that because there' be one transformation into it and then we just deal with one so and there's proofs in their spec for tomorrow I mean I do like your proposed fracture um but on the detailed overview I mean the0 one and two probably going to take like two to four minutes um and that means you know we have like

10 12 minutes if you want to keep within like a 15 minute bound which I think would be good otherwise people are going to get tired right um so 10 minutes for the overview part which I think means that we definitely should give a clear overview of what kind of eips we have and what kind of problems or categories of of changes each of those focus on but obviously we we cannot really dive deep into the IPS and the probably would be Overkill anyway uh people will get like extremely tired um but do you have like a is yeah do you have a good idea of how should we

group uh the features um let me grab my here's a talk I gave at E Chicago um you you want to start looking at slide 20 24 I grouped him just by eiip so I talked about static relative jumps then I talked about code sections

so that was 4200 4750 code sections functions 663 unlimited Swap and dupe we probably want to revise my slide there to consider exchange um we don't have an EIP for data operations yet um explain how this is to deal with and I probably explain for each of these how these address one of the required breakage things so data operations we would explain that we need to do this to replace all of our uh code introspection things so I list you know why we're Banning op codes and why this replaces those I think the data operations is a big one that's going to need that pitch um slide 28

um is create three and create four um and then call to delegate call two how that's dealing with gas um that's 76 7069 3540 eof code um and then other there's a small list of other things so actually maybe I should share this um we got to isolate this share screen yeah so as far as um so start with the

container layout and I just blew through this really quick but 4200 static relative jumps um just talk about why we need those three and what they do um did deal with containers yet um code sections and functions then talked about that um this is new functionality um it's not breaking things but it helps code size and reusability um unlimited Swap and dup like I said we would need update this exchange um this I like putting this up here because it's got a low EIP number so we can really pitch that we're dealing with longstanding problems and the reason I would say that this

couldn't be done until now is because the immediate code because when I started this presentation um is to a you know relatively audience that was unaware of a lot of evm I I told the story of how adding relative jumps just couldn't be done and what broke it um I think everyone on the call is probably aware of that so we probably don't need to tell that story but like unlimited Swap and dupes we couldn't do without more immediate arguments and this solves a lot of you know long long requested features and then the data operations again we talk about this in context of if we're going to break things like code observability here's what it takes to replace it and get the functionality we need um same with create three and create four that's

the other half of code observability we need to be able to create stuff without putting the bite code into memory and then call two and delegate call two if we're going to break gas observability here's what it looks like and what we would need to fix it and call code's just a bonus um code validation um this is mostly I don't know if it's necessary to break well I mean we are breaking things we're not letting just random garbage go out there U but the value that we get from this going forward um is we can do more logical transitions from from uh past versions of thef to Future versions and then

other eof interactions some other random things that we needed to deal with some Corner cases and stack validation um this allows for deeper compiler black magic and this is an AI generated thing I said generate Terrors of Hanoi and computers don't get how to play teras of Hanoi because this is like the wrongest thing you can do in teras of Hanoi so I think that's a great you know explanation of how we can do that um and then I'll listed the future bubbles but where was the uh there was one slide that I focused on compatible versus incompatible changes so I think this is probably another point we need to make are we going to add features to the EO to eof yes we are

the stuff on the left column is the stuff of ranking space for that's easier to add the stuff in the right column is basically impossible to add um without changing the E version we're doing these things here we're doing it once ideally we're breaking everything we can um so if we're just adding new OP codes we're adding new bite sequences but I think these are the two standards if we're making them invalid bite sequence valid then that's fine and we're treating all prior contracts the same and so these things don't require a contract version bump we don't have to change the eof version if we're just simply making new stuff but if we're changing semantics like self-destruct typically that's incompatible um we don't execute

contracts the same with self-destruct anymore typically incompatible and uh we're getting rid of features uh you can't do arbitrary jumps from call data code again we're also removing that um so these are the sort of things that we would try to avoid and these are the big things we listed so this might be a backup slide we could have up to say well how are you going to handle adding handle adding new features into eof um that you know with their smaller features like the new OP codes we're looking at putting in like evm Max is a great example of a compatible change it's just a bunch of new OP codes it's adding functionality and it's not breaking things and we would you know it could still go into eof V1 just with a

future reversion like eof v11 you know what we would call that or the uh like what we're doing today with all of our Fork versions of the evm so and I couldn't resist the main so here's my list of things we were breaking so would you would you suggest to are you volunteering to to run maybe a shorter version of these slides yes I can I can trim these down I can get a revision ready in a few hours based on what I proposed take all the cutesy

stuff out and get it down to 15 minutes yeah I think that that would be nice um I would definitely try to focus on the structure you suggested MH um which may need you know some changes to this and right I feel like maybe you know some of the slides are maybe too detailed um agreed I mean yeah they can they can stay detailed but maybe we don't need to like talk about each of those points just on High level yeah I think we I I agree take out all the detail okay yeah so I'll get this going

go ahead I I I will be around late tonight have with this yeah yeah yeah no but I mean you know to to review any any different versions of the slides or any of that um but yeah tomorrow we I mean I I will be on the call of course um I think everybody else from ipsilon going to be there um yeah I mean I I don't think you know yeah maybe there's some pieces where we probably should speak up as Epsilon um just that it doesn't come off that ipsilon has stopped working on this because you know we

haven't um but I I don't think it has to be us you know presenting it because you do have um a good set of slides and and a good story um so I think you should be doing it I just want to avoid the the notion that uh you know Epsilon is done working on EF and then because that would be like a bad signal right so that that's maybe the only thing we have to somehow avoid and I mean they going to be there um I'm not sure if you have any any suggestions how or is this even like a you know a valid concern okay all right so I'll start triming

these down I should have you guys are epsilon's mostly Europe based right yeah okay so I'll probably just need to wake up earlier and check my slack well before sometimes I wake up right before alore dance but I'll be a bit more responsible this time yeah maybe don't sleep through allette you know this time haven't done cool I I'm probably going to take at least an hour break uh if not too but otherwise yeah I'm going to be available late which means uh for at least another

five hours five six hours okay um yeah I'll I'll try and get something ready within two hours so take a two hour break sounds good I mean yeah this was my feedback I'm not sure Ric Andre from ipsilon any any any feedback from our perspective no I'm I'm fine with this so thanks D for for volunteers and this presentation it should be great and I also will available tomorrow morning to to review it cool so I'll get i'll get slides

updated within two hours and uh then plan on when I'll wake up tomorrow for for for full feedback so yeah great thank you great thanks as some Charles do do you have any any feedback to the slides um not on the slides exactly but I think axic you mentioned being confident about the proposed changes and I think that from Viper's perspective you know I would be most confident if there weren't any performance regressions being introduced in e and I'm talking about code size regressions I mean those are

really I mean which one is the biggest one is the return data load or think the biggest one is actually the jump fi yeah or the the stack validation rules yeah I think on on confidence with those I guess we are tending towards like on the jump F question at least we're tending towards choosing one or the other right so it's a matter of which is the better solution it's not the question whether something will change um so I think on that maybe we can be like more confident that that that question can be solved um maybe there's less confidence

on the return data load because it's yet another inst raction but um I tend to be I think that again solidity would be in favor of because they raised it before um I think in terms of of confidence whether some those features would be liked by the compilers uh there's no lack of confidence there the the only issue we we have is this recurring issue of too many instructions and too many changes right that that's the the only bands side yeah so Dan do you actually have any any

idea regarding um because this question probably going to come up right it's just so many instructions do we have a good uh a good answer to that um so yeah I was going to put together a page on testing um I think one of the things we have going for us is I think evm testing is more understood now than it was a few years ago we' got a couple of great fuzzers Guido V is is writing an amazing fuzzer that's getting some amazing findings um and we don't need to have these large interop events uh because you can test the evm and isolation you don't need to test um gets evm interacting with bass's evm there's no interaction there's only one set of

inputs so it's a lot easier to test these there's a lot less devop setup it's mostly sitting time grinding on the fuzzers and we would just need to write a fuzzer against the container format we' need to write fuzzers that generate extra code sections to to exercise that code and of course the fuzzers that exercise the current operations and some of the findings from Marius and greo are that um as as far as the Legacy EVMS all the major all the active um EVMS that are um live on the network right now are all giving the same answers so we've got we've got tools that'll get us the signals we need which I think is is you know we didn't quite have these tools

last you know before the merge I don't think we really quite cracked the nut on how good fuzzing was going to be in finding all of these issues we didn't have good good enough fuzzing Frameworks for this back when we were doing the the Berlin and those those types of changes so I think we've really improved the testing so I think I'll put a slide together on testing as well um saying that it's going to be simpler and it's better understood and we have a lot of the framework in place so I guess you will have a slide regarding testing and what you said on fuzing

yeah yeah I think the two parts is testing one and two which I think you cover on the slides is um these big um this these big changes uh like code and gas observability uh it's just an implication they depend on on um these new instructions and in fact I think for most of them um we are equal number of instructions um we don't really add many new but you know we disable as many maybe the only exception is so like for data observability we are kind of equal or less for creation we we do have more because of the return

um and maybe jumps it's it's a bit more instructions than what we remove so um code sections is New D new unlimited dup and swap is new um there's no deletes there um let me go back down my list do do you think maybe we should have like um at table of um these instructions are added these are removed and what's the balance that would be I think interesting in valuable it would be what sorry I think that would be valuable to

have that that table yeah yeah the I I mean it's like a double sword but um on one side at least I me depending what number we get on one side at least it shows that okay yeah it's a lot of instruction but we also remove a lot and if if the difference um is really maybe like five six instructions and I think we are kind of good because you know it's not significantly more complex instruction countwise just a lot of them are replaced I feel like we can also just start killing off dup and swap

instructions [Laughter] yeah because I mean nobody really you're not that well liked and we're net one here that's good yeah I think we're like net one hand it's the call F and the RF I think where the real ads come in all right yeah let me know if if I

can help with the slides in any way but at least um I will be able to review them yeah I'll I'll get to a first pass I'll start turning from here for a couple of hours and then share it on the evm channel right this was a monster Marathon off of UF call but it was worth it think we we got most of most of it sorted um yeah charers I mean don't don't be concerned I think the the size regressions be it's it's going to be sorted um so yeah I wouldn't be concerned with the regressions yeah okay and I also want to

um emphasize the importance of exchange but we can all get on the city and discuss that yeah yeah exactly I think it's it's better if we if you first get um consensus between solidity and Viper um with is like two add questions and I wouldn't raise eyebrows on all Cavs before that I mean there's no point because we know there there's going to be a solution to it um we just need to organize the discussion you wouldn't raise what sorry I wouldn't raise any eyebrows on all CVS that oh there is one outstanding question here and you know yeah okay I wouldn't make I wouldn't give extra gr to skeptical

people all right awesome I have nothing else to say um so from my perspective thank you all and uh see you tomorrow right thanks guys see you thank bye thank you bye-bye