FOCIL Breakout #44
FOCIL Breakout · 13 Oct 2026 · 49:28
FOCIL Breakout #44, held on 13 October 2026. FOCIL, or fork-choice enforced inclusion lists under EIP-7805, is a proposal to make it harder for block builders to censor transactions. Prysm was joining Heze devnet 2, and Nethermind needs to assess the execution layer changes for EIP-8198 before devnet 2.
Speakers
Topics
From FOCIL Breakout, hosted by Ethereum Foundation.
Transcript
Jihoon Song: Reminiscing, let's dive in. Hello everyone, welcome to FOCIL Breakout. 44. Let's start with Heze devnet 1. Yes, yes. the link to… The DORA, the network is generally healthy, but some slots are being missed. The same says, because Lighthouse has an implement, it should extend payload. Can anyone from Lighthouse share? What the current status is.
Rahul Barman: Yep. Thank you, Jihoon. Hey everyone, I'm Rahul, also a protocol fellow working alongside with Cristian here, on FOCIL. Sorry I haven't made it to these calls before. I had some timing conflicts, but I should be able to join from now on. Anyways, the update from the Lighthouse is, we did participate for devnet 1, but with the assumption that the payloads would satisfy the inclusion list for this devnet, so we intentionally left the fork choice enforcement stopped. But, as you can see, as Barnabas started testing censorship, the Lighthouse diverged from the other clients, and we realized we needed that part as well. So I put together a PR for the, the RIP branch to add the enforcement, as well. It's currently under review. And, hopefully it gets merged this week.
Jihoon Song: Great, thank you. I remember I said that this network would be just for happy cases, but yeah, we're also testing censoring cases, and thanks for sharing the updates. Also, there are… Some inactive validators, validator index from 2,200 to 2,206. They're not slashed, but they're just inactive. Does anyone know what happened to them? Yeah. We can take that offline. Do any other clients have any updates?
Iván | ethrex: on our side, we are ready for Heze devnet 2. We've implemented 8198. One question I had was. I remember that yesterday we talked about using 12 seconds, but our implementation is using the changes in the base fee and the block schedule. I don't know if we need to keep those or not.
Jihoon Song: Yes, so for Heze devnet 2, we were gonna use 12 seconds, so it's basically no op, but It's a… As a side, we also want to test The slot reduction to 10 seconds locally. So, not sure how your branch strategy works, but it'd be nice if you could have two versions of that. you know, implementation.
Iván | ethrex: Okay, I'll see what we can do. Right now, we have just the version that complies with the spec.
Jihoon Song: Okay, cool. Thank you. Jun?
Jun Song: Hi all, I'm Jun from Prysm Team, and this is first time joining FOCIL Breakout, because, Prysm team will participate, the Heze devnet 2. And I'm still working on the FOCIL implementation, although Terrence had, implementation, a long time ago. I should, rebase, his work and make it, running, in the FOCIL-debt-on-world, and it seems pretty good, so. I'm planning to sync, with the current, devnet, with my Prysm work, and it seems like this… it will be a good. I can be more confident about my FOCIL work after I test with the current devnet. So, that's my update from Prysm.
Jihoon Song: Thanks for the update. Any other clients?
NC: For Lodestar, we have merged, EIP… 8365, 8015, and 8198 into our trunk branch. So we still have FOCIL branch, that we aim to get it merged, in the next couple days. Otherwise, we will be… Ready for Heze devnet 2. And, I just realized that Lodestar also, Create the ILs. When we received execution payload, not after we called a new payload call. So… This is something that we also need to change.
Jihoon Song: Okay, cool.
Marc Harvey-Hill: On Nethermind side, so I've still been working a bit more on the frames and FOCIL specs and our implementation. I think we should be ready for the next devnet, but, I just need to look into 8198, actually, because I hadn't, thought about whether that needed EL changes, but, yeah, I'll have a look into that.
Nico Flaig: Well, there's something I'm curious about. So what NC just said and what Toni is asking. So I think what NC meant in our case is we use the payload available event, but that is fired without having the payload executed. by the EL, right? So, we would build it wrongly on the parent, in some cases, so there's a race condition. But I think from a CL side, we should… eagerly do it once the payload is executed, I guess. And when there's no payload, we wait for the deadline, I suppose. Curious if anyone has thought about this.
NC: I think what you have described is what the spec says, right? like, try to eagerly, run the execution payload first, and then create the IL, but if that fails, we fall back to Just creating an IL without. Executing the execution payload.
Nico Flaig: Yeah, I think the problem we had, right, is we did it too early, so we triggered the IL when the payload was available, so… It's not a good IL quality in that case. Is that the issue you described? Or maybe I'm misunderstanding what the issue was.
NC: Yes. So, in other words, like, Lodestar always uses the fallback, as the spec described. not… Trying to… Do the payload first, then the IL.
Jihoon Song: Okay, correct. Do we have any more updates or comments?
Nico Flaig: I just want to note, so our FOCIL devnet 1 branch is kind of, I accidentally broke it by merging our trunk branch into it. So it has quick slots and everything else in there. So we run a pinned image right now on the devnet 1. But I also tested this morning running quick slots with FOCIL with 10 second slots, like transition on Heze. And that seems to work well for us at least. But do we want to target Heze devnet 2 branches? What's the plan? How long do we keep the devnet 1 up, essentially?
Jihoon Song: Yeah, I guess that decision is up to pandas. But there are… a few PRs that would be added to Heze devnet 2. We will cover it. A moment later, it's all about FOCIL, so… I think, yeah, I think you need to make some changes there. Yeah, regarding keeping up devnet 1, I think it makes sense to just keep it until we have devnet 2. Right, let's move on to spec updates. First off, it's not a spec, but… I want to share that the EIP is being updated. I rebased it to Heze from Fulu, and reflected all the changes made so far. Note that it doesn't include the transaction… interaction mechanism with frames. I can add in once we settle in some design down the road.
For spec updates, there have been a few CL-specs updates. Here's the list of the PRs. So the first two are minor bug fixes, and the last one is about IL deadline that we discussed yesterday in ACDT. And I also updated… The spec sheet, so you can find more info there. Yeah. Are there any comments or questions? Nico, do you want to elaborate your comment on Heze?
Nico Flaig: Oh, wait.
Jihoon Song: want.
Nico Flaig: Oh no, it's just our branches are messed up because we are too far ahead and already have the Heze EIPs. Next, like, so I'm just wondering how… like, if there's a Lodestar bug on Heze devnet 1, we have no branch to backport this right now.
Jihoon Song: Oh, I see.
Nico Flaig: But I'm not sure it's needed, to be honest. But I was curious about this 9 seconds into the slot, maybe we can discuss that more. Also, I was reviewing our code, how we, at the start of the slot. like, send another FCU to the EL, to re… like, to apply a superset of the observed ILs. And what I'm mostly curious about, how efficient are ELs to apply transactions, like, new transactions on top of a payload they already sealed? Because my guess is, like, the EL already calculated the state root, right, of the payload. And then they have to apply new transactions on top of that? Like, how fast are ELs doing this?
Jihoon Song: Yeah, how are ELs implemented in this regard? I wonder if we can get some insights from EL devs. Like, do we initiate a new building process, or do we… Add any missing IL transactions somehow? Like, I'll plan the only way. I think the main question here is, How long does it take? To update the payload, to make sure IL compliant, yes, Fabio?
Fabio Di Fabio: So I think this is heavily. implementation-dependent in our case, in Besu case. There is already an iteration when the block is built. So… Until the CL call get payloads. The EL continues to iterate, building always a better block with incoming transaction, including new inclusion lists. So it's not appended to the existing one, but a new one. It started considering the new inclusion list.
Jihoon Song: Yeah. And that's also my understanding. that most of ELs, maybe all ELs, are implemented in that way, you know, keep updating their payload periodically to produce more profitable blocks. I wonder if there is any plan to make some… You know, so, building strategy. optimized for IL. Like, let's say… You'll receive a fork choice update called with some IL that you haven't seen before, then maybe you can adopt You can, you can… kickstart that strategy. very quickly… turn your payload into IL compliant instead of running the whole building process again. Of course, this is also implementation details. I know that some clients have more sophisticated algorithm than just building it from scratch, and then compare which one is more profitable.
Fabio Di Fabio: Yeah.
Jihoon Song: answer.
Fabio Di Fabio: that's.
Jihoon Song: Because.
Fabio Di Fabio: Yeah, I want to complete how it works on Besu. So, the first iteration before used to build a block without any transaction in order to be able to respond to something if the get payload was very quick after the fork choice. Now, since this empty block will, Not satisfy the inclusion list. We… at the For the first iteration, we'll only build the block, including the ILs that we received. So this is the… we call this the minimal block. So this minimal block should be faster to build than other interactions. So we… Could be ready to respond to a get payload. If the… if the get payload is very quick.
And after that. We also, when we received the ILs, we also, send them to the public transaction pool. So that the bulk building will. In an optimistic way, so it's not that we wait for the transaction to be added to the pool, but if they are, they will be sorted according to the… Paying fee, actually, no? So… And at the end, of course, we will append any other IL transaction that has not been selected by the normal organic process.
Jihoon Song: I see. Thank you. Just curious, let's say two transactions are included in a payload in previous building cycles. Is there any case that those two… the order of those two transactions is changed?
Fabio Di Fabio: This is very… technical detail. It could have happen. If they are not the first for the sender, and the… initial for the sender has been replaced to bump the fee, I think this could happen. But I think this is very, implementation-specific. So, yes, I think in some cases it could happen, that the order changes. Ice again.
Jihoon Song: That makes sense.
Fabio Di Fabio: Is that an issue?
Jihoon Song: Probably not, but I need to think more about this, but it might… make some IL transaction. Be omitted validly. But yeah. I don't have a specific scenario on top of my head, but yeah. But it's not a big of a deal, I think.
Fabio Di Fabio: Yeah, because every iteration is, IL conform. So it's checked to be… to satisfy IL, so there should be no issue, at least. I'm not aware at the moment, so if you find something, yeah, let me know.
Jihoon Song: Yep. Cool. Do any EL devs want to answer Toni's question in the chat? I know that that's also… Very situational. It depends on when you call the fork choice updated and when you call getPayload and how. long the EL sets the building duration.
Nico Flaig: To be honest, it's mostly my curiosity how ELs do this today and how easily they can apply IL transactions. But… yeah, maybe… I guess the question is, do we need to call, prepare, like, in the previous slot, we prepare the payload, do we need to call this really late to make sure we see the superset of ILs, or have seen everything? Or is it fine to call it in the start of the slot again, basically?
Jihoon Song: In my opinion, calling it at, like, 10 seconds, if… You saw some ILs. Around or after 9 seconds would be enough, because other attesters We're gonna, if they follow the spec. Honestly, then they were gonna ignore IL if they saw it after 9 seconds mark. So, calling it… calling on FCU… At the start of the next slot is… quite conservative. But yeah, do you have any concern in your mind regarding this 9 seconds mark?
Nico Flaig: I mean, so today we call it at 8 seconds, right? The prepare payload, at least Lodestar does, and then… we actually haven't added it, but if the PTC votes against the payload, and we have to build on empty, then we tell the EL prepare on empty instead of full, also in the previous slot. And then the final decision, basically, what payload we pick, is at the start of the slot. So what we prepare in the previous slot could even be mispredicted.
Jihoon Song: Right, so what has changed with ILs? like, before… before Heze, when do you call FCU, and when do you call GetPayload?
Nico Flaig: So FCU we call at eight seconds in the previous slot. And, get payload, we call, at the start of the next slot. Like, 100 MS into the slot or something, because we need to, calculate our proposal head and stuff, so there's some work that is done before we call it.
Jihoon Song: I see, and if PTC votes. affect your fork choice decision, then you were gonna call another FCU.
Nico Flaig: Yeah, there are several factors, I guess. So there's also the problem if the EL payload takes long to execute, right? That's another problem if it takes longer than 8 seconds. So I think anyway, we need to maybe call the prepare payload later in the previous slot. Like maybe.
Jihoon Song: seconds.
Nico Flaig: This is maybe the correct timeline.
Jihoon Song: But here, calling on FCU at a second is also implementation details, right? Like, other clients might call it at some different time.
Nico Flaig: Yeah, it's basically a trade-off, right? You want to give the EL as much time to produce a good payload. But also you don't want to produce it on the wrong head and then later have to. caught, say to the EL that they have to prepare on a different head.
Jihoon Song: Yeah.
Nico Flaig: Which can happen in the worst case anyway, if there's, like, deep branches and unstable chain, but… And the happy path, at least, usually doesn't happen.
Jihoon Song: Yeah. To answer Toni's question in the chat. It's hard to say yes or no. It could be one second less time for a local building, but… You know, there are multiple factors, so it might not. And it doesn't mean that you cannot start local building with, before 9 seconds, you can, but you… Wanna include more ILs if you see it before 9 seconds mark.
Nico Flaig: Yeah, that's the thing, right? I don't think it reduces the local build time. Like, if ELs can just apply the… Yeah, if execution layers can just apply the ILs on top of an existing payload and, like, reseal the payload, then… You don't really lose local building time, I think.
Jihoon Song: Yeah. And this is very… Implementation detail stuff, so… You know, I I also I've been also thinking about like whether we were gonna have some EL. have some optimized strategy for ILs. But maybe it's a bit early to tell. Right, so, do we have more comments or questions? Before we move to FOCIL and frames.
Fabio Di Fabio: I have a question. Since this week was… I was working on. Persisting the result of the new payload. for the fork choice update. I was wondering if there are normal cases. Where… A new payload is called with a different Inclusion list.
Jihoon Song: There could be. It could be… called with more ILs or less IL. So, when you… when the CL sees more ILs, and if they wanna… Have them included in the payload. They were gonna call… oh, sorry, new payload, you said.
Fabio Di Fabio: New payload, not fork choice, yes.
Jihoon Song: I don't think so. Yeah.
Fabio Di Fabio: So, let's say, basically changing the… The result saying that inclusion list was satisfied. to not satisfied or.
Jihoon Song: I see. I think this should not happen, because attesters should have frozen their IL view. Way much before they called new payload, they should have frozen it, like. 9 seconds in the previous slot. So this… this should not happen.
Fabio Di Fabio: Okay, so if this happens is a bug or something. Okay. Bad happening, so, yeah.
Jihoon Song: Hmm, yeah.
Fabio Di Fabio: Thank you.
Jihoon Song: Yeah, this should not happen. The only case that I can think of is… An equivocation. But… this Equivocation… is not a case in this scenario, because you will gonna ignore ILs from previous slot. So, equivocation you see after Preferred slot doesn't really affect on your, IL view. So, yeah, I don't think this will gonna happen.
Fabio Di Fabio: Okay, thanks.
Jihoon Song: Okay, thank you. I think it's a good time to move on to FOCIL and frames. So… Marc has prepared some material we can discuss over. Here are the links. Marc, do you want to give us some intro?
Marc Harvey-Hill: Yeah, I can just give, like, a brief summary of, what I've worked on. So, I mean, mostly it's just kind of, realizing the details of, Thomas' informational EIP. So yeah, so mostly it's around the handling of the profile two transactions. So… Yeah, so with, frame transactions, unlike previously, where we executed everything at the end of the block. Now the builder has to specify a specific index where they have evaluated the transaction. So, to actually support that, we… I added, like, a… A new object like the claims object which maps the transaction hashes.
To where… the index where the builder has evaluated them. So this object, the builder is gonna, include the root in their bid. So, like, to commit to it, and then it'll be passed along in the, Execution payload envelope. So… Yeah, so as well as that, there's also a new ID which is included, so that binds, the execution payload as long as… as well as the claims, and that's going to be passed, So it's kind of passed in a similar way to how we handle the payload ID currently, so… The EL's gonna return it on new payload, this ID, and then…
Yeah, sorry, I'm getting a bit, so… Yeah, sorry, I had to just throw some slides to make this a little bit clearer to explain. So yeah, it's essentially, like, we just need a new object, which is gonna show, like, where the builder is claiming that they want all of the transactions to be checked. And as well as that, we have this new, limit, so… And. Essentially, like, each of the individual ILs, we want to bound the amount of computation that needs to be done to verify the validation prefixes. And we want that to be handled, like, per IL, so we don't want, like, an honest… IL, proposer to… Kind of have their… All of the,
The validation gas used up by someone else. So, we need to include… A new object, which… the EL can use to identify which IL each transaction came from. So that then they can check this limit individually per inclusion list. So yeah, there's this new, like, membership, bitmap. Yeah, I mean, that pretty much summarizes it. Yeah, so please, review the specs, it would be good to kind of, if, especially ethrex could have a look at those, specs. And give some feedback there. Yeah, sorry, that wasn't a very clear explanation.
Jihoon Song: That was great. Thanks. I have a couple of questions. So, currently. Max verify gas per IL is set to 1 million gas. I wonder how many frame transactions do we expect with 1 mil?
Marc Harvey-Hill: Yeah, I'm not sure off the top of my head.
Jihoon Song: I see. Does ethrex know by any chance?
Iván | ethrex: Sorry, what was the question?
Jihoon Song: Yeah, I wonder… If you know how many frame transactions. We can execute with 1 million gas.
Iván | ethrex: No, but it would be interesting to to measure.
Jihoon Song: I see. Yeah, I was just curious, because… you know, now we have two limits per IL. One is size limit, and the other one is gas limit, so I'm just curious, like, how many… What would be the expected size that frame transactions would take? An inclusion list. 50 regular transactions. Amen. Regular legacy transactions, not frame transactions, right? Few… two to three privacy transactions, and… Do we know… How big is those privacy transactions? Oh, yeah, right, alright, it's not a… it's not for standard. frame transactions.
Oh, what's the 500k gas mean? Oh, I see, yeah, do you know how big? The… those private transactions are. invites.
Toni Wahrstätter: Okay, it might just be myself. I'm not very quick. They are not very big. So I think with post-quantum, they might turn bigger because the proof size will increase. But today, Railgun and Tornado Cash are not really big from call data perspective.
Jihoon Song: Is it similar to regular transactions?
Toni Wahrstätter: Yeah, probably like a complex DeFi transaction. They look similar.
Jihoon Song: I see. I've, relevant question to this one. So, the membership is needed to Let the EL know. which IL this transaction was belonged to, so that they can, you know, measure how many gas. IL has consumed so far. And… I think alternative design here is letting the CL to pass ILs instead of IL transactions. Which means the EL will do the deduplication, and omission check, and the return. According to the PR omission claims, and the rest stays the same. So, the downside is that this will gonna consume more engine API bandwidth. But maybe it's a cleaner design.
We… Tapped into this… Direction before, when we discussed I think it was Beacon API event or something for builders. And we just decided to stay as is, and revisit this later. And, yeah, going with frames… the interaction with frames, maybe we need to cover this direction once more. Yeah, Tony.
Toni Wahrstätter: Yeah, am I right, with my understanding that we have to Enforce this 1 million, verify frame verify gas limit, we have to enforce it on the EL side, because the CLs cannot look into transactions. So, that's why the EL still needs, like, a mapping from which transaction comes from which IL, because only then you can enforce The 1 million verify gas per, Yeah.
Jihoon Song: essentially.
Toni Wahrstätter: Royal. Okay. Yeah.
Jihoon Song: Yeah, that's my understanding, too. And to… To that end, the CL has to do some stuff. Like… You know, making that mapping. Basically doing some byte-to-byte comparison. But… is this the best abstraction that we can have? That's my question, like, what if we just let EL to do everything related to transactions? Because they do They, they, they are good at that, so… But the downside is it will consume more engine API bandwidth, so there's a trade-off. But we're gonna make the spec. And maybe client implementation. Simpler. So I think this is worth to explore down the road. Another… I mean, the other question that I have is. this new… ID thing?
Engine get… inclusion list status V1, from my understanding. This makes new payload or fork choice updated async, but… CL will have to wait for IL validation result anyway, so I wonder what's the rationale behind this proposal?
Marc Harvey-Hill: Yeah, I mean, it's possible we don't need the ID if we go with that other approach. On.
Jihoon Song: I see. I guess it was… this is… this was more for… Efficiency and optimization? Yeah.
Marc Harvey-Hill: Yeah, pretty much. But so you think it probably isn't worth doing, maybe?
Jihoon Song: Yeah, it'd be nice if you can have more feedback from CL and EL devs, Yeah. Anyway, that's the question that I got. Thanks for preparing these PRs. Do we have… for comments or questions. We are… we still have some time left, so we can… discuss more.
Nico Flaig: I was wondering, do we have a censoring builder now? And if we do, how, like, should it work? like, the trivial way to censor, right, is just to do an empty payload. I'm not sure that is what Barnabas did.
Jihoon Song: Yeah. I guess not. We don't have him here, so… Is your builder… capable of censoring.
Nico Flaig: Not right now. I haven't updated it for FOCIL yet.
Jihoon Song: I see. I think we can… We could use some devnet in the future to, you know. make something like… something similar. To that Death Star. Producing some censoring payloads, so on and so forth, like, attesting to wrong payload, and see what happens. Any other comments or questions? Before we wrap up this call. I'd like to discuss… Breakout schedule, so we were gonna… have…
Our next devnet in two weeks, which is one week before Devcon. I guess not many people will be traveling at that time, so we can… Have that call as scheduled. And I guess then. the next call… is… one week after Devcon, so… I guess it's better to push it back by one week. Which is… the 17th November, instead of 10th. Are we good with this schedule, or is it still only to… Settle in.
To answer this question… Yeah, to answers. To answer the question, I'm not sure yet. It will be absorbed by ACDT at some point in time, but… Maybe it could be… By the time we have Heze devnet 2, Or maybe it could be… Sometime later. But I think we will know once we get there, so… Yeah, I think we can just say that we can just continue FOCIL-specific discussion. And… in this breakout, because we are still discussing some Glamsterdam stuff in ACDT, even in CL breakout. But yeah.
that the time is coming that we're gonna just move to ACDT. To Ivan's question, the next breakout, which is 45, will be 2 weeks from now. And the one after would be… On the 17th, if we push it back by one week. Instead of the 10th. Or we can just, you know, decide it in the next breakout. Because we were going to have it anyway. Yeah, let's just… let's just say that we're gonna have the one after on the 17th instead of 10th tentatively, and then just review it later. Yeah, Does anyone have any last comments or questions?
All right, thank you, everyone. See you in two weeks. Thank you.
Fabio Di Fabio: Thank you, bye.
Marc Harvey-Hill: spa.
Nico Flaig: you.
Iván | ethrex: But.
Transcript adapted from ethereum/pm, CC BY-SA 3.0.