Use advanced state for block production (#2241)

## Issue Addressed

NA

## Proposed Changes

- Use the pre-states from #2174 during block production.
    - Running this on Pyrmont shows block production times dropping from ~550ms to ~150ms.
- Create `crit` and `warn` logs when a block is published to the API later than we expect.
    - On mainnet we are issuing a warn if the block is published more than 1s later than the slot start and a crit for more than 3s.
- Rename some methods on the `SnapshotCache` for clarity.
- Add the ability to pass the state root to `BeaconChain::produce_block_on_state` to avoid computing a state root. This is a very common LH optimization.
- Add a metric that tracks how late we broadcast blocks received from the HTTP API. This is *technically* a duplicate of a `ValidatorMonitor` log, but I wanted to have it for the case where we aren't monitoring validators too.
This commit is contained in:
Paul Hauner
2021-03-04 04:43:31 +00:00
parent 363f15f362
commit e4eb0eb168
7 changed files with 153 additions and 32 deletions

View File

@@ -13,7 +13,8 @@ mod validator_inclusion;
use beacon_chain::{
attestation_verification::SignatureVerifiedAttestation,
observed_operations::ObservationOutcome, validator_monitor::timestamp_now,
observed_operations::ObservationOutcome,
validator_monitor::{get_block_delay_ms, timestamp_now},
AttestationError as AttnError, BeaconChain, BeaconChainError, BeaconChainTypes,
};
use beacon_proposer_cache::BeaconProposerCache;
@@ -822,6 +823,15 @@ pub fn serve<T: BeaconChainTypes>(
PubsubMessage::BeaconBlock(Box::new(block.clone())),
)?;
// Determine the delay after the start of the slot, register it with metrics.
let delay =
get_block_delay_ms(seen_timestamp, &block.message, &chain.slot_clock);
metrics::observe_duration(
&metrics::HTTP_API_BLOCK_BROADCAST_DELAY_TIMES,
delay,
);
match chain.process_block(block.clone()) {
Ok(root) => {
info!(
@@ -844,6 +854,33 @@ pub fn serve<T: BeaconChainTypes>(
.fork_choice()
.map_err(warp_utils::reject::beacon_chain_error)?;
// Perform some logging to inform users if their blocks are being produced
// late.
//
// Check to see the thresholds are non-zero to avoid logging errors with small
// slot times (e.g., during testing)
let crit_threshold = chain.spec.seconds_per_slot / 3;
let warn_threshold = chain.spec.seconds_per_slot / 6;
if crit_threshold > 0 && delay.as_secs() > crit_threshold {
crit!(
log,
"Block was broadcast too late";
"root" => ?root,
"slot" => block.slot(),
"delay_ms" => delay.as_millis(),
"msg" => "system may be overloaded, block likely to be orphaned",
)
} else if warn_threshold > 0 && delay.as_secs() > warn_threshold {
warn!(
log,
"Block broadcast was delayed";
"root" => ?root,
"slot" => block.slot(),
"delay_ms" => delay.as_millis(),
"msg" => "system may be overloaded, block may be orphaned",
)
}
Ok(())
}
Err(e) => {

View File

@@ -29,4 +29,8 @@ lazy_static::lazy_static! {
"http_api_beacon_proposer_cache_misses_total",
"Count of times the proposer cache has been missed",
);
pub static ref HTTP_API_BLOCK_BROADCAST_DELAY_TIMES: Result<Histogram> = try_create_histogram(
"http_api_block_broadcast_delay_times",
"Time between start of the slot and when the block was broadcast"
);
}