Add unsafe attester crate

This commit is contained in:
Paul Hauner
2019-01-28 11:23:30 +11:00
parent d5da84d967
commit acf8b79fe9
8 changed files with 437 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
use crate::traits::{BeaconNode, BeaconNodeError, PublishOutcome};
use std::sync::RwLock;
use types::{AttestationData, Signature};
type ProduceResult = Result<Option<AttestationData>, BeaconNodeError>;
type PublishResult = Result<PublishOutcome, BeaconNodeError>;
/// A test-only struct used to simulate a Beacon Node.
#[derive(Default)]
pub struct TestBeaconNode {
pub produce_input: RwLock<Option<(u64, u64)>>,
pub produce_result: RwLock<Option<ProduceResult>>,
pub publish_input: RwLock<Option<(AttestationData, Signature, u64)>>,
pub publish_result: RwLock<Option<PublishResult>>,
}
impl TestBeaconNode {
pub fn set_next_produce_result(&self, result: ProduceResult) {
*self.produce_result.write().unwrap() = Some(result);
}
pub fn set_next_publish_result(&self, result: PublishResult) {
*self.publish_result.write().unwrap() = Some(result);
}
}
impl BeaconNode for TestBeaconNode {
fn produce_attestation_data(&self, slot: u64, shard: u64) -> ProduceResult {
*self.produce_input.write().unwrap() = Some((slot, shard));
match *self.produce_result.read().unwrap() {
Some(ref r) => r.clone(),
None => panic!("TestBeaconNode: produce_result == None"),
}
}
fn publish_attestation_data(
&self,
attestation_data: AttestationData,
signature: Signature,
validator_index: u64,
) -> PublishResult {
*self.publish_input.write().unwrap() = Some((attestation_data, signature, validator_index));
match *self.publish_result.read().unwrap() {
Some(ref r) => r.clone(),
None => panic!("TestBeaconNode: publish_result == None"),
}
}
}

View File

@@ -0,0 +1,44 @@
use crate::{DutiesReader, DutiesReaderError};
use std::collections::HashMap;
pub struct TestEpochMap {
epoch_length: u64,
validator_index: Option<u64>,
map: HashMap<u64, (u64, u64)>,
}
impl TestEpochMap {
pub fn new(epoch_length: u64) -> Self {
Self {
epoch_length,
validator_index: None,
map: HashMap::new(),
}
}
pub fn insert_attestation_shard(&mut self, slot: u64, shard: u64) {
let epoch = slot / self.epoch_length;
self.map.insert(epoch, (slot, shard));
}
pub fn set_validator_index(&mut self, index: Option<u64>) {
self.validator_index = index;
}
}
impl DutiesReader for TestEpochMap {
fn attestation_shard(&self, slot: u64) -> Result<Option<u64>, DutiesReaderError> {
let epoch = slot / self.epoch_length;
match self.map.get(&epoch) {
Some((attest_slot, attest_shard)) if *attest_slot == slot => Ok(Some(*attest_shard)),
Some((attest_slot, _attest_shard)) if *attest_slot != slot => Ok(None),
_ => Err(DutiesReaderError::UnknownEpoch),
}
}
fn validator_index(&self) -> Option<u64> {
self.validator_index
}
}

View File

@@ -0,0 +1,7 @@
mod beacon_node;
mod epoch_map;
mod signer;
pub use self::beacon_node::TestBeaconNode;
pub use self::epoch_map::TestEpochMap;
pub use self::signer::TestSigner;

View File

@@ -0,0 +1,31 @@
use crate::traits::Signer;
use std::sync::RwLock;
use types::{Keypair, Signature};
/// A test-only struct used to simulate a Beacon Node.
pub struct TestSigner {
keypair: Keypair,
should_sign: RwLock<bool>,
}
impl TestSigner {
/// Produce a new TestSigner with signing enabled by default.
pub fn new(keypair: Keypair) -> Self {
Self {
keypair,
should_sign: RwLock::new(true),
}
}
/// If set to `false`, the service will refuse to sign all messages. Otherwise, all messages
/// will be signed.
pub fn enable_signing(&self, enabled: bool) {
*self.should_sign.write().unwrap() = enabled;
}
}
impl Signer for TestSigner {
fn bls_sign(&self, message: &[u8]) -> Option<Signature> {
Some(Signature::new(message, &self.keypair.sk))
}
}