EOF Implementers Call #53

EOF Implementers Call · 17 Jul 2024 · 47:19

EOF Implementers Call #53, held on 17 July 2024. 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

I'd like to welcome everyone to eof implementor call number 53 it's the 17th of July um our agenda initially is client updates compiler updates spec updates um a couple one requests from solidity and one request about delegate call testing updates um I have a couple a few questions on testing and other items if anybody has anything else they'd like to put in the agenda um feel free to drop it into the meeting chat and we'll come to it on a time available basis um but first client updates uh let's see aan NE mind do you want to go ahead and start us out hi

uh can you hear me yes we can hear you perfect uh we are dealing with the the failing test the pp failing tests and we are making some progress so far we have I think EF create and the the new create transaction tests that are failing because of some gas issues I presume and we are trying to get to the bottom of it okay yep that's why we write test the test will generally guide you in the right directions to what's actually broken although it might take a bit to figure out how to fix it in your system um yeah if you have questions about what the test is is testing always feel free

to reach out into the Discord um um Andre evm 1 Aragon 3 uh no significant updates in1 like all the implementation is merged by this point cool dragon W uh I'm passing state test but there are few changes for validation that I need to implement other than that it looks good okay um I'll speak for Basu um a couple weeks ago evm one dropped some of their tests into the test format um found a couple bugs and bases that we

fixed one relating to um input data for create um that was kind of an entertaining one and another one um and this is something both GI and Basu had wrong we had the stack order wrong on exd call we had value coming before the argument um offset and argument size um so that was a fairly easy fix and I wrote up a bunch of tests just merged it last night um that exercises um that stack ordering and uh at the requested test I also verify that uh the input call data doesn't get overwritten when you do a sub call um so we got uh tests covering those failures now um I got a patch into gu um to fix that part of their bug um and I don't see anyone from

gu on the call is that correct okay um anyone from ethereum JS um anyone from Aragon 2.0 um see uh that's testing cover tracker we don't have the

uh Matrix on here do we yeah oh here oh it is on e.org it's included that's right um trying think if I'm missing anyone that's on this um so I guess we'll go to compiler updates um are there any compiler people on I know Charles said he wouldn't make it do we have solidity on any updates from ipsilon about the proof of concept compiler okay doesn't sound too exciting

um oh eels anyone from eel on okay so yeah Els is working on their implementation of it um three weeks ago so it looks like like most people are taking July off for EC and other things just something I'm trying to do cool um so it doesn't look like we have any compiler updates um spec updates so the first question comes from

solidity yeah it turns out actually they already discussed it and came to conclusion it's not that important to change this Daniel posted the uh comment here but the idea was to change the address derivations uh formula to include input uh to UF crate uh there is Constructor arguments from solidity because that was how Legacy behaved The Constructor arguments were inside the init code so they were hashed and now like what this one test uh behaves differently in EF than it was in Legacy the addresses Collide um and there is in

the description of PR but yeah they they discussed and it changes uh the way they handle addresses basically change for eof anyway so it's not that important to keep this compatibility okay I think we shouldn't do anything about this all right and if they're not here to they've already said they're cool with it it's been discussed so if anyone else has any comments chime in on this [Music] okay um the next question requested by

fanio um on the call is he oh yes he is awesome I'll let you lead this yeah yes so this isn't the right okay so the second section yeah uh there is this restriction youf one contracts can only delegate call youf one contracts and it's motivated by the self-destruct issues uh so first I was wondering if it's you know we still consider it necessary given EIP 6780 but more important than that I think that this restriction is introducing a new failure mode that is pretty bad um for which I think the

Restriction needs to be lifted and so it's described here but I'll say it so imagine that you have an um hold on I need to remember how this worked uh yeah so imagine that you have a proxy an upgradable proxy which is an ef1 contract and it's working fine it's using a e eof uh implementation uh so it delegate calls to an E contract and it works fine but you update you upgrade it by changing the implementation address in storage to a new contract that turns out to be a legacy

contract and subsequently the proxy will not work because delegate call uh will begin to fail when it attempts to delegate call from the eof proxy to the Legacy implementation contract and in for some proxies this is a irrecoverable error because the upgrade logic is not in the proxy itself but is in the implementation contract and it may not be uh detected until it's too late so yeah let me know what you think

um wish Asic was here or uh some of the other um Andrea Hugo do you have any oh Asic is here okay yeah I mean my question is why would you I don't fully get it why would you have the need to upgrade to a legacy contract well you don't have the need but it can happen and uh it's just one more thing you'd have to check for right it's a new kind of error uh one more thing you have to check for during an upgrade process um it's not that you would need it it might happen accidentally because your compiler was configured in one way or another and there was nothing in the middle that

detected it until it was too late but also this is about bit upgradable proxy so even if you make this mistake which would be very unfortunate you should be able to upgrade it again right right so not necessarily because some proxies don't contain the upgrade logic in the proxy they handle it by forwarding the the call to the upgrade function uh through delegate call to the implementation Target contract so the only way to modify the storage variable that contains the current delegation Target is through delegate

call yeah I mean that that's an interesting con concern but generally I mean it's not like a new problem right because this is kind of similar to the problem when you deploy a broken proxy Target and you know in the case you explained that will also break or break even um the the proxy the only the only new newly introduced issue is that you may be misconfigured your compiler right I mean it's I see it as a new way that the target could be broken I actually

don't know what other kinds of broken you were thinking of that may already be possible I mean you explained that in some cases the proxy upgrade process does require a working Target because actual upgrades partially maybe implemented in the Target itself and if you deploy a broken Target today then you break the proxy the same way so the problem you know this set of issues kind of already exist it's just a new version of the issue in in my opinion yeah it to me it feels quite different or yeah or at least significantly different in

that if you for example you tested the implementation kind of in isolation it would work but then once you do it it doesn't work I don't know my feeling here is like this I would ask like sort of why is the Restriction in place and it seems to me like the Restriction was put in place before self-destruct had been neutralized and the motivation was to prevent errors like the parents multi but one that's no longer needed and second it's adding a new kind of error so it just seems kind of unfortunate no I I don't think it's for

self-destruct generally it's it's to avoid any unknown unknowns um in the in the sense that EF you know changes semantics of a number of op codes and removes them and if you and based on those semantics the the contract which originates delegate call um can make assumptions as long as the target is always e because it will share the same semantics but if the I mean as I said you know it's a lot of unknown unknowns that was the the main motivation that um and sorry I'm kind of tired today so I cannot really think more cohesively but you know if

you allow Legacy as a Target then you have to base your assumption based on Legacy and not UF because if you can call into Legacy then you may as well just call into Legacy so your based assumptions are Legacy and not UF anymore yeah can someone think of an example of like a I understand that it's unknown unnown but like what kind of assumption are we thinking of here you can you can start doing code introspection again so you could do you know what's the gas um all that s stuff isn't that stuff can do through call yeah what's unique about delegate

call um in this self-destruct situation is an effect of the account that was eof and you can introspect code and introspect gas by jumping out to a uh to a legacy one without needing the security context sorry without meeting the security context well without the security I'm mixing metaphors without needing to have the collar the set to you whoever you were we don't we don't need what delegate call provides to to to break that out of the container yep

I mean what else are we Banning and getting rid of an eof um the delegate call is the only sensible way to circumvent it or what changes might happen in Legacy that we don't want to see run in eof I guess are the two questions to ask about about this ban because right now we don't have a sweep op code um in eof so that's the one thing that the current formulation self-destruct would provide which is a way to clear out all of your balance um without deleting the contract or deleting the storage I haven't I can't think of anything that

this having delegate called to Legacy W Drake but I'm not as right I was hoping might chime in on that yeah and I guess the next question is if we change this rule do we have to change it now or could we change it in a future version of the eof is this a a oneway door to leave it in because I think taking it out a oneway door with with versioning isn't it possible

to to removing remove it or add it back in in any version in the future so there there's two aspects of versioning there's a compatible change and there's an incompatible change um if we remove it adding it back in would be incompatible change and that would require a new eof version and we would need to live side by side by existing eof contracts that require that behavior um whereas right now um if you do try and delegate call out to a legacy it's going to fail with an exception um and when when uh right now uh things that cause exceptions that don't like the address base expansion um I think

are falling into the compatible change category so um you know the concern is that it's going to be you know user error possibly some design requirement that you have to use a specific version of solidity that doesn't support eof um could require the proxy contract to change um but yeah basically Alex's argument was these are not new issues introduced by this but they exist um it's just another thing in the check box um I'm not feeling there's consensus to change it um but I also want to point out that this could be changed in the future whereas if we remove the Restriction reing it would require harder

changes so at this at this late stage you know spec changes require a fairly High bar so it's not clear to me that uh removing the Restriction would be a compatible change that sort of consistent with how You' thought about other changes right like if we're going to add new OP codes I would say removing the change um removing the Restriction of delegate call would be on the level of add adding address bace expansion and on the level of adding new OP codes um that's something we could do with just a new Fork version that doesn't require a side by side support of evm but if we were to say um let's say we're banning all all

the pushup codes and requiring a new or not we ban all the dup op codes and require using the dupen operation that would require side by side yeah um support of another version of evm of the of the eof so um I mean the it does present a problem but the solution can be achieved without such an incompatible change so I I don't think it quite reaches the level of needing to change it unfortunately yeah so it it can be achieved but it is a a change to the semantics of an code that may have deployed contracts I don't because the failure mode is to do

an exceptional halt um it's really not something you can depend on within it because you you Legacy call out to to a contract your whole stack frame pops with a with a halt and you're instantly out of the contract so my view hasn't been change in this call I still feel that this restriction should be lifted but um I'll keep thinking about it and I would uh appreciate if others would keep considering it as well I understand that there's not a lot of time but I do see this as a new kind of error um and as someone that's done a lot of work to try

to prevent errors around um breaking proxies irrecoverably and so on this is like one more thing that we'll have to uh be dealing with and and I think it is um important to consider removing the Restriction okay maybe we can discuss it next week um but we're not going to come to support this week on it I don't think so um and I think we need to time box it and move on a couple more um questions actually one and it ties back to some earlier discussions we had regarding um xcode hash and you know

whether to have like an instruction for hcode or is code or whatever um if and and in that discussion we kind of also discuss maybe we could have a flag on a call or you know have the three return uh values whether the the call ended up at an account an EA or code execution anyway if if you do if he would have like a way to tell that the target is in UF contract without revealing anything more then these process could do the check you know is a target E before they they proceed so that may be one way to alleviate the the problem yeah I agree it wouldn't be my

preferred thing but um I agree that that would be a workaround it's it's sort of acceptable I think it's possible like if you call Legacy and X call from there yeah I mean there work obviously but you know we have this longer discussion and probably should be agenda for the next call um just bring it up now but we had this longer discussion whether we we have the return values in the call whether we have flag or whether we have other instruction to tell what is the Target and you know maybe if we if we have more reasons for that instruction then maybe that's that's a better approach approach and this may be like

an extra reason for it yeah um that didn't get put on this call we definitely need to discuss um because this is a higher level issue with solidity um because they also need to figure out not just solidity um 721 is a contract is is an account a cont contct or not and yeah so that was um the two main options which actually was in in here um whether we have an is contract op code which we could have

return one and two whether it's one for legacy and two for eof um is one way that could be changed or if we stick with the other option of having call status expand to say I called a legacy I called an eof i called an account um yeah that's I totally see that yeah so let's let's make sure that gets on next week's call um and everyone think about it in the meantime um if those would solve the solution and which ones would be preferable and me go back to 53

I think those were the two spec update questions any other spec update questions all right um so let's move on to testing um Mario do you have any comments before we go into the specific questions not really uh there are some opprs I've been trying to review um I will get them get to them probably today or tomorrow but yeah nothing nothing specific

okay um any other open comments about test before I go into my three questions from anyone uh yeah could we got a tag on top of the new eof test in GitHub so that it's version cuz we pull pull down on the tags Mario is that something that can be done I I didn't get the question uh a version tag of the current a new version tag of what's current in the tests yep all right Mason gun right or bra sorry I didn't I didn't have that so uh yeah and new version of the

what is currently in main but based on Cancun or based on PR I guess I guess Cancun because that's that's what we have been doing so far Cancun is what we've been doing that's one of my three questions all right I see yep um I mean the okay I see there's two tags yeah what what version are you needing to test off of a Cancun based eof or Prague based eof um I didn't notice there was a difference I was just using version 105 105 okay which which uh client are you testing

in uh NE mind never mind okay um so I guess let's go with my three questions that'll probably help inform some of why this is relevant so my first question um for the eof tests container kind has been added um I know B's implemented it um evm 1's implemented it uh has anyone else implemented it and are using it in test right now uh yeah harm are talking about init code from section yes in it code and runtime yes yeah we have that okay um so there are tests out there now that will fail if

you don't take container kind into consideration and I think that's probably what re ran into um they're mostly in go ahead sorry are you talking are you talking about validation yes validation okay yeah yeah that that test I'm failing yeah I need yeah there's a couple of eof create contracts um that we're testing um deploy code as the rout and validating from there and um return contracts not available at the root container level because it's supposed to be a nit code um when coming in from create transactions so it's it's one of those you know questionable things but

yeah that's the container kind in there spells it out what context is being used in want to be tested um the next question is TN do only gu ev1 and um Basu have TN support right now eels also have it eels okay so Lucas nethermind has a PR with it and I haven't reviewed the newest version yet I will probably review it tomorrow but we're also close to having it okay um so there's a new flag coming in in some of the TN stuff that's going

to affect eof and it's more like it's more affecting prag and Cancun stuff than eof UF is just guess to be the first um consumer of it um but with with the new ition of system contracts and um requests implementing the block header the question and also these um state things as a side effect of these system contracts um it's it's impacted and I think it also impacted the ethereum test for a while um whether not you update those so a new flag's been added um is state test in TN and what that means is you don't do any of your Block Level handling on it um there used to be a flag um when you used to set the rewards as Z where there's a couple of other old

flags with retest at that you would use but if you see that in a TNN what it means is don't do coinbase rewards um block rewards you're still going to do transaction coinbase Awards I think um but you're not also not also not going to do deposits withdrawals or consolidations or any of the generic request stuff so any of the stuff that's coming in new for um for uh pectra and some of the Cancun stuff um that was already existing with withdrawals so it's going to be the same testing code it's just you're not going to run those and that affects this state hash that comes out and the Alec at the allocations that come out that affects the state route um get pr4

supporting state test okay good G has it and also if if you go to into the pr from G there's an example in a in a comment below that you can see the exact uh behavior that we yeah for example that that one is the is one of the system contracts so before if you have this the state test set to false you will see the storage um get modified because you are actually Implement you are actually executing the block uh Block Level uh changes whereas if you said this FL to two it is suspected that the the system Contra is not executed at

the end of block and you can see that the storage is not there this is just one example yeah because the uh let me convert this to decimal the um Beacon chain is the one that always always gets us because you have to set up the last time you set it and if you're setting the beacon route to zeros it still has to set up what the time that Beacon route was which is time is set to a th for most of the tests that's where the 38 comes in so that's usually what's breaking a lot of the tests when literally every test starts breaking um that's one of the things and it's going to get more consistent with um these uh new uh requests that are going to come

in um the generic requests in Cancun not Cancun uh Prague so the next question um right now we're developing tests off of a Cancun base with Cancun plus uh the 76 92 changes um should we be shifting to Prague as the base and including all New Prague features including potentially the um the requests and that impacts the block header in the block tests and the state tests not the state tests the block tests and the um Hive tests our teams ready to merge in their devet one and devet 2 stuff into their

eof I think M1 doesn't have anything for can ready yet for Cancun yeah seems too early for us for at least okay um do you you you do support the beacon chain updates at all I mean for for prag for now yeah okay when do we feel we should shift over to the Prague stuff though um nether mind is it going to be

a problem building eof off of Cancun and then shifting to Prague I don't think so but Iman can you confirm or B I haven't looked at U code for some time we are not sure about the status of the other PRS but I think we prefer it this way until later a bit until we pass at least we pass all the tests okay um and reth you're currently

building off of Cancun or Prague uh Prague we just to finish finish the support for authorization transection m version forite one but you have state test support right yeah we can yeah we can leverage those and your state tests don't apply the beacon chain updates no okay so it feels like most people are still able to or preferring to point to Cancun or can support the state test it's going to break uh block taste tests

and I don't know anyone uses Hive tests um outside of Hive um but it looks like answer that we're going to stick with Cancun for at least the next month or so okay um any other testing concerns or other items all right um if we're not hearing any uh so this week um is an off cycle call um

last week was Etc I was also on vacation at a family Memorial um so this is actually a fill in for last week's meeting uh the next meeting will be next week and then the ideal would be to go to the two-e Cadence off of um off of allord dev's uh execution layer um so hopefully we'll be able to stick with that but we're going to have another meeting next week um any other comments before we end the call any other questions right we want it next week but not in two

weeks and so the idea um when we don't have conferences and other um vacations and family issues getting in the way is that we have it every other week um opposite acde do we want to discuss the is contract right now or you know given we have like 15 minutes left or do it next week but then um for next week we could actually async prepare much better proposals I suppose yeah we can discuss it um yeah just no decision on it I

think it's fine so um one of my pitches for um addressing so bit of background um ERC 721 absolutely requires as part of their spe the ability to say is this account a contract or is this account an eoa and we don't really have way to distinguish that and solidity put put in some code to make sure you don't accidentally call eoas when you're expecting a contract which is where this originally came up but the 721 requirement I think really forces us to do that um the is contract I think is one solution there's there's two main Solutions um my favorite is is contract but I would be okay if we also

did return code changes exd call series op codes but the is contract one um basically takes over the EXT um code size operation and it fixes it to return a fixed value um and I'm thinking maybe we want to change it to return one of two fixed values um because the check that there's written into erc721 is a check is code size greater than zero so we have the same op code at the same location provide something that is greater than zero when it's a contract um then that provides us the information we need and if it returns one for a legacy contract and two for an eof contract um that would address um the needs of literally what 721 would do so we could

use the old code containerize it and it would work just the same um so that's the distinct Advantage I see for is contract but another option is um to change return code of EXT call um Hugo you came off mute you got comments on that no I don't have any comment okay anybody have okay uh Fria yeah is it a third option to do a separate call status op code what would a call status op code be so the the issue with changing the return values of the call up codes is

that it introduces or it requires a longer sequence of uh operations to check that a call failed or not right uh so that would be more gas expensive um the one way to keep that as cheap as it is currently is to add a separate op code to get flags or status codes for the call that just the last call that was done um so the yeah it just achieves keeping it cheap um and getting all the information that we want out of failures or success is even yeah this is the first time like a

Col that's been proposed I know it's um there was one EIP that didn't get much traction to track things like overflow and underflow and arithmetic operations and we would need some sort of a flag call to get the flags out of it from the last time the flag was set or cleared um and this could you know potentially provide that yeah well the the one that I was thinking was specifically about calls um but yeah I guess it's General Flags register that could be used for that I will say that for calls I also think there are other flags that we might be interested in such as that the sub call run out of gas which is uh because of the removal of gas um introspection is

no longer possible but some use cases require that kind of information like a 4337 entry point that is currently not implementable in UF go ahead the arithmetic Flags would it some because we had a similar proposal um and we reviewed the number of options having Flags not having Flags Etc and I think in turned out that the flag version is is probably was the worst one um so I wouldn't probably mix that um with the the call Flags uh and wanted to bring up one more option we kept discussing on and off that call would return uh two values

which again would be like a brand new concept two stack items but at least in that case you could just pop the one you don't need um yeah I'm not sure if that's that's a better option it's just you know one other option um we have been discussing um but as a closing statement I would say that I think generally we were looking to optimize for the the most common case to to make sure that the instructions are the cheapest on the the most commonly used case which usually is what solidity implements um in other cases can be more expensive uh it would be interesting to know you know this Fleck proposal um if you could make up like a

a write up of this how does it look like for the the common case in solidity versus other cases so just to make sure I understood um you were s I think I make like a i explore the the call status op code and see what it would look like for the code gen for solidity in the common case which I guess is like checking did the call succeed yeah I mean the the ask is two parts one is because you mentioned you know there may be other flags of importance um so if you could just write them down you know any list that may be like a good start uh for you know next

week's discussion but second it would be interesting to see how you know this the status version translates into solidity uh what solidity does and um and maybe you know any of the other cases you think about so pushing two values is also it would be notable it be the first op code to return multiple values but it would still be a net shrink of the um of the

stack because we already require uh three op codes so while novel it's not problematic regarding the one of the suggestions in the chat for code version and this sort of wanting to stay as far as possible from code introspection the way that I understand uh code introspection is not

desirable in case in the future you want to make any translations to the bite code but it's like just being able to observe that there is or isn't code in there or even whether it is a specific eof version or an eoff contract is that any do we see any problem from that is there a chance that Legacy contracts become e in the future um yes theoretical chance there is I guess but yeah I meant like if you translate one UF version to another and some another contract assumes this one

version or like Yeah because it can read it so can make assumptions about it I guess and not support the next version so something will be broken but this is Ready Go version is part of the code and observing it is also part of code observation I guess yeah ter RI on that um translating code I think one of the ideas was not just necessarily between eof versions like let's say we got rid of um dupen a dup and required everyone to use dupen

we could rewrite that and have mostly the same code um but also if we're going to translate the code into a ZK system going to trans the code into um some IR that um that uh supports um you know compilation to it um or we did directly compile it down to say x86 and that's the Canticle code for it um if we don't have we don't have the ability to introspect into it um we can't cross that barrier and contracts won't break when systems do those changes um so that's I think one of the motivating factors and I think the most critical one is of course the translation of this code into a ZK validity proof um and putting things like what version are you makes us

hardcode it or do nasty tricks like put the entire bite code of the original into the data section so if somebody queries it that bite code still available um if they if they read from the code um or read from external code so that's a lot of the motivation was to make things know the ZK translation in particular um more cost effective any other questions

all right um if there's nothing more um I guess we'll see everyone next week um at the same time in the same Zoom address uh thanks everyone for all the work they've been doing in E really appreciate it talk to you later thank you byby you