Follow-up from #4931, where the “one slot vs persist” penalty question was raised but not explicitly resolved.
Reading the current Heze/Gloas fork-choice, it looks like IL non-compliance is handled through payload_inclusion_list_satisfaction + should_extend_payload, so get_head() prefers EMPTY for the previous-slot payload when that payload failed the IL constraints. But I don’t see an explicit rule making that penalty persistent for descendants of the FULL payload.
Concretely: suppose a FULL payload at slot N is locally known to be IL-incompliant, but a branch building on that FULL survives and, by slot N+15, has the most attesting weight and an IL-compliant head. Should a FOCIL node still consider that branch eligible to become head?
If this is not already handled elsewhere, I think it may be worth making IL non-compliance sticky for the FULL payload branch only:
A fork-choice node should be ineligible to become head if its path depends on any ancestor FULL payload for which is_payload_inclusion_list_satisfied(store, root) == False.
Important distinction: this should taint only descendants that build on the bad FULL payload, not the beacon root or the EMPTY path. The EMPTY path remains the valid reorg escape.
This would preserve the current immediate reorg behavior while preventing a later head from “laundering” an old IL-incompliant payload just by building enough compliant descendants on top of it. It also seems aligned with the intuition that FOCIL enforcement should mean “do not build canonical history on top of an IL-incompliant execution payload”, rather than only “try to reorg it in the next slot”.
Follow-up from #4931, where the “one slot vs persist” penalty question was raised but not explicitly resolved.
Reading the current Heze/Gloas fork-choice, it looks like IL non-compliance is handled through
payload_inclusion_list_satisfaction+should_extend_payload, soget_head()prefersEMPTYfor the previous-slot payload when that payload failed the IL constraints. But I don’t see an explicit rule making that penalty persistent for descendants of theFULLpayload.Concretely: suppose a
FULLpayload at slotNis locally known to be IL-incompliant, but a branch building on thatFULLsurvives and, by slotN+15, has the most attesting weight and an IL-compliant head. Should a FOCIL node still consider that branch eligible to become head?If this is not already handled elsewhere, I think it may be worth making IL non-compliance sticky for the
FULLpayload branch only:Important distinction: this should taint only descendants that build on the bad
FULLpayload, not the beacon root or theEMPTYpath. TheEMPTYpath remains the valid reorg escape.This would preserve the current immediate reorg behavior while preventing a later head from “laundering” an old IL-incompliant payload just by building enough compliant descendants on top of it. It also seems aligned with the intuition that FOCIL enforcement should mean “do not build canonical history on top of an IL-incompliant execution payload”, rather than only “try to reorg it in the next slot”.