Potuz’s node was chugging along pretty happily following the chain. It unfortunately suffered a power loss and was unavailable for 5 days. He was so unlucky that during the 4th day, the chain stopped finalizing. So Potuz’s node has just restarted and finds itself leaking for the last 5 days, and being increasingly penalized since the last day of non-finality. His node starts requesting blocks by range. His last synced block was in slot S, the finalized checkpoint slot was F (4 days after S) and about one day from the current slot C. So Potuz’s node requests all blocks from S until C. Most nodes break this process in two logically (although not necessarily implementation-wise) different processes, the finalized range S -> F and the unfinalized section F -> C. This post will focus on the finalized section.
When the node receives the first chain of blocks starting at S, the CL executes the state transition. Crucially, blocks come with their corresponding execution payloads embedded in them. The CL sends these payloads to the EL for validation (we’ll go over variants of this below) and the EL can validate them immediately since the EL is starting up also from S. Eventually the node reaches C and everyone is happy.
One variant that clients use is to not send anything to the EL during the finalized section. They verify that the blockhash declared in the payload actually matches the payload and perform the CL state transition. Once they reach F they send a new payload to the EL. In this situation the EL will have all of the chain between S and F missing, so they can’t really validate the payload that is being sent. The EL checks the blockhash and returns SYNCING in this case, as they are in the process of catching up. Eventually the EL catches up and both CL and EL continue syncing in tandem.
Question 1 Is this behavior wasteful in bandwidth? Payloads are being requested twice by this node it seems.
Question 2 I have described two different behaviors that are applied today: the CL sends every block to the EL or the CL sends only unfinalized blocks to the EL but it performs the blockhash check itself. Can a node in either of these two approaches sync through a finalized but invalid block and be tricked into thinking it was valid?
A situation that is akin to the above one is if in addition to the node being 5 days offline, upon restart, the EL database has been erased. In this case even in the first behavior, the EL cannot validate blocks as they arrive because the entire state is missing (in addition to the parent blocks). In this case the EL starts syncing by some magical process. I will call this process snap sync admitting that there may be some other more magical and obscure ways of syncing. In this case the EL will start regenerating some state from its peers in such a way that it will be able to validate the incoming blocks. In this situation, but during the second behavior in which clients do not send new payloads to the EL, the EL will trigger this state syncing when it receives the first FCU.
Gloas syncing
Gloas presents us with a new paradigm: payloads and blocks are now separated and are not necessarily distributed by the same peers/networks.
To reproduce the exact same behavior as the above two scenarios, clients would request both blocks and payloads by range from S to C, they would perform the CL state transition using only the blocks, and will either send the payload to the EL for validation or validate the blockhash themselves as above.
The main question that justifies this note is
Question 3 What if the CL doesn’t even request the payloads from S to F? Can a node be tricked into thinking an invalid finalized block is actually valid?
In this case the CL would simply perform all the CL state transition up to the finalized checkpoint F and only request payloads for the unfinalized section. Thus, the EL, would have the entire range from S to F missing when it receives the fist payload. If the EL would simply request the missing range on their own and validate the blocks until it connects with the blocks after F then it seems that the answer would be no. If however snapshot syncing is triggered or some dark magic syncing system I’m unaware of, I do not know what the answer is above. If the EL validates all blocks then it seems to me that this system avoids the bandwidth waste of question 1.
Trust assumptions
What I am mostly interested is in enforcing the following statement
And my questions are essentially split in two
- Is the above statement true today?
- Will it remain true in Gloas if nodes do not request payloads by range?
The above seems to be true in the case the node restarts and actually validates all blocks, either on its own or getting them from the CL, it seems irrelevant to check the blockhash on the CL side if eventually the EL will have to check it unless I’m missing something.
However, in the presence of snapshot syncing, it seems to me that the trust assumption on the snapshot remains and the above statement is broken before and after Gloas. So it’s not clear to me what the CL gains by checking the payload blockhash and it seems in all cases the situation does not change if the CL simply syncs the CL blocks, trusting the validators and letting the EL eventually catch up on its own.
