You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: state_machine.rs
    path of file: ./repos/namada/crates/proof_of_stake/src/tests
    
    the code of the file until where you have to start completion: //! Test PoS transitions with a state machine

use std::cmp;
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
use std::ops::Deref;

use assert_matches::assert_matches;
use itertools::Itertools;
use namada_core::address::{self, Address};
use namada_core::dec::Dec;
use namada_core::key;
use namada_core::key::common::PublicKey;
use namada_core::storage::Epoch;
use namada_core::token::Change;
use namada_governance::parameters::GovernanceParameters;
use namada_state::testing::TestState;
use namada_storage::collections::lazy_map::{
    Collectable, NestedSubKey, SubKey,
};
use namada_storage::StorageRead;
use proptest::prelude::*;
use proptest::test_runner::Config;
use proptest_state_machine::{
    prop_state_machine, ReferenceStateMachine, StateMachineTest,
};
// Use `RUST_LOG=info` (or another tracing level) and `--nocapture` to see
// `tracing` logs from tests
use test_log::test;

use crate::parameters::testing::arb_rate;
use crate::parameters::PosParams;
use crate::storage::{
    enqueued_slashes_handle, read_all_validator_addresses,
    read_below_capacity_validator_set_addresses,
    read_below_capacity_validator_set_addresses_with_stake,
    read_below_threshold_validator_set_addresses,
    read_consensus_validator_set_addresses_with_stake,
};
use crate::tests::helpers::{advance_epoch, arb_params_and_genesis_validators};
use crate::token::{self, read_balance};
use crate::types::{
    BondId, EagerRedelegatedBondsMap, GenesisValidator, ReverseOrdTokenAmount,
    Slash, SlashType, ValidatorState, WeightedValidator,
};
use crate::{
    below_capacity_validator_set_handle, consensus_validator_set_handle,
    read_pos_params, redelegate_tokens, validator_deltas_handle,
    validator_slashes_handle, validator_state_handle, BondsForRemovalRes,
    EagerRedelegatedUnbonds, FoldRedelegatedBondsResult, ModifiedRedelegation,
    RedelegationError, ResultSlashing,
};

prop_state_machine! {
    #![proptest_config(Config {
        cases: 2,
        .. Config::default()
    })]
    #[test]
    /// A `StateMachineTest` implemented on `PosState`
    fn pos_state_machine_test(sequential 500 => ConcretePosState);
}

type AbstractDelegatorRedelegatedBonded = BTreeMap<
    Address,
    BTreeMap<
        Address,
        BTreeMap<Epoch, BTreeMap<Address, BTreeMap<Epoch, token::Amount>>>,
    >,
>;

type AbstractDelegatorRedelegatedUnbonded = BTreeMap<
    Address,
    BTreeMap<
        Address,
        BTreeMap<
            (Epoch, Epoch),
            BTreeMap<Address, BTreeMap<Epoch, token::Amount>>,
        >,
    >,
>;

type AbstractValidatorTotalRedelegatedBonded = BTreeMap<
    Address,
    BTreeMap<Epoch, BTreeMap<Address, BTreeMap<Epoch, token::Amount>>>,
>;

type AbstractTotalRedelegatedUnbonded = BTr
    
    fn init_state() -> BoxedStrategy<Self::State> {
        tracing::debug!("\nInitializing abstract state machine");
        arb_params_and_genesis_validators(Some(8), 8..10)
            .prop_map(|(params, genesis_validators)| {
                let gov_params = GovernanceParameters::default();
                let params = params.with_gov_params(&gov_params);
                let epoch = Epoch::default();
                let mut state = Self {
                    epoch,
                    params,
                    gov_params,
                    genesis_validators: genesis_validators
                        .into_iter()
                        // Sorted by stake to fill in the consensus set first
                        .sorted_by(|a, b| Ord::cmp(&a.tokens, &b.tokens))
                        .rev()
                        .collect(),
                    bonds: Default::default(),
                    total_bonded: Default::default(),
                    unbonds: Default::default(),
                    validator_stakes: Default::default(),
                    consensus_set: Default::default(),
                    below_capacity_set: Default::default(),
                    below_threshold_set: Default::default(),
                    validator_states: Default::default(),
                    validator_slashes: Default::default(),
                    enqueued_slashes: Default::default(),
                    validator_last_slash_epochs: Default::default(),
                    total_unbonded: Default::default(),
                    delegator_redelegated_bonded: Default::default(),
                    delegator_redelegated_unbonded: Default::default(),
                    validator_total_redelegated_bonded: Default::default(),
                    validator_total_redelegated_unbonded: Default::default(),
                    incoming_redelegations: Default::default(),
                    outgoing_redelegations: Default::default(),
                };

                for GenesisValidator {
                    address,
                    tokens,
                    consensus_key: _,
                    protocol_key: _,
                    eth_cold_key: _,
                    eth_hot_key: _,
                    commission_rate: _,
                    max_commission_rate_change: _,
                    metadata: _,
                } in state.genesis_validators.clone()
                {
                    let bonds = state
                        .bonds
                        .entry(BondId {
                            source: address.clone(),
                            validator: address.clone(),
                        })
                        .or_default();
                    bonds.insert(epoch, tokens);

                    let total_bonded =
                        state.total_bonded.entry(address.clone()).or_default();
                    total_bonded.insert(epoch, tokens);

                    let total_stakes =
                        state.validator_stakes.entry(epoch).or_default();
                    total_stakes.insert(address.clone(), tokens);

                    let consensus_set =
                        state.consensus_set.entry(epoch).or_default();
                    let consensus_vals_len = consensus_set
                        .iter()
                        .map(|(_stake, validators)| validators.len() as u64)
                        .sum();

                    if tokens < state.params.validator_stake_threshold {
                        state
                            .below_threshold_set
                            .entry(epoch)
                            .or_default()
                            .insert(address.clone());
                        state
                            .validator_states
                            .entry(epoch)
                            .or_default()
                            .insert(address, ValidatorState::BelowThreshold);
                    } else if state.params.max_validator_slots
                        > consensus_vals_len
                    {
                        state
                            .validator_states
                            .entry(epoch)
                            .or_default()
                            .insert(address.clone(), ValidatorState::Consensus);
                        consensus_set
                            .entry(tokens)
                            .or_default()
                            .push_back(address);
                    } else {
                        state
                            .validator_states
                            .entry(epoch)
                            .or_default()
                            .insert(
                                address.clone(),
                                ValidatorState::BelowCapacity,
                            );
                        let below_cap_set =
                            state.below_capacity_set.entry(epoch).or_default();
                        below_cap_set
                            .entry(ReverseOrdTokenAmount(tokens))
                            .or_default()
                            .push_back(address)
                    };
                }
                // Ensure that below-capacity and below-threshold sets are
                // initialized even if empty
                state.below_capacity_set.entry(epoch).or_default();
                state.below_threshold_set.entry(epoch).or_default();

                // Copy validator sets up to pipeline epoch
                for epoch in epoch.next().iter_range(state.params.pipeline_len)
                {
                    state.copy_discrete_epoched_data(epoch)
                }
                state
            })
            .boxed()
    }