Update beacon_chain as per test bugs
This commit is contained in:
parent
643fc20063
commit
f4f5b3a13c
@ -8,16 +8,23 @@ use types::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Outcome {
|
pub enum ValidBlock {
|
||||||
FutureSlot,
|
|
||||||
Processed,
|
Processed,
|
||||||
NewCanonicalBlock,
|
}
|
||||||
NewReorgBlock,
|
|
||||||
NewForkBlock,
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum InvalidBlock {
|
||||||
|
FutureSlot,
|
||||||
StateTransitionFailed(TransitionError),
|
StateTransitionFailed(TransitionError),
|
||||||
StateRootMismatch,
|
StateRootMismatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum Outcome {
|
||||||
|
ValidBlock(ValidBlock),
|
||||||
|
InvalidBlock(InvalidBlock),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
DBError(String),
|
DBError(String),
|
||||||
@ -70,7 +77,7 @@ where
|
|||||||
|
|
||||||
// Block from future slots (i.e., greater than the present slot) should not be processed.
|
// Block from future slots (i.e., greater than the present slot) should not be processed.
|
||||||
if block.slot() > present_slot {
|
if block.slot() > present_slot {
|
||||||
return Ok(Outcome::FutureSlot);
|
return Ok(Outcome::InvalidBlock(InvalidBlock::FutureSlot));
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent_block_root = block.parent_root();
|
let parent_block_root = block.parent_root();
|
||||||
@ -80,7 +87,8 @@ where
|
|||||||
.get_reader(&parent_block_root)?
|
.get_reader(&parent_block_root)?
|
||||||
.ok_or(Error::MissingParentBlock(parent_block_root))?;
|
.ok_or(Error::MissingParentBlock(parent_block_root))?;
|
||||||
|
|
||||||
let parent_state_root = parent_block.parent_root();
|
let parent_state_root = parent_block.state_root();
|
||||||
|
|
||||||
let parent_state = self
|
let parent_state = self
|
||||||
.state_store
|
.state_store
|
||||||
.get_reader(&parent_state_root)?
|
.get_reader(&parent_state_root)?
|
||||||
@ -90,13 +98,17 @@ where
|
|||||||
|
|
||||||
let state = match self.state_transition(parent_state, &block) {
|
let state = match self.state_transition(parent_state, &block) {
|
||||||
Ok(state) => state,
|
Ok(state) => state,
|
||||||
Err(error) => return Ok(Outcome::StateTransitionFailed(error)),
|
Err(error) => {
|
||||||
|
return Ok(Outcome::InvalidBlock(InvalidBlock::StateTransitionFailed(
|
||||||
|
error,
|
||||||
|
)))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let state_root = state.canonical_root();
|
let state_root = state.canonical_root();
|
||||||
|
|
||||||
if block.state_root != state_root {
|
if block.state_root != state_root {
|
||||||
return Ok(Outcome::StateRootMismatch);
|
return Ok(Outcome::InvalidBlock(InvalidBlock::StateRootMismatch));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the block and state.
|
// Store the block and state.
|
||||||
@ -119,7 +131,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The block was sucessfully processed.
|
// The block was sucessfully processed.
|
||||||
Ok(Outcome::Processed)
|
Ok(Outcome::ValidBlock(ValidBlock::Processed))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
beacon_node/beacon_chain/src/finalized_head.rs
Normal file
34
beacon_node/beacon_chain/src/finalized_head.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use crate::{BeaconChain, CheckPoint, ClientDB, SlotClock};
|
||||||
|
use std::sync::RwLockReadGuard;
|
||||||
|
use types::{BeaconBlock, BeaconState, Hash256};
|
||||||
|
|
||||||
|
impl<T, U> BeaconChain<T, U>
|
||||||
|
where
|
||||||
|
T: ClientDB,
|
||||||
|
U: SlotClock,
|
||||||
|
{
|
||||||
|
pub fn update_finalized_head(
|
||||||
|
&self,
|
||||||
|
new_beacon_block: BeaconBlock,
|
||||||
|
new_beacon_block_root: Hash256,
|
||||||
|
new_beacon_state: BeaconState,
|
||||||
|
new_beacon_state_root: Hash256,
|
||||||
|
) {
|
||||||
|
let mut finalized_head = self
|
||||||
|
.finalized_head
|
||||||
|
.write()
|
||||||
|
.expect("CRITICAL: finalized_head poisioned.");
|
||||||
|
finalized_head.update(
|
||||||
|
new_beacon_block,
|
||||||
|
new_beacon_block_root,
|
||||||
|
new_beacon_state,
|
||||||
|
new_beacon_state_root,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finalized_head(&self) -> RwLockReadGuard<CheckPoint> {
|
||||||
|
self.finalized_head
|
||||||
|
.read()
|
||||||
|
.expect("CRITICAL: finalized_head poisioned.")
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
mod attestation_targets;
|
mod attestation_targets;
|
||||||
mod block_graph;
|
mod block_graph;
|
||||||
mod block_processing;
|
pub mod block_processing;
|
||||||
pub mod block_production;
|
pub mod block_production;
|
||||||
mod canonical_head;
|
mod canonical_head;
|
||||||
|
mod finalized_head;
|
||||||
mod info;
|
mod info;
|
||||||
mod lmd_ghost;
|
mod lmd_ghost;
|
||||||
mod state_transition;
|
mod state_transition;
|
||||||
@ -17,9 +18,8 @@ use genesis::{genesis_beacon_block, genesis_beacon_state, GenesisError};
|
|||||||
use slot_clock::SlotClock;
|
use slot_clock::SlotClock;
|
||||||
use spec::ChainSpec;
|
use spec::ChainSpec;
|
||||||
use ssz::ssz_encode;
|
use ssz::ssz_encode;
|
||||||
use std::collections::{HashMap, HashSet};
|
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use types::{BeaconBlock, BeaconState, Hash256, PublicKey};
|
use types::{BeaconBlock, BeaconState, Hash256};
|
||||||
|
|
||||||
pub use self::block_processing::Outcome as BlockProcessingOutcome;
|
pub use self::block_processing::Outcome as BlockProcessingOutcome;
|
||||||
|
|
||||||
|
@ -32,7 +32,31 @@ where
|
|||||||
U: SlotClock,
|
U: SlotClock,
|
||||||
Error: From<<U as SlotClock>::Error>,
|
Error: From<<U as SlotClock>::Error>,
|
||||||
{
|
{
|
||||||
pub fn slow_lmd_ghost(&mut self, start_hash: &Hash256) -> Result<Hash256, Error> {
|
pub fn fork_choice(&self) -> Result<(), Error> {
|
||||||
|
let present_head = &self.finalized_head().beacon_block_root;
|
||||||
|
|
||||||
|
let new_head = self.slow_lmd_ghost(&self.finalized_head().beacon_block_root)?;
|
||||||
|
|
||||||
|
if new_head != *present_head {
|
||||||
|
let block = self
|
||||||
|
.block_store
|
||||||
|
.get_deserialized(&new_head)?
|
||||||
|
.ok_or_else(|| Error::MissingBeaconBlock(new_head))?;
|
||||||
|
let block_root = block.canonical_root();
|
||||||
|
|
||||||
|
let state = self
|
||||||
|
.state_store
|
||||||
|
.get_deserialized(&block.state_root)?
|
||||||
|
.ok_or_else(|| Error::MissingBeaconState(block.state_root))?;
|
||||||
|
let state_root = state.canonical_root();
|
||||||
|
|
||||||
|
self.update_canonical_head(block, block_root, state, state_root);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn slow_lmd_ghost(&self, start_hash: &Hash256) -> Result<Hash256, Error> {
|
||||||
let start = self
|
let start = self
|
||||||
.block_store
|
.block_store
|
||||||
.get_reader(&start_hash)?
|
.get_reader(&start_hash)?
|
||||||
|
@ -20,8 +20,9 @@ fn rig_can_generate_validators() {
|
|||||||
let validators = generate_validators(2, &chain);
|
let validators = generate_validators(2, &chain);
|
||||||
chain.spec = inject_validators_into_spec(chain.spec.clone(), &validators[..]);
|
chain.spec = inject_validators_into_spec(chain.spec.clone(), &validators[..]);
|
||||||
*/
|
*/
|
||||||
let mut rig = TestRig::new(ChainSpec::foundation());
|
let validator_count = 2;
|
||||||
rig.generate_validators(2);
|
let mut rig = TestRig::new(ChainSpec::foundation(), validator_count);
|
||||||
|
rig.produce_next_slot();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,22 +1,27 @@
|
|||||||
|
use beacon_chain::block_processing::{Error as ProcessingError, Outcome as ProcessingOutcome};
|
||||||
use beacon_chain::{block_production::Error as BlockProductionError, BeaconChain};
|
use beacon_chain::{block_production::Error as BlockProductionError, BeaconChain};
|
||||||
use block_producer::{BeaconNode as BeaconBlockNode, BeaconNodeError as BeaconBlockNodeError};
|
use block_producer::{
|
||||||
|
BeaconNode as BeaconBlockNode, BeaconNodeError as BeaconBlockNodeError, PublishOutcome,
|
||||||
|
};
|
||||||
use db::ClientDB;
|
use db::ClientDB;
|
||||||
use slot_clock::SlotClock;
|
use slot_clock::SlotClock;
|
||||||
|
use std::sync::Arc;
|
||||||
use types::{BeaconBlock, PublicKey, Signature};
|
use types::{BeaconBlock, PublicKey, Signature};
|
||||||
|
|
||||||
pub struct DirectBeaconNode<'a, T: ClientDB, U: SlotClock> {
|
pub struct DirectBeaconNode<T: ClientDB, U: SlotClock> {
|
||||||
beacon_chain: &'a BeaconChain<T, U>,
|
beacon_chain: Arc<BeaconChain<T, U>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: ClientDB, U: SlotClock> DirectBeaconNode<'a, T, U> {
|
impl<T: ClientDB, U: SlotClock> DirectBeaconNode<T, U> {
|
||||||
pub fn new(beacon_chain: &'a BeaconChain<T, U>) -> Self {
|
pub fn new(beacon_chain: Arc<BeaconChain<T, U>>) -> Self {
|
||||||
Self { beacon_chain }
|
Self { beacon_chain }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: ClientDB, U: SlotClock> BeaconBlockNode for DirectBeaconNode<'a, T, U>
|
impl<T: ClientDB, U: SlotClock> BeaconBlockNode for DirectBeaconNode<T, U>
|
||||||
where
|
where
|
||||||
BlockProductionError: From<<U>::Error>,
|
BlockProductionError: From<<U>::Error>,
|
||||||
|
ProcessingError: From<<U as SlotClock>::Error>,
|
||||||
{
|
{
|
||||||
fn proposer_nonce(&self, pubkey: &PublicKey) -> Result<u64, BeaconBlockNodeError> {
|
fn proposer_nonce(&self, pubkey: &PublicKey) -> Result<u64, BeaconBlockNodeError> {
|
||||||
let validator_index = self
|
let validator_index = self
|
||||||
@ -51,8 +56,16 @@ where {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the value specified by the `set_next_publish_result`.
|
fn publish_beacon_block(
|
||||||
fn publish_beacon_block(&self, block: BeaconBlock) -> Result<bool, BeaconBlockNodeError> {
|
&self,
|
||||||
Err(BeaconBlockNodeError::DecodeFailure)
|
block: BeaconBlock,
|
||||||
|
) -> Result<PublishOutcome, BeaconBlockNodeError> {
|
||||||
|
match self.beacon_chain.process_block(block) {
|
||||||
|
Ok(ProcessingOutcome::ValidBlock(_)) => Ok(PublishOutcome::ValidBlock),
|
||||||
|
Ok(ProcessingOutcome::InvalidBlock(reason)) => {
|
||||||
|
Ok(PublishOutcome::InvalidBlock(format!("{:?}", reason)))
|
||||||
|
}
|
||||||
|
Err(error) => Err(BeaconBlockNodeError::RemoteFailure(format!("{:?}", error))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,16 @@ use beacon_chain::{block_production::Error as BlockProductionError, BeaconChain}
|
|||||||
use block_producer::{DutiesReader, DutiesReaderError};
|
use block_producer::{DutiesReader, DutiesReaderError};
|
||||||
use db::ClientDB;
|
use db::ClientDB;
|
||||||
use slot_clock::SlotClock;
|
use slot_clock::SlotClock;
|
||||||
|
use std::sync::Arc;
|
||||||
use types::PublicKey;
|
use types::PublicKey;
|
||||||
|
|
||||||
pub struct DirectDuties<'a, T: ClientDB, U: SlotClock> {
|
pub struct DirectDuties<T: ClientDB, U: SlotClock> {
|
||||||
beacon_chain: &'a BeaconChain<T, U>,
|
beacon_chain: Arc<BeaconChain<T, U>>,
|
||||||
pubkey: PublicKey,
|
pubkey: PublicKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: ClientDB, U: SlotClock> DirectDuties<'a, T, U> {
|
impl<T: ClientDB, U: SlotClock> DirectDuties<T, U> {
|
||||||
pub fn new(pubkey: PublicKey, beacon_chain: &'a BeaconChain<T, U>) -> Self {
|
pub fn new(pubkey: PublicKey, beacon_chain: Arc<BeaconChain<T, U>>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
beacon_chain,
|
beacon_chain,
|
||||||
pubkey,
|
pubkey,
|
||||||
@ -18,11 +19,11 @@ impl<'a, T: ClientDB, U: SlotClock> DirectDuties<'a, T, U> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: ClientDB, U: SlotClock> DutiesReader for DirectDuties<'a, T, U>
|
impl<T: ClientDB, U: SlotClock> DutiesReader for DirectDuties<T, U>
|
||||||
where
|
where
|
||||||
BlockProductionError: From<<U>::Error>,
|
BlockProductionError: From<<U>::Error>,
|
||||||
{
|
{
|
||||||
fn is_block_production_slot(&self, _epoch: u64, slot: u64) -> Result<bool, DutiesReaderError> {
|
fn is_block_production_slot(&self, slot: u64) -> Result<bool, DutiesReaderError> {
|
||||||
let validator_index = self
|
let validator_index = self
|
||||||
.beacon_chain
|
.beacon_chain
|
||||||
.validator_index(&self.pubkey)
|
.validator_index(&self.pubkey)
|
||||||
|
@ -11,75 +11,77 @@ use spec::ChainSpec;
|
|||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use types::{Keypair, Validator};
|
use types::{Keypair, Validator};
|
||||||
|
|
||||||
pub struct TestRig<'a> {
|
pub struct TestRig {
|
||||||
db: Arc<MemoryDB>,
|
db: Arc<MemoryDB>,
|
||||||
beacon_chain: BeaconChain<MemoryDB, TestingSlotClock>,
|
beacon_chain: Arc<BeaconChain<MemoryDB, TestingSlotClock>>,
|
||||||
block_store: Arc<BeaconBlockStore<MemoryDB>>,
|
block_store: Arc<BeaconBlockStore<MemoryDB>>,
|
||||||
state_store: Arc<BeaconStateStore<MemoryDB>>,
|
state_store: Arc<BeaconStateStore<MemoryDB>>,
|
||||||
validators: Vec<TestValidator<'a>>,
|
validators: Vec<TestValidator>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TestRig<'a> {
|
impl TestRig {
|
||||||
pub fn new(spec: ChainSpec) -> Self {
|
pub fn new(mut spec: ChainSpec, validator_count: usize) -> Self {
|
||||||
let db = Arc::new(MemoryDB::open());
|
let db = Arc::new(MemoryDB::open());
|
||||||
let block_store = Arc::new(BeaconBlockStore::new(db.clone()));
|
let block_store = Arc::new(BeaconBlockStore::new(db.clone()));
|
||||||
let state_store = Arc::new(BeaconStateStore::new(db.clone()));
|
let state_store = Arc::new(BeaconStateStore::new(db.clone()));
|
||||||
|
|
||||||
let slot_clock = TestingSlotClock::new(0);
|
let slot_clock = TestingSlotClock::new(0);
|
||||||
|
|
||||||
let mut beacon_chain =
|
// Remove the validators present in the spec (if any).
|
||||||
BeaconChain::genesis(state_store.clone(), block_store.clone(), slot_clock, spec)
|
spec.initial_validators = Vec::with_capacity(validator_count);
|
||||||
.unwrap();
|
spec.initial_balances = Vec::with_capacity(validator_count);
|
||||||
|
|
||||||
/*
|
// Insert `validator_count` new `Validator` records into the spec, retaining the keypairs
|
||||||
let validators = generate_validators(validator_count, &beacon_chain);
|
// for later user.
|
||||||
beacon_chain.spec = inject_validators_into_spec(beacon_chain.spec.clone(), &validators[..]);
|
let mut keypairs = Vec::with_capacity(validator_count);
|
||||||
*/
|
for _ in 0..validator_count {
|
||||||
|
let keypair = Keypair::random();
|
||||||
|
|
||||||
|
spec.initial_validators.push(Validator {
|
||||||
|
pubkey: keypair.pk.clone(),
|
||||||
|
..std::default::Default::default()
|
||||||
|
});
|
||||||
|
spec.initial_balances.push(32_000_000_000); // 32 ETH
|
||||||
|
|
||||||
|
keypairs.push(keypair);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the Beacon Chain
|
||||||
|
let beacon_chain = Arc::new(
|
||||||
|
BeaconChain::genesis(state_store.clone(), block_store.clone(), slot_clock, spec)
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Spawn the test validator instances.
|
||||||
|
let mut validators = Vec::with_capacity(validator_count);
|
||||||
|
for keypair in keypairs {
|
||||||
|
validators.push(TestValidator::new(keypair.clone(), beacon_chain.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
beacon_chain,
|
beacon_chain,
|
||||||
block_store,
|
block_store,
|
||||||
state_store,
|
state_store,
|
||||||
validators: vec![],
|
validators,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_validators(&'a mut self, validator_count: usize) {
|
pub fn produce_next_slot(&mut self) {
|
||||||
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
|
let slot = self
|
||||||
.beacon_chain
|
.beacon_chain
|
||||||
.present_slot()
|
.present_slot()
|
||||||
.expect("Unable to determine slot.")
|
.expect("Unable to determine slot.")
|
||||||
+ 1;
|
+ 1;
|
||||||
|
|
||||||
self.beacon_chain.slot_clock.set_slot(slot);
|
self.beacon_chain.slot_clock.set_slot(slot);
|
||||||
|
|
||||||
let block_proposer = self
|
let proposer = self
|
||||||
.beacon_chain
|
.beacon_chain
|
||||||
.block_proposer(slot)
|
.block_proposer(slot)
|
||||||
.expect("Unable to determine proposer.");
|
.expect("Unable to determine proposer.");
|
||||||
|
|
||||||
let validator = self
|
self.validators[proposer].set_slot(slot);
|
||||||
.validators
|
self.validators[proposer].produce_block().unwrap();
|
||||||
.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
|
|
||||||
}
|
|
||||||
|
@ -1,36 +1,46 @@
|
|||||||
use super::{DirectBeaconNode, DirectDuties};
|
use super::{DirectBeaconNode, DirectDuties};
|
||||||
use beacon_chain::BeaconChain;
|
use beacon_chain::BeaconChain;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use block_producer::{test_utils::TestSigner, BlockProducer};
|
use block_producer::{test_utils::TestSigner, BlockProducer, Error as PollError};
|
||||||
use db::MemoryDB;
|
use db::MemoryDB;
|
||||||
use slot_clock::TestingSlotClock;
|
use slot_clock::TestingSlotClock;
|
||||||
use spec::ChainSpec;
|
use spec::ChainSpec;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use types::{Keypair, Validator};
|
use types::{Keypair, Validator};
|
||||||
|
|
||||||
pub struct TestValidator<'a> {
|
pub use block_producer::PollOutcome;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum ProduceError {
|
||||||
|
DidNotProduce(PollOutcome),
|
||||||
|
PollError(PollError),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TestValidator {
|
||||||
block_producer: BlockProducer<
|
block_producer: BlockProducer<
|
||||||
TestingSlotClock,
|
TestingSlotClock,
|
||||||
DirectBeaconNode<'a, MemoryDB, TestingSlotClock>,
|
DirectBeaconNode<MemoryDB, TestingSlotClock>,
|
||||||
DirectDuties<'a, MemoryDB, TestingSlotClock>,
|
DirectDuties<MemoryDB, TestingSlotClock>,
|
||||||
TestSigner,
|
TestSigner,
|
||||||
>,
|
>,
|
||||||
spec: Arc<ChainSpec>,
|
spec: Arc<ChainSpec>,
|
||||||
epoch_map: Arc<DirectDuties<'a, MemoryDB, TestingSlotClock>>,
|
epoch_map: Arc<DirectDuties<MemoryDB, TestingSlotClock>>,
|
||||||
keypair: Keypair,
|
keypair: Keypair,
|
||||||
beacon_node: Arc<DirectBeaconNode<'a, MemoryDB, TestingSlotClock>>,
|
beacon_node: Arc<DirectBeaconNode<MemoryDB, TestingSlotClock>>,
|
||||||
slot_clock: Arc<RwLock<TestingSlotClock>>,
|
slot_clock: Arc<TestingSlotClock>,
|
||||||
signer: Arc<TestSigner>,
|
signer: Arc<TestSigner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TestValidator<'a> {
|
impl TestValidator {
|
||||||
pub fn new(beacon_chain: &'a BeaconChain<MemoryDB, TestingSlotClock>) -> Self {
|
pub fn new(
|
||||||
|
keypair: Keypair,
|
||||||
|
beacon_chain: Arc<BeaconChain<MemoryDB, TestingSlotClock>>,
|
||||||
|
) -> Self {
|
||||||
let spec = Arc::new(ChainSpec::foundation());
|
let spec = Arc::new(ChainSpec::foundation());
|
||||||
let keypair = Keypair::random();
|
let slot_clock = Arc::new(TestingSlotClock::new(0));
|
||||||
let slot_clock = Arc::new(RwLock::new(TestingSlotClock::new(0)));
|
|
||||||
let signer = Arc::new(TestSigner::new(keypair.clone()));
|
let signer = Arc::new(TestSigner::new(keypair.clone()));
|
||||||
let beacon_node = Arc::new(DirectBeaconNode::new(beacon_chain));
|
let beacon_node = Arc::new(DirectBeaconNode::new(beacon_chain.clone()));
|
||||||
let epoch_map = Arc::new(DirectDuties::new(keypair.pk.clone(), beacon_chain));
|
let epoch_map = Arc::new(DirectDuties::new(keypair.pk.clone(), beacon_chain.clone()));
|
||||||
|
|
||||||
let block_producer = BlockProducer::new(
|
let block_producer = BlockProducer::new(
|
||||||
spec.clone(),
|
spec.clone(),
|
||||||
@ -52,10 +62,15 @@ impl<'a> TestValidator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validator_record(&self) -> Validator {
|
pub fn produce_block(&mut self) -> Result<PollOutcome, ProduceError> {
|
||||||
Validator {
|
match self.block_producer.poll() {
|
||||||
pubkey: self.keypair.pk.clone(),
|
Ok(PollOutcome::BlockProduced(slot)) => Ok(PollOutcome::BlockProduced(slot)),
|
||||||
..std::default::Default::default()
|
Ok(outcome) => Err(ProduceError::DidNotProduce(outcome)),
|
||||||
|
Err(error) => Err(ProduceError::PollError(error)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_slot(&mut self, slot: u64) {
|
||||||
|
self.slot_clock.set_slot(slot)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user