pub trait Upgrade<P: Pools> {
type PoolState: Into<P::PoolState> + for<'de> Deserialize<'de> + Clone;
type BlockState: Into<P::BlockState> + for<'de> Deserialize<'de> + Clone;
const POOL_STATE_MEMORY: u8;
const BLOCK_STATE_MEMORY: u8;
}Expand description
The Upgrade trait is used to handle state migrations when the state type of a Pools implementation changes.
Assume MyPools originally has a pool state type MyPoolState and block state type MyBlockState.
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Default)]
pub struct MyPoolState {
pub txid: Txid,
pub nonce: u64,
pub coin_reserved: Vec<CoinBalance>,
pub btc_reserved: u64,
pub utxos: Vec<Utxo>,
pub attributes: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Default)]
pub struct MyBlockState {
pub block_number: u32,
}
impl Pools for MyPools {
type PoolState = MyPoolState;
type BlockState = MyBlockState;
const POOL_STATE_MEMORY: u8 = 1;
const BLOCK_STATE_MEMORY: u8 = 2;
}Now we would like to update the MyPoolState type.
The best practice is to rename the MyPoolState to OldPoolState and define a new state type MyPoolState
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Default)]
pub struct OldPoolState {
pub txid: Txid,
pub nonce: u64,
pub coin_reserved: Vec<CoinBalance>,
pub btc_reserved: u64,
pub utxos: Vec<Utxo>,
pub attributes: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Default)]
pub struct MyPoolState {
pub txid: Txid,
pub nonce: u64,
pub coin_reserved: Vec<CoinBalance>,
pub btc_reserved: u64,
pub utxos: Vec<Utxo>,
pub attributes: String,
pub new_field: u32,
}
impl Into<MyState> for OldState {
fn into(self) -> MyState {
// ...
}
}
#[upgrade]
impl Upgrade<MyPools> for MyPools {
type PoolState = OldState;
type BlockState = u32;
// there is where we store the pool data before upgrade
const POOL_STATE_MEMORY: u8 = 1;
const BLOCK_STATE_MEMORY: u8 = 2;
}
impl Pools for MyPools {
type PoolState = MyPoolState;
type BlockState = u32;
// this is where we store the pool data after upgrade
const POOL_STATE_MEMORY: u8 = 3;
const BLOCK_STATE_MEMORY: u8 = 4;
}
Now you can call MyPools::upgrade() in the post_upgrade hook.
Required Associated Constants§
Sourceconst POOL_STATE_MEMORY: u8
const POOL_STATE_MEMORY: u8
The memory ID for the pool state storage in the previous version.
Sourceconst BLOCK_STATE_MEMORY: u8
const BLOCK_STATE_MEMORY: u8
The memory ID for the block state storage in the previous version.
Required Associated Types§
Sourcetype PoolState: Into<P::PoolState> + for<'de> Deserialize<'de> + Clone
type PoolState: Into<P::PoolState> + for<'de> Deserialize<'de> + Clone
The previous pool state type before the upgrade.
Sourcetype BlockState: Into<P::BlockState> + for<'de> Deserialize<'de> + Clone
type BlockState: Into<P::BlockState> + for<'de> Deserialize<'de> + Clone
The previous block state type before the upgrade.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.