EOF Implementers Call #8
EOF Implementers Call · 22 Feb 2023 · 54:13
EOF Implementers Call #8, held on 22 February 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
hi everyone this is um eof implementers call number eight and I think this will be a short one because a lot of people are often on holidays um I think usually we go through around just to see what everyone did um so maybe let's do that and um yeah I would suggest start with Dano because basus starts with the letter b we've had we have your F1 implemented we haven't done much movement on 1.1 waiting for some of the specs to settle for exactly what needs to be implemented in the interim we've got out of the CNN
tool implemented um which should help getting reference tests um I know uh Dimitri was pretty excited we saw the first PR come through it's not quite ready yet um there's some packaging issues but that's uh we've been focusing on getting working so that um if things get wherever I think he's gonna Blended first they can get tested first um rather than having to wait for the get implementation um and it seems like we're all settling on the t8n tool for the interface rather than the retest death interfaces because the testing team has been pointing um never mind and evm1 that tool instead of standing up the RPC server so that should improve the testing story when we get to uh final implementation to provide better vectors for us to do differential testing against and also so
that any client with the correct answers can create can fill the tests so that's what we've been doing the past couple of weeks awesome so you have like the entire teeth and implemented and you merged UF fully as well so you're able to to fill any tests right right in uh Cancun well it's it's targeted at Cancun even though the tests the reference tests still Target Shanghai that needs to be fixed so if you target Cancun eof V1 should be turned on ready to test I'm sure there's differences in there we just haven't you know done a full differential run so that's good
[Music] should we move on to another mine Ahmad or I'm on do you guys want to give this an update uh okay well another month we kind of finish the implementation of eof1 we didn't merge it yet since we are still doing some optimizations and some trying some stuff out uh when it comes to UF v1.1 and or your V2 we still haven't started on that stuff still waiting to
see what what happens and what we decide and yeah that's mostly it but I actually would like to ask you Alex uh one thing is that like since we have eof1 and eof 1.1 uh when we are going to the hard Fork it's gonna be 1.1 it's not going to be one correct so we're gonna go right away with eof 1.1 without the first version yes that's correct I mean that's the idea okay just making sure because
yeah then I would ask what is the status of the spec or finalization of the spec of eof 1.1 is there anything to discuss about the spec of 1.1 uh I obviously we don't have probably enough attendance to discuss a lot of things but yeah yeah there's there's definitely a lot to discuss um I mean let me give just a brief update from Epsilon um and then we can jump into the discussions so from Epsilon I mean just starting with evm1 uh they also fully emerged T8 and
support which yeah I think it's it's not like 100 Complete because things like supporting the logs Bloom filter that is being implemented currently there's a PR for it and there's also work for the b11r but the currently merged version is already capable of filling tests um eof tests um however the complete I mean the big eof support is a merging to evm1 it only has 35 40 100 670 in the master
but we have a large PR with every single EIP implemented in it um that is the next goal to be merged and then evm1 could also be used to field tests um but since Basu has it implemented um maybe basically is the best client currently just affiliof tests um separately to this we have a PR uh on which Android is working which is basically EOS 2.0 so it's APR for create tree and the return contract and the goal of this is just to have a working implementation to discover any
any issues we didn't really think about and we in fact we did find uh some cases like we need um error handling when the auxiliary data is larger than what would fit into the data section um so I think it it is a useful um a way to to prototype test and get more data on it um and then separately outside of evm1 we did a complete review of the checklist and updated um the status of uh every single client and also the testing suite and regarding
the testing speed from our side it seems to be like mostly complete vr7 is submitted for every single EIP including 54.50 I think the last two is this 4750 and 5450 tests haven't been merged yet but PR's exist with the test cases we wanted to have for them um so from that perspective um we kind of consider lucky with one um almost complete with the exception of um at least one discussion which is the type section Flags and for that I posted a document
um with a number of different proposals had to accomplish that the main point for this type section of flags is to support non-returning functions I mean that is the immediate need we want to fill because that feature has been requested from solidity but as part of this discussion it opens up the door to support more flags and some ideas we discussed that we could have pure Purity level so like pure view functions and beyond that um I don't well yeah the other option the other like feature we thought about
that maybe one could Mark any code but that seems to be even less useful um the point is that we are unsure whether anything like Purity makes sense or any anything else could make sense and that's why uh we would like to discuss this um this document and I think this is the likely the last discussion needed to close down eof1 and and then we can move on to to 1.1 for which um no proper spec access um but my plan was to to modify uh to create a copy of the unified spec and modify it to you know to include the the changes
the the alternative is to have like one document which just describes the differences to eof1 um but we already have such documents um so I'm not sure what is the best option having like you know a diff or having like this complete UF 1.1 unified spec um and I kind of bled into like discussions apart from the updates but yeah should we discuss these like to be your questions or do you guys have any any questions to the updates I gave yeah the the non-returning functions
um means that a given function wouldn't be returning to the color and the significance is that right now we need to if you are so by calling you need to to make sure that the the Kohli has um exact number of outputs um because the the the outputs are validated and the main use case solidity has is have like an error handling function and they want to share this error handling function across a number of um other functions
and the colors likely have very different number of outputs and in the current system they cannot really share the same they can't really easily share the same um error handling functions um so that that's the the main use case when we Mark a function on returning then the the number of outputs are don't need to be validated um another question would be if if a function is non-returning does that mean that I can use a non-returning function call as a terminating instruction yeah yeah I would say so
so I guess effectively like try cats but at the VM level but but if we use the sorry to interrupt you can go ahead no I just didn't understood what um what app could you refer to or like yeah for me it uh the question is if we can use an unreturning function as a like uh terminating instruction that would really complicate the code that we use for validation to validate that the code ends with the terminating function instruction because
that means that if we have a call method uh instruction at the very end we have to check that the call is calling an unreturning function and if it's not then we will uh like say that it's not valid which increases the complexity of the validation operation is that something that we would like really would like to introduce or allow or or do we just say no we're not gonna allow uh call uh function call to be a terminating instruction and that means that after it we will have to do return or something
no so we have another instruction which was part of 4750 but it has been removed and moved into another VIP which is to jump if jump to function and that's the way you would use non-returning functions you would jump to them and uh and so the jump f is is basically a terminating instruction got it got it so as you can see in the without having like this non-returning um flag um let's say you call into a function and that jumps to another one and where you jumped uh returns uh this this
target function has to have the same number of outputs as the first one right that's the current case and introducing this non-returning flag um removes this requirement but if it's not returning it wouldn't have any return values anyway with it well you could have multiple people jump into it then I get it then now so if one question I have is if these flags are there if you have a non-returning function and you don't flag it is that a validation error or is it an option to flag one that matches it or do all functions that match the case have to have the flag now I think it has to be done at
validation time but when you compile it and then compile a function in solidity and it happens to not return if I don't set the non-returning flag will that then become a validation error yeah I'm kind of slow today because I haven't fully yeah I haven't been that much part of the the debilitation discussions right yeah I cannot give like a clear answer right now okay so that's that's one thing I would want to clarified in this spec um that the flags whether or not the flags have to be put on functions that match the standards or if they may be put on the functions that match the
standards because if it's May that simplifies the issue for the compiler and if it's a must I mean if it's all done ahead of time and we're not analyzing it you know that's it's it could possibly be um quadratic for the compiler but who cares about people with radic for the compiler because you can always cancel it as long as it's linear for validation so yeah I mean the specific case for solidity is that it already knows you know which these which are these but what about Viper a new language or what if solidity has a bug yeah I mean that's fair that you know
other languages may have different design um or compilers we have different design where they don't really notice but yeah yeah I'm not sure I can't be of like real value from this conversation on at least the arguments around the non-returning I think it has been the biggest debate has been between Daniel and the Pavel who I think have the most context on the different options they discussed um I think have the non-returning should work probably has to be discussed in a call where both of them attend
what we could discuss is assuming we want to have this flag how do we how do we store where do we store this indication and what the size of it should be like should it just be one bit returning non-returning or should it be more like is there other flags that people were suggesting like as you said there is the pure thing but what what benefit would um introducing this pure flag would uh would do um so share that document
um in the chat here but I associate it I think last week sometime on Discord and the short answer is we don't know if anything so we like fairly certain and the non-returning flag makes sense uh somehow indicating it but we're unsure if anything else really makes sense we I mean like this Purity stuff is something we identified as like potentially maybe useful um and I think the main discussion we have been going around is um what to anticipate and how much effort do we need to put into forward compatibility and and they came up with a number of
different options had to to represent this if we want to support um multiple Flags um if we only want to support this feature we already kind of have an answer to that we kind of have a special value in the outputs because we already restrict the the outputs to seven bits so we could We have basically two options there we just use like a reserved value like 0ff for the outputs or we could treat the the top bit as a signal and then use the the
bottom seven bits um just like a bit um a bit set and so one example is we could have the value 81 and hex um which is the top bit set and the lowest bit set to signal that this is non-returning and then we still have options together like Flags in the um if you want more than this non-returning then we definitely need to discuss the the other options so a couple of uses I could see for these flags but this is only an eof world would be for um like each call when you set the static flag you can verify it
along the way you can do quicker approving that the call is going to be static we could require the static plaid for some of those um similarly for uh just in time compilation of the code you can look at the flags to make assumptions about the compilations um my question is is it worth imposing that analysis on everyone when only you know hypothetical implementations would be using these flags is this the return of the um the bloom bits in the receipt so I think it's it's cool but I'm I'm concerned about the utility also just to make sure even if we think that this Purity makes sense I don't think we would introduce this
feature in you know 1.1 or 2.0 or anytime soon uh we would just want to make sure that the header is forward compatible to support us my mind you have your hands up uh I have a few questions first this Purity thing that all the other flags aren't they compiler specific like the compiler needs them to emit specific code or optimized code but should they be visible to the VM if we might not be in need and then
and also the other question is what happens after running a non-terminating functions function do we just stop interpretation the batch code if so doesn't a function section ending with a stop-up code do the same thing yeah I'm just going to briefly answer if anybody else's other opinions than um give it after select this topic of code wherever the stop code is that just terminates execution successfully with not returning anything in the written buffer or written data
buffer um the non-returning functions um I mean if they're working on returning it just means that they're not returning to the caller they have to be terminating they have to have like a terminating instruction at the end so they still have to clearly stop execution and regarding the the purity if we would have Purity Flags um in the type section that would have to be enforced um by validation and what that means is um that those given code sections couldn't use Specific Instructions so if
it would set set to be like a view function that would mean it couldn't use S store couldn't use call but could use a slow then static call and if it's pure then it couldn't even use as an example um so it had to be it would need to be done at validation time foreign I mean like about the view and the pure uh like
I understand the appeal but again what is the use case like what what benefit will they bring to the AVM I would say it's more like um a security I mean two two cases where it helps it's um it could help with security um and it could also help it um execution time because
one could translate different functions yeah I see I mean you said eot um yeah exactly I mean if if you know that some of these don't really touch States you may yeah you may have like more efficient options I mean to be honest we haven't really explored like the concrete usefulness it does seem to be useful but just stating again the main reason we discuss this whether we want to be future compatible and have a flex field first of all um and if none of these make if you
don't want to be feature compatible then we should just choose the easy option have a special value for the non-returning functions Greg I think you have your mic on maybe you wanted to add something um it sounds like to some extent you're just asking what can we validate um that would be clearly an error at runtime that anything we can validate that would be an error at runtime
um was is probably worth validating even if we can't easily think of a use case right now um there's a lot of users out there and so you're dragging on the call oh he bumped off
yeah so anybody has like any other hunch if any another flag would be useful generally um apart from the ones we discussed any other feature which could be enabled reflex I mean we can flag functions that may fail you mean like use reverts or have unexpected failures um you know like out of gas or yeah can can we maybe take like a just a
round in where are we leaning towards so one option is having you know flags extensible flags um we're not having them because we don't see too much value do you want to like get everyone to just say which direction they're leaning towards I would go with extensible flags but only like very limited so I wouldn't go with eight bits with the full byte I would go like something like of four bet or
something like this I'm weakly against because I'm concerned about the uh the effort return ratio that we're going to get out of this I'm not seeing what critical spaces is opening up that can only ever be opened up now um because if we needed to we could get another format where we could put flags at a different um section that we could add later rather than having to put it into the type 3 section not type three like the client three data so I'm hesitant to get fully on board with this without you know a concrete
value saying this is how it makes it better in the future when we do implement it so that's that's that's kind of what I'm waiting for I'm just trying to write up a comment on the checklist just to record you know what we discussed so then you're leaning towards not adding Flex right now only addicting when when the need arises is that correct yeah yeah and you know creating space for things that we might have I'm afraid we're going to wind up with something like you know the bloom bits again in the receipt something that sounded like a good idea that no one ever actually implemented um that you know are continuing to impose restrictions on us as we go forward
and I can right now after I heard his argument I kinda agree and the whole idea of bof is that upgrades can be virgined and contracts can be virgined and since everything is Virgin what what preventing us from just introduced these new flags that are needed later on with the new version and we can easily upgrade old contracts into new contracts with this version with these flags because um we can probably introspect the code and see that like this function does not return and we can flag it in that case if needed
but yeah basically we can also check like if we're gonna have a pure flag or a view flag we can check what type of instructions are executed inside this function and if there is if these fun app codes are not used then we can mark it with these flags also so the upgrade path is clear there is no need to include it from now so when I say weekly against if it goes
in anyway I'm not going to block it so that's what I mean by that I kind of agree that we have the the flags um or this exact reason that we can make upgrades um but at the same time reflecting to the past couple of months it seems to to be a lot of pushback in terms of having multiple versions so maybe that just means you know we the version is really just the Last Resort
um you know for things like this uh it would just mean that the feature wouldn't be worth the introduct introducing because nobody wants a new version and maybe that's correct because if the feature is useful enough maybe that's a forcing function but then just judging based on how much perspective in the UF itself got maybe the system isn't perfect yet um but does that mean that in the case that we won we add this uh eight bit field that we would have a hard Fork implementing this
new pure view blah blah Flags without a bump in the version of eof that's a good point I'm I'm pretty sure it goes against the whole idea of eof like the whole idea is that we we want to have things be clear as if it's this specific version then it has these specific set of handling of instructions and validations etc etc etc and that anything that changes it needs a virgin bump
that that was the premise as far as I knew I don't know so some of the pushback that I recall from from the uh offside interop is that they want a future world where clients only need to have one version of the evm for a current Fork I mean they're not doing any historical validation they can get rid of it and remove it so we're going to be stuck with at least two because of legacy and eof but they don't want to have like five because it's worth the four different versions of eof um so that's the reason why they want the pushback so that um so that at a current Fork there's only the eof version and the Legacy version so so we would if we were to do a breaking change we would need to have some sort of a a transpilation that we
could point at the old contracts to bring them into new States um so that's some of the pushback against just adding an inversion is they don't want out of control code growth like we've experienced with the current Legacy version of of the evm we've got basically on nine versions that you need a tweak and and configure your evm to be able to validate all stuff back in the previous history um once they saw the previous history version then you don't need night versions but then you know they don't get rid of the thing where they still have to have two versions of the evm so they want to try and put a lid on that that's that's where some of the the desires to not have multiple versions at the same time and I think the compromise we're willing to make is there's not multiple versions of eof
at the same time um adding a pure um is is uh compatible we don't need to to bump the version because if something isn't marked pure it doesn't matter that it is in fact pure adding a pure flag later just allows us to check that something that the author claimed to be pure was in fact pure but it has no effect on what went before so yeah as much as possible we can add new features without without breaking anything but the concern I have is if you care
about peer you're probably doing analysis anyway and you could get the answer that it's pure without the flag so why are we requiring everyone to calculate and validate pure when the utility cases for the pure flag exist if you're not existing are kind of small I'm concerned that we're pushing work on everyone for something that only one implementation might benefit from and then by my benefit I mean they could actually calculate it themselves since they already care about that data that's that's my concern with the current Flags out there again if they go in I'm not going to you know push back or try and sabotage it but I want us to think about you know is this the right thing to do yeah I don't know but um it's more like stating the number of
arguments to a function you're just stating part of the interface that you can check um checking it checking it at validation time otherwise you can do for optimization purposes but not for checking the interface and I don't I don't know how far we might want to go with that but anything that you can specify about the interface to be checked a validation time increases the type safety of your program right but in the case of function arguments we're actually matching up to make sure well let's make sure that we have this many on the stack before we proceed so that count has an impact on the interpretation time whereas the
impact of a pure in theory has no impact on the interpretation time um I don't see I I would need to be presented with some some how would this make The Interpreter better how would this make a you know I definitely make an aot compile better because you know even in the eot compiled because you still have to keep in the message frame the link to the state well for a period you can get rid of it to the state um but for like read only you know it what where is the advantage of this where does this speed up and provide value to the execution process would be my question rather than it's nice to be explicit about what you're adding what is it actually changing I don't know that it adds anything it's it's just type safety at validation time
you don't need the number of arguments you can check it validation time that the stack is okay without stating up front what the number of arguments is you can just check at validation time that you use the arguments consistently so any of this is a matter of what do we want to State um in the program itself to type check and validation time and pure sounds useful I don't have a strong opinion on whether we should have Pierre I'm just saying that's the point of it is as I said uh
there might be other points but that's the main one yeah I think Daniel your reasoning is um it's correct that you know if um I'm going to be push the burden on everyone even if nobody uses the feature but I think like this pure and view is actually a bad example for that because we do need to do code validation of each of the code sections and what this flag would do uh it's just reduced the number of
accepted instructions in the validation run so in that sense it doesn't actually put like extra burden um on the VM because the validation has to be done anyway um but yeah otherwise I definitely agree that we shouldn't really add features which um the VM wouldn't benefit from yeah I mean please go ahead uh yeah I was just gonna say that I kind of agree with you since
these uh validations for pure and for View and other stuff can be done they would be done once they will not be done twice at runtime or even if they are not included as Flags like if the VM implementer needs to know if a function section is a pure function section they don't need a flag to verify it because the flag would be just I kind of went the case of to to validate whether the compiler is telling the truth but when it comes to use to use case we will validate it anyways and based on the results we will for alt
will emits code or we will interpret code or whatever the need of that flag for us but my point is in either ways it will be validated so we don't need it to be in the bicycle so I think the the entire debate whether to have Flags or not goes back to this one premise whether we can have flags and then
introduce features without bumping the UF version right because if he if he cannot then there's no point having like a forward compatible field we're gonna change or we could change the format anyway to be honest this feels like uh like a very primitive effective system that we are trying to add to the byte code here pure uh total or whatever other effects that can be added but I don't think the VM will benefit from them since we can just verify them if our VM has some specific implementations that are
interested in six units so we don't need to impose them on everyone to have to validate these functions or these flags while we know that only certain ones will need it because they have some specific technological stuff that goes underneath the hood um to so to clarify what I'm saying is that if a client is seeing a benefit in having in defining if this function is pure or if it's view then they can simply while validating the function check the op codes and if it accesses
memory and load it's a view and if it doesn't then it's a pure and in that case they can flag it but without imposing this on is that what you're trying to say Amen yeah exactly so they can do it for themselves and use it themselves not force it on everyone so there's one more use case we thought about is the init code uh marking a code section uh which is used as init code and there have been like a number of
different designs on how even this uh contract creation like in uf2 would could work and um with these Factory contracts you could definitely have like multiple edit codes in the same container but it's it's unclear um you know which direction we're going to go with this and from that's that reason just having just mandating their that the first code section is in a code is good enough but there's one other site to this um is had to actually uh finalize the creation within the init code
and in Legacy we just used return op code to return the entire code uh we want to place into the state um but in euf 2 it's slightly more complicated because we don't want to um have access to all the the code and everything in memory so The Current Designs have a new instruction called return contract um which take a memory area for auxiliary data which gets appended to the container and sorry that this was so long-winded but the the one problem or like it's not the big problem but just one thing we we need to do
is check whether we are in an init code context because outside of that this return data return contract uh should not be um valid so if we would have this init code as a flag then we could easily easily validate that this return contract up code only is presenting in code sections which are meant to be in a code but again this will be introduced in aof2 which is a virgin bump so if we really need it in the flag we can just say okay then we will introduce the flag in version 2. and not introduce it in version one we were also contemplating making eof quote to a forward compatible that doesn't require a version bump
um so that's part of the design space that we're trying to keep available so that all the byte codes are still the same it's just suddenly you can now use these new OP codes that are introduced if you follow the rules so there is also a path for keeping you know forward compatible changes that don't require a bump like we've been doing forever in the Legacy evm so one of my concerns about this is one of the discussions we had about the space we wanted for create was we wanted zero ability to put op codes in memory um because that has um I've been doing a little bit of ZK research that has a very positive impact if the execution and the logic are
entirely separate so I mean maybe we need to keep it open just in case it has for net code and just do the bit packing and don't use any of the flags that might be the solution that we have here um but I'm skeptical of some of the flags but the in a code flag we might need that space we might not and that everyone's going to use a net code um but I'm I'm still in favor of solutions that involve by code never hitting operational memory that would make things a lot um better for the ZK world but I think might open up new possibilities but that's a discussion we're going to have in a much future date we just need to preserve space for us to do what we need to do so that might be the argument we
need to keep the flag space open so if he would have to send it code flag then then you would be in favor of having like a flex field so I think I think the possibility of the net code flag I think is a strong argument to the possibility of a pure and uh um static flag so that I think there's there's a case where we need to keep the Flags open but not specify any of them in the 1.1 version but just outline these are the things we're considering but we're not
committed to shipping any of them yet yeah exactly I mean we wouldn't Define any of them um we only have five minutes left I think maybe the best way forward because we didn't had a number of people like we have been like active previously on this call maybe we shouldn't do a final decision on this today anyway um so I would suggest that um you know all of you just think about this you can leave comments on the document as well and then maybe on the next call we should be in a position to make a final
decision on this um but there's one last topic I think we can fit into the three minutes what is the best way for the US 1.1 spec and the number of options I see is we just create the diff um just State you know how it changes from uf1 another option is that we take a copy of this unified spec and just modify it um so it has everything clearly what 1.1 would look like and then you know whether any of these should be an EIP or not so what's the what's the view what direction should we go
I'm not sure what document you're referring to at this point but I'd really like to see a meta EIP pulling this all together because we have a lot of hack MD sort of scattered around it seems and I I can't always find them and I can't always uh can't always use them effectively because I'm not in the organization in addition to a meta EIP I would kind of be in favor of going back and changing the eips I mean these never shipped in a proof fashion so they're not finalized stuff like we would be uh
increasing the scope of what operations are invalid we'll be adding entries to it I think we just go back and edit that e to add it to it as far as as far as the differential and people who are curious about the history can just go back to the get the GitHub and look at the state of the spec at a certain time so that's you know maybe in the comment stream we could Point them to a static copy of the markdown to say here's what the meta-eat looked like at this point in time for those interested um but I don't think we need to keep this rejected version um in the in the eip's because it wasn't ever fully shipped and finalized um but you know if we want to do a new
one that specifies the changes on top of those three eats that's a viable path too or five heaps are ever going to eat through this yeah I think the only reason we haven't just gone and changed it um because we've seen a value and maybe this is wrong but we've seen value that um the the clients who started to work on EOS one they can complete that work with the test Suite as it is and the eips and then then maybe it's easier to once everybody is on on the same page um just to modify the IPS and roll out the the UF 1.1 changes um but maybe this is this is a bad
assumption and we don't need to wait for everyone to to finish it with one uh what are we actually going to ship that is what what's actually going to go to final hopefully 1.1 then that's what the EIP needs to describe right yeah I think baseball is not affected that much because basically merged everything
but we're getting that in mind what would you uh are you guys planning to merge to the current set of um PR's um which is uf1 or um if you do like this 1.1 then you would just keep them open and then do the changes there what is the plan yeah so like the idea is that we don't really like to merge stuff if it is not tested on the ethereum tests uh consensus tests etc etc so we keep everything in a PR in a branch we keep updating it if eorf V 1.1 the spec is
finalized then we will implement the changes and then we can then test everything once the tests are finalized it's always for for nevermind it's all the bottleneck is always ethereum tests in my opinion if these are finalized then we can move a lot quicker in my opinion okay then since we are like on the top there um I think my suggestion is then that we're gonna probably create a single PR on the eip's repo and not merge it um which has all the changes um and we can we can discuss the the
changes there and hopefully all the consensus tests are or execution tests are merged suit enough with 5450 um and at that point we can just record you know all the commit hashes of like the final euf one test suite and and eips and we can record it in the the checklist um and so if people want to test for uf1 they can still do that and we can start merging the IPS at that point does that sound like a plan sounds reasonable the pr I think solves The Meta EIP concern we could have one location for them and just merge the pr when we're fine ready to finalize it
all right I will write this summary down in the channel and then we can take it there and because Puja has to leave thank you Puja for recording and hosting us and thank you everyone talk to you soon thank you thank you thanks bye