Skip to content

Commit 179de15

Browse files
authored
Merge pull request #4555 from anoma/murisi/accelerate-epochs
Murisi/accelerate epochs
2 parents b4486cf + e741e76 commit 179de15

File tree

4 files changed

+128
-1
lines changed

4 files changed

+128
-1
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Added an example migration that immediately changes epoch durations.
2+
([\#4555](https://github.com/anoma/namada/pull/4555))

crates/migrations/src/foreign_types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ derive_typehash!(Vec::<u8>);
1212
derive_typehash!(Vec::<String>);
1313
derive_typehash!(u64);
1414
derive_typehash!(u128);
15+
derive_typehash!(Option::<u32>);
1516
#[cfg(feature = "masp")]
1617
derive_typehash!(masp_primitives::convert::AllowedConversion);

crates/sdk/src/migrations.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ const PRINTLN_CUTOFF: usize = 300;
2626

2727
/// For migrations involving the conversion state
2828
pub const CONVERSION_STATE_KEY: &str = "conversion_state";
29+
/// Key holding minimum start height for next epoch
30+
pub const NEXT_EPOCH_MIN_START_HEIGHT_KEY: &str = "next_epoch_min_start_height";
31+
/// Key holding minimum start time for next epoch
32+
pub const NEXT_EPOCH_MIN_START_TIME_KEY: &str = "next_epoch_min_start_time";
33+
/// Key holding number of blocks till next epoch
34+
pub const UPDATE_EPOCH_BLOCKS_DELAY_KEY: &str = "update_epoch_blocks_delay";
2935

3036
#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
3137
enum UpdateBytes {
@@ -319,6 +325,51 @@ impl DbUpdateType {
319325
})?;
320326
// Make sure to put the conversion state into memory too
321327
state.in_mem_mut().conversion_state = conversion_state;
328+
} else if DbColFam::STATE == *cf
329+
&& NEXT_EPOCH_MIN_START_HEIGHT_KEY == key.to_string()
330+
{
331+
let next_epoch_min_start_height = crate::decode(value)
332+
.map_err(|_| {
333+
eyre::eyre!(
334+
"The value provided for the key {} is not a \
335+
valid BlockHeight",
336+
key,
337+
)
338+
})?;
339+
// Make sure to put the next epoch minimum start height into
340+
// memory too
341+
state.in_mem_mut().next_epoch_min_start_height =
342+
next_epoch_min_start_height;
343+
} else if DbColFam::STATE == *cf
344+
&& NEXT_EPOCH_MIN_START_TIME_KEY == key.to_string()
345+
{
346+
let next_epoch_min_start_time = crate::decode(value)
347+
.map_err(|_| {
348+
eyre::eyre!(
349+
"The value provided for the key {} is not a \
350+
valid DateTimeUtc",
351+
key,
352+
)
353+
})?;
354+
// Make sure to put the next epoch minimum start time into
355+
// memory too
356+
state.in_mem_mut().next_epoch_min_start_time =
357+
next_epoch_min_start_time;
358+
} else if DbColFam::STATE == *cf
359+
&& UPDATE_EPOCH_BLOCKS_DELAY_KEY == key.to_string()
360+
{
361+
let update_epoch_blocks_delay = crate::decode(value)
362+
.map_err(|_| {
363+
eyre::eyre!(
364+
"The value provided for the key {} is not a \
365+
valid Option<u32>",
366+
key,
367+
)
368+
})?;
369+
// Make sure to put the update epoch blocks delay into
370+
// memory too
371+
state.in_mem_mut().update_epoch_blocks_delay =
372+
update_epoch_blocks_delay;
322373
}
323374

324375
migrator.write(state.db(), key, cf, value, persist_diffs);
@@ -609,6 +660,7 @@ derive_borshdeserializer!(Vec::<String>);
609660
derive_borshdeserializer!(u64);
610661
derive_borshdeserializer!(u128);
611662
derive_borshdeserializer!(namada_core::hash::Hash);
663+
derive_borshdeserializer!(Option::<u32>);
612664
derive_borshdeserializer!(masp_primitives::convert::AllowedConversion);
613665

614666
#[derive(BorshSerialize, BorshDeserialize)]

examples/make-db-migration.rs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ use masp_primitives::ff::PrimeField;
77
use masp_primitives::sapling::Node;
88
use masp_primitives::transaction::components::I128Sum;
99
use namada_core::borsh::BorshSerializeExt;
10+
use namada_core::chain::BlockHeight;
1011
use namada_core::dec::Dec;
1112
use namada_core::hash::Hash;
1213
use namada_core::masp::{Precision, encode_asset_type};
1314
use namada_core::storage::Key;
15+
use namada_core::time::MIN_UTC;
1416
use namada_macros::BorshDeserializer;
1517
use namada_migrations::REGISTER_DESERIALIZERS;
16-
use namada_parameters::storage::get_tx_allowlist_storage_key;
18+
use namada_parameters::EpochDuration;
19+
use namada_parameters::storage::{
20+
get_epoch_duration_storage_key, get_epochs_per_year_key,
21+
get_masp_epoch_multiplier_key, get_tx_allowlist_storage_key,
22+
};
1723
use namada_sdk::address::Address;
1824
use namada_sdk::ibc::trace::ibc_token;
1925
use namada_sdk::masp_primitives::asset_type::AssetType;
@@ -734,6 +740,63 @@ pub fn shielded_reward_parameters_migration(
734740
}
735741
}
736742

743+
/// Demonstrate accelerating epochs
744+
pub fn accelerate_epoch_migration(updates: &mut Vec<migrations::DbUpdateType>) {
745+
// Set the number of epochs per year to the specified constant
746+
const EPOCHS_PER_YEAR: u64 = 175200;
747+
let epochs_per_year_key = get_epochs_per_year_key();
748+
updates.push(migrations::DbUpdateType::Add {
749+
key: epochs_per_year_key,
750+
cf: DbColFam::SUBSPACE,
751+
value: EPOCHS_PER_YEAR.into(),
752+
force: false,
753+
});
754+
// Set the MASP epoch multiplier to the specified constant
755+
const MASP_EPOCH_MULTIPLIER: u64 = 2;
756+
let masp_epoch_multiplier_key = get_masp_epoch_multiplier_key();
757+
updates.push(migrations::DbUpdateType::Add {
758+
key: masp_epoch_multiplier_key,
759+
cf: DbColFam::SUBSPACE,
760+
value: MASP_EPOCH_MULTIPLIER.into(),
761+
force: false,
762+
});
763+
// Set the epoch duration to the specified constant
764+
const MIN_NUM_OF_BLOCKS: u64 = 4;
765+
let epy_i64 = i64::try_from(EPOCHS_PER_YEAR)
766+
.expect("`epochs_per_year` must not exceed `i64::MAX`");
767+
#[allow(clippy::arithmetic_side_effects)]
768+
let min_duration: i64 = 60 * 60 * 24 * 365 / epy_i64;
769+
let epoch_duration = EpochDuration {
770+
min_num_of_blocks: MIN_NUM_OF_BLOCKS,
771+
min_duration: namada_sdk::time::Duration::seconds(min_duration).into(),
772+
};
773+
let epoch_duration_key = get_epoch_duration_storage_key();
774+
updates.push(migrations::DbUpdateType::Add {
775+
key: epoch_duration_key,
776+
cf: DbColFam::SUBSPACE,
777+
value: epoch_duration.into(),
778+
force: false,
779+
});
780+
// Set the next epoch's block height to zero in order to force transition
781+
updates.push(migrations::DbUpdateType::Add {
782+
key: migrations::NEXT_EPOCH_MIN_START_HEIGHT_KEY
783+
.parse()
784+
.expect("unable to construct conversion state key"),
785+
cf: DbColFam::STATE,
786+
value: BlockHeight(0).into(),
787+
force: false,
788+
});
789+
// Set the next epoch's start time to a minimum in order to force transition
790+
updates.push(migrations::DbUpdateType::Add {
791+
key: migrations::NEXT_EPOCH_MIN_START_TIME_KEY
792+
.parse()
793+
.expect("unable to construct conversion state key"),
794+
cf: DbColFam::STATE,
795+
value: MIN_UTC.into(),
796+
force: false,
797+
});
798+
}
799+
737800
/// Generate various migrations
738801
pub fn main() {
739802
// Write an example migration that updates minted balances
@@ -796,4 +859,13 @@ pub fn main() {
796859
serde_json::to_string(&reward_parameter_changes).unwrap(),
797860
)
798861
.unwrap();
862+
// Write an example migration that accelerates epochs
863+
let mut accelerate_epochs_changes =
864+
migrations::DbChanges { changes: vec![] };
865+
accelerate_epoch_migration(&mut accelerate_epochs_changes.changes);
866+
std::fs::write(
867+
"accelerate_epochs_migration.json",
868+
serde_json::to_string(&accelerate_epochs_changes).unwrap(),
869+
)
870+
.unwrap();
799871
}

0 commit comments

Comments
 (0)