EOF Implementers Call #23
EOF Implementers Call · 20 Sept 2023 · 58:48
EOF Implementers Call #23, held on 20 September 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
[Music] hey everyone welcome to the eof implementers call number 23 uh let's just go ahead and get started with client updates really fast and then we can get into the open questions that Andre sum summarized so does any client want to share what they've been up to the last few weeks denin I assume most people are thinking about Den con yeah we also don't have much in vm1
related to E but one thing we implemented gr 4 instruction but haven't tested it thoroughly yet because we first need to implement blob transactions support and then gr for transactions are extend in those so we are blocked by that a bit but instruction itself is very similar to a crate 3 so it's not much complexity there sorry could you say again why it's blocked on blob transaction it's just uh grade four transactions are extending blob transactions adding new Fields there so we first need to support blob transactions and then extend
those why would you BL transactions yeah blob transactions require blobs don't they so we can't extend that right I don't think a blob transaction can be included without minimum one blob like the blob transactions yeah yeah so blob transactions I wouldn't think of them as the next progression of transactions it's actually a very specialized transaction type specifically for rollups and it doesn't support any yeah contract creation Behavior so I think that if you're doing this create for transaction it should
just be an extension of the 1559 transaction without a blobs field does this mean then that we either use grade three or grade four or blobs in transaction and we can't use both I think one of the original design goals or I mean maybe not a design goal but a thought with blob transactions is that creating contracts and including blobs is not a very relevant use case um and yeah we just didn't want want to
support it because of the additional testing surface it requires because as you know whenever you have these things you have to test both how things behave with a nit code how things behave if you call code and so the idea was just let's make it so that it's not possible to create with blob transactions and I think with create 4 we probably also are happy with that because the thing is if we add create for to blob transactions then we also have to do it for, 1559 transactions cuz blob transactions are extremely specialized and yeah it's not really uh it's not really the transaction type
that will become like the majority used transaction type yeah makes sense yeah so there's a corner case where they would both be creating a blob and wanting to do create forign a transaction do we just prohibit that you can't post a blob and do we create four does create four add additional fields to the transaction type is that the thing and then it uses that stuff yeah so I mean it just yeah I mean what happens if you call create four from a legacy transaction type it just fails I would hope it would see I think
create four needs integration with uh the protocol and I think that's I think notionally create 4 is the idea of how we do it but I think the specs of how we're doing it are going to change dramatically when it actually gets implemented I think it works better in an ssz world where we have an ssz transaction where you magically add whatever other pieces you need and take out what you don't but I don't think we're there interesting okay yeah uh maybe something to further discuss but yeah as of right now Bob
transactions are super specialized I would not extend it with the create four Fields I would do that for the 1559 transaction um great that's probably all the updates do we want to jump into well I guess yeah any from Viper side in the last couple weeks uh Hey I just joined the call um nothing new but yeah it looks like Andre put together this list of open questions so um maybe we should just talk about those yeah let's do it Andre do you want
to jump into the questions you posted yeah there's not much new or nothing new and we've discussed this over past meetings and I don't think there's much new from our side regarding this so like so for the first one I have one thought uh so this is Charles's idea to not U uh or rather to to do uh deploy time validation of first level sub containers and then avoid doing it at grade three execution uh so for me this seems like some kind of inconsistency or like
creating a context dependent behavior of grade three because some grade 3s then will do will not do this runtime validation but some will still have to do to do it because grade three can be NE one not at the first level so if unit code contains another gr three then it will have to do the relation still so that's my current thinking about this my hangup on this is there's some validations that will fail when it's as a subc container but when it's inflated with auxiliary data it'll it'll pass so if you're pending data that uh data operation is referring to um the immediate mode one um that one would
fail so it's possible to have contracts that could become legal when create read but that wouldn't be legal within the subc container so I think it's cleaner just to not validate anything that's in a subc container and take the runtime hit we're charging gas for it anyway yeah this applies to deployed code only as I understand Charles's idea it's about validating init code similarly I don't think we should validate until we're actually about to instantiate the contract because the validation could change what if you append enough data such that the um uh the data read operation succeeds in the
immediate mode or what if you don't depend enough it could change um you know what's in the container can be invalid but you add enough auxiliary data suddenly it is valid so that's that's the problem I see there uh that's interesting I think my idea about validating the NIT code is just the code itself not like it just like basically cach is the step that you're going to do every single time at runtime um but I think I actually don't understand the the new create semantics as well as other people in this call so that's all so I would think that
would be a client optimization that they could do they could do a pre validation but if we were to have some things that could you know validate partially and different things we only have one level of validation right now either the whole contract as it is as valid or it isn't and to to to do that efficiently we need to introduce another form of validation where everything except for your um from the data load and operation is validated um I think there's some kind of benefit to having typed in it code so instead of just saying um you know we're going to load some data and from some
data section and deploy it to say this section is definitely a nit code and we're we're going to it's going to function as a nit code and we're going to you know hopefully call Deploy on it at some point right but we don't have a mode where we validate just the code sections and besides data load in is one of of those codes we would need to validate and would then need to to to validate it would need a reference a legal spot in the data section uh is that like a nested data section so like it's like a data section
in the in code is that what you're saying yeah it would be a nested data section it would be within the container why can uh and nit code has a data section so a nit code is its own eof container and then the deployed contract is its own container within that um if you go to if you click on my create F1 there's a visual in that which for create F by the way I want to kind of withdraw it um I don't there's issues with it but if you look at the
um the factory contract let me go ahead and share make this smaller so it's not g to blow everyone's screen up um is it cre here we go so um here's your factory cont contract which is this whole thing is the container including both code and data sections you call create three you reference a container within it so this entire container contains a nit code and possibly data and the one underneath it so actually the one we're deploying is too
deep and if you go even deeper the deployer itself would have its own rapper contract that you would init I mean this is just the Fallout of how create 3 is defined so the data section you would refer to your entire init code would be one entire container and it would deploy another contract inside of it I me it's just the the nature of how a nit code was defined to work inside of ethereum and how people are going to expect it so it's like the weird intersection of how we want subcontainers to work and how a nit code is defined to work so every Factor contracts going to have
at least two two nested layers of subcontracts I think uh whoever was working on solidity gone through this a few months ago you have you been saying some stuff
Charles or have you been on mute the whole time no no no I'm just uh listening uh so yeah yeah so I mean I think that the this thing in your diagram called child contract init code can be validated um but maybe maybe I'm still missing something screen yeah yeah I think that is true because so this data load and
validation problem is only a problem because we append the code append the auxilary data to data section and this is for the container that has been deployed but this child contract init code is init code container it's another container and even if it has data loow in it's the data section won't be changed so theoretically we could like kind of cach or but then we would need to have two separate validation modes because when we validate this container in and of itself um and execute it we would not validate this one you know as because we're validating this container as a container and then we wouldn't validate
this one yeah I mean it's it's just first level validation and then first level in which context because then we have this one um where we'd have to do the init code when we come in at the beginning of a transaction the actual contract that gets deployed doesn't validate this first level that's in yeah yeah that is true so it's seems that it's difficult even to distinguish which level we are at when we're executing so I I'm suspecting it's not even possible in the end I think it's either full validation
all the way to the bottom or top level validation only are the only two um Solutions that'll that'll that'll survive as an attack surface yeah I'm I'm looking at the the mega spec and uh there's these references to in nit code
mode uh but it's not really defined I think that's a runtime change um and that has to do with return contract init code mode is execution of container given to grade three yep and we turn on return contract and we turn off return and
stop yeah maybe I need to think about this more but I mean it kind of seems tractable right like especially because data and code is now separated so now you can be
like oh well we know all the code that could possibly be deployed out of this contract even nested contracts um but maybe but we don't know if it's valid because we would then require because of data load in um some of those init codes would need to be deployed with extended code section with extended data sections to become valid yeah we kind of don't know which containers will be given to create three and which will be given to return yeah
um it's interesting that the return contract is always like a nested container um cuz like it could actually be a pointer to a section in the factory contract it should be a container because we deploy entire container with data section and everything yeah I'm saying uh here where like child contract nit code is inside of the fact contract um I'm wondering if this problem gets fixed if like the child contract gets
unnested how do I go into Ed mode yeah so we pull child contract to the same side as the init code sign into a hmd so I can edit it all right can I edit my stuff now here we go
I think that would mean that init code at the point of return contract is referencing a container that is outside of the current container which is weird it is a little bit but it's because you're executing it in a niit code right it kind of how would that work for the deployer how would that work for a for a top level deployer though because you'd have to contain yeah you would still have to contain it yeah you can't have like a deployer of a deployer of a deployer or something like this or like you the deployer is the NIT code and it couldn't have pure code it would have to have child code so I think these nested containers are just what we have to do deal
with so when you do it from a top level transaction um you can't depend data you have to bring it in with all the data you want which is fine because you control the transaction it's just the case of these Factory contracts BR need to data to deal with things like immutable values yeah right but I mean the this child contract in nit code container is not actually like a regular container right like um it can only be run in in nit code mode actually so if you know it still has access to every other operation it can do everything else but it can't do return or stop so like if you're running if you know that child contract in nit code has like a flag that marks it as a
nit code then you can validate its child code sections I think yeah I mean again I'm not as close to the implementation as as a lot of people here I think these uh init code mode errors are tagged as runtime not validation errors you can have returned um contract anywhere it's just when you're executing it if you're not in anit code mode it becomes an invalid operation so it's not a validation error um is that is that a is that a desired um
property it's simpler it makes it easy to validate because you validate every code on the same standards it's just at runtime you do the return contract you check a i in nit code mode if so you you uh you would return the uh contract it is a little bit simpler the reason we need return contract is so it can give data to the subcontract which may have been passed in from the parent right I see that um by the way uh uh sorry uh the the oxide is passing from the
parent so oh in memory yeah so let's say our Factory contract is a pool and we have our two erc20 contracts we pass those two to data as as uh as call data not as call data as auxiliary data this executes it pulls the auxiliary data and passes the auxiliary data again to the actual deployed pool contract yeah uh I think this spec wording could be clarified a little bit to say that Ox data is coming from memory it's not coming from memory it's coming from the actual data section uh return so when we're in the child contract init code that contract would have been
manipulated to add the extra data to the data section so Factory contract calls this we have Ox data we rewrite this with the ox data included in the data data section so it executes this it pulls its Ox data it pulls data from its data section and passes that in as Ox data in a child contract yeah but o data is from memory right right so you'd have to take it from your data section load it into memory and then in the return data contract return that memory section sure but so return contract these Ox data offset and Ox data size are referring to something in memory right yes yeah yeah
I think the spec can be clarified with that because it could be pointing to some data section or it I am always a guest because I don't have
an ethereum um I mean so I guess what this conversation is kind of illustrating for me is that like um maybe in it code mode is different enough to Warrant like slightly different validation rules I don't feel it is um unless we we would need to put a flag in the container to say this is an init code container yes and that's how we would
need to Signal it yes I mean I think that's good anyways and then we would have two separate validation checks and right now we only have one set of validation checks that every container must pass and I think that's uh more problematic place to introduce bugs then if we have that flag at runtime where you run your operation you see you're not in in nit code mode which the clients already have an anit code mode setup um to handle um so you see you're in anit code mode and you know you know this operation is invalid because you're not in Ni code mode yeah and I thought that the point of eof is to like make code more safe um so it kind of
doesn't align with that goal because now introducing instructions that are mode dependent whether they're valid or not so the safety also comes in an engineering perspective I don't think splitting into two in it code um two validation modes um is warranted for this small of a change um for me to support multiple validation modes I would want some better return so there there's runtime safety and then there's engineering safety what multiple validation modes buys us is that we can validate init code at deploy time not at runtime um which I think pays off in the end
because paying the cost of validating um code from the factory every time you want to run a deploy operation can add up but that cost is built into the cost of the create oper add cost that's born by so it's a cost that's born by users right so it's paid for it's appropriately build and handled I'm saying that if we maybe have different validation for nit code then users don't have to bear that cost but we still have the problem that to validate a nested container we would have to have different rules for data load in to deal with whether or not enough data is being
passed in or not we still couldn't validate it runtime actually because it seems yeah I don't understand it seems like data load and is okay even in init code mode it's not the init code mode it's validating it because it might be pointing to data let me find validation rules code validation embedded in it container may have data load and instructions referring to data
in Ox data part that is pended um so this is when so this is like when you call return contract right right in Return of contract then we can validate it so this is after init code runs and during return contract execution right right in the in the child contract and potentially the init code
contract um why does it apply in the unit code contract because the unit code contract can also auxiliary data applied because itself is like being returned from Return contract no because it's being called create three contains auxiliary data create three pops value salt data offset data size what's data set is the ox data pass through
without not necessary so data of certain data size is just input to create three execution and can be passed through if you you can be modified and passed through or whatever yeah but we have to catenate the data section here as part of the execution well that's in return data contract yeah I mean I'm thinking quickly here but like can't we have a special rule for data load and inside init mode in code mode which is like we only need to do data load and validation or
something uh Because by the time that we get to return contract we already have a lot of data we already have a lot of information about the deployed code um the only thing we don't know is the size of the ox dat that's passed so when you call return contract you can just like validate that Ox data offset and Ox data L are like that sounds like a client optimization not something we should write into the spec that's my take on it uh well client optimiz I think my position is that it kind of is a client optimization but if it can you know improve the gas schedule for
like users then that is also good for like the entire network right yeah but I think the risk of introducing this level complexity into the spec is not worth the gas savings it's going to result in a fork more likely than the amount of savings we're going to get damage from the fork is going to be more than the gas savings we'll get from the end user on a net cost basis multiplying the impact by the likelihood
um should we table this as unresolved and work at some of the other open issues to see if we can resolve some of those yeah yeah I think we're kind of all on the same page um and I think the only question is if like the benefit is worth the tradeoff or if there's some some way of thinking about it that makes it easier to reason about yeah so one is unresolved to create three variant that adds address parameters to get a nit code from a container of another account so Andre what was this specifically
uh was Char idea also like my take on this is that is also like addition that we could leave without and I wouldn't add it into the first version probably okay because we a nice to have my concern is that like pushing any features out makes it very difficult to get them in later unless they're breaking changes I think we can bring them in and I don't think it create copy operation which is kind of what this is would be a breaking change it took us like three years to get M
Copy it yeah we didn't it wasn't it didn't get the right attention in allore devs true so create three is is bubble there's I don't think there's opposition to it other than size I don't think there's a standard a spec concern for it so resolve that is space available yeah the other thing is to have um create three just always takeing address
parameter but then how would we get the contract loaded in initially I mean I think that was one of the proposals to have all contracts just be copi with memory sets but how do you see the first one to get out there how do you just drop contracts in the locations um I mean create to get the current behavior create three you would just call create three with like address right but it's pointing to an address of an existing contract how do we get that first contract onto the chain so this would be a replacement for create 3 would' be a new
thing I mean how does create three get cont on so you can take an entire eof container in a contract creation transaction and execute that that's how the spec is currently written that represents situation then the then the create message call or the create transaction won't run in the first place um so what's going to wind up deploying at the address is the factory contract and during a nit code it runs the code from this container but that's not the code at the address it's the code at the init
code it's just the weird way init code Works in ethereum right now even before eof wait I thought that like the way you deploy contracts in UF is to use create four with extra transaction time create for is how you would do it in something like a smart contract wallet where you would need to specify the contract outside of the contract you're deploying so right now the way it's specified only EAS can can deploy contracts and create four is how smart contract wallets would create contracts which has its own set of issues that I'd like to discuss in due
time um so I must be missing something again uh which is like how do contracts like right now to deploy contracts you just like send them to the create address right right You' do it you would do a, 1559 transaction and the input data would be the entire eof container and so the client would see that it's an eof container that we're we're running and it would validate the container it would start executing at operation zero but the code does not exist yet until we get contract and at that point all of the the contract storage that has been set is part of the construction and that contract data
that's done by return contract data if it's invalidated those get put in the new account address and during a nit code it executes as though it's in the address of the contract it's going to be created without any of its code right so I mean there's no create three yet right all there is is create uh sorry return contract in this initial creation transaction so with without create three the only way to create eof contracts is just through a create transaction right so what what sorry what's the problem then I don't I'm not sure you are the one expressing the problem I was explaining the spec I mean what's the problem with
adding an address um argument to create three so that's an entirely different form of create that we can't adding address to Crate 3 is changing to Crate three to always copy existing contracts that are out there how do we get that first contract out there without create three and we would have to rely on contract create transactions um to copy what's out there it wouldn't be a very good Factory because you just have stub contracts that do nothing and then you it we're we're separating out into separate addresses I mean we could do it that way um it's just not self-contained and then how would you
get the address into the factory contract you need to do some pen stuff um it would require multiple transactions to deploy a contract a factory contract whereas this requires only one uh sorry I don't get it um like to get the same semantics as the current crate 3 you just like add address to the stack right but you would need to have you don't have the same semantics because you'd have to deploy a stub contract for your factory this little child contract init code this would be need to be
predeployment contracts not self-contained which I would argue it's a security risk uh I don't understand why they have to be not self-contained like why can't they reference themselves they don't with deployment right you could get it through an OP code but then it would be referencing its top level self not the thing that is deploying inside of it the factory is different from the
pool you'd only be referencing the factory you could create factories of factories but you could never have the pool you'd have the factory code as part of the pool can we move on to non-cre and come back to create as a group later because there's some other issues that aren't related to create Charles I didn't hear that yeah I said sure okay so um I'm gonna withdraw
create f um my reason for that has to do with you can't get an address over the init code in the way it's it's structured um so we can just three is done um four jump fi um I think the current situation is it's on the bubble because of um too much to ship yeah I think so okay swap MN similarly go ahead yeah same it's like addition that may be nice but again I didn't I'm again stating anything not not strictly needed okay
so like just to too big liked swwa MN liked just too big return data load I think similarly useful just too big and exd data copy so like four through seven are all good in principle just too big of space okay gas costs which gas costs are missing yeah I don't didn't make a list of all of them but at least I remember return data contract for example it currently in my implementation it is cost zero because return is zero but it does the appending
which is non constant operation even so might be even Dynamic cost so not sure okay um so I think we just go ahead I I I think that um I know the suggestions made by Viper are kind of useful like uh without jump fi and return data load we get Cod siiz regressions and I think swap MN is um basically like if we're going to do EIP 663 um then swap MN should be in there because I think it's actually more
useful than the other stack operations so I mean I don't disagree that it's valuable and it would make things a lot better for Viper um the concern is we're going to have an even larger spec and if we have too much data I'm afraid the core devs are going to say eof is not worth it let's just stick with Legacy forever um and the more stuff we Pile in the high jump F why is Jump F important I mean why is Jump f and like swap M Swap n and dup n are are why are these instructions going in I mean you're right we probably could
shave them out to make it easier to get through I mean it's just horse trading it's yeah I'm not sure why those made it and those didn't because those were initially thought of in the first in the first pass of this I mean there's got to be some some it could in some don't I don't know that I don't know that could claim it's fair right well I mean on the issue of fairness like pretty much all of the the I mean feedback was requested on UF and you know I've been consistently giving feedback but like none of the suggestions have actually made it
in and so yeah I mean talking about putting them in in the future so I failed to see how like going through this same process is is going to so what I thought is we would tag these for Osaka these non-breaking changes as a group so um jum fi swap MN return data load EXT data copy um those if they pass Community muster would be going as a group in Osaka because we've already got a huge testing surface and it's actually an argument for pulling some stuff out um if we need to reduce the size that's not essential to it like we could pull out 663 to reduce
the size and that's that there's a valid argument there to make it more palatable it's all core devs right well I mean I think these should at least be on the same footing as the as the eips that uh they're providing kind of feedback for yeah um this another issue is like 663 um is an EIP that existed uh for years so I think that's another swap MN is is a you know it's useful for Viper but I don't think that the way solidity Maps its variables it's as useful to them so I think that's why it didn't come in I think it's years ago I think it's actually useful for everybody um right it can be it is can be useful for
everybody but I think that's why Viper didn't propose not s didn't propose it any earlier because their model didn't depend on it whereas Viper's model does so I think that why it didn't show up years ago I don't think Viper's model depends on it I think that the argument is that if we're going to have these stack scheduling instructions then swap MN is like I mean so I think there's multiple scheding there's multiple steps and we're trying to skip steps first we need to get an eof container deployed they can do backwards compatible changes but if we put every possible thing we want in the future we'll never get it as it stands we have to put every possible breaking change in to get acceptance
from all cevs and that's what's driving its size so that's why I think there's resistance to non-breaking changes because we can add those non-breaking changes later but these breaking changes have to happen now well if I'm understanding this argument correctly then we should be considering shaving more things out of UF yeah just what I proposed yeah that's what's needed to get it past all C devs we should shave off what's there to the bare minimum that's but I think that the the the initial proposal should probably contain more things that I mean if that's the strategy then then the initial proposal should contain more things and maybe some things get shaved
off later right so there's what's necessary for breaking what's necessary to replicate current behavior and what could add value and I think the add value stuff I think by default should go into Osaka and and it's the stuff that's needed to replicate current behavior that is the stuff that's at risk is the stuff that um is where most of the discussion comes in I think there's some of that stuff in that category that we shouldn't shave out that we could that is needed to replicate current Behavior Uh such as and those are just the categories I'm putting them in I mean if we were to go through this exercise those are the things we would need to to do the operations for example the data operations would replicate current behavior not strictly necessarily for the container we could evolve it
compatibly with the data but we would be losing functionality that um is is wouldn't be a parity so like the data operations are existing Behavior swap MN we've never had that before so that would be new behaviors that would be a class three you know if class one is required class two replicates current behavior and class three is new is new Behavior right I mean so maybe we should go through and do that for all existing things possibly I mean I think part of it is we need to get a temperature check for all
core devs outside of this call to see how concerned they are about the size and how they feel about adding you know four through seven um and if they actually want us to shave stuff down I mean we're talking hypotheticals here C we need get check at least four and six um we're I mean like basically I looked at the spec and I looked at how we need to imp Implement things and it does I mean it causes code siiz regressions okay so that's that's an argument for bringing them in for moving them to
class two um but at at a certain point we have to shut the door there's lots of things could always do at some point we have to shut the door and ship something so that's another one of my concerns of spending long meetings arguing over fairness is we just need to get something out there so we can go through this exercise but we can't spend forever doing we didn't even talk about the minor nice
to have I think those are based on the discussions about size all off the table some of them reduce actually I complexity okay and which ones would reduce well like 10.3 this is maybe haven't discussed this before we did uh so this is instead of Max stack height requiring the exact the exact Max stack height that is calculated during validation it can mean the upper bound so we allow any any
value below and this will simplify testing at least that's the motivation for this because in test we can just put Max value in the header and then not not care about it then right in the test is easier than and well in Spec wise it's just um one line change from equal to less less than or equal so could that be an attack Vector where everyone sets Max stack size to 1024 I don't think because it it only affects I guess call F spec overflow check so if you put Max everywhere you
only reduce the possible Max call stack depth call St dep okay so um on that theme also reading through this 101 looks like a breaking change we would need to do that now or never to forbid unreachable sections yeah um 10 to make data section optional um I'd call that type two um it's well it's breaking and it's nice to have so if it's not present it's implied zero um well this one actually I think simplifies a bit right the parsing and
validation maybe because so yeah motivation for this is the it was made mandatory at the point when we didn't have subcontainers and and it was argued that having data section mandatory is making makes parsing simpler but now we have container sections that are that are not Bor that are optional so it's like like a mess data section is mandatory but can be zero container sections are optional and cannot be zero okay so that was my next question if it's optional zero is an invalid container that's good so I think that's a type one
change create four I need to read through this and parse it really quick this is something to do from the spec I guess just limiting the number or the or and or the size of in containers of the transaction it's like a question to the spec of the new transaction type didn't Shanghai put in a transaction uh in it code limit that's twice the uh code limit uh yes yeah yeah Shanghai so would that be the same value I guess this applies yes but also the
number of them do we have a limit on the number of init codes in a transaction because it's so I promised idea about create for one of my concerns about about accessing by um index is that this won't translate well to user operations so if I have a user operation that's creating a contract and I have index one and five people come in with a user operation creating a transaction at index one there's only one index one in the bundle transaction um if I were to make a change to create four I would want to have it reference it by cash of the container so you can have it anywhere
you can reorder it and it's going to grab it by hash from the transaction so it identifies it without position so you can take these five different bundled user operations that are creating small contracts put them together and you can just order in any way because they're all going to reference their needed um in nit code by hash but then you know we would need to have some definition in um in the create in the user operation to specify these things that would need to be pulled out and put them in transaction object so would require changes to 4337 because we need to pull stuff out of the transaction or we would need to allow create forward reference I mean because user
transactions come in at runtime yeah this a kind of Break Stuff with 4337 I think this is a bigger meta discussion that's just as impactful as as what Viper needs um to make their code efficient um because the metat the uh user operations are the same level of code introspection that you would see from um creating your own B code so that's my concern with crate 4 um I see we're two minutes over time um probably should end the discussion here yeah probably good um seems like we
covered a lot of ground just wanted to mention we have one more of these calls also before we're trying to present on allore devs I think the allord devs we were looking at was October 12 is that people remember yeah sweet yeah so yeah I mean it would be good to talk about B asynchronously in the next uh two weeks and try and resolve these things so that on the next call in two weeks time from now we have a pretty good idea not too many open questions and we can you know maybe just talk a little bit about maybe yeah reducing scope slightly for what is presented on all C devs or just like strategize a bit about how to
present to all C devs and then that will give one week for um yeah I assume the Epsilon team to prepare to present it okay so the first item is going to be allore Dev strategy and then we can go back into these yeah I think next week that's play cool uh I guess thanks a lot guys uh we'll see you in the VM channel on Discord in the meantime otherwise talk again in two weeks have a good rest of your day