Skip to content

Commit 8bc446a

Browse files
authored
penumbra: add migration for mainnet3 (#5151)
## Describe your changes Updates the default `pd migrate` behavior to apply mainnet migration 3, a no-op migration to coordinate dependency updates related to IBC handling. ## Issue ticket number and link See #5150. ## Testing and review The changes presented here are necessary, but not sufficient. Once the suitable fixes have been released, we'll need to add them here, and likely also in [ibc-types](https://github.com/penumbra-zone/ibc-types), and bump local references. Then we'll exercise the upgrade logic on a devnet created for this purpose. ## 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: > This PR will affect consensus and therefore provides a migration to aid in applying the consensus-breaking change safely.
1 parent 4fd362c commit 8bc446a

File tree

6 files changed

+116
-4
lines changed

6 files changed

+116
-4
lines changed

COMPATIBILITY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
| 7 (Testnet 78) | v0.78.x | v0.37.5 | v1 |
1010
| 7 (Mainnet) | v0.79.x | v0.37.x | v1 |
1111
| 8 (Mainnet) | v0.80.x | v0.37.x | v1 |
12-
| 9 (Mainnet) | v0.81.x | v0.37.x | v1 |
12+
| 9 (Mainnet) | v0.81.x -> v1.3.x | v0.37.x | v1 |
13+
| 10 (Mainnet) | v1.4.x | v0.37.x | v1 |

crates/bin/pd/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use cnidarium::Storage;
1212
use metrics_exporter_prometheus::PrometheusBuilder;
1313
use pd::{
1414
cli::{NetworkCommand, Opt, RootCommand},
15-
migrate::Migration::{Mainnet2, ReadyToStart},
15+
migrate::Migration::{Mainnet3, ReadyToStart},
1616
network::{
1717
config::{get_network_dir, parse_tm_address, url_has_necessary_parts},
1818
generate::NetworkConfig,
@@ -502,7 +502,7 @@ async fn main() -> anyhow::Result<()> {
502502

503503
let genesis_start = pd::migrate::last_block_timestamp(pd_home.clone()).await?;
504504
tracing::info!(?genesis_start, "last block timestamp");
505-
Mainnet2
505+
Mainnet3
506506
.migrate(pd_home.clone(), comet_home, Some(genesis_start), force)
507507
.instrument(pd_migrate_span)
508508
.await

crates/bin/pd/src/migrate.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//! in order to be compatible with the network post-chain-upgrade.
77
mod mainnet1;
88
mod mainnet2;
9+
mod mainnet3;
910
mod reset_halt_bit;
1011
mod simple;
1112
mod testnet72;
@@ -60,6 +61,9 @@ pub enum Migration {
6061
/// Mainnet-2 migration:
6162
/// - no-op
6263
Mainnet2,
64+
/// Mainnet-3 migration:
65+
/// - no-op
66+
Mainnet3,
6367
}
6468

6569
impl Migration {
@@ -112,6 +116,9 @@ impl Migration {
112116
Migration::Mainnet2 => {
113117
mainnet2::migrate(storage, pd_home.clone(), genesis_start).await?;
114118
}
119+
Migration::Mainnet3 => {
120+
mainnet3::migrate(storage, pd_home.clone(), genesis_start).await?;
121+
}
115122
// We keep historical migrations around for now, this will help inform an abstracted
116123
// design. Feel free to remove it if it's causing you trouble.
117124
_ => unimplemented!("the specified migration is unimplemented"),
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//! Migration for shipping consensus-breaking IBC changes, updating
2+
//! IBC-related dependencies for light-client verification paths, via
3+
//! `tendermint-rs` and associated `ibc-types` deps.
4+
use cnidarium::{StateDelta, Storage};
5+
use jmt::RootHash;
6+
use penumbra_sdk_app::app::StateReadExt as _;
7+
use penumbra_sdk_app::app_version::migrate_app_version;
8+
use penumbra_sdk_governance::StateWriteExt;
9+
use penumbra_sdk_sct::component::clock::EpochManager;
10+
use penumbra_sdk_sct::component::clock::EpochRead;
11+
use std::path::PathBuf;
12+
use tracing::instrument;
13+
14+
use crate::network::generate::NetworkConfig;
15+
16+
/// Run the full migration, emitting a new genesis event, representing historical state.
17+
///
18+
/// This will have the effect of reinserting packets which had acknowledgements containing
19+
/// errors, and erroneously removed from state, as if the acknowledgements had contained successes.
20+
#[instrument]
21+
pub async fn migrate(
22+
storage: Storage,
23+
pd_home: PathBuf,
24+
genesis_start: Option<tendermint::time::Time>,
25+
) -> anyhow::Result<()> {
26+
// Setup:
27+
let initial_state = storage.latest_snapshot();
28+
let chain_id = initial_state.get_chain_id().await?;
29+
let root_hash = initial_state
30+
.root_hash()
31+
.await
32+
.expect("chain state has a root hash");
33+
// We obtain the pre-upgrade hash solely to log it as a result.
34+
let pre_upgrade_root_hash: RootHash = root_hash.into();
35+
let pre_upgrade_height = initial_state
36+
.get_block_height()
37+
.await
38+
.expect("chain state has a block height");
39+
let post_upgrade_height = pre_upgrade_height.wrapping_add(1);
40+
41+
let mut delta = StateDelta::new(initial_state);
42+
let (migration_duration, post_upgrade_root_hash) = {
43+
let start_time = std::time::SystemTime::now();
44+
45+
migrate_app_version(&mut delta, 10).await?;
46+
47+
// Reset the application height and halt flag.
48+
delta.ready_to_start();
49+
delta.put_block_height(0u64);
50+
51+
// Finally, commit the changes to the chain state.
52+
let post_upgrade_root_hash = storage.commit_in_place(delta).await?;
53+
tracing::info!(?post_upgrade_root_hash, "post-migration root hash");
54+
55+
(
56+
start_time.elapsed().expect("start is set"),
57+
post_upgrade_root_hash,
58+
)
59+
};
60+
storage.release().await;
61+
62+
// The migration is complete, now we need to generate a genesis file. To do this, we need
63+
// to lookup a validator view from the chain, and specify the post-upgrade app hash and
64+
// initial height.
65+
let app_state = penumbra_sdk_app::genesis::Content {
66+
chain_id,
67+
..Default::default()
68+
};
69+
let mut genesis = NetworkConfig::make_genesis(app_state.clone()).expect("can make genesis");
70+
genesis.app_hash = post_upgrade_root_hash
71+
.0
72+
.to_vec()
73+
.try_into()
74+
.expect("infallible conversion");
75+
76+
genesis.initial_height = post_upgrade_height as i64;
77+
genesis.genesis_time = genesis_start.unwrap_or_else(|| {
78+
let now = tendermint::time::Time::now();
79+
tracing::info!(%now, "no genesis time provided, detecting a testing setup");
80+
now
81+
});
82+
let checkpoint = post_upgrade_root_hash.0.to_vec();
83+
let genesis = NetworkConfig::make_checkpoint(genesis, Some(checkpoint));
84+
let genesis_json = serde_json::to_string(&genesis).expect("can serialize genesis");
85+
tracing::info!("genesis: {}", genesis_json);
86+
let genesis_path = pd_home.join("genesis.json");
87+
std::fs::write(genesis_path, genesis_json).expect("can write genesis");
88+
89+
let validator_state_path = pd_home.join("priv_validator_state.json");
90+
let fresh_validator_state = crate::network::generate::NetworkValidator::initial_state();
91+
std::fs::write(validator_state_path, fresh_validator_state).expect("can write validator state");
92+
93+
tracing::info!(
94+
pre_upgrade_height,
95+
post_upgrade_height,
96+
?pre_upgrade_root_hash,
97+
?post_upgrade_root_hash,
98+
duration = migration_duration.as_secs(),
99+
"successful migration!"
100+
);
101+
102+
Ok(())
103+
}

crates/core/app/src/app_version.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// Representation of the Penumbra application version. Notably, this is distinct
22
/// from the crate version(s). This number should only ever be incremented.
3-
pub const APP_VERSION: u64 = 9;
3+
pub const APP_VERSION: u64 = 10;
44

55
cfg_if::cfg_if! {
66
if #[cfg(feature="component")] {

crates/core/app/src/app_version/component.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn version_to_software_version(version: u64) -> &'static str {
1717
7 => "v0.79.x",
1818
8 => "v0.80.x",
1919
9 => "v0.81.x",
20+
10 => "v1.4.x",
2021
_ => "unknown",
2122
}
2223
}

0 commit comments

Comments
 (0)