mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-11 18:04:18 +00:00
Add progress on test rig
This commit is contained in:
58
beacon_node/beacon_chain/tests/utils/direct_beacon_node.rs
Normal file
58
beacon_node/beacon_chain/tests/utils/direct_beacon_node.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use beacon_chain::{block_production::Error as BlockProductionError, BeaconChain};
|
||||
use block_producer::{BeaconNode as BeaconBlockNode, BeaconNodeError as BeaconBlockNodeError};
|
||||
use db::ClientDB;
|
||||
use slot_clock::SlotClock;
|
||||
use types::{BeaconBlock, PublicKey, Signature};
|
||||
|
||||
pub struct DirectBeaconNode<'a, T: ClientDB, U: SlotClock> {
|
||||
beacon_chain: &'a BeaconChain<T, U>,
|
||||
}
|
||||
|
||||
impl<'a, T: ClientDB, U: SlotClock> DirectBeaconNode<'a, T, U> {
|
||||
pub fn new(beacon_chain: &'a BeaconChain<T, U>) -> Self {
|
||||
Self { beacon_chain }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ClientDB, U: SlotClock> BeaconBlockNode for DirectBeaconNode<'a, T, U>
|
||||
where
|
||||
BlockProductionError: From<<U>::Error>,
|
||||
{
|
||||
fn proposer_nonce(&self, pubkey: &PublicKey) -> Result<u64, BeaconBlockNodeError> {
|
||||
let validator_index = self
|
||||
.beacon_chain
|
||||
.validator_index(pubkey)
|
||||
.ok_or_else(|| BeaconBlockNodeError::RemoteFailure("pubkey unknown.".to_string()))?;
|
||||
|
||||
self.beacon_chain
|
||||
.proposer_slots(validator_index)
|
||||
.ok_or_else(|| {
|
||||
BeaconBlockNodeError::RemoteFailure("validator_index unknown.".to_string())
|
||||
})
|
||||
}
|
||||
|
||||
fn produce_beacon_block(
|
||||
&self,
|
||||
slot: u64,
|
||||
randao_reveal: &Signature,
|
||||
) -> Result<Option<BeaconBlock>, BeaconBlockNodeError>
|
||||
where {
|
||||
let (block, _state) = self
|
||||
.beacon_chain
|
||||
.produce_block(randao_reveal.clone())
|
||||
.map_err(|e| BeaconBlockNodeError::RemoteFailure(format!("{:?}", e)))?;
|
||||
|
||||
if block.slot == slot {
|
||||
Ok(Some(block))
|
||||
} else {
|
||||
Err(BeaconBlockNodeError::RemoteFailure(
|
||||
"Unable to produce at non-current slot.".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the value specified by the `set_next_publish_result`.
|
||||
fn publish_beacon_block(&self, block: BeaconBlock) -> Result<bool, BeaconBlockNodeError> {
|
||||
Err(BeaconBlockNodeError::DecodeFailure)
|
||||
}
|
||||
}
|
||||
37
beacon_node/beacon_chain/tests/utils/direct_duties.rs
Normal file
37
beacon_node/beacon_chain/tests/utils/direct_duties.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
use beacon_chain::{block_production::Error as BlockProductionError, BeaconChain};
|
||||
use block_producer::{DutiesReader, DutiesReaderError};
|
||||
use db::ClientDB;
|
||||
use slot_clock::SlotClock;
|
||||
use types::PublicKey;
|
||||
|
||||
pub struct DirectDuties<'a, T: ClientDB, U: SlotClock> {
|
||||
beacon_chain: &'a BeaconChain<T, U>,
|
||||
pubkey: PublicKey,
|
||||
}
|
||||
|
||||
impl<'a, T: ClientDB, U: SlotClock> DirectDuties<'a, T, U> {
|
||||
pub fn new(pubkey: PublicKey, beacon_chain: &'a BeaconChain<T, U>) -> Self {
|
||||
Self {
|
||||
beacon_chain,
|
||||
pubkey,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ClientDB, U: SlotClock> DutiesReader for DirectDuties<'a, T, U>
|
||||
where
|
||||
BlockProductionError: From<<U>::Error>,
|
||||
{
|
||||
fn is_block_production_slot(&self, _epoch: u64, slot: u64) -> Result<bool, DutiesReaderError> {
|
||||
let validator_index = self
|
||||
.beacon_chain
|
||||
.validator_index(&self.pubkey)
|
||||
.ok_or_else(|| DutiesReaderError::UnknownValidator)?;
|
||||
|
||||
match self.beacon_chain.block_proposer(slot) {
|
||||
Some(proposer) if proposer == validator_index => Ok(true),
|
||||
Some(_) => Ok(false),
|
||||
None => Err(DutiesReaderError::UnknownEpoch),
|
||||
}
|
||||
}
|
||||
}
|
||||
9
beacon_node/beacon_chain/tests/utils/mod.rs
Normal file
9
beacon_node/beacon_chain/tests/utils/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
mod direct_beacon_node;
|
||||
mod direct_duties;
|
||||
mod test_rig;
|
||||
mod validator;
|
||||
|
||||
pub use self::direct_beacon_node::DirectBeaconNode;
|
||||
pub use self::direct_duties::DirectDuties;
|
||||
pub use self::test_rig::TestRig;
|
||||
pub use self::validator::TestValidator;
|
||||
85
beacon_node/beacon_chain/tests/utils/test_rig.rs
Normal file
85
beacon_node/beacon_chain/tests/utils/test_rig.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
use super::{DirectBeaconNode, DirectDuties, TestValidator};
|
||||
use beacon_chain::BeaconChain;
|
||||
#[cfg(test)]
|
||||
use block_producer::{test_utils::TestSigner, BlockProducer};
|
||||
use db::{
|
||||
stores::{BeaconBlockStore, BeaconStateStore},
|
||||
MemoryDB,
|
||||
};
|
||||
use slot_clock::TestingSlotClock;
|
||||
use spec::ChainSpec;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use types::{Keypair, Validator};
|
||||
|
||||
pub struct TestRig<'a> {
|
||||
db: Arc<MemoryDB>,
|
||||
beacon_chain: BeaconChain<MemoryDB, TestingSlotClock>,
|
||||
block_store: Arc<BeaconBlockStore<MemoryDB>>,
|
||||
state_store: Arc<BeaconStateStore<MemoryDB>>,
|
||||
validators: Vec<TestValidator<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> TestRig<'a> {
|
||||
pub fn new(spec: ChainSpec) -> Self {
|
||||
let db = Arc::new(MemoryDB::open());
|
||||
let block_store = Arc::new(BeaconBlockStore::new(db.clone()));
|
||||
let state_store = Arc::new(BeaconStateStore::new(db.clone()));
|
||||
|
||||
let slot_clock = TestingSlotClock::new(0);
|
||||
|
||||
let mut beacon_chain =
|
||||
BeaconChain::genesis(state_store.clone(), block_store.clone(), slot_clock, spec)
|
||||
.unwrap();
|
||||
|
||||
/*
|
||||
let validators = generate_validators(validator_count, &beacon_chain);
|
||||
beacon_chain.spec = inject_validators_into_spec(beacon_chain.spec.clone(), &validators[..]);
|
||||
*/
|
||||
|
||||
Self {
|
||||
db,
|
||||
beacon_chain,
|
||||
block_store,
|
||||
state_store,
|
||||
validators: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_validators(&'a mut self, validator_count: usize) {
|
||||
self.validators = Vec::with_capacity(validator_count);
|
||||
for _ in 0..validator_count {
|
||||
self.validators.push(TestValidator::new(&self.beacon_chain));
|
||||
}
|
||||
self.beacon_chain.spec =
|
||||
inject_validators_into_spec(self.beacon_chain.spec.clone(), &self.validators[..]);
|
||||
}
|
||||
|
||||
pub fn process_next_slot(&mut self) {
|
||||
let slot = self
|
||||
.beacon_chain
|
||||
.present_slot()
|
||||
.expect("Unable to determine slot.")
|
||||
+ 1;
|
||||
self.beacon_chain.slot_clock.set_slot(slot);
|
||||
|
||||
let block_proposer = self
|
||||
.beacon_chain
|
||||
.block_proposer(slot)
|
||||
.expect("Unable to determine proposer.");
|
||||
|
||||
let validator = self
|
||||
.validators
|
||||
.get(block_proposer)
|
||||
.expect("Block proposer unknown");
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_validators_into_spec(mut spec: ChainSpec, validators: &[TestValidator]) -> ChainSpec {
|
||||
spec.initial_validators = Vec::with_capacity(validators.len());
|
||||
spec.initial_balances = Vec::with_capacity(validators.len());
|
||||
for validator in validators {
|
||||
spec.initial_validators.push(validator.validator_record());
|
||||
spec.initial_balances.push(32_000_000_000); // 32 ETH
|
||||
}
|
||||
spec
|
||||
}
|
||||
61
beacon_node/beacon_chain/tests/utils/validator.rs
Normal file
61
beacon_node/beacon_chain/tests/utils/validator.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use super::{DirectBeaconNode, DirectDuties};
|
||||
use beacon_chain::BeaconChain;
|
||||
#[cfg(test)]
|
||||
use block_producer::{test_utils::TestSigner, BlockProducer};
|
||||
use db::MemoryDB;
|
||||
use slot_clock::TestingSlotClock;
|
||||
use spec::ChainSpec;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use types::{Keypair, Validator};
|
||||
|
||||
pub struct TestValidator<'a> {
|
||||
block_producer: BlockProducer<
|
||||
TestingSlotClock,
|
||||
DirectBeaconNode<'a, MemoryDB, TestingSlotClock>,
|
||||
DirectDuties<'a, MemoryDB, TestingSlotClock>,
|
||||
TestSigner,
|
||||
>,
|
||||
spec: Arc<ChainSpec>,
|
||||
epoch_map: Arc<DirectDuties<'a, MemoryDB, TestingSlotClock>>,
|
||||
keypair: Keypair,
|
||||
beacon_node: Arc<DirectBeaconNode<'a, MemoryDB, TestingSlotClock>>,
|
||||
slot_clock: Arc<RwLock<TestingSlotClock>>,
|
||||
signer: Arc<TestSigner>,
|
||||
}
|
||||
|
||||
impl<'a> TestValidator<'a> {
|
||||
pub fn new(beacon_chain: &'a BeaconChain<MemoryDB, TestingSlotClock>) -> Self {
|
||||
let spec = Arc::new(ChainSpec::foundation());
|
||||
let keypair = Keypair::random();
|
||||
let slot_clock = Arc::new(RwLock::new(TestingSlotClock::new(0)));
|
||||
let signer = Arc::new(TestSigner::new(keypair.clone()));
|
||||
let beacon_node = Arc::new(DirectBeaconNode::new(beacon_chain));
|
||||
let epoch_map = Arc::new(DirectDuties::new(keypair.pk.clone(), beacon_chain));
|
||||
|
||||
let block_producer = BlockProducer::new(
|
||||
spec.clone(),
|
||||
keypair.pk.clone(),
|
||||
epoch_map.clone(),
|
||||
slot_clock.clone(),
|
||||
beacon_node.clone(),
|
||||
signer.clone(),
|
||||
);
|
||||
|
||||
Self {
|
||||
block_producer,
|
||||
spec,
|
||||
epoch_map,
|
||||
keypair,
|
||||
beacon_node,
|
||||
slot_clock,
|
||||
signer,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn validator_record(&self) -> Validator {
|
||||
Validator {
|
||||
pubkey: self.keypair.pk.clone(),
|
||||
..std::default::Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user