pub fn restore(&mut self, start_height: u64) {
        let target_height = self.replay_target_height.map(Height::from);
        let backup_dir = self.backup_dir.as_ref().expect("No backup path found");
        let start_height = Height::from(start_height);
        let mut height_to_batches = backup::heights_to_artifacts_metadata(backup_dir, start_height)
            .unwrap_or_else(|err| panic!("File scanning failed: {:?}", err));
        println!(
            "Restoring the replica state of subnet {:?} starting from the height {:?}",
            backup_dir, start_height
        );
        // Assert consistent initial state
        backup::assert_consistency_and_clean_up(
            &*self.state_manager,
            self.consensus_pool.as_mut().unwrap(),
        );
        // We start with the specified height and restore heights until we run out of
        // heights on the backup spool or bump into a newer replica version.
        loop {
            let result = backup::deserialize_consensus_artifacts(
                self.registry.clone(),
                self.consensus_pool.as_mut().unwrap(),
                &mut height_to_batches,
                self.subnet_id,
                &self.replica_version,
                self.state_manager.latest_state_height(),
            );

            let last_batch_height = self.deliver_batches(
                &self.message_routing,
                &PoolReader::new(self.consensus_pool.as_ref().unwrap()),
                self.replay_target_height.map(Height::from),
            );
            self.wait_for_state(last_batch_height);
            if let Some(height) = target_height {
                if last_batch_height >= height {
                    println!("Target height {} reached.", height);
                    return;
                }
            }

            match result {
                // Since the pool cache assumes we always have at most one CUP inside the pool,
                // we should deliver all batches before inserting a new CUP into the pool.
                backup::ExitPoint::CUPHeightWasFinalized(cup_height) => {
                    backup::insert_cup_at_height(
                        self.consensus_pool.as_mut().unwrap(),
                        self.registry.clone(),
                        self.subnet_id,
                        backup_dir,
                        cup_height,
                    );
                    backup::assert_consistency_and_clean_up(
                        &*self.state_manager,
                        self.consensus_pool.as_mut().unwrap(),
                    );
                }
                // When we run into a proposal referencing a newer registry version, we need to dump
                // all changes from the registry canister into the local store and apply them.
                backup::ExitPoint::NewerRegistryVersion(new_version) => {
                    self.update_registry_local_store();
                    self.registry
                        .poll_once()
                        .expect("Couldn't update the registry from the local store");
                    assert!(
                        self.registry.get_latest_version() >= new_version,
                        "The registry client couldn't be updated to version {:?} (highest available version is {:?})",
                        new_version, self.registry.get_latest_version()
                    );
                    println!("Updated the registry.");
                }
                backup::ExitPoint::StateBehind(certified_height) => {
                    assert!(
                        certified_height <= self.state_manager.latest_state_height(),
                        "The state manager didn't catch up with the expected certified height"
                    );
                    self.state_manager.remove_states_below(certified_height);
                }
                backup::ExitPoint::Done => {
                    println!(
                        "Restored the state at the height {:?}",
                        self.state_manager.latest_state_height()
                    );
                    return;
                }
            }
        }
    }
/// Restores the execution state starting from the given height.
Restores the execution state starting from the given height.
Restores the execution state starting from the given height .
pub fn restore(&mut self, start_height: u64) {
        let target_height = self.replay_target_height.map(Height::from);
        let backup_dir = self.backup_dir.as_ref().expect("No backup path found");
        let start_height = Height::from(start_height);
        let mut height_to_batches = backup::heights_to_artifacts_metadata(backup_dir, start_height)
            .unwrap_or_else(|err| panic!("File scanning failed: {:?}", err));
        println!(
            "Restoring the replica state of subnet {:?} starting from the height {:?}",
            backup_dir, start_height
        );
        // Assert consistent initial state
        backup::assert_consistency_and_clean_up(
            &*self.state_manager,
            self.consensus_pool.as_mut().unwrap(),
        );
        // We start with the specified height and restore heights until we run out of
        // heights on the backup spool or bump into a newer replica version.
        loop {
            let result = backup::deserialize_consensus_artifacts(
                self.registry.clone(),
                self.consensus_pool.as_mut().unwrap(),
                &mut height_to_batches,
                self.subnet_id,
                &self.replica_version,
                self.state_manager.latest_state_height(),
            );
            let last_batch_height = self.deliver_batches(
                &self.message_routing,
                &PoolReader::new(self.consensus_pool.as_ref().unwrap()),
                self.replay_target_height.map(Height::from),
            );
            self.wait_for_state(last_batch_height);
            if let Some(height) = target_height {
                if last_batch_height >= height {
                    println!("Target height {} reached.", height);
                    return;
                }
            }
            match result {
                // Since the pool cache assumes we always have at most one CUP inside the pool,
                // we should deliver all batches before inserting a new CUP into the pool.
                backup::ExitPoint::CUPHeightWasFinalized(cup_height) => {
                    backup::insert_cup_at_height(
                        self.consensus_pool.as_mut().unwrap(),
                        self.registry.clone(),
                        self.subnet_id,
                        backup_dir,
                        cup_height,
                    );
                    backup::assert_consistency_and_clean_up(
                        &*self.state_manager,
                        self.consensus_pool.as_mut().unwrap(),
                    );
                }
                // When we run into a proposal referencing a newer registry version, we need to dump
                // all changes from the registry canister into the local store and apply them.
                backup::ExitPoint::NewerRegistryVersion(new_version) => {
                    self.update_registry_local_store();
                    self.registry
                        .poll_once()
                        .expect("Couldn't update the registry from the local store");
                    assert!(
                        self.registry.get_latest_version() >= new_version,
                        "The registry client couldn't be updated to version {:?} (highest available version is {:?})",
                        new_version, self.registry.get_latest_version()
                    );
                    println!("Updated the registry.");
                }
                backup::ExitPoint::StateBehind(certified_height) => {
                    assert!(
                        certified_height <= self.state_manager.latest_state_height(),
                        "The state manager didn't catch up with the expected certified height"
                    );
                    self.state_manager.remove_states_below(certified_height);
                }
                backup::ExitPoint::Done => {
                    println!(
                        "Restored the state at the height {:?}",
                        self.state_manager.latest_state_height()
                    );
                    return;
                }
            }
        }
    }
pub fn restore ( & mut self , start_height : u64 ) { let target_height = self . replay_target_height . map ( Height :: from ) ; let backup_dir = self . backup_dir . as_ref ( ) . expect ( " " ) ; let start_height = Height :: from ( start_height ) ; let mut height_to_batches = backup :: heights_to_artifacts_metadata ( backup_dir , start_height ) . unwrap_or_else ( | err | panic ! ( " " err ) ) ; println ! ( " " backup_dir start_height ) ; // Assert consistent initial state backup :: assert_consistency_and_clean_up ( & * self . state_manager , self . consensus_pool . as_mut ( ) . unwrap ( ) , ) ; // We start with the specified height and restore heights until we run out of // heights on the backup spool or bump into a newer replica version. loop { let result = backup :: deserialize_consensus_artifacts ( self . registry . clone ( ) , self . consensus_pool . as_mut ( ) . unwrap ( ) , & mut height_to_batches , self . subnet_id , & self . replica_version , self . state_manager . latest_state_height ( ) , ) ; let last_batch_height = self . deliver_batches ( & self . message_routing , & PoolReader :: new ( self . consensus_pool . as_ref ( ) . unwrap ( ) ) , self . replay_target_height . map ( Height :: from ) , ) ; self . wait_for_state ( last_batch_height ) ; if let Some ( height ) = target_height { if last_batch_height >= height { println ! ( " " height ) ; return ; } } match result { // Since the pool cache assumes we always have at most one CUP inside the pool, // we should deliver all batches before inserting a new CUP into the pool. backup :: ExitPoint :: CUPHeightWasFinalized ( cup_height ) => { backup :: insert_cup_at_height ( self . consensus_pool . as_mut ( ) . unwrap ( ) , self . registry . clone ( ) , self . subnet_id , backup_dir , cup_height , ) ; backup :: assert_consistency_and_clean_up ( & * self . state_manager , self . consensus_pool . as_mut ( ) . unwrap ( ) , ) ; } // When we run into a proposal referencing a newer registry version, we need to dump // all changes from the registry canister into the local store and apply them. backup :: ExitPoint :: NewerRegistryVersion ( new_version ) => { self . update_registry_local_store ( ) ; self . registry . poll_once ( ) . expect ( " " ) ; assert ! ( self registry get_latest_version ( ) new_version " " new_version self registry get_latest_version ( ) ) ; println ! ( " " ) ; } backup :: ExitPoint :: StateBehind ( certified_height ) => { assert ! ( certified_height self state_manager latest_state_height ( ) " " ) ; self . state_manager . remove_states_below ( certified_height ) ; } backup :: ExitPoint :: Done => { println ! ( " " self state_manager latest_state_height ( ) ) ; return ; } } } }
Restores the execution state starting from the given height.
Restores the execution state starting from the given height .
&mut self
start_height
u64
&mut self
start_height
u64