#[cfg(any(test, feature = "test-helpers"))]
mod test;
mod simple_list;
mod safe_contract;
mod contract;
mod multi;
use std::sync::Weak;
use client_traits::EngineClient;
use common_types::{
BlockNumber,
header::Header,
ids::BlockId,
errors::VapcoreError,
engines::machine::{Call, AuxiliaryData},
};
use enjen::SystemCall;
use vapory_types::{H256, Address};
use vapjson::spec::ValidatorSet as ValidatorSpec;
use mashina::Machine;
use tetsy_util_mem as malloc_size_of;
use tetsy_bytes::Bytes;
#[cfg(any(test, feature = "test-helpers"))]
pub use self::test::TestSet;
pub use self::simple_list::SimpleList;
use self::contract::ValidatorContract;
use self::safe_contract::ValidatorSafeContract;
use self::multi::Multi;
pub fn new_validator_set(spec: ValidatorSpec) -> Box<dyn ValidatorSet> {
match spec {
ValidatorSpec::List(list) => Box::new(SimpleList::new(list.into_iter().map(Into::into).collect())),
ValidatorSpec::SafeContract(address) => Box::new(ValidatorSafeContract::new(address.into())),
ValidatorSpec::Contract(address) => Box::new(ValidatorContract::new(address.into())),
ValidatorSpec::Multi(sequence) => Box::new(
Multi::new(sequence.into_iter().map(|(block, set)| (block.into(), new_validator_set(set))).collect())
),
}
}
pub trait ValidatorSet: Send + Sync + 'static {
fn default_caller(&self, block_id: BlockId) -> Box<Call>;
fn contains(&self, parent: &H256, address: &Address) -> bool {
let default = self.default_caller(BlockId::Hash(*parent));
self.contains_with_caller(parent, address, &*default)
}
fn get(&self, parent: &H256, nonce: usize) -> Address {
let default = self.default_caller(BlockId::Hash(*parent));
self.get_with_caller(parent, nonce, &*default)
}
fn count(&self, parent: &H256) -> usize {
let default = self.default_caller(BlockId::Hash(*parent));
self.count_with_caller(parent, &*default)
}
fn on_epoch_begin(&self, _first: bool, _header: &Header, _call: &mut SystemCall) -> Result<(), VapcoreError> {
Ok(())
}
fn genesis_epoch_data(&self, _header: &Header, _call: &Call) -> Result<Vec<u8>, String> { Ok(Vec::new()) }
fn is_epoch_end(&self, first: bool, chain_head: &Header) -> Option<Vec<u8>>;
fn signals_epoch_end(
&self,
first: bool,
header: &Header,
aux: AuxiliaryData,
) -> enjen::EpochChange;
fn epoch_set(&self, first: bool, mashina: &Machine, number: BlockNumber, proof: &[u8])
-> Result<(SimpleList, Option<H256>), VapcoreError>;
fn contains_with_caller(&self, parent_block_hash: &H256, address: &Address, caller: &Call) -> bool;
fn get_with_caller(&self, parent_block_hash: &H256, nonce: usize, caller: &Call) -> Address;
fn count_with_caller(&self, parent_block_hash: &H256, caller: &Call) -> usize;
fn report_malicious(&self, _validator: &Address, _set_block: BlockNumber, _block: BlockNumber, _proof: Bytes) {}
fn report_benign(&self, _validator: &Address, _set_block: BlockNumber, _block: BlockNumber) {}
fn register_client(&self, _client: Weak<dyn EngineClient>) {}
}