eth_multicall Meeting, Apr 7, 2025
eth_multicall and eth_simulate Meetings · 7 Apr 2025 · 25:15
A meeting of the developers working on eth_multicall and its successor eth_simulate, held on 7 April 2025. Client and tooling teams compare implementations and work on the specification for simulating transactions. This meeting covers a client implementation update and the spec for eth_simulateV2.
Topics
From eth_multicall and eth_simulate Meetings, hosted by Ethereum Foundation.
Transcript
Hey, hello. I don't have any progress updates. Anyone else have nothing from my side? Nothing really from me. Maybe something from Rahit. I don't know. Yeah. Uh I kind of worked on the uh H mismatch. Uh I kind of had a fix for uh the uh for the um the extra bite that uh we had added. Now h are matching but gas for gas limit for a transaction wasn't matching. So the problem is get
uh for a transaction if gas limit is not satisfied get uses as much as possible from the uh block limit like dog gas but in our case we kind of uh divide the blog gas by total number of transactions so I can I I was working on that I mean it's kind of fixed now guesses are matching but now on non ns for a transaction is not matching uh for get uh nons of a transaction it starts from zero but for us for some reason it starts from one so I again uh I'm working on it
how does the no start for one but they still the transaction still went through with the one uh for us uh we had hardcoded the nons one for a transaction if it is not specified. Okay, that sounds it's would fail every time with the first non is zero and no. Yeah, I think uh for get it is zero that's why for us tests are not passing otherwise you're feding your first transaction and the don't need to
be one cuz when it's zero then then there's no the account has no transactions or is the first valid non is it zero then I think it's one for get I think is zero it checked okay I'll check again I'll check again and I I paste the whole transaction detail on telegram. Uh yeah, I think the first valid non is zero. So this is a answer to kilari.
Okay. H just trying to look from the chat what it is. Yeah. Like it's zero. So then the default should be zero as well. Yeah. regarding the gas limit. Um, yeah, I'm I'm not sure which one is the agreed upon behavior. I'm open to changing if cuz I do remember we were kind of discussing between these two options. If if you haven't specified the gas limit, then it should be the block gas limit. But I think if there's two
transaction then it should be divide by two. I think that's what we are agreed. Yeah, that is what mind is doing. But for get it's different then I would think that the get is wrong there. Don't know. Um yeah and we wanted to do this because then we can compute this in advance whereas Oh sorry for the noise. Um whereas alternatively we would
have to process the transaction first and then we can compute the gas limit for the next transactions. But what get is doing is it always maxing the max and then you can overload or if you have I thought that we are assigning the gas limits one by one. So like after processing the first one then whatever remains we assign it to the next transaction.
So I think never mind takes the remaining gas limit in a block that wasn't assigned and just divides it equally between transactions. Oh okay. But I would say that's that doesn't make sense because um we I remember we were discussing this to do the like splits by number of transactions but only right in the beginning because I remember the discussion was can we make it so that we can compute the whole transaction object statically without any execution.
we we are taking the whole blocks gas and then we are subtracting the amount of the gas limits that are specified already and then the the remaining gas is then split within all the transactions that's I think it should work so you can calculate this static length because you can scan through the block to see which are defined already why do we need to be able to calculate this in advance uh That's a good question. I I remember that we disc like I remember that this was the context when we changed the kind of the formula. I think it was because then we can kind of compute the transaction hash
already and this will result in some simplifications. But anyway, I think that I mean if we don't want to have that feature to like be able to premp compute then why not just assign the rest of the block guess and why divide it. So what is currently doing because I didn't get that. Uh so for the first transaction the whole gas limit is assigned for the second one it's block gas limit minus the gas usage of the first transaction. So it isn't so it is dynamic actually. Okay. It is dynamic.
Yes. I I'm just saying that I remember that when we decided to change the formula we wanted to we did it with the idea to make it static. Okay. But we didn't. But G didn't make it static. So I'm confused. Yeah. Yeah. I mean G is still dynamic. It's still on the old formula. So this is I will I Yeah. This is why I suggested that I can change this. Mhm. Um but then I also don't see the point of doing this divide if it's still dynamic.
Yeah. If it's dynam Yeah. One or the other, right? Yeah. Yeah. Exactly. So the the two reasonable solutions that we all agree are both reasonable is at the very beginning of the block before we do anything we take the block gas limit subtract out known transactions divide by the number remaining and every transaction gets that amount. The other option and the other option is to iterate over each of the transactions processing them in order and then the next transaction always gets whatever's left in the block and then next one gets whatever's left etc. Right? So we agree those two are reasonable and it sounds like right now Nethermind is doing one the spec says
another one and Nethermind's doing neither. Uh no mind is doing what is in the spec I think. Yes. Yes. What's in the spec we doing? Oh, so it is static. Yes. So the dynamic one is a bit more flexible, right? Because Yeah. Yeah. You can crump the static one is static. It's simpler in in a way being static though not that much to be honest. So we need agree on the static one or change the spec and never mind.
Which one do you prefer, guys? I mean, we I think back when we discussed this, I was I favor the dynamic one, and I still do mildly, but not nearly enough to go and change a bunch of stuff. So, if everybody's fine with the with the static one, um, we can go with that. So, okay, let's circle back to one question. Is there any advantages of being able to calculate statically things?
[Music] Mhm. I assume that clients may want to be able to fill out the transaction details of every transaction before processing them. There might be just simp code simplicity wise. I can see that. I think that was the point. Mhm. Okay. Yeah. for us as well. Uh if if we go for the dynamic then we need to do a lot of changes like processing step do we? Yeah, I don't think we need to do lot of changes a bit transition.
This is something that doesn't happen on the mainet in a way because you always know that those in advance. So then I would think this is kind of special case that you dynamically need to adjust those. I would imagine it's harder for the clients in general. Um I don't think it's that hard. It's implementable. Yeah. So the thing is that we still need to compute the nons. Can't do that up front. N can be computed up front. Well, I'm not sure the 7702. No, I don't know what happens with N with 72. Oh yeah, that's a whole other
kind of worms. But like even in a normal case uh normal case we can you just need to you need to get a list of all the accounts that are touched in the transactions then get their nons before execute anything then you can set all the nonses and then start executing because uh does contract deployment change knots? Yes, especially. Yeah. Yeah. But like the transaction that does the contract deployment doesn't add an extra nons, right?
You still increment by one. Yeah. Yeah. But the nons of the contract itself also increased by one. Oh, and then you might have a transaction later on that is from a contract generated even not even that. So you may have transaction A that generates a contract and then transaction B which comes after it executes from that contract but that contract didn't that address didn't exists in state prior to the creation transaction which is in the simulation stack and so in that case I guess you could reasonably guess that there is a nons of one because any contract that gets created gets a nons
of one maybe. So if you see an address you've never I don't know because if you see an address you've never seen before, you don't know if it's an EOA with non zero or if it's a contract that will be created with nons one. Yeah. So you do need to execute in order to get the nons right. Yeah, I think that execute because like take the following example. We can still self-destruct within the same transaction. Like if there's a create and then a self-destruct, this would effectively increase increment the nons by one. And then if you simulate a call
from this address, which is main unlikely because when do you have the private key to a contract that you created? But then because this is simulation, it's certainly possible. Yeah, I think I I would be okay with that scenario just being an error on mainet. Um, but even if we were to decide that, you still have the other situation where you just you don't know whether a given address is an EOA that's never been touched or a contract that will be created earlier in the stack. And you can't know that until after everything in the stack before you has been executed.
Okay. So, I would go with dynamic with both. I think we might have static nons. I'm not sure at the moment. So, we might be wrong in this scenario. I certainly would not not have thought of this until we brought this conversation up. This is very edge case. I think this is very like edge case stuff. Intercept intercept also doesn't handle this kind of case. I didn't even know that when you said creating a contract that it increments the contract amounts.
I never heard of that. Oh, what? Changing the spec to dynamic gas. If we have dynamic nons, let's have dynamic gas. Oh, we should have dynamic nons. Sounds like no one does, but we should. Well, G does, I think. Right. What do we do? Dynamic. Oh, yeah. We have both of them dynamic. Okay. So, yeah. So, yeah, I'm leaning lean towards dynamic then. If we're going to have to do dynam dynamic knots anyways, it means all the infrastructure for having some parts of the transaction not filled in prior to execution um we have to have the infrastructure for that and so you might as well use that for the gas as well which gives a better
user experience I think. And we are talking only about nonvalidating mode right or validating mode too. I think validating allows you to leave things out, right? Okay. So both. Mhm. Okay. both I think I thought in validating you have to set gas limit and you have to set nons oh you don't need to calculate those okay I think the validation mode should be correct transaction except that the signature doesn't need to be valid I well I don't think G is checking that those fields were present in validation
mode. It's almost almost like we should have agreed on a validation mode spec at some point. I thought we did. No, we kept punting and punting and punting and finally we said, you know what, let's just get B1 out there without it. Maybe in B2 we'll we'll specify it clearly. We never agreed on like what all the errors are and all that stuff. But we never got to the error part. But other than that, maybe let's start with required fields. Yeah, sure. Yeah, let's get the That's the basics. That's the basics.
Violation. What? Yeah, I thought they had to be it works like it works with the main net. So in the mainet those are regard fields. We cannot send a transaction without non show without gas limit. Is it written somewhere? Let's see.
uh read that that it's closely approximates real EV and location bas transaction for contracts. Yes. So there's those two Yeah, there's those two exceptions that are skipped and otherwise it should be like minutes. Oh, so I think part of the problem is if you do Yeah.
So, okay. So, this one is a bit blurry I think for me because when you do e send transaction then you can certainly leave out these fields and the clients will fill it out for for you. No one should ever be using e send transaction with a client though like really we should deprecate that whole method and I know it's useful for debugging it's only for I think but e simulate is a call to a client not to a wallet yeah and you should not have your private keys in your client and transaction should be wallet and transaction so it's in the wrong
name space yes yes I agree H so do I agree on doing the dynamic gas limit? So I modify that gas limit stuff. Yes, I think I think we're all in agreement on dynamic cast limit and dynamic knots. I think dynam is something that we have as we have already. What was that? I think for nons I assume we are doing that already.
Uh, sounds like Nethermind. How does Na work in in Nethermind? I thought they were just defaulting to one one which was wrong, but otherwise it's dynamic. Right. So, I think I think the what we need is we need to just make sure there's a test case for the scenario where you create a contract and then a transaction later makes a call from that contract. Make sure that works and the nonsense is correct. But I cannot see what the nons is for that. Well, I guess need after that I need to cure the nons of the uh the transaction hash should include the nons, right?
But there's no transaction hash if the contact is sending it. We don't get transaction hashes in the uh response. I mean you you get it for the cannot send contract transaction from direct to execute a contract and then that does something. What do you mean? You can't just do a send a transaction from a contract. I thought that was like literally explicitly why we have this.
Oh, you mean for that case? Oh yeah. So the you have two transactions in a bundle or in a simulation stack. First transaction deploys a contract just from an EOA regular contract deploy. Second transaction makes a does something from that newly created contract and we need to make sure the nons in that second transaction is correct. No I see. No. Yes. Yes. So if we can create a test for that I it sounds like Nethermind fail that one right now and G should pass it right now but it would be good to validate both.
I think we calculate nons before for every transaction before processing a transaction you do it uh another mind does it dynamically. So right before each transaction you calculate the months. Okay. You don't think we can freeze the spec sometime? We already did right like three months ago. Yeah.
But but now we are modifying it again. Uh yes, because uh I mean this the question is is do we we have clients that are disagreeing. We can either stick to the spec doggedly or we can just make the spec spec match one of the two clients that we think is better and it sounds like we all agree spec spec is the law. This isn't Ethereum code is not law. Spec is not law.
else. I don't have Does Nethermind have the debug simulate released on the main already? If so, we could operate our Nethermind. I could test it. Uh, let me check. Just give me one minute. I forgot. Do do you know if there's any kind of technology how you could kind of convert the debug trace output into something that looks more like solid so that you know which function was called and that kind of things is does that kind of libraries exist or is that something only that tenderly has in in
house there open source there is a built-in tracer uh that you might want let me try to find it which When was it? I I would need to look at the OP coach, but something more with no human readable. Give me a sec. Um, there's something called cold tracer. Do you have link link to that?
Not really. Uh but uh basically when you are doing the back trace you can put a tracer by name in the options. Is it a setting for the tracer I can pass in the RPC? Yes. Give me a So basically, let me find try to find something in the docs called tracer. It hasn't been it hasn't been released yet.
H it hasn't been released. Oh, okay. So if you go to here there's even this so you can have you can pass an options right this is the back trace call but it's same options would be the last parameter and you just do something like that wait this four byte tracer as well yeah there's also four byte tracer Mhm.
Yeah, this industry need to try this thing. Yeah. So those two are will give you a way smaller output. Yeah. Like I guess more understandable. Yeah. Yeah. Yeah. Without all the details. Mhm. Much more comparable. Yeah. This one or for by tracer. Mhm. Yeah. To try that. Do anything else?
No, nothing for myself. Okay. See you next week.