Skip to content

Commit

Permalink
pd: add migration for testnet77
Browse files Browse the repository at this point in the history
Adds a new migration, which resets the halt bit. No other migration
logic is required, as no state-breaking changes are slated for testnet
77. This way, we preserve `pd migrate` as the default invocation for
node operators. Also changed here are the APP_VERSION and corresponding
docs entries.

Refs #4497.
  • Loading branch information
conorsch committed May 30, 2024
1 parent 6dc03da commit fa7af55
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 4 deletions.
1 change: 1 addition & 0 deletions COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
| 3 (Testnet 74) | v0.74.x | v0.37.5 | v1 |
| 4 (Testnet 75) | v0.75.x | v0.37.5 | v1 |
| 5 (Testnet 76) | v0.76.x | v0.37.5 | v1 |
| 6 (Testnet 77) | v0.77.x | v0.37.5 | v1 |
4 changes: 2 additions & 2 deletions crates/bin/pd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use cnidarium::Storage;
use metrics_exporter_prometheus::PrometheusBuilder;
use pd::{
cli::{Opt, RootCommand, TestnetCommand},
migrate::Migration::{ReadyToStart, Testnet76},
migrate::Migration::{ReadyToStart, Testnet77},
testnet::{
config::{get_testnet_dir, parse_tm_address, url_has_necessary_parts},
generate::TestnetConfig,
Expand Down Expand Up @@ -458,7 +458,7 @@ async fn main() -> anyhow::Result<()> {

let genesis_start = pd::migrate::last_block_timestamp(pd_home.clone()).await?;
tracing::info!(?genesis_start, "last block timestamp");
Testnet76
Testnet77
.migrate(pd_home.clone(), comet_home, Some(genesis_start), force)
.instrument(pd_migrate_span)
.await
Expand Down
7 changes: 7 additions & 0 deletions crates/bin/pd/src/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod simple;
mod testnet72;
mod testnet74;
mod testnet76;
mod testnet77;

use anyhow::{ensure, Context};
use penumbra_governance::StateReadExt;
Expand Down Expand Up @@ -43,6 +44,9 @@ pub enum Migration {
/// - Heal the auction component's VCB tally.
/// - Update FMD parameters to new protobuf structure.
Testnet76,
/// Testnet-77 migration:
/// - Reset the halt bit
Testnet77,
}

impl Migration {
Expand Down Expand Up @@ -88,6 +92,9 @@ impl Migration {
Migration::Testnet76 => {
testnet76::migrate(storage, pd_home.clone(), genesis_start).await?
}
Migration::Testnet77 => {
testnet77::migrate(storage, pd_home.clone(), genesis_start).await?
}
};

if let Some(comet_home) = comet_home {
Expand Down
78 changes: 78 additions & 0 deletions crates/bin/pd/src/migrate/testnet77.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//! Contains functions related to the migration script of Testnet77.
//! The Testnet 77 release included several consensus-breaking changes,
//! but no state-breaking changes, so the migration is essentially a no-op,
//! other than resetting the halt bit.
use anyhow;
use cnidarium::Storage;
use jmt::RootHash;
use penumbra_app::app::StateReadExt as _;
use penumbra_sct::component::clock::EpochRead;
use std::path::PathBuf;
use tracing::instrument;

use crate::testnet::generate::TestnetConfig;

/// Run the full migration, given an export path and a start time for genesis.
///
/// Menu:
/// - Reconstruct a correct VCB balance for the auction component.
#[instrument]
pub async fn migrate(
storage: Storage,
pd_home: PathBuf,
genesis_start: Option<tendermint::time::Time>,
) -> anyhow::Result<()> {
// Setup:
let initial_state = storage.latest_snapshot();
let chain_id = initial_state.get_chain_id().await?;
let root_hash = initial_state
.root_hash()
.await
.expect("chain state has a root hash");
let pre_upgrade_root_hash: RootHash = root_hash.into();
let pre_upgrade_height = initial_state
.get_block_height()
.await
.expect("chain state has a block height");
let post_upgrade_height = pre_upgrade_height.wrapping_add(1);
storage.release().await;

// The migration is complete, now we need to generate a genesis file. To do this, we need
// to lookup a validator view from the chain, and specify the post-upgrade app hash and
// initial height.
let app_state = penumbra_app::genesis::Content {
chain_id,
..Default::default()
};
let mut genesis = TestnetConfig::make_genesis(app_state.clone()).expect("can make genesis");
genesis.app_hash = pre_upgrade_root_hash
.0
.to_vec()
.try_into()
.expect("infallible conversion");

genesis.initial_height = post_upgrade_height as i64;
genesis.genesis_time = genesis_start.unwrap_or_else(|| {
let now = tendermint::time::Time::now();
tracing::info!(%now, "no genesis time provided, detecting a testing setup");
now
});
let checkpoint = pre_upgrade_root_hash.0.to_vec();
let genesis = TestnetConfig::make_checkpoint(genesis, Some(checkpoint));
let genesis_json = serde_json::to_string(&genesis).expect("can serialize genesis");
tracing::info!("genesis: {}", genesis_json);
let genesis_path = pd_home.join("genesis.json");
std::fs::write(genesis_path, genesis_json).expect("can write genesis");

let validator_state_path = pd_home.join("priv_validator_state.json");
let fresh_validator_state = crate::testnet::generate::TestnetValidator::initial_state();
std::fs::write(validator_state_path, fresh_validator_state).expect("can write validator state");

tracing::info!(
pre_upgrade_height,
?pre_upgrade_root_hash,
"successful migration!"
);

Ok(())
}
2 changes: 1 addition & 1 deletion crates/core/app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use once_cell::sync::Lazy;

/// Representation of the Penumbra application version. Notably, this is distinct
/// from the crate version(s). This number should only ever be incremented.
pub const APP_VERSION: u64 = 5;
pub const APP_VERSION: u64 = 6;

pub static SUBSTORE_PREFIXES: Lazy<Vec<String>> = Lazy::new(|| {
vec![
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/src/node/pd/chain-upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ so that your node state is recoverable.
1. Stop both `pd` and `cometbft`. Depending on how you run Penumbra, this could mean `sudo systemctl stop penumbra cometbft`.
2. Download the latest version of `pd` and install it. Run `pd --version` and confirm you see `{{ #include ../../penumbra_version.md }}` before proceeding.
3. Optionally, use `pd export` to create a snapshot of the `pd` state.
4. Apply the migration with `pd migrate --force --home PD_HOME --comet-home COMETBFT_HOME`. If using the default home locations (from `pd testnet join`), you can omit the paths and just run `pd migrate`.
4. Apply the migration with `pd migrate --home PD_HOME --comet-home COMETBFT_HOME`. If using the default home locations (from `pd testnet join`), you can omit the paths and just run `pd migrate`.

Finally, restart the node, e.g. `sudo systemctl restart penumbra cometbft`. Check the logs, and you should see the chain progressing
past the halt height `n`.

0 comments on commit fa7af55

Please sign in to comment.