# Consensus API enhancement
This document proposes a number of changes to the [existing](https://github.com/ethereum/rayonism/blob/master/specs/merge.md#consensus-json-rpc) communication protocol. It doesn't add any requirement to the underlying communication protocol, i.e. HTTP-based JSON-RPC should be sufficient to implement these changes.
- **ConsensusProcessed**. New type of message indicating that consensus block has been processed and respective execution payload either should be discarded or may be persisted depending on the validity of consensus block.
*Note*: two different beacon blocks may refer to the same execution payload and one of these two blocks may be invalid while the other one is not. Beacon block root added to `NewBlock` and `ConsensusProcessed` message payloads may distinguish two copies of the same execution payload.
- **Payload cache**. Given parallel processing of beacon block and execution payload, `NewBlock` and `ConsensusProcessed` messages will be sent indepdendently from each other, without any strict order. A tiny cache, holding execution payload until `ConsensusProcessed` comes in, is required to properly handle these two types of messages.
The cache should also keep a reference to a beacon block (see the note above). In addition, it removes the requirement to preserve the order of `NewBlock` and `SetHead` messages as the information they contain may also be cached. Getting rid of strict message order makes the protocol more resilient.
*Note*: with randao mixed into execution payload two beacon blocks are no longer able to reference the same execution payload. It should be enough to use `execution_payload.block_hash` for this cache and as payload identifier for all the messages.
- **GetPowBlock**. Transition process requires new type of message that nudges execution client to execute particular PoW block and send the response back to the consensus client, execution client will have to pull this block from the wire if needed.
An alternative is to use `eth_getBlockByHash` and rely upon PoW block gossip, assuming that the possibility of not receiving a PoW block via gossip is negligible enough for our use case.
*Note*: processing of this request may be time intensive and would require either increase of connection timeout or use of SSE stream or underlying protocol to be bi-directional to send the response in async fashion.
- **SetPosOperatingMode**. There are [three operating modes](https://hackmd.io/@n0ble/ethereum_consensus_upgrade_mainnet_perspective#Transition-process) that execution client will switch between during transition process. Bootstrap of the state sync process depends on the mode the execution client is operating in. Consensus client may get this information in advance by reading the state at WS checkpoint and explicitly notify execution client that the chain has already switched to PoS.
Alternatively, execution client should always start operating in PoW mode and listen to `NewBlock` and `FinalizeBlock` messages for further switching between modes. This approach will create a weird state of execution client that is trying to sync the state relying on PoW chain data while the network is already operating in the PoS mode.
*Note:* We might want all switches between modes to be explicit and triggered by consensus layer. It gives a flexibility to the transition process from consensus PoV, cleaner design and implementation.
- **NoParent**. Execution client may respond with `NoParent` to `NewBlock` message to let the consensus side know that the parent is unknown and provide additional information about the head of execution chain. Next, consensus client may replay blocks if the gap between execution chain's head and its own head is relatively small. This behaviour should aid for faster recovery after failures that has lead to inconsistency in chain data storages between the clients.
Currently, execution client will have to go and pull missing information (either pulling the state or blocks) from the wire if the gap is encountered.
- **Status**. Last two messages could be unified into a single status message that is sent at the beginning of communication between consensus and execution client. This message should be responded accodingly with the status of execution side to provide consensus client with the information that would be enough to make next steps.
*Note:* identifying the beginning of communication could be a problem as there is no session established between the parties.
- **Push processed blocks**. The execution layer may push every PoW block that is processed and considered as valid to the consensus layer. Consensus layer will cache those blocks that satisfies transition conditions allowing for smoother transition process.
Currently, consensus layer have to request PoW blocks on demand which could causes addition delay in the fork choice.