use ssz_derive::{Decode, Encode}; use state_processing::ConsensusContext; use std::collections::HashMap; use types::{EthSpec, Hash256, IndexedAttestation, Slot}; /// The consensus context is stored on disk as part of the data availability overflow cache. /// /// We use this separate struct to keep the on-disk format stable in the presence of changes to the /// in-memory `ConsensusContext`. You MUST NOT change the fields of this struct without /// superstructing it and implementing a schema migration. #[derive(Debug, PartialEq, Clone, Encode, Decode)] pub struct OnDiskConsensusContext { /// Slot to act as an identifier/safeguard slot: Slot, /// Proposer index of the block at `slot`. proposer_index: Option, /// Block root of the block at `slot`. current_block_root: Option, /// We keep the indexed attestations in the *in-memory* version of this struct so that we don't /// need to regenerate them if roundtripping via this type *without* going to disk. /// /// They are not part of the on-disk format. #[ssz(skip_serializing, skip_deserializing)] indexed_attestations: HashMap>, } impl OnDiskConsensusContext { pub fn from_consensus_context(ctxt: ConsensusContext) -> Self { // Match exhaustively on fields here so we are forced to *consider* updating the on-disk // format when the `ConsensusContext` fields change. let ConsensusContext { slot, previous_epoch: _, current_epoch: _, proposer_index, current_block_root, indexed_attestations, } = ctxt; OnDiskConsensusContext { slot, proposer_index, current_block_root, indexed_attestations, } } pub fn into_consensus_context(self) -> ConsensusContext { let OnDiskConsensusContext { slot, proposer_index, current_block_root, indexed_attestations, } = self; let mut ctxt = ConsensusContext::new(slot); if let Some(proposer_index) = proposer_index { ctxt = ctxt.set_proposer_index(proposer_index); } if let Some(block_root) = current_block_root { ctxt = ctxt.set_current_block_root(block_root); } ctxt.set_indexed_attestations(indexed_attestations) } }