From 9942c18c1180dc178eeebe5c00ed0f0edbe7bfae Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Tue, 9 Jul 2024 10:24:49 +1000 Subject: [PATCH] Delete old database schemas (#6051) * Delete old database schemas * Fix docs (thanks CK) * Fix beacon-chain tests --- .../src/beacon_fork_choice_store.rs | 62 +-------- .../beacon_chain/src/persisted_fork_choice.rs | 30 +---- beacon_node/beacon_chain/src/schema_change.rs | 29 +---- .../src/schema_change/migration_schema_v17.rs | 88 ------------- .../src/schema_change/migration_schema_v18.rs | 119 ------------------ .../src/schema_change/migration_schema_v19.rs | 65 ---------- beacon_node/beacon_chain/tests/store_tests.rs | 8 +- beacon_node/eth1/src/deposit_cache.rs | 5 +- beacon_node/eth1/src/inner.rs | 7 +- beacon_node/eth1/src/lib.rs | 4 +- book/src/database-migrations.md | 35 +++--- consensus/proto_array/src/lib.rs | 2 +- consensus/proto_array/src/proto_array.rs | 59 +-------- consensus/proto_array/src/ssz_container.rs | 47 +------ 14 files changed, 32 insertions(+), 528 deletions(-) delete mode 100644 beacon_node/beacon_chain/src/schema_change/migration_schema_v17.rs delete mode 100644 beacon_node/beacon_chain/src/schema_change/migration_schema_v18.rs delete mode 100644 beacon_node/beacon_chain/src/schema_change/migration_schema_v19.rs diff --git a/beacon_node/beacon_chain/src/beacon_fork_choice_store.rs b/beacon_node/beacon_chain/src/beacon_fork_choice_store.rs index f7f389c543..f746b68996 100644 --- a/beacon_node/beacon_chain/src/beacon_fork_choice_store.rs +++ b/beacon_node/beacon_chain/src/beacon_fork_choice_store.rs @@ -20,26 +20,12 @@ use types::{ Hash256, Slot, }; -/// Ensure this justified checkpoint has an epoch of 0 so that it is never -/// greater than the justified checkpoint and enshrined as the actual justified -/// checkpoint. -const JUNK_BEST_JUSTIFIED_CHECKPOINT: Checkpoint = Checkpoint { - epoch: Epoch::new(0), - root: Hash256::repeat_byte(0), -}; - #[derive(Debug)] pub enum Error { - UnableToReadSlot, - UnableToReadTime, - InvalidGenesisSnapshot(Slot), - AncestorUnknown { ancestor_slot: Slot }, - UninitializedBestJustifiedBalances, FailedToReadBlock(StoreError), MissingBlock(Hash256), FailedToReadState(StoreError), MissingState(Hash256), - InvalidPersistedBytes(ssz::DecodeError), BeaconStateError(BeaconStateError), Arith(ArithError), } @@ -66,7 +52,6 @@ const MAX_BALANCE_CACHE_SIZE: usize = 4; )] pub(crate) struct CacheItem { pub(crate) block_root: Hash256, - #[superstruct(only(V8))] pub(crate) epoch: Epoch, pub(crate) balances: Vec, } @@ -79,7 +64,6 @@ pub(crate) type CacheItem = CacheItemV8; no_enum )] pub struct BalancesCache { - #[superstruct(only(V8))] pub(crate) items: Vec, } @@ -365,59 +349,15 @@ where pub type PersistedForkChoiceStore = PersistedForkChoiceStoreV17; /// A container which allows persisting the `BeaconForkChoiceStore` to the on-disk database. -#[superstruct( - variants(V11, V17), - variant_attributes(derive(Encode, Decode)), - no_enum -)] +#[superstruct(variants(V17), variant_attributes(derive(Encode, Decode)), no_enum)] pub struct PersistedForkChoiceStore { - #[superstruct(only(V11, V17))] pub balances_cache: BalancesCacheV8, pub time: Slot, pub finalized_checkpoint: Checkpoint, pub justified_checkpoint: Checkpoint, pub justified_balances: Vec, - #[superstruct(only(V11))] - pub best_justified_checkpoint: Checkpoint, - #[superstruct(only(V11, V17))] pub unrealized_justified_checkpoint: Checkpoint, - #[superstruct(only(V11, V17))] pub unrealized_finalized_checkpoint: Checkpoint, - #[superstruct(only(V11, V17))] pub proposer_boost_root: Hash256, - #[superstruct(only(V11, V17))] pub equivocating_indices: BTreeSet, } - -impl From for PersistedForkChoiceStore { - fn from(from: PersistedForkChoiceStoreV11) -> PersistedForkChoiceStore { - PersistedForkChoiceStore { - balances_cache: from.balances_cache, - time: from.time, - finalized_checkpoint: from.finalized_checkpoint, - justified_checkpoint: from.justified_checkpoint, - justified_balances: from.justified_balances, - unrealized_justified_checkpoint: from.unrealized_justified_checkpoint, - unrealized_finalized_checkpoint: from.unrealized_finalized_checkpoint, - proposer_boost_root: from.proposer_boost_root, - equivocating_indices: from.equivocating_indices, - } - } -} - -impl From for PersistedForkChoiceStoreV11 { - fn from(from: PersistedForkChoiceStore) -> PersistedForkChoiceStoreV11 { - PersistedForkChoiceStoreV11 { - balances_cache: from.balances_cache, - time: from.time, - finalized_checkpoint: from.finalized_checkpoint, - justified_checkpoint: from.justified_checkpoint, - justified_balances: from.justified_balances, - best_justified_checkpoint: JUNK_BEST_JUSTIFIED_CHECKPOINT, - unrealized_justified_checkpoint: from.unrealized_justified_checkpoint, - unrealized_finalized_checkpoint: from.unrealized_finalized_checkpoint, - proposer_boost_root: from.proposer_boost_root, - equivocating_indices: from.equivocating_indices, - } - } -} diff --git a/beacon_node/beacon_chain/src/persisted_fork_choice.rs b/beacon_node/beacon_chain/src/persisted_fork_choice.rs index 5e50c3433a..8961a74c3d 100644 --- a/beacon_node/beacon_chain/src/persisted_fork_choice.rs +++ b/beacon_node/beacon_chain/src/persisted_fork_choice.rs @@ -1,4 +1,4 @@ -use crate::beacon_fork_choice_store::{PersistedForkChoiceStoreV11, PersistedForkChoiceStoreV17}; +use crate::beacon_fork_choice_store::PersistedForkChoiceStoreV17; use ssz::{Decode, Encode}; use ssz_derive::{Decode, Encode}; use store::{DBColumn, Error, StoreItem}; @@ -7,37 +7,12 @@ use superstruct::superstruct; // If adding a new version you should update this type alias and fix the breakages. pub type PersistedForkChoice = PersistedForkChoiceV17; -#[superstruct( - variants(V11, V17), - variant_attributes(derive(Encode, Decode)), - no_enum -)] +#[superstruct(variants(V17), variant_attributes(derive(Encode, Decode)), no_enum)] pub struct PersistedForkChoice { pub fork_choice: fork_choice::PersistedForkChoice, - #[superstruct(only(V11))] - pub fork_choice_store: PersistedForkChoiceStoreV11, - #[superstruct(only(V17))] pub fork_choice_store: PersistedForkChoiceStoreV17, } -impl From for PersistedForkChoice { - fn from(from: PersistedForkChoiceV11) -> PersistedForkChoice { - PersistedForkChoice { - fork_choice: from.fork_choice, - fork_choice_store: from.fork_choice_store.into(), - } - } -} - -impl From for PersistedForkChoiceV11 { - fn from(from: PersistedForkChoice) -> PersistedForkChoiceV11 { - PersistedForkChoiceV11 { - fork_choice: from.fork_choice, - fork_choice_store: from.fork_choice_store.into(), - } - } -} - macro_rules! impl_store_item { ($type:ty) => { impl StoreItem for $type { @@ -56,5 +31,4 @@ macro_rules! impl_store_item { }; } -impl_store_item!(PersistedForkChoiceV11); impl_store_item!(PersistedForkChoiceV17); diff --git a/beacon_node/beacon_chain/src/schema_change.rs b/beacon_node/beacon_chain/src/schema_change.rs index 3fe75e348c..4f7770e22c 100644 --- a/beacon_node/beacon_chain/src/schema_change.rs +++ b/beacon_node/beacon_chain/src/schema_change.rs @@ -1,7 +1,4 @@ //! Utilities for managing database schema changes. -mod migration_schema_v17; -mod migration_schema_v18; -mod migration_schema_v19; mod migration_schema_v20; mod migration_schema_v21; @@ -54,32 +51,8 @@ pub fn migrate_schema( } // - // Migrations from before SchemaVersion(16) are deprecated. + // Migrations from before SchemaVersion(19) are deprecated. // - (SchemaVersion(16), SchemaVersion(17)) => { - let ops = migration_schema_v17::upgrade_to_v17::(db.clone(), log)?; - db.store_schema_version_atomically(to, ops) - } - (SchemaVersion(17), SchemaVersion(16)) => { - let ops = migration_schema_v17::downgrade_from_v17::(db.clone(), log)?; - db.store_schema_version_atomically(to, ops) - } - (SchemaVersion(17), SchemaVersion(18)) => { - let ops = migration_schema_v18::upgrade_to_v18::(db.clone(), log)?; - db.store_schema_version_atomically(to, ops) - } - (SchemaVersion(18), SchemaVersion(17)) => { - let ops = migration_schema_v18::downgrade_from_v18::(db.clone(), log)?; - db.store_schema_version_atomically(to, ops) - } - (SchemaVersion(18), SchemaVersion(19)) => { - let ops = migration_schema_v19::upgrade_to_v19::(db.clone(), log)?; - db.store_schema_version_atomically(to, ops) - } - (SchemaVersion(19), SchemaVersion(18)) => { - let ops = migration_schema_v19::downgrade_from_v19::(db.clone(), log)?; - db.store_schema_version_atomically(to, ops) - } (SchemaVersion(19), SchemaVersion(20)) => { let ops = migration_schema_v20::upgrade_to_v20::(db.clone(), log)?; db.store_schema_version_atomically(to, ops) diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v17.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v17.rs deleted file mode 100644 index 770cbb8ab5..0000000000 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v17.rs +++ /dev/null @@ -1,88 +0,0 @@ -use crate::beacon_chain::{BeaconChainTypes, FORK_CHOICE_DB_KEY}; -use crate::persisted_fork_choice::{PersistedForkChoiceV11, PersistedForkChoiceV17}; -use proto_array::core::{SszContainerV16, SszContainerV17}; -use slog::{debug, Logger}; -use ssz::{Decode, Encode}; -use std::sync::Arc; -use store::{Error, HotColdDB, KeyValueStoreOp, StoreItem}; - -pub fn upgrade_fork_choice( - mut fork_choice: PersistedForkChoiceV11, -) -> Result { - let ssz_container_v16 = SszContainerV16::from_ssz_bytes( - &fork_choice.fork_choice.proto_array_bytes, - ) - .map_err(|e| { - Error::SchemaMigrationError(format!( - "Failed to decode ProtoArrayForkChoice during schema migration: {:?}", - e - )) - })?; - - let ssz_container_v17: SszContainerV17 = ssz_container_v16.try_into().map_err(|e| { - Error::SchemaMigrationError(format!( - "Missing checkpoint during schema migration: {:?}", - e - )) - })?; - fork_choice.fork_choice.proto_array_bytes = ssz_container_v17.as_ssz_bytes(); - - Ok(fork_choice.into()) -} - -pub fn downgrade_fork_choice( - mut fork_choice: PersistedForkChoiceV17, -) -> Result { - let ssz_container_v17 = SszContainerV17::from_ssz_bytes( - &fork_choice.fork_choice.proto_array_bytes, - ) - .map_err(|e| { - Error::SchemaMigrationError(format!( - "Failed to decode ProtoArrayForkChoice during schema migration: {:?}", - e - )) - })?; - - let ssz_container_v16: SszContainerV16 = ssz_container_v17.into(); - fork_choice.fork_choice.proto_array_bytes = ssz_container_v16.as_ssz_bytes(); - - Ok(fork_choice.into()) -} - -pub fn upgrade_to_v17( - db: Arc>, - log: Logger, -) -> Result, Error> { - // Get persisted_fork_choice. - let v11 = db - .get_item::(&FORK_CHOICE_DB_KEY)? - .ok_or_else(|| Error::SchemaMigrationError("fork choice missing from database".into()))?; - - let v17 = upgrade_fork_choice(v11)?; - - debug!( - log, - "Removing unused best_justified_checkpoint from fork choice store." - ); - - Ok(vec![v17.as_kv_store_op(FORK_CHOICE_DB_KEY)]) -} - -pub fn downgrade_from_v17( - db: Arc>, - log: Logger, -) -> Result, Error> { - // Get persisted_fork_choice. - let v17 = db - .get_item::(&FORK_CHOICE_DB_KEY)? - .ok_or_else(|| Error::SchemaMigrationError("fork choice missing from database".into()))?; - - let v11 = downgrade_fork_choice(v17)?; - - debug!( - log, - "Adding junk best_justified_checkpoint to fork choice store." - ); - - Ok(vec![v11.as_kv_store_op(FORK_CHOICE_DB_KEY)]) -} diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v18.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v18.rs deleted file mode 100644 index 04a9da8412..0000000000 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v18.rs +++ /dev/null @@ -1,119 +0,0 @@ -use crate::beacon_chain::BeaconChainTypes; -use slog::{error, info, warn, Logger}; -use slot_clock::SlotClock; -use std::sync::Arc; -use std::time::Duration; -use store::{ - get_key_for_col, metadata::BLOB_INFO_KEY, DBColumn, Error, HotColdDB, KeyValueStoreOp, -}; -use types::{Epoch, EthSpec, Hash256, Slot}; - -/// The slot clock isn't usually available before the database is initialized, so we construct a -/// temporary slot clock by reading the genesis state. It should always exist if the database is -/// initialized at a prior schema version, however we still handle the lack of genesis state -/// gracefully. -fn get_slot_clock( - db: &HotColdDB, - log: &Logger, -) -> Result, Error> { - let spec = db.get_chain_spec(); - let Some(genesis_block) = db.get_blinded_block(&Hash256::zero())? else { - error!(log, "Missing genesis block"); - return Ok(None); - }; - let Some(genesis_state) = db.get_state(&genesis_block.state_root(), Some(Slot::new(0)))? else { - error!(log, "Missing genesis state"; "state_root" => ?genesis_block.state_root()); - return Ok(None); - }; - Ok(Some(T::SlotClock::new( - spec.genesis_slot, - Duration::from_secs(genesis_state.genesis_time()), - Duration::from_secs(spec.seconds_per_slot), - ))) -} - -fn get_current_epoch( - db: &Arc>, - log: &Logger, -) -> Result { - get_slot_clock::(db, log)? - .and_then(|clock| clock.now()) - .map(|slot| slot.epoch(T::EthSpec::slots_per_epoch())) - .ok_or(Error::SlotClockUnavailableForMigration) -} - -pub fn upgrade_to_v18( - db: Arc>, - log: Logger, -) -> Result, Error> { - db.heal_freezer_block_roots_at_split()?; - db.heal_freezer_block_roots_at_genesis()?; - info!(log, "Healed freezer block roots"); - - // No-op, even if Deneb has already occurred. The database is probably borked in this case, but - // *maybe* the fork recovery will revert the minority fork and succeed. - if let Some(deneb_fork_epoch) = db.get_chain_spec().deneb_fork_epoch { - let current_epoch = get_current_epoch::(&db, &log)?; - if current_epoch >= deneb_fork_epoch { - warn!( - log, - "Attempting upgrade to v18 schema"; - "info" => "this may not work as Deneb has already been activated" - ); - } else { - info!( - log, - "Upgrading to v18 schema"; - "info" => "ready for Deneb", - "epochs_until_deneb" => deneb_fork_epoch - current_epoch - ); - } - } else { - info!( - log, - "Upgrading to v18 schema"; - "info" => "ready for Deneb once it is scheduled" - ); - } - Ok(vec![]) -} - -pub fn downgrade_from_v18( - db: Arc>, - log: Logger, -) -> Result, Error> { - // We cannot downgrade from V18 once the Deneb fork has been activated, because there will - // be blobs and blob metadata in the database that aren't understood by the V17 schema. - if let Some(deneb_fork_epoch) = db.get_chain_spec().deneb_fork_epoch { - let current_epoch = get_current_epoch::(&db, &log)?; - if current_epoch >= deneb_fork_epoch { - error!( - log, - "Deneb already active: v18+ is mandatory"; - "current_epoch" => current_epoch, - "deneb_fork_epoch" => deneb_fork_epoch, - ); - return Err(Error::UnableToDowngrade); - } else { - info!( - log, - "Downgrading to v17 schema"; - "info" => "you will need to upgrade before Deneb", - "epochs_until_deneb" => deneb_fork_epoch - current_epoch - ); - } - } else { - info!( - log, - "Downgrading to v17 schema"; - "info" => "you need to upgrade before Deneb", - ); - } - - let ops = vec![KeyValueStoreOp::DeleteKey(get_key_for_col( - DBColumn::BeaconMeta.into(), - BLOB_INFO_KEY.as_bytes(), - ))]; - - Ok(ops) -} diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v19.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v19.rs deleted file mode 100644 index 578e9bad31..0000000000 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v19.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::beacon_chain::BeaconChainTypes; -use slog::{debug, info, Logger}; -use std::sync::Arc; -use store::{get_key_for_col, DBColumn, Error, HotColdDB, KeyValueStore, KeyValueStoreOp}; - -pub fn upgrade_to_v19( - db: Arc>, - log: Logger, -) -> Result, Error> { - let mut hot_delete_ops = vec![]; - let mut blob_keys = vec![]; - let column = DBColumn::BeaconBlob; - - debug!(log, "Migrating from v18 to v19"); - // Iterate through the blobs on disk. - for res in db.hot_db.iter_column_keys::>(column) { - let key = res?; - let key_col = get_key_for_col(column.as_str(), &key); - hot_delete_ops.push(KeyValueStoreOp::DeleteKey(key_col)); - blob_keys.push(key); - } - - let num_blobs = blob_keys.len(); - debug!(log, "Collected {} blob lists to migrate", num_blobs); - - let batch_size = 500; - let mut batch = Vec::with_capacity(batch_size); - - for key in blob_keys { - let next_blob = db.hot_db.get_bytes(column.as_str(), &key)?; - if let Some(next_blob) = next_blob { - let key_col = get_key_for_col(column.as_str(), &key); - batch.push(KeyValueStoreOp::PutKeyValue(key_col, next_blob)); - - if batch.len() >= batch_size { - db.blobs_db.do_atomically(batch.clone())?; - batch.clear(); - } - } - } - - // Process the remaining batch if it's not empty - if !batch.is_empty() { - db.blobs_db.do_atomically(batch)?; - } - - debug!(log, "Wrote {} blobs to the blobs db", num_blobs); - - // Delete all the blobs - info!(log, "Upgrading to v19 schema"); - Ok(hot_delete_ops) -} - -pub fn downgrade_from_v19( - _db: Arc>, - log: Logger, -) -> Result, Error> { - // No-op - info!( - log, - "Downgrading to v18 schema"; - ); - - Ok(vec![]) -} diff --git a/beacon_node/beacon_chain/tests/store_tests.rs b/beacon_node/beacon_chain/tests/store_tests.rs index c2468102ee..6b77df4f81 100644 --- a/beacon_node/beacon_chain/tests/store_tests.rs +++ b/beacon_node/beacon_chain/tests/store_tests.rs @@ -3050,13 +3050,7 @@ async fn schema_downgrade_to_min_version() { ) .await; - let min_version = if harness.spec.deneb_fork_epoch.is_some() { - // Can't downgrade beyond V18 once Deneb is reached, for simplicity don't test that - // at all if Deneb is enabled. - SchemaVersion(18) - } else { - SchemaVersion(16) - }; + let min_version = SchemaVersion(19); // Save the slot clock so that the new harness doesn't revert in time. let slot_clock = harness.chain.slot_clock.clone(); diff --git a/beacon_node/eth1/src/deposit_cache.rs b/beacon_node/eth1/src/deposit_cache.rs index 75391e58a0..b443f739e8 100644 --- a/beacon_node/eth1/src/deposit_cache.rs +++ b/beacon_node/eth1/src/deposit_cache.rs @@ -54,7 +54,7 @@ pub enum Error { pub type SszDepositCache = SszDepositCacheV13; #[superstruct( - variants(V1, V13), + variants(V13), variant_attributes(derive(Encode, Decode, Clone)), no_enum )] @@ -62,11 +62,8 @@ pub struct SszDepositCache { pub logs: Vec, pub leaves: Vec, pub deposit_contract_deploy_block: u64, - #[superstruct(only(V13))] pub finalized_deposit_count: u64, - #[superstruct(only(V13))] pub finalized_block_height: u64, - #[superstruct(only(V13))] pub deposit_tree_snapshot: Option, pub deposit_roots: Vec, } diff --git a/beacon_node/eth1/src/inner.rs b/beacon_node/eth1/src/inner.rs index 0468a02d2e..452922b173 100644 --- a/beacon_node/eth1/src/inner.rs +++ b/beacon_node/eth1/src/inner.rs @@ -2,7 +2,7 @@ use crate::service::endpoint_from_config; use crate::Config; use crate::{ block_cache::{BlockCache, Eth1Block}, - deposit_cache::{DepositCache, SszDepositCache, SszDepositCacheV1, SszDepositCacheV13}, + deposit_cache::{DepositCache, SszDepositCache, SszDepositCacheV13}, }; use execution_layer::HttpJsonRpc; use parking_lot::RwLock; @@ -90,15 +90,12 @@ impl Inner { pub type SszEth1Cache = SszEth1CacheV13; #[superstruct( - variants(V1, V13), + variants(V13), variant_attributes(derive(Encode, Decode, Clone)), no_enum )] pub struct SszEth1Cache { pub block_cache: BlockCache, - #[superstruct(only(V1))] - pub deposit_cache: SszDepositCacheV1, - #[superstruct(only(V13))] pub deposit_cache: SszDepositCacheV13, #[ssz(with = "four_byte_option_u64")] pub last_processed_block: Option, diff --git a/beacon_node/eth1/src/lib.rs b/beacon_node/eth1/src/lib.rs index 9d6cb7c847..9c4f9a1d8d 100644 --- a/beacon_node/eth1/src/lib.rs +++ b/beacon_node/eth1/src/lib.rs @@ -5,9 +5,9 @@ mod metrics; mod service; pub use block_cache::{BlockCache, Eth1Block}; -pub use deposit_cache::{DepositCache, SszDepositCache, SszDepositCacheV1, SszDepositCacheV13}; +pub use deposit_cache::{DepositCache, SszDepositCache, SszDepositCacheV13}; pub use execution_layer::http::deposit_log::DepositLog; -pub use inner::{SszEth1Cache, SszEth1CacheV1, SszEth1CacheV13}; +pub use inner::{SszEth1Cache, SszEth1CacheV13}; pub use service::{ BlockCacheUpdateOutcome, Config, DepositCacheUpdateOutcome, Error, Eth1Endpoint, Service, DEFAULT_CHAIN_ID, diff --git a/book/src/database-migrations.md b/book/src/database-migrations.md index 611c61cb9c..fc16641da0 100644 --- a/book/src/database-migrations.md +++ b/book/src/database-migrations.md @@ -16,21 +16,19 @@ validator client or the slasher**. | Lighthouse version | Release date | Schema version | Downgrade available? | |--------------------|--------------|----------------|----------------------| -| v5.2.0 | Jun 2024 | v19 | yes before Deneb | -| v5.1.0 | Mar 2024 | v19 | yes before Deneb | -| v5.0.0 | Feb 2024 | v19 | yes before Deneb | -| v4.6.0 | Dec 2023 | v19 | yes before Deneb | -| v4.6.0-rc.0 | Dec 2023 | v18 | yes before Deneb | -| v4.5.0 | Sep 2023 | v17 | yes | -| v4.4.0 | Aug 2023 | v17 | yes | -| v4.3.0 | Jul 2023 | v17 | yes | -| v4.2.0 | May 2023 | v17 | yes | -| v4.1.0 | Apr 2023 | v16 | no | -| v4.0.1 | Mar 2023 | v16 | no | +| v5.3.0 | Aug 2024 TBD | v22 TBD | no (TBD) | +| v5.2.0 | Jun 2024 | v19 | no | +| v5.1.0 | Mar 2024 | v19 | no | +| v5.0.0 | Feb 2024 | v19 | no | +| v4.6.0 | Dec 2023 | v19 | no | > **Note**: All point releases (e.g. v4.4.1) are schema-compatible with the prior minor release > (e.g. v4.4.0). +> **Note**: Even if no schema downgrade is available, it is still possible to move between versions +> that use the same schema. E.g. you can downgrade from v5.2.0 to v5.0.0 because both use schema +> v19. + > **Note**: Support for old schemas is gradually removed from newer versions of Lighthouse. We usually do this after a major version has been out for a while and everyone has upgraded. Deprecated schema versions for previous releases are archived under @@ -210,12 +208,15 @@ Here are the steps to prune historic states: | Lighthouse version | Release date | Schema version | Downgrade available? | |--------------------|--------------|----------------|-------------------------------------| -| v4.6.0 | Dec 2023 | v19 | yes before Deneb | -| v4.6.0-rc.0 | Dec 2023 | v18 | yes before Deneb | -| v4.5.0 | Sep 2023 | v17 | yes | -| v4.4.0 | Aug 2023 | v17 | yes | -| v4.3.0 | Jul 2023 | v17 | yes | -| v4.2.0 | May 2023 | v17 | yes | +| v5.2.0 | Jun 2024 | v19 | yes before Deneb using <= v5.2.1 | +| v5.1.0 | Mar 2024 | v19 | yes before Deneb using <= v5.2.1 | +| v5.0.0 | Feb 2024 | v19 | yes before Deneb using <= v5.2.1 | +| v4.6.0 | Dec 2023 | v19 | yes before Deneb using <= v5.2.1 | +| v4.6.0-rc.0 | Dec 2023 | v18 | yes before Deneb using <= v5.2.1 | +| v4.5.0 | Sep 2023 | v17 | yes using <= v5.2.1 | +| v4.4.0 | Aug 2023 | v17 | yes using <= v5.2.1 | +| v4.3.0 | Jul 2023 | v17 | yes using <= v5.2.1 | +| v4.2.0 | May 2023 | v17 | yes using <= v5.2.1 | | v4.1.0 | Apr 2023 | v16 | yes before Capella using <= v4.5.0 | | v4.0.1 | Mar 2023 | v16 | yes before Capella using <= v4.5.0 | | v3.5.0 | Feb 2023 | v15 | yes before Capella using <= v4.5.0 | diff --git a/consensus/proto_array/src/lib.rs b/consensus/proto_array/src/lib.rs index 780563954c..b05a55e686 100644 --- a/consensus/proto_array/src/lib.rs +++ b/consensus/proto_array/src/lib.rs @@ -16,5 +16,5 @@ pub use error::Error; pub mod core { pub use super::proto_array::{ProposerBoost, ProtoArray, ProtoNode}; pub use super::proto_array_fork_choice::VoteTracker; - pub use super::ssz_container::{SszContainer, SszContainerV16, SszContainerV17}; + pub use super::ssz_container::{SszContainer, SszContainerV17}; } diff --git a/consensus/proto_array/src/proto_array.rs b/consensus/proto_array/src/proto_array.rs index d50153bfe8..efe154a27e 100644 --- a/consensus/proto_array/src/proto_array.rs +++ b/consensus/proto_array/src/proto_array.rs @@ -70,7 +70,7 @@ impl InvalidationOperation { pub type ProtoNode = ProtoNodeV17; #[superstruct( - variants(V16, V17), + variants(V17), variant_attributes(derive(Clone, PartialEq, Debug, Encode, Decode, Serialize, Deserialize)), no_enum )] @@ -92,12 +92,6 @@ pub struct ProtoNode { pub root: Hash256, #[ssz(with = "four_byte_option_usize")] pub parent: Option, - #[superstruct(only(V16))] - #[ssz(with = "four_byte_option_checkpoint")] - pub justified_checkpoint: Option, - #[superstruct(only(V16))] - #[ssz(with = "four_byte_option_checkpoint")] - pub finalized_checkpoint: Option, #[superstruct(only(V17))] pub justified_checkpoint: Checkpoint, #[superstruct(only(V17))] @@ -116,57 +110,6 @@ pub struct ProtoNode { pub unrealized_finalized_checkpoint: Option, } -impl TryInto for ProtoNodeV16 { - type Error = Error; - - fn try_into(self) -> Result { - let result = ProtoNode { - slot: self.slot, - state_root: self.state_root, - target_root: self.target_root, - current_epoch_shuffling_id: self.current_epoch_shuffling_id, - next_epoch_shuffling_id: self.next_epoch_shuffling_id, - root: self.root, - parent: self.parent, - justified_checkpoint: self - .justified_checkpoint - .ok_or(Error::MissingJustifiedCheckpoint)?, - finalized_checkpoint: self - .finalized_checkpoint - .ok_or(Error::MissingFinalizedCheckpoint)?, - weight: self.weight, - best_child: self.best_child, - best_descendant: self.best_descendant, - execution_status: self.execution_status, - unrealized_justified_checkpoint: self.unrealized_justified_checkpoint, - unrealized_finalized_checkpoint: self.unrealized_finalized_checkpoint, - }; - Ok(result) - } -} - -impl From for ProtoNodeV16 { - fn from(from: ProtoNode) -> ProtoNodeV16 { - ProtoNodeV16 { - slot: from.slot, - state_root: from.state_root, - target_root: from.target_root, - current_epoch_shuffling_id: from.current_epoch_shuffling_id, - next_epoch_shuffling_id: from.next_epoch_shuffling_id, - root: from.root, - parent: from.parent, - justified_checkpoint: Some(from.justified_checkpoint), - finalized_checkpoint: Some(from.finalized_checkpoint), - weight: from.weight, - best_child: from.best_child, - best_descendant: from.best_descendant, - execution_status: from.execution_status, - unrealized_justified_checkpoint: from.unrealized_justified_checkpoint, - unrealized_finalized_checkpoint: from.unrealized_finalized_checkpoint, - } - } -} - #[derive(PartialEq, Debug, Encode, Decode, Serialize, Deserialize, Copy, Clone)] pub struct ProposerBoost { pub root: Hash256, diff --git a/consensus/proto_array/src/ssz_container.rs b/consensus/proto_array/src/ssz_container.rs index a6d585758b..8abb60d8e6 100644 --- a/consensus/proto_array/src/ssz_container.rs +++ b/consensus/proto_array/src/ssz_container.rs @@ -1,6 +1,6 @@ use crate::proto_array::ProposerBoost; use crate::{ - proto_array::{ProtoArray, ProtoNodeV16, ProtoNodeV17}, + proto_array::{ProtoArray, ProtoNodeV17}, proto_array_fork_choice::{ElasticList, ProtoArrayForkChoice, VoteTracker}, Error, JustifiedBalances, }; @@ -16,62 +16,19 @@ four_byte_option_impl!(four_byte_option_checkpoint, Checkpoint); pub type SszContainer = SszContainerV17; -#[superstruct( - variants(V16, V17), - variant_attributes(derive(Encode, Decode)), - no_enum -)] +#[superstruct(variants(V17), variant_attributes(derive(Encode, Decode)), no_enum)] pub struct SszContainer { pub votes: Vec, pub balances: Vec, pub prune_threshold: usize, pub justified_checkpoint: Checkpoint, pub finalized_checkpoint: Checkpoint, - #[superstruct(only(V16))] - pub nodes: Vec, #[superstruct(only(V17))] pub nodes: Vec, pub indices: Vec<(Hash256, usize)>, pub previous_proposer_boost: ProposerBoost, } -impl TryInto for SszContainerV16 { - type Error = Error; - - fn try_into(self) -> Result { - let nodes: Result, Error> = - self.nodes.into_iter().map(TryInto::try_into).collect(); - - Ok(SszContainer { - votes: self.votes, - balances: self.balances, - prune_threshold: self.prune_threshold, - justified_checkpoint: self.justified_checkpoint, - finalized_checkpoint: self.finalized_checkpoint, - nodes: nodes?, - indices: self.indices, - previous_proposer_boost: self.previous_proposer_boost, - }) - } -} - -impl From for SszContainerV16 { - fn from(from: SszContainer) -> SszContainerV16 { - let nodes = from.nodes.into_iter().map(Into::into).collect(); - - SszContainerV16 { - votes: from.votes, - balances: from.balances, - prune_threshold: from.prune_threshold, - justified_checkpoint: from.justified_checkpoint, - finalized_checkpoint: from.finalized_checkpoint, - nodes, - indices: from.indices, - previous_proposer_boost: from.previous_proposer_boost, - } - } -} - impl From<&ProtoArrayForkChoice> for SszContainer { fn from(from: &ProtoArrayForkChoice) -> Self { let proto_array = &from.proto_array;