# ILs To bundle or not to bundle There has been plenty of discussions that have been repeated and going in circles about whether to bundle the IL sidecar and gossip it with the block or not. As we have been repeating the same arguments over and over again for several months now, I think it's better to put our thoughts in one place in writing. ## The argument to bundle (and my reply to them) - We have learnt with blobs that asynchronous validation of blocks pose a high complexity danger with several edge cases to be handled separately. Had we known this in advance we would have thought twice before deciding to unbundling the blobs and we would have tested for longer the bundled version. In view of the early versions of the IL spec, this was a very valid concern: we would not import a block if the IL was missing and would even mark it as invalid without an available IL, exactly in parallel with the blob paths. As far as I understand, this was the main concern raised by @tersec from Nimbus. However, the parallel with blobs is not really that close. In fact, as long as validators do not attest to blocks where they have not processed a valid IL and as long as they do not propose blocks on top of such parents, a validating client can validate blocks in a synchronous manner exactly as they do today. That is, IL availability is not a *validity* condition for blocks, but rather an off-chain criteria to check for *viability for head*. - There is a line of tought that bundling makes the code simpler. I argue otherwise. Lets consider what a validating code would need to do to handle bundled ILs+Blocks: - On each received block, the client will have to go into the gossip message to check if in fact the message does not correspond to an already imported block. This is because now a proposer will be allowed to gossip different blocks without being slashed (due to his being allowed to submit different ILs with the same block). This requires tinkering at the first p2p anti-dos level to quickly discard these messages. - If the IL is invalid and the block is valid, the block will be deemed invalid by this client, while other clients may find the same block valid if it came bundled with a valid IL. This allows a proposer to force split views in which clients will be requesting a block by RPC in case the split tips for inclusion. This is an easy split view on head which was the very reason we decided to not commit the summary on the beacon block. - Consider on the other hand the situation in which the proposer sends valid and invalid ILs for the same block, but in an unbundled situation. Here the split is exactly the same as that we are currently subject to: some validators will have imported the block with an available IL and some without it available. If the split tips towards inclusion, those validators that have the IL as unavailable will already have imported the block, there is nothing else that they need to do. The next proposer also makes sure to guarantee that the IL was indeed available, since his block has to satisfy it. This point in itself should be more than enough of a basis to completely disregard the idea of bundling the IL together with the block. - There is the argument that even if we import the blocks to forkchoice without seeing the valid IL, if these blocks are heavily attested and we are proposing the next slot then we would need to request the IL by RPC to propose. To this I would argue that the bundled situation is even worse, and this is analogous to something that we currently are subject to: if you are the proposer of slot N+1 and during slot N you do not receive the block at all, but you see a lot of attestations for N, you will be requesting the block N by RPC anyway. In the context of unbundled IL this actually becomes easier to identify, since in this case we even know for a fact what is the blockroot of the head block so we know by counting attestations that we have been isolated and we would have to request an IL to satisfy if we have not received it. More on timings below. - @terencechain mentions that there are less edge cases to consider, but I think this is simply not true. If we had tied the validity condition of blocks to the availability of the IL then this would be the case. But in general, it is much simpler to validate two independent messages than to validate the union of both. When the validation depends on validating a union, we have to deal with each of the parts failing reverting the full validation and potentially re-requesting the full block+IL, resulting in multiple times the bandwidth from these RPC requests for the full block when perhaps the validator only needs a valid IL. When the validation is independent, the client only needs to set independent handlers for each message: a valid block in the call to `on_block` results in a forkchoice node with the corresponding block. A valid IL in the call to `on_inclusion_list` results in the turning of the `il_available` boolean into true. There are no edge cases to consider. The one line change to forkchoice to handle unavailable ILs is simply filter from `is_viable_for_head` any tip that has this boolean as false. ## The arguments for unbundling Besides the strong case about the split views forcing validators to requests by RPCs, we gain the following from unbundling the IL - There is no need to change the interactions with the relay at all: the builder does not care about the IL for the current slot, nor does the relay. If we were to bundle them, the validator would have to send it entirely to the relay when it requests the header/block. Notice that also it becomes harder for the proposer to send different ILs in this situation since it would only be able to do so once it receives the full block back from the relay (again with the full IL, so how many roundtrips are we counting now?) - Decoupling of validation: altough we already talked as to how much easier it is to validate separate messages than the union, I can stress enough how much better of a pipelining it is, there is no need to stress the node into validating the CL block together with the IL **at the same time**, the proposer of N+1 in fact can broadcast an IL for it as soon as it has imported the head block N. He can do so typically 10 seconds before his own slot arrives! validators can schedule to validate this IL when their CPU is idle from both CL and EL work, this is a double win situation. - By broadcasting early the IL, the validator can make public his intention of reorging a previously imported block, notifying builders about this ahead of time, and builders can act better with this information at hand. - Gossip propagation of blocks becomes better since the block is smaller and travels faster, and each hop has to do less verification to both drop repeated messages or rebroadcast valid ones.