From 288211052520d5b8959ef45f5d1aeeef1e5037d9 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Mon, 28 Jan 2019 17:07:13 +1100 Subject: [PATCH] Add attesatation aggregation to test harness --- .../beacon_chain/src/block_production.rs | 10 ++- .../beacon_chain/test_harness/src/harness.rs | 64 +++++++++++++++---- .../src/validator/beacon_node/attester.rs | 6 +- .../beacon_chain/test_harness/tests/chain.rs | 2 +- 4 files changed, 61 insertions(+), 21 deletions(-) diff --git a/beacon_node/beacon_chain/src/block_production.rs b/beacon_node/beacon_chain/src/block_production.rs index 50baf12ba..58f3ae2cc 100644 --- a/beacon_node/beacon_chain/src/block_production.rs +++ b/beacon_node/beacon_chain/src/block_production.rs @@ -45,6 +45,13 @@ where .into_beacon_state() .ok_or_else(|| Error::DBError("State invalid.".to_string()))?; + let attestations = self + .attestation_aggregator + .read() + .unwrap() + // TODO: advance the parent_state slot. + .get_attestations_for_state(&parent_state, &self.spec); + let mut block = BeaconBlock { slot: present_slot, parent_root: parent_root.clone(), @@ -59,7 +66,7 @@ where body: BeaconBlockBody { proposer_slashings: vec![], casper_slashings: vec![], - attestations: vec![], + attestations: attestations, custody_reseeds: vec![], custody_challenges: vec![], custody_responses: vec![], @@ -70,7 +77,6 @@ where let state = self.state_transition_without_verifying_block_signature(parent_state, &block)?; - let state_root = state.canonical_root(); block.state_root = state_root; diff --git a/beacon_node/beacon_chain/test_harness/src/harness.rs b/beacon_node/beacon_chain/test_harness/src/harness.rs index 2f4c11aef..b96636c8d 100644 --- a/beacon_node/beacon_chain/test_harness/src/harness.rs +++ b/beacon_node/beacon_chain/test_harness/src/harness.rs @@ -9,7 +9,7 @@ use slot_clock::TestingSlotClock; use std::fs::File; use std::io::prelude::*; use std::sync::Arc; -use types::{BeaconBlock, ChainSpec, Keypair, Validator}; +use types::{BeaconBlock, ChainSpec, FreeAttestation, Keypair, Validator}; pub struct BeaconChainHarness { pub db: Arc, @@ -74,33 +74,69 @@ impl BeaconChainHarness { } } - pub fn advance_chain_without_block(&mut self) -> BeaconBlock { - self.produce_next_slot() - } - - pub fn advance_chain_with_block(&mut self) { - let block = self.produce_next_slot(); - self.beacon_chain.process_block(block).unwrap(); - } - - fn produce_next_slot(&mut self) -> BeaconBlock { + /// Move the `slot_clock` for the `BeaconChain` forward one slot. + /// + /// This is the equivalent of advancing a system clock forward one `SLOT_DURATION`. + pub fn increment_beacon_chain_slot(&mut self) { let slot = self .beacon_chain .present_slot() .expect("Unable to determine slot.") + 1; - self.beacon_chain.slot_clock.set_slot(slot); + } + + /// Gather the `FreeAttestation`s from the valiators. + /// + /// Note: validators will only produce attestations _once per slot_. So, if you call this twice + /// you'll only get attestations on the first run. + pub fn gather_free_attesations(&mut self) -> Vec { + let present_slot = self.beacon_chain.present_slot().unwrap(); + + let mut free_attestations = vec![]; + for validator in &mut self.validators { + // Advance the validator slot. + validator.set_slot(present_slot); + + // Prompt the validator to produce an attestation (if required). + if let Ok(free_attestation) = validator.produce_free_attestation() { + free_attestations.push(free_attestation); + } + } + free_attestations + } + + /// Get the block from the proposer for the slot. + /// + /// Note: the validator will only produce it _once per slot_. So, if you call this twice you'll + /// only get a block once. + pub fn produce_block(&mut self) -> BeaconBlock { + let present_slot = self.beacon_chain.present_slot().unwrap(); let proposer = self .beacon_chain - .block_proposer(slot) + .block_proposer(present_slot) .expect("Unable to determine proposer."); - self.validators[proposer].set_slot(slot); self.validators[proposer].produce_block().unwrap() } + /// Advances the chain with a BeaconBlock and attestations from all validators. + /// + /// This is the ideal scenario for the Beacon Chain, 100% honest participation from + /// validators. + pub fn advance_chain_with_block(&mut self) { + self.increment_beacon_chain_slot(); + let free_attestations = self.gather_free_attesations(); + for free_attestation in free_attestations { + self.beacon_chain + .process_free_attestation(free_attestation.clone()) + .unwrap(); + } + let block = self.produce_block(); + self.beacon_chain.process_block(block).unwrap(); + } + pub fn chain_dump(&self) -> Result, DumpError> { self.beacon_chain.chain_dump() } diff --git a/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/attester.rs b/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/attester.rs index 4ef0efe36..9c6ce7456 100644 --- a/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/attester.rs +++ b/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/attester.rs @@ -26,9 +26,7 @@ where &self, free_attestation: FreeAttestation, ) -> Result { - match self.beacon_chain.process_free_attestation(free_attestation) { - Ok(_) => Ok(PublishOutcome::ValidAttestation), - Err(e) => Err(NodeError::RemoteFailure(format!("{:?}", e))), - } + self.published_attestations.write().push(free_attestation); + Ok(PublishOutcome::ValidAttestation) } } diff --git a/beacon_node/beacon_chain/test_harness/tests/chain.rs b/beacon_node/beacon_chain/test_harness/tests/chain.rs index bac1e1347..bbe52ac0d 100644 --- a/beacon_node/beacon_chain/test_harness/tests/chain.rs +++ b/beacon_node/beacon_chain/test_harness/tests/chain.rs @@ -12,7 +12,7 @@ fn it_can_build_on_genesis_block() { #[test] #[ignore] fn it_can_produce_past_first_epoch_boundary() { - let validator_count = 2; + let validator_count = 100; let mut harness = BeaconChainHarness::new(ChainSpec::foundation(), validator_count); let blocks = harness.spec.epoch_length + 1;