Add more checks and logging before genesis (#4730)

## Proposed Changes

This PR adds more logging prior to genesis, particularly on networks that start with execution enabled.

There are new checks using `eth_getBlockByHash/Number` to verify that the genesis state's `latest_execution_payload_header` matches the execution node's genesis block.

The first commit also runs the merge-readiness/Capella-readiness checks prior to genesis. This has two effects:

- Give more information on the execution node's status and its readiness for genesis.
- Prevent the `el_offline` status from being set on `/eth/v1/node/syncing`, which previously caused the VC to complain loudly.

I would like to include this for the Holesky reboot. It would have caught the misconfig that doomed the first Holesky.

## Additional Info

- Geth doesn't serve payload bodies prior to genesis, which is why we use the legacy methods. I haven't checked with other ELs yet.
- Currently this is logging errors with _Capella_ genesis states generated by `ethereum-genesis-generator` because the `withdrawals_root` is not set correctly (it is 0x0). This is not a blocker for Holesky, as it starts from Bellatrix (Pari is investigating).
This commit is contained in:
Michael Sproul
2023-09-21 00:26:53 +00:00
parent 1e9925435e
commit 5a35278aea
6 changed files with 209 additions and 10 deletions

View File

@@ -1,7 +1,7 @@
use crate::metrics;
use beacon_chain::{
capella_readiness::CapellaReadiness,
merge_readiness::{MergeConfig, MergeReadiness},
merge_readiness::{GenesisExecutionPayloadStatus, MergeConfig, MergeReadiness},
BeaconChain, BeaconChainTypes, ExecutionStatus,
};
use lighthouse_network::{types::SyncState, NetworkGlobals};
@@ -62,6 +62,9 @@ pub fn spawn_notifier<T: BeaconChainTypes>(
"wait_time" => estimated_time_pretty(Some(next_slot.as_secs() as f64)),
);
eth1_logging(&beacon_chain, &log);
merge_readiness_logging(Slot::new(0), &beacon_chain, &log).await;
capella_readiness_logging(Slot::new(0), &beacon_chain, &log).await;
genesis_execution_payload_logging(&beacon_chain, &log).await;
sleep(slot_duration).await;
}
_ => break,
@@ -365,7 +368,7 @@ async fn merge_readiness_logging<T: BeaconChainTypes>(
return;
}
match beacon_chain.check_merge_readiness().await {
match beacon_chain.check_merge_readiness(current_slot).await {
MergeReadiness::Ready {
config,
current_difficulty,
@@ -476,6 +479,79 @@ async fn capella_readiness_logging<T: BeaconChainTypes>(
}
}
async fn genesis_execution_payload_logging<T: BeaconChainTypes>(
beacon_chain: &BeaconChain<T>,
log: &Logger,
) {
match beacon_chain
.check_genesis_execution_payload_is_correct()
.await
{
Ok(GenesisExecutionPayloadStatus::Correct(block_hash)) => {
info!(
log,
"Execution enabled from genesis";
"genesis_payload_block_hash" => ?block_hash,
);
}
Ok(GenesisExecutionPayloadStatus::BlockHashMismatch { got, expected }) => {
error!(
log,
"Genesis payload block hash mismatch";
"info" => "genesis is misconfigured and likely to fail",
"consensus_node_block_hash" => ?expected,
"execution_node_block_hash" => ?got,
);
}
Ok(GenesisExecutionPayloadStatus::TransactionsRootMismatch { got, expected }) => {
error!(
log,
"Genesis payload transactions root mismatch";
"info" => "genesis is misconfigured and likely to fail",
"consensus_node_transactions_root" => ?expected,
"execution_node_transactions_root" => ?got,
);
}
Ok(GenesisExecutionPayloadStatus::WithdrawalsRootMismatch { got, expected }) => {
error!(
log,
"Genesis payload withdrawals root mismatch";
"info" => "genesis is misconfigured and likely to fail",
"consensus_node_withdrawals_root" => ?expected,
"execution_node_withdrawals_root" => ?got,
);
}
Ok(GenesisExecutionPayloadStatus::OtherMismatch) => {
error!(
log,
"Genesis payload header mismatch";
"info" => "genesis is misconfigured and likely to fail",
"detail" => "see debug logs for payload headers"
);
}
Ok(GenesisExecutionPayloadStatus::Irrelevant) => {
info!(
log,
"Execution is not enabled from genesis";
);
}
Ok(GenesisExecutionPayloadStatus::AlreadyHappened) => {
warn!(
log,
"Unable to check genesis which has already occurred";
"info" => "this is probably a race condition or a bug"
);
}
Err(e) => {
error!(
log,
"Unable to check genesis execution payload";
"error" => ?e
);
}
}
}
fn eth1_logging<T: BeaconChainTypes>(beacon_chain: &BeaconChain<T>, log: &Logger) {
let current_slot_opt = beacon_chain.slot().ok();