Re-org test_harness files for consistency
This commit is contained in:
parent
0120082f6b
commit
4008ec9b25
@ -1,26 +0,0 @@
|
|||||||
use super::DirectBeaconNode;
|
|
||||||
use attester::{BeaconNode as AttesterBeaconNode, BeaconNodeError as NodeError, PublishOutcome};
|
|
||||||
use db::ClientDB;
|
|
||||||
use slot_clock::SlotClock;
|
|
||||||
use types::{AttestationData, FreeAttestation};
|
|
||||||
|
|
||||||
impl<T: ClientDB, U: SlotClock> AttesterBeaconNode for DirectBeaconNode<T, U> {
|
|
||||||
fn produce_attestation_data(
|
|
||||||
&self,
|
|
||||||
_slot: u64,
|
|
||||||
shard: u64,
|
|
||||||
) -> Result<Option<AttestationData>, NodeError> {
|
|
||||||
match self.beacon_chain.produce_attestation_data(shard) {
|
|
||||||
Ok(attestation_data) => Ok(Some(attestation_data)),
|
|
||||||
Err(e) => Err(NodeError::RemoteFailure(format!("{:?}", e))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn publish_attestation_data(
|
|
||||||
&self,
|
|
||||||
free_attestation: FreeAttestation,
|
|
||||||
) -> Result<PublishOutcome, NodeError> {
|
|
||||||
self.published_attestations.write().push(free_attestation);
|
|
||||||
Ok(PublishOutcome::ValidAttestation)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
use beacon_chain::BeaconChain;
|
|
||||||
use db::ClientDB;
|
|
||||||
use parking_lot::RwLock;
|
|
||||||
use slot_clock::SlotClock;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use types::{BeaconBlock, FreeAttestation};
|
|
||||||
|
|
||||||
mod attester;
|
|
||||||
mod producer;
|
|
||||||
|
|
||||||
/// Connect directly to a borrowed `BeaconChain` instance so an attester/producer can request/submit
|
|
||||||
/// blocks/attestations.
|
|
||||||
///
|
|
||||||
/// `BeaconBlock`s and `FreeAttestation`s are not actually published to the `BeaconChain`, instead
|
|
||||||
/// they are stored inside this struct. This is to allow one to benchmark the submission of the
|
|
||||||
/// block/attestation directly, or modify it before submission.
|
|
||||||
pub struct DirectBeaconNode<T: ClientDB, U: SlotClock> {
|
|
||||||
beacon_chain: Arc<BeaconChain<T, U>>,
|
|
||||||
published_blocks: RwLock<Vec<BeaconBlock>>,
|
|
||||||
published_attestations: RwLock<Vec<FreeAttestation>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ClientDB, U: SlotClock> DirectBeaconNode<T, U> {
|
|
||||||
pub fn new(beacon_chain: Arc<BeaconChain<T, U>>) -> Self {
|
|
||||||
Self {
|
|
||||||
beacon_chain,
|
|
||||||
published_blocks: RwLock::new(vec![]),
|
|
||||||
published_attestations: RwLock::new(vec![]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the last published block (if any).
|
|
||||||
pub fn last_published_block(&self) -> Option<BeaconBlock> {
|
|
||||||
Some(self.published_blocks.read().last()?.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the last published attestation (if any).
|
|
||||||
pub fn last_published_free_attestation(&self) -> Option<FreeAttestation> {
|
|
||||||
Some(self.published_attestations.read().last()?.clone())
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
use super::DirectBeaconNode;
|
|
||||||
use block_producer::{
|
|
||||||
BeaconNode as BeaconBlockNode, BeaconNodeError as BeaconBlockNodeError, PublishOutcome,
|
|
||||||
};
|
|
||||||
use db::ClientDB;
|
|
||||||
use slot_clock::SlotClock;
|
|
||||||
use types::{BeaconBlock, PublicKey, Signature};
|
|
||||||
|
|
||||||
impl<T: ClientDB, U: SlotClock> BeaconBlockNode for DirectBeaconNode<T, U> {
|
|
||||||
/// Requests the `proposer_nonce` from the `BeaconChain`.
|
|
||||||
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())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Requests a new `BeaconBlock from the `BeaconChain`.
|
|
||||||
fn produce_beacon_block(
|
|
||||||
&self,
|
|
||||||
slot: u64,
|
|
||||||
randao_reveal: &Signature,
|
|
||||||
) -> Result<Option<BeaconBlock>, BeaconBlockNodeError> {
|
|
||||||
let (block, _state) = self
|
|
||||||
.beacon_chain
|
|
||||||
.produce_block(randao_reveal.clone())
|
|
||||||
.ok_or_else(|| {
|
|
||||||
BeaconBlockNodeError::RemoteFailure(format!("Did not produce block."))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if block.slot == slot {
|
|
||||||
Ok(Some(block))
|
|
||||||
} else {
|
|
||||||
Err(BeaconBlockNodeError::RemoteFailure(
|
|
||||||
"Unable to produce at non-current slot.".to_string(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A block is not _actually_ published to the `BeaconChain`, instead it is stored in the
|
|
||||||
/// `published_block_vec` and a successful `ValidBlock` is returned to the caller.
|
|
||||||
///
|
|
||||||
/// The block may be retrieved and then applied to the `BeaconChain` manually, potentially in a
|
|
||||||
/// benchmarking scenario.
|
|
||||||
fn publish_beacon_block(
|
|
||||||
&self,
|
|
||||||
block: BeaconBlock,
|
|
||||||
) -> Result<PublishOutcome, BeaconBlockNodeError> {
|
|
||||||
self.published_blocks.write().push(block);
|
|
||||||
Ok(PublishOutcome::ValidBlock)
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,121 @@
|
|||||||
|
use attester::{
|
||||||
|
BeaconNode as AttesterBeaconNode, BeaconNodeError as NodeError,
|
||||||
|
PublishOutcome as AttestationPublishOutcome,
|
||||||
|
};
|
||||||
|
use beacon_chain::BeaconChain;
|
||||||
|
use block_producer::{
|
||||||
|
BeaconNode as BeaconBlockNode, BeaconNodeError as BeaconBlockNodeError,
|
||||||
|
PublishOutcome as BlockPublishOutcome,
|
||||||
|
};
|
||||||
|
use db::ClientDB;
|
||||||
|
use parking_lot::RwLock;
|
||||||
|
use slot_clock::SlotClock;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use types::{AttestationData, BeaconBlock, FreeAttestation, PublicKey, Signature};
|
||||||
|
|
||||||
|
// mod attester;
|
||||||
|
// mod producer;
|
||||||
|
|
||||||
|
/// Connect directly to a borrowed `BeaconChain` instance so an attester/producer can request/submit
|
||||||
|
/// blocks/attestations.
|
||||||
|
///
|
||||||
|
/// `BeaconBlock`s and `FreeAttestation`s are not actually published to the `BeaconChain`, instead
|
||||||
|
/// they are stored inside this struct. This is to allow one to benchmark the submission of the
|
||||||
|
/// block/attestation directly, or modify it before submission.
|
||||||
|
pub struct DirectBeaconNode<T: ClientDB, U: SlotClock> {
|
||||||
|
beacon_chain: Arc<BeaconChain<T, U>>,
|
||||||
|
published_blocks: RwLock<Vec<BeaconBlock>>,
|
||||||
|
published_attestations: RwLock<Vec<FreeAttestation>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ClientDB, U: SlotClock> DirectBeaconNode<T, U> {
|
||||||
|
pub fn new(beacon_chain: Arc<BeaconChain<T, U>>) -> Self {
|
||||||
|
Self {
|
||||||
|
beacon_chain,
|
||||||
|
published_blocks: RwLock::new(vec![]),
|
||||||
|
published_attestations: RwLock::new(vec![]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the last published block (if any).
|
||||||
|
pub fn last_published_block(&self) -> Option<BeaconBlock> {
|
||||||
|
Some(self.published_blocks.read().last()?.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the last published attestation (if any).
|
||||||
|
pub fn last_published_free_attestation(&self) -> Option<FreeAttestation> {
|
||||||
|
Some(self.published_attestations.read().last()?.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ClientDB, U: SlotClock> AttesterBeaconNode for DirectBeaconNode<T, U> {
|
||||||
|
fn produce_attestation_data(
|
||||||
|
&self,
|
||||||
|
_slot: u64,
|
||||||
|
shard: u64,
|
||||||
|
) -> Result<Option<AttestationData>, NodeError> {
|
||||||
|
match self.beacon_chain.produce_attestation_data(shard) {
|
||||||
|
Ok(attestation_data) => Ok(Some(attestation_data)),
|
||||||
|
Err(e) => Err(NodeError::RemoteFailure(format!("{:?}", e))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn publish_attestation_data(
|
||||||
|
&self,
|
||||||
|
free_attestation: FreeAttestation,
|
||||||
|
) -> Result<AttestationPublishOutcome, NodeError> {
|
||||||
|
self.published_attestations.write().push(free_attestation);
|
||||||
|
Ok(AttestationPublishOutcome::ValidAttestation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ClientDB, U: SlotClock> BeaconBlockNode for DirectBeaconNode<T, U> {
|
||||||
|
/// Requests the `proposer_nonce` from the `BeaconChain`.
|
||||||
|
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())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Requests a new `BeaconBlock from the `BeaconChain`.
|
||||||
|
fn produce_beacon_block(
|
||||||
|
&self,
|
||||||
|
slot: u64,
|
||||||
|
randao_reveal: &Signature,
|
||||||
|
) -> Result<Option<BeaconBlock>, BeaconBlockNodeError> {
|
||||||
|
let (block, _state) = self
|
||||||
|
.beacon_chain
|
||||||
|
.produce_block(randao_reveal.clone())
|
||||||
|
.ok_or_else(|| {
|
||||||
|
BeaconBlockNodeError::RemoteFailure(format!("Did not produce block."))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if block.slot == slot {
|
||||||
|
Ok(Some(block))
|
||||||
|
} else {
|
||||||
|
Err(BeaconBlockNodeError::RemoteFailure(
|
||||||
|
"Unable to produce at non-current slot.".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A block is not _actually_ published to the `BeaconChain`, instead it is stored in the
|
||||||
|
/// `published_block_vec` and a successful `ValidBlock` is returned to the caller.
|
||||||
|
///
|
||||||
|
/// The block may be retrieved and then applied to the `BeaconChain` manually, potentially in a
|
||||||
|
/// benchmarking scenario.
|
||||||
|
fn publish_beacon_block(
|
||||||
|
&self,
|
||||||
|
block: BeaconBlock,
|
||||||
|
) -> Result<BlockPublishOutcome, BeaconBlockNodeError> {
|
||||||
|
self.published_blocks.write().push(block);
|
||||||
|
Ok(BlockPublishOutcome::ValidBlock)
|
||||||
|
}
|
||||||
|
}
|
@ -1,137 +1,6 @@
|
|||||||
use attester::{Attester, Error as AttestationPollError};
|
mod direct_beacon_node;
|
||||||
use beacon_chain::BeaconChain;
|
|
||||||
use block_producer::{BlockProducer, Error as BlockPollError};
|
|
||||||
use db::MemoryDB;
|
|
||||||
use signer::TestSigner;
|
|
||||||
use slot_clock::TestingSlotClock;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use types::{BeaconBlock, ChainSpec, FreeAttestation, Keypair};
|
|
||||||
mod beacon_node;
|
|
||||||
mod direct_duties;
|
mod direct_duties;
|
||||||
mod signer;
|
mod signer;
|
||||||
|
mod validator;
|
||||||
|
|
||||||
pub use self::beacon_node::DirectBeaconNode;
|
pub use self::validator::TestValidator;
|
||||||
pub use self::direct_duties::DirectDuties;
|
|
||||||
pub use attester::PollOutcome as AttestationPollOutcome;
|
|
||||||
pub use block_producer::PollOutcome as BlockPollOutcome;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum BlockProduceError {
|
|
||||||
DidNotProduce(BlockPollOutcome),
|
|
||||||
PollError(BlockPollError),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum AttestationProduceError {
|
|
||||||
DidNotProduce(AttestationPollOutcome),
|
|
||||||
PollError(AttestationPollError),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A `BlockProducer` and `Attester` which sign using a common keypair.
|
|
||||||
///
|
|
||||||
/// The test validator connects directly to a borrowed `BeaconChain` struct. It is useful for
|
|
||||||
/// testing that the core proposer and attester logic is functioning. Also for supporting beacon
|
|
||||||
/// chain tests.
|
|
||||||
pub struct TestValidator {
|
|
||||||
pub block_producer: BlockProducer<
|
|
||||||
TestingSlotClock,
|
|
||||||
DirectBeaconNode<MemoryDB, TestingSlotClock>,
|
|
||||||
DirectDuties<MemoryDB, TestingSlotClock>,
|
|
||||||
TestSigner,
|
|
||||||
>,
|
|
||||||
pub attester: Attester<
|
|
||||||
TestingSlotClock,
|
|
||||||
DirectBeaconNode<MemoryDB, TestingSlotClock>,
|
|
||||||
DirectDuties<MemoryDB, TestingSlotClock>,
|
|
||||||
TestSigner,
|
|
||||||
>,
|
|
||||||
pub spec: Arc<ChainSpec>,
|
|
||||||
pub epoch_map: Arc<DirectDuties<MemoryDB, TestingSlotClock>>,
|
|
||||||
pub keypair: Keypair,
|
|
||||||
pub beacon_node: Arc<DirectBeaconNode<MemoryDB, TestingSlotClock>>,
|
|
||||||
pub slot_clock: Arc<TestingSlotClock>,
|
|
||||||
pub signer: Arc<TestSigner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TestValidator {
|
|
||||||
/// Create a new TestValidator that signs with the given keypair, operates per the given spec and connects to the
|
|
||||||
/// supplied beacon node.
|
|
||||||
///
|
|
||||||
/// A `BlockProducer` and `Attester` is created..
|
|
||||||
pub fn new(
|
|
||||||
keypair: Keypair,
|
|
||||||
beacon_chain: Arc<BeaconChain<MemoryDB, TestingSlotClock>>,
|
|
||||||
spec: Arc<ChainSpec>,
|
|
||||||
) -> Self {
|
|
||||||
let slot_clock = Arc::new(TestingSlotClock::new(spec.genesis_slot));
|
|
||||||
let signer = Arc::new(TestSigner::new(keypair.clone()));
|
|
||||||
let beacon_node = Arc::new(DirectBeaconNode::new(beacon_chain.clone()));
|
|
||||||
let epoch_map = Arc::new(DirectDuties::new(keypair.pk.clone(), beacon_chain.clone()));
|
|
||||||
|
|
||||||
let block_producer = BlockProducer::new(
|
|
||||||
spec.clone(),
|
|
||||||
keypair.pk.clone(),
|
|
||||||
epoch_map.clone(),
|
|
||||||
slot_clock.clone(),
|
|
||||||
beacon_node.clone(),
|
|
||||||
signer.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let attester = Attester::new(
|
|
||||||
epoch_map.clone(),
|
|
||||||
slot_clock.clone(),
|
|
||||||
beacon_node.clone(),
|
|
||||||
signer.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
block_producer,
|
|
||||||
attester,
|
|
||||||
spec,
|
|
||||||
epoch_map,
|
|
||||||
keypair,
|
|
||||||
beacon_node,
|
|
||||||
slot_clock,
|
|
||||||
signer,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run the `poll` function on the `BlockProducer` and produce a block.
|
|
||||||
///
|
|
||||||
/// An error is returned if the producer refuses to produce.
|
|
||||||
pub fn produce_block(&mut self) -> Result<BeaconBlock, BlockProduceError> {
|
|
||||||
// Using `DirectBeaconNode`, the validator will always return sucessufully if it tries to
|
|
||||||
// publish a block.
|
|
||||||
match self.block_producer.poll() {
|
|
||||||
Ok(BlockPollOutcome::BlockProduced(_)) => {}
|
|
||||||
Ok(outcome) => return Err(BlockProduceError::DidNotProduce(outcome)),
|
|
||||||
Err(error) => return Err(BlockProduceError::PollError(error)),
|
|
||||||
};
|
|
||||||
Ok(self
|
|
||||||
.beacon_node
|
|
||||||
.last_published_block()
|
|
||||||
.expect("Unable to obtain produced block."))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run the `poll` function on the `Attester` and produce a `FreeAttestation`.
|
|
||||||
///
|
|
||||||
/// An error is returned if the attester refuses to attest.
|
|
||||||
pub fn produce_free_attestation(&mut self) -> Result<FreeAttestation, AttestationProduceError> {
|
|
||||||
match self.attester.poll() {
|
|
||||||
Ok(AttestationPollOutcome::AttestationProduced(_)) => {}
|
|
||||||
Ok(outcome) => return Err(AttestationProduceError::DidNotProduce(outcome)),
|
|
||||||
Err(error) => return Err(AttestationProduceError::PollError(error)),
|
|
||||||
};
|
|
||||||
Ok(self
|
|
||||||
.beacon_node
|
|
||||||
.last_published_free_attestation()
|
|
||||||
.expect("Unable to obtain produced attestation."))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the validators slot clock to the specified slot.
|
|
||||||
///
|
|
||||||
/// The validators slot clock will always read this value until it is set to something else.
|
|
||||||
pub fn set_slot(&mut self, slot: u64) {
|
|
||||||
self.slot_clock.set_slot(slot)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
133
beacon_node/beacon_chain/test_harness/src/validator/validator.rs
Normal file
133
beacon_node/beacon_chain/test_harness/src/validator/validator.rs
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
use super::direct_beacon_node::DirectBeaconNode;
|
||||||
|
use super::direct_duties::DirectDuties;
|
||||||
|
use super::signer::TestSigner;
|
||||||
|
use attester::PollOutcome as AttestationPollOutcome;
|
||||||
|
use attester::{Attester, Error as AttestationPollError};
|
||||||
|
use beacon_chain::BeaconChain;
|
||||||
|
use block_producer::PollOutcome as BlockPollOutcome;
|
||||||
|
use block_producer::{BlockProducer, Error as BlockPollError};
|
||||||
|
use db::MemoryDB;
|
||||||
|
use slot_clock::TestingSlotClock;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use types::{BeaconBlock, ChainSpec, FreeAttestation, Keypair};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum BlockProduceError {
|
||||||
|
DidNotProduce(BlockPollOutcome),
|
||||||
|
PollError(BlockPollError),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum AttestationProduceError {
|
||||||
|
DidNotProduce(AttestationPollOutcome),
|
||||||
|
PollError(AttestationPollError),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A `BlockProducer` and `Attester` which sign using a common keypair.
|
||||||
|
///
|
||||||
|
/// The test validator connects directly to a borrowed `BeaconChain` struct. It is useful for
|
||||||
|
/// testing that the core proposer and attester logic is functioning. Also for supporting beacon
|
||||||
|
/// chain tests.
|
||||||
|
pub struct TestValidator {
|
||||||
|
pub block_producer: BlockProducer<
|
||||||
|
TestingSlotClock,
|
||||||
|
DirectBeaconNode<MemoryDB, TestingSlotClock>,
|
||||||
|
DirectDuties<MemoryDB, TestingSlotClock>,
|
||||||
|
TestSigner,
|
||||||
|
>,
|
||||||
|
pub attester: Attester<
|
||||||
|
TestingSlotClock,
|
||||||
|
DirectBeaconNode<MemoryDB, TestingSlotClock>,
|
||||||
|
DirectDuties<MemoryDB, TestingSlotClock>,
|
||||||
|
TestSigner,
|
||||||
|
>,
|
||||||
|
pub spec: Arc<ChainSpec>,
|
||||||
|
pub epoch_map: Arc<DirectDuties<MemoryDB, TestingSlotClock>>,
|
||||||
|
pub keypair: Keypair,
|
||||||
|
pub beacon_node: Arc<DirectBeaconNode<MemoryDB, TestingSlotClock>>,
|
||||||
|
pub slot_clock: Arc<TestingSlotClock>,
|
||||||
|
pub signer: Arc<TestSigner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestValidator {
|
||||||
|
/// Create a new TestValidator that signs with the given keypair, operates per the given spec and connects to the
|
||||||
|
/// supplied beacon node.
|
||||||
|
///
|
||||||
|
/// A `BlockProducer` and `Attester` is created..
|
||||||
|
pub fn new(
|
||||||
|
keypair: Keypair,
|
||||||
|
beacon_chain: Arc<BeaconChain<MemoryDB, TestingSlotClock>>,
|
||||||
|
spec: Arc<ChainSpec>,
|
||||||
|
) -> Self {
|
||||||
|
let slot_clock = Arc::new(TestingSlotClock::new(spec.genesis_slot));
|
||||||
|
let signer = Arc::new(TestSigner::new(keypair.clone()));
|
||||||
|
let beacon_node = Arc::new(DirectBeaconNode::new(beacon_chain.clone()));
|
||||||
|
let epoch_map = Arc::new(DirectDuties::new(keypair.pk.clone(), beacon_chain.clone()));
|
||||||
|
|
||||||
|
let block_producer = BlockProducer::new(
|
||||||
|
spec.clone(),
|
||||||
|
keypair.pk.clone(),
|
||||||
|
epoch_map.clone(),
|
||||||
|
slot_clock.clone(),
|
||||||
|
beacon_node.clone(),
|
||||||
|
signer.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let attester = Attester::new(
|
||||||
|
epoch_map.clone(),
|
||||||
|
slot_clock.clone(),
|
||||||
|
beacon_node.clone(),
|
||||||
|
signer.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
block_producer,
|
||||||
|
attester,
|
||||||
|
spec,
|
||||||
|
epoch_map,
|
||||||
|
keypair,
|
||||||
|
beacon_node,
|
||||||
|
slot_clock,
|
||||||
|
signer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run the `poll` function on the `BlockProducer` and produce a block.
|
||||||
|
///
|
||||||
|
/// An error is returned if the producer refuses to produce.
|
||||||
|
pub fn produce_block(&mut self) -> Result<BeaconBlock, BlockProduceError> {
|
||||||
|
// Using `DirectBeaconNode`, the validator will always return sucessufully if it tries to
|
||||||
|
// publish a block.
|
||||||
|
match self.block_producer.poll() {
|
||||||
|
Ok(BlockPollOutcome::BlockProduced(_)) => {}
|
||||||
|
Ok(outcome) => return Err(BlockProduceError::DidNotProduce(outcome)),
|
||||||
|
Err(error) => return Err(BlockProduceError::PollError(error)),
|
||||||
|
};
|
||||||
|
Ok(self
|
||||||
|
.beacon_node
|
||||||
|
.last_published_block()
|
||||||
|
.expect("Unable to obtain produced block."))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run the `poll` function on the `Attester` and produce a `FreeAttestation`.
|
||||||
|
///
|
||||||
|
/// An error is returned if the attester refuses to attest.
|
||||||
|
pub fn produce_free_attestation(&mut self) -> Result<FreeAttestation, AttestationProduceError> {
|
||||||
|
match self.attester.poll() {
|
||||||
|
Ok(AttestationPollOutcome::AttestationProduced(_)) => {}
|
||||||
|
Ok(outcome) => return Err(AttestationProduceError::DidNotProduce(outcome)),
|
||||||
|
Err(error) => return Err(AttestationProduceError::PollError(error)),
|
||||||
|
};
|
||||||
|
Ok(self
|
||||||
|
.beacon_node
|
||||||
|
.last_published_free_attestation()
|
||||||
|
.expect("Unable to obtain produced attestation."))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the validators slot clock to the specified slot.
|
||||||
|
///
|
||||||
|
/// The validators slot clock will always read this value until it is set to something else.
|
||||||
|
pub fn set_slot(&mut self, slot: u64) {
|
||||||
|
self.slot_clock.set_slot(slot)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user