use exonum::{
crypto::Hash,
runtime::{ArtifactId, InstanceId},
};
use exonum_derive::*;
use exonum_merkledb::{
access::{Access, FromAccess, Prefixed},
Entry, Fork, ProofEntry, ProofMapIndex, ValueSetIndex,
};
use super::{
migration_state::MigrationState, multisig::MultisigIndex, AsyncEventState,
ConfigProposalWithHash, DeployRequest, MigrationRequest, SupervisorConfig,
};
#[doc(hidden)] #[derive(Debug, FromAccess)]
pub struct SchemaImpl<T: Access> {
#[from_access(flatten)]
pub public: Schema<T>,
pub vacant_instance_id: Entry<T::Base, InstanceId>,
pub deploy_requests: MultisigIndex<T, DeployRequest>,
pub deploy_confirmations: MultisigIndex<T, DeployRequest>,
pub deploy_states: ProofMapIndex<T::Base, DeployRequest, AsyncEventState>,
pub pending_deployments: ProofMapIndex<T::Base, ArtifactId, DeployRequest>,
pub config_confirms: MultisigIndex<T, Hash>,
pub configuration_number: Entry<T::Base, u64>,
pub migration_requests: MultisigIndex<T, MigrationRequest>,
pub migration_states: ProofMapIndex<T::Base, MigrationRequest, MigrationState>,
pub migration_confirmations: MultisigIndex<T, MigrationRequest>,
pub pending_migrations: ValueSetIndex<T::Base, MigrationRequest>,
pub migrations_to_flush: ValueSetIndex<T::Base, MigrationRequest>,
}
#[derive(Debug, FromAccess, RequireArtifact)]
pub struct Schema<T: Access> {
pub configuration: ProofEntry<T::Base, SupervisorConfig>,
pub pending_proposal: ProofEntry<T::Base, ConfigProposalWithHash>,
}
impl<T: Access> SchemaImpl<T> {
pub fn new(access: T) -> Self {
Self::from_root(access).unwrap()
}
pub fn get_configuration_number(&self) -> u64 {
self.configuration_number.get().unwrap_or(0)
}
pub fn supervisor_config(&self) -> SupervisorConfig {
self.public
.configuration
.get()
.expect("Supervisor entity was not configured; unable to load configuration")
}
pub fn migration_state_unchecked(&self, request: &MigrationRequest) -> MigrationState {
self.migration_states
.get(request)
.expect("BUG: Migration succeed, but does not have a stored state")
}
}
impl SchemaImpl<Prefixed<&Fork>> {
pub fn increase_configuration_number(&mut self) {
let new_configuration_number = self.get_configuration_number() + 1;
self.configuration_number.set(new_configuration_number);
}
pub(crate) fn assign_instance_id(&mut self) -> Option<InstanceId> {
let id = self.vacant_instance_id.get()?;
self.vacant_instance_id.set(id + 1);
Some(id)
}
}