Skip to content

Commit

Permalink
pd: add no-op migration for APP_VERSION 10 (#5074)
Browse files Browse the repository at this point in the history
## Describe your changes

Follow-up to #5073, which should have included a no-op migration.

## Issue ticket number and link

Towards #5010. 

## Testing and review

This work will be used to perform a chain upgrade on the PL testnet.
Once that's done, we should expect CI to pass fully on this PR, in
particular the "testnet-integration" suite.

## Checklist before requesting a review

- [x] I have added guiding text to explain how a reviewer should test
these changes.

- [x] If this code contains consensus-breaking changes, I have added the
"consensus-breaking" label. Otherwise, I declare my belief that there
are not consensus-breaking changes, for the following reason:

  > provides migration logic for proposed protocol-breaking changes
  • Loading branch information
conorsch committed Feb 21, 2025
1 parent 67fd47c commit be0a5c2
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 91 deletions.
100 changes: 50 additions & 50 deletions Cargo.lock

Large diffs are not rendered by default.

70 changes: 35 additions & 35 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ rate-limit = { existing-packages = 50 }
[workspace.package]
authors = ["Penumbra Labs <[email protected]"]
edition = "2021"
version = "2.0.0-alpha.0"
version = "2.0.0-alpha.1"
repository = "https://github.com/penumbra-zone/penumbra"
homepage = "https://penumbra.zone"
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -142,12 +142,12 @@ chacha20poly1305 = { version = "0.9.0" }
chrono = { default-features = false, version = "0.4" }
clap = { version = "3.2" }
cnidarium = { version = "0.83", default-features = false}
cnidarium-component = { default-features = false, version = "2.0.0-alpha.0", path = "crates/cnidarium-component" }
cometindex = { version = "2.0.0-alpha.0", path = "crates/util/cometindex" }
cnidarium-component = { default-features = false, version = "2.0.0-alpha.1", path = "crates/cnidarium-component" }
cometindex = { version = "2.0.0-alpha.1", path = "crates/util/cometindex" }
criterion = { version = "0.4" }
decaf377 = { default-features = false, version = "0.10.1" }
decaf377-fmd = { version = "2.0.0-alpha.0", path = "crates/crypto/decaf377-fmd" }
decaf377-ka = { version = "2.0.0-alpha.0", path = "crates/crypto/decaf377-ka" }
decaf377-fmd = { version = "2.0.0-alpha.1", path = "crates/crypto/decaf377-fmd" }
decaf377-ka = { version = "2.0.0-alpha.1", path = "crates/crypto/decaf377-ka" }
decaf377-rdsa = { version = "0.11.0" }
derivative = { version = "2.2" }
directories = { version = "4.0.1" }
Expand Down Expand Up @@ -175,36 +175,36 @@ once_cell = { version = "1.8" }
parking_lot = { version = "0.12.1" }
pbjson = { version = "0.7.0" }
pbjson-types = { version = "0.7.0" }
penumbra-sdk-app = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/app" }
penumbra-sdk-asset = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/asset" }
penumbra-sdk-community-pool = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/community-pool" }
penumbra-sdk-compact-block = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/compact-block" }
penumbra-sdk-custody = { version = "2.0.0-alpha.0", path = "crates/custody" }
penumbra-sdk-auction = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/auction" }
penumbra-sdk-dex = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/dex" }
penumbra-sdk-distributions = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/distributions" }
penumbra-sdk-fee = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/fee" }
penumbra-sdk-funding = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/funding" }
penumbra-sdk-governance = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/governance" }
penumbra-sdk-ibc = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/ibc" }
penumbra-sdk-keys = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/keys" }
penumbra-sdk-mock-client = { version = "2.0.0-alpha.0", path = "crates/test/mock-client" }
penumbra-sdk-mock-consensus = { version = "2.0.0-alpha.0", path = "crates/test/mock-consensus" }
penumbra-sdk-mock-tendermint-proxy = { version = "2.0.0-alpha.0", path = "crates/test/mock-tendermint-proxy" }
penumbra-sdk-num = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/num" }
penumbra-sdk-proof-params = { default-features = false, version = "2.0.0-alpha.0", path = "crates/crypto/proof-params" }
penumbra-sdk-proof-setup = { version = "2.0.0-alpha.0", path = "crates/crypto/proof-setup" }
penumbra-sdk-proto = { default-features = false, version = "2.0.0-alpha.0", path = "crates/proto" }
penumbra-sdk-sct = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/sct" }
penumbra-sdk-shielded-pool = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/shielded-pool" }
penumbra-sdk-stake = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/component/stake" }
penumbra-sdk-tct = { default-features = false, version = "2.0.0-alpha.0", path = "crates/crypto/tct" }
penumbra-sdk-test-subscriber = { version = "2.0.0-alpha.0", path = "crates/test/tracing-subscriber" }
penumbra-sdk-tower-trace = { version = "2.0.0-alpha.0", path = "crates/util/tower-trace" }
penumbra-sdk-transaction = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/transaction" }
penumbra-sdk-txhash = { default-features = false, version = "2.0.0-alpha.0", path = "crates/core/txhash" }
penumbra-sdk-view = { version = "2.0.0-alpha.0", path = "crates/view" }
penumbra-sdk-wallet = { version = "2.0.0-alpha.0", path = "crates/wallet" }
penumbra-sdk-app = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/app" }
penumbra-sdk-asset = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/asset" }
penumbra-sdk-community-pool = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/community-pool" }
penumbra-sdk-compact-block = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/compact-block" }
penumbra-sdk-custody = { version = "2.0.0-alpha.1", path = "crates/custody" }
penumbra-sdk-auction = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/auction" }
penumbra-sdk-dex = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/dex" }
penumbra-sdk-distributions = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/distributions" }
penumbra-sdk-fee = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/fee" }
penumbra-sdk-funding = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/funding" }
penumbra-sdk-governance = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/governance" }
penumbra-sdk-ibc = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/ibc" }
penumbra-sdk-keys = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/keys" }
penumbra-sdk-mock-client = { version = "2.0.0-alpha.1", path = "crates/test/mock-client" }
penumbra-sdk-mock-consensus = { version = "2.0.0-alpha.1", path = "crates/test/mock-consensus" }
penumbra-sdk-mock-tendermint-proxy = { version = "2.0.0-alpha.1", path = "crates/test/mock-tendermint-proxy" }
penumbra-sdk-num = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/num" }
penumbra-sdk-proof-params = { default-features = false, version = "2.0.0-alpha.1", path = "crates/crypto/proof-params" }
penumbra-sdk-proof-setup = { version = "2.0.0-alpha.1", path = "crates/crypto/proof-setup" }
penumbra-sdk-proto = { default-features = false, version = "2.0.0-alpha.1", path = "crates/proto" }
penumbra-sdk-sct = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/sct" }
penumbra-sdk-shielded-pool = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/shielded-pool" }
penumbra-sdk-stake = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/component/stake" }
penumbra-sdk-tct = { default-features = false, version = "2.0.0-alpha.1", path = "crates/crypto/tct" }
penumbra-sdk-test-subscriber = { version = "2.0.0-alpha.1", path = "crates/test/tracing-subscriber" }
penumbra-sdk-tower-trace = { version = "2.0.0-alpha.1", path = "crates/util/tower-trace" }
penumbra-sdk-transaction = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/transaction" }
penumbra-sdk-txhash = { default-features = false, version = "2.0.0-alpha.1", path = "crates/core/txhash" }
penumbra-sdk-view = { version = "2.0.0-alpha.1", path = "crates/view" }
penumbra-sdk-wallet = { version = "2.0.0-alpha.1", path = "crates/wallet" }
pin-project = { version = "1.0.12" }
pin-project-lite = { version = "0.2.9" }
poseidon377 = { version = "1.2.0" }
Expand Down
4 changes: 2 additions & 2 deletions crates/bin/pd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ once_cell = { workspace = true }
pbjson-types = { workspace = true }
penumbra-sdk-app = { workspace = true, default-features = true }
penumbra-sdk-asset = { workspace = true, default-features = true }
penumbra-sdk-auto-https = { version = "2.0.0-alpha.0", path = "../../util/auto-https" }
penumbra-sdk-auto-https = { version = "2.0.0-alpha.1", path = "../../util/auto-https" }
penumbra-sdk-compact-block = { workspace = true, default-features = true }
penumbra-sdk-custody = { workspace = true }
penumbra-sdk-auction = { workspace = true, features = ["parallel"], default-features = true }
Expand All @@ -76,7 +76,7 @@ penumbra-sdk-sct = { workspace = true, default-features = tr
penumbra-sdk-shielded-pool = { workspace = true, features = ["parallel"], default-features = true }
penumbra-sdk-stake = { workspace = true, features = ["parallel"], default-features = true }
penumbra-sdk-tct = { workspace = true, default-features = true }
penumbra-sdk-tendermint-proxy = { version = "2.0.0-alpha.0", path = "../../util/tendermint-proxy" }
penumbra-sdk-tendermint-proxy = { version = "2.0.0-alpha.1", path = "../../util/tendermint-proxy" }
penumbra-sdk-tower-trace = { workspace = true }
penumbra-sdk-transaction = { workspace = true, default-features = true }
pin-project = { workspace = true }
Expand Down
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::{NetworkCommand, Opt, RootCommand},
migrate::Migration::{Mainnet2, ReadyToStart},
migrate::Migration::{Mainnet3, ReadyToStart},
network::{
config::{get_network_dir, parse_tm_address, url_has_necessary_parts},
generate::NetworkConfig,
Expand Down Expand Up @@ -502,7 +502,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");
Mainnet2
Mainnet3
.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 @@ -6,6 +6,7 @@
//! in order to be compatible with the network post-chain-upgrade.
mod mainnet1;
mod mainnet2;
mod mainnet3;
mod reset_halt_bit;
mod simple;
mod testnet72;
Expand Down Expand Up @@ -60,6 +61,9 @@ pub enum Migration {
/// Mainnet-2 migration:
/// - no-op
Mainnet2,
/// Mainnet-3 migration:
/// - no-op
Mainnet3,
}

impl Migration {
Expand Down Expand Up @@ -112,6 +116,9 @@ impl Migration {
Migration::Mainnet2 => {
mainnet2::migrate(storage, pd_home.clone(), genesis_start).await?;
}
Migration::Mainnet3 => {
mainnet3::migrate(storage, pd_home.clone(), genesis_start).await?;
}
// We keep historical migrations around for now, this will help inform an abstracted
// design. Feel free to remove it if it's causing you trouble.
_ => unimplemented!("the specified migration is unimplemented"),
Expand Down
102 changes: 102 additions & 0 deletions crates/bin/pd/src/migrate/mainnet3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//! Migration for shipping consensus-breaking LQT functionality.
//!
//! This migration is a no-op in terms of state. It'll perform the required
//! APP_VERSION munging for UIP-6, and generate the usual new genesis and validator
//! watermark files.
use cnidarium::{StateDelta, Storage};
use jmt::RootHash;
use penumbra_sdk_app::app::StateReadExt as _;
use penumbra_sdk_app::app_version::migrate_app_version;
use penumbra_sdk_governance::StateWriteExt;
use penumbra_sdk_sct::component::clock::EpochManager;
use penumbra_sdk_sct::component::clock::EpochRead;
use std::path::PathBuf;
use tracing::instrument;

use crate::network::generate::NetworkConfig;

/// Run the full migration, emitting a new genesis event, representing historical state.
#[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");
// We obtain the pre-upgrade hash solely to log it as a result.
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);

let mut delta = StateDelta::new(initial_state);
let (migration_duration, post_upgrade_root_hash) = {
let start_time = std::time::SystemTime::now();

migrate_app_version(&mut delta, 10).await?;

// Reset the application height and halt flag.
delta.ready_to_start();
delta.put_block_height(0u64);

// Finally, commit the changes to the chain state.
let post_upgrade_root_hash = storage.commit_in_place(delta).await?;
tracing::info!(?post_upgrade_root_hash, "post-migration root hash");

(
start_time.elapsed().expect("start is set"),
post_upgrade_root_hash,
)
};
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_sdk_app::genesis::Content {
chain_id,
..Default::default()
};
let mut genesis = NetworkConfig::make_genesis(app_state.clone()).expect("can make genesis");
genesis.app_hash = post_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 = post_upgrade_root_hash.0.to_vec();
let genesis = NetworkConfig::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::network::generate::NetworkValidator::initial_state();
std::fs::write(validator_state_path, fresh_validator_state).expect("can write validator state");

tracing::info!(
pre_upgrade_height,
post_upgrade_height,
?pre_upgrade_root_hash,
?post_upgrade_root_hash,
duration = migration_duration.as_secs(),
"successful migration!"
);

Ok(())
}
2 changes: 1 addition & 1 deletion crates/bin/pmonitor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ colored = "2.1.0"
directories = {workspace = true}
futures = {workspace = true}
indicatif = {workspace = true}
pcli = {version = "2.0.0-alpha.0", path = "../pcli", default-features = true}
pcli = {version = "2.0.0-alpha.1", path = "../pcli", default-features = true}
penumbra-sdk-app = {workspace = true}
penumbra-sdk-asset = {workspace = true, default-features = false}
penumbra-sdk-compact-block = {workspace = true, default-features = false}
Expand Down
2 changes: 2 additions & 0 deletions crates/core/app/src/app_version/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ enum CheckContext {

/// Check that the expected version matches the found version, if it set.
/// This will return an error if the versions do not match.
#[tracing::instrument]
fn check_version(ctx: CheckContext, expected: u64, found: Option<u64>) -> anyhow::Result<()> {
tracing::debug!("running version check");
let found = found.unwrap_or(expected);
if found == expected {
return Ok(());
Expand Down
2 changes: 1 addition & 1 deletion crates/custody/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ blake2b_simd = {workspace = true}
bytes = {workspace = true, features = ["serde"]}
chacha20poly1305 = {workspace = true}
decaf377 = {workspace = true}
decaf377-frost = { version = "2.0.0-alpha.0", path = "../crypto/decaf377-frost" }
decaf377-frost = { version = "2.0.0-alpha.1", path = "../crypto/decaf377-frost" }
decaf377-ka = {workspace = true}
decaf377-rdsa = {workspace = true}
ed25519-consensus = {workspace = true}
Expand Down

0 comments on commit be0a5c2

Please sign in to comment.