66eca1a882
## Proposed Changes This PR has two aims: to speed up attestation packing in the op pool, and to fix bugs in the verification of attester slashings, proposer slashings and voluntary exits. The changes are bundled into a single database schema upgrade (v12). Attestation packing is sped up by removing several inefficiencies: - No more recalculation of `attesting_indices` during packing. - No (unnecessary) examination of the `ParticipationFlags`: a bitfield suffices. See `RewardCache`. - No re-checking of attestation validity during packing: the `AttestationMap` provides attestations which are "correct by construction" (I have checked this using Hydra). - No SSZ re-serialization for the clunky `AttestationId` type (it can be removed in a future release). So far the speed-up seems to be roughly 2-10x, from 500ms down to 50-100ms. Verification of attester slashings, proposer slashings and voluntary exits is fixed by: - Tracking the `ForkVersion`s that were used to verify each message inside the `SigVerifiedOp`. This allows us to quickly re-verify that they match the head state's opinion of what the `ForkVersion` should be at the epoch(s) relevant to the message. - Storing the `SigVerifiedOp` on disk rather than the raw operation. This allows us to continue track the fork versions after a reboot. This is mostly contained in this commit 52bb1840ae5c4356a8fc3a51e5df23ed65ed2c7f. ## Additional Info The schema upgrade uses the justified state to re-verify attestations and compute `attesting_indices` for them. It will drop any attestations that fail to verify, by the logic that attestations are most valuable in the few slots after they're observed, and are probably stale and useless by the time a node restarts. Exits and proposer slashings and similarly re-verified to obtain `SigVerifiedOp`s. This PR contains a runtime killswitch `--paranoid-block-proposal` which opts out of all the optimisations in favour of closely verifying every included message. Although I'm quite sure that the optimisations are correct this flag could be useful in the event of an unforeseen emergency. Finally, you might notice that the `RewardCache` appears quite useless in its current form because it is only updated on the hot-path immediately before proposal. My hope is that in future we can shift calls to `RewardCache::update` into the background, e.g. while performing the state advance. It is also forward-looking to `tree-states` compatibility, where iterating and indexing `state.{previous,current}_epoch_participation` is expensive and needs to be minimised.
61 lines
2.8 KiB
Rust
61 lines
2.8 KiB
Rust
use serde_derive::{Deserialize, Serialize};
|
|
use types::Checkpoint;
|
|
|
|
pub const DEFAULT_FORK_CHOICE_BEFORE_PROPOSAL_TIMEOUT: u64 = 250;
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
|
pub struct ChainConfig {
|
|
/// Maximum number of slots to skip when importing a consensus message (e.g., block,
|
|
/// attestation, etc).
|
|
///
|
|
/// If `None`, there is no limit.
|
|
pub import_max_skip_slots: Option<u64>,
|
|
/// A user-input `Checkpoint` that must exist in the beacon chain's sync path.
|
|
///
|
|
/// If `None`, there is no weak subjectivity verification.
|
|
pub weak_subjectivity_checkpoint: Option<Checkpoint>,
|
|
/// Determine whether to reconstruct historic states, usually after a checkpoint sync.
|
|
pub reconstruct_historic_states: bool,
|
|
/// Whether timeouts on `TimeoutRwLock`s are enabled or not.
|
|
pub enable_lock_timeouts: bool,
|
|
/// The max size of a message that can be sent over the network.
|
|
pub max_network_size: usize,
|
|
/// Number of milliseconds to wait for fork choice before proposing a block.
|
|
///
|
|
/// If set to 0 then block proposal will not wait for fork choice at all.
|
|
pub fork_choice_before_proposal_timeout_ms: u64,
|
|
/// Number of skip slots in a row before the BN refuses to use connected builders during payload construction.
|
|
pub builder_fallback_skips: usize,
|
|
/// Number of skip slots in the past `SLOTS_PER_EPOCH` before the BN refuses to use connected
|
|
/// builders during payload construction.
|
|
pub builder_fallback_skips_per_epoch: usize,
|
|
/// Number of epochs since finalization before the BN refuses to use connected builders during
|
|
/// payload construction.
|
|
pub builder_fallback_epochs_since_finalization: usize,
|
|
/// Whether any chain health checks should be considered when deciding whether to use the builder API.
|
|
pub builder_fallback_disable_checks: bool,
|
|
pub count_unrealized: bool,
|
|
/// Whether to apply paranoid checks to blocks proposed by this beacon node.
|
|
pub paranoid_block_proposal: bool,
|
|
}
|
|
|
|
impl Default for ChainConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
import_max_skip_slots: None,
|
|
weak_subjectivity_checkpoint: None,
|
|
reconstruct_historic_states: false,
|
|
enable_lock_timeouts: true,
|
|
max_network_size: 10 * 1_048_576, // 10M
|
|
fork_choice_before_proposal_timeout_ms: DEFAULT_FORK_CHOICE_BEFORE_PROPOSAL_TIMEOUT,
|
|
// Builder fallback configs that are set in `clap` will override these.
|
|
builder_fallback_skips: 3,
|
|
builder_fallback_skips_per_epoch: 8,
|
|
builder_fallback_epochs_since_finalization: 3,
|
|
builder_fallback_disable_checks: false,
|
|
count_unrealized: true,
|
|
paranoid_block_proposal: false,
|
|
}
|
|
}
|
|
}
|