EIP-7928: Block-Level Access Lists

If seems could be quite useful from security monitoring standpoint, as we can easier access state changes and do block-level assessments;

Would it make sense to have 7702 delegation designation traced there as well?

Yeah you can infer the delegation already statically having the raw transaction (tx type, tx_to + calldata should be enough to tell where an EOA will delegate to).
Furthermore, with regards to 7702, the BAL will contain the nonce change + a code change for the respective EOA. So, should have everything needed.

I added one additional sentence to the EIP to clarify that delegation indicators as inlcuded in BALs:

1 Like

Yeah, looking again code_changes should be sufficient

Would be interested in getting your opinion on one question that is still open. Should the BAL include state locations that are nod modified but still needed during execution (without any post-value but just the signal that a certain storage slot is needed) e.g. from BALANCE opcode. The argument against including those is that is adds additional 50% in size. On the other hand, from the performance persepctive, it might be enabling parallel batch I/O.
Curious what you think about security/auditing aspects here.

@yoavw are there any important interplays/gains to be aware of between BALs and native AA storage restrictions?

I’m curious about your opinion on how to best deprecate EIP-2930 Access Lists. I see the following two options:

  • cleanly deprecate by removing - very much not backwards compatible but removes code which is generally nice.
  • reprice them to silently deprecate them (economically). I proposed something like this here.

I’m not sure if there are usecases that are maybe not that visible on chain where it is urgently needed that txs come with state access predeclared (even though its correctness isn’t enforced). I don’t have a strong opinion and see why a clean removal of everything 2930 related might be the best option.

I agree with the economic approach. Penalize them according to their burden on the network, and people will stop using them. It also seems fairly simple.

I would like for that change to be in the same hark fork as the replacement mechanism (which I hope is a strict block access list though I haven’t been following this discussion recently), but if tx access lists are already a net negative then they should be deprecated as soon as possible.

Yeah agree, it’s best for Glamsterdam.

The thing that matters most to me is that the worst-case block size was significantly reduced with 7623, but the new worst-case block size now includes of a transaction that used 3/5 of the gas available for 2930 ALs and the rest for calldata. This is because you’d still get the cheaper 4/16 calldata price.

1 Like

If the main reason for this is to enable hint based parallel execution scheduling, in terms of block data overhead it might be a lot cheaper to only encode transaction dependencies.

I.e. each transaction has a list of the “direct parent” tx index. (E.g. a dependency chain A->B->C has B declare A and C declare B). As this only requires small integer types it’s a lot cheaper when it comes to bandwidth and metadata storage.
There is a parallel smart contract execution engine called Chiron that does it that way.

Right, this is an interesting idea as the data footprint would be kept minimal but the problem with this is that it doesn’t help in worst-cases.
For such, you’d get a block and see that it contains a long dependency chain but you cannot parallelize anything. Limiting the length of those dependency chains in-protocol comes with other problems such as DoS.
Also, without having the state diffs in blocks, you can’t use them for things like syncing or for running a partially stateless node, which might becomes possible with zkEVMs.

Yes, it only limits the data in the block, it doesn’t solve long dependency chains clogging up execution. Limiting the length of the dependency chains should be fine from a DoS perspective as you could argue that this doesn’t change the status quo too much.

Say you have currently a block limit of “g” and now with parallelization you go “g*c” if you limit the sequential limit to “g” you have the same DoS protection as the current protocol.

I do agree on the state diffs though, it doesn’t replace those for sure. But aren’t those independent of the access list? (i.e. only storing the parent index replaces access lists, but not state diffs).

It’s not fine in terms of DoS.
I could DoS a builder with transaction that do a lot of computation and in the end of the transaction touch some shared storage slot, thus extend the dependency chain (of my own transactions) over it’s limit, invalidating the block. At this point, the builder wasted resources executing my transaction just to find out it can’t be included although it would fit into the block with respect to the available gas and the transaction gas limit.

Fair point. Perfect deterministic solutions are hard to find for this. Couldn’t this at least be partially solved by adjusting the way the block is filled up? Say, the proposer traverses the transaction set in a way that it includes “non conflicting transactions” first and then prioritizes transactions that fit into “any sequential path window”?

This would further complicate things as MEV extracting transaction would game the system to maintain top-of-block execution guarantees. I think the current solution with having BALs with state diffs + state locations is a quite good compromise.
Still, I like ideas around splitting the block in smaller chunks, potentially, having chunks with specific use cases (payments, trading, etc), and I’ve recently written a post about it:

Lmk if you got feedback!