Extend BeaconChain persistence testing

This commit is contained in:
Paul Hauner
2019-11-30 13:57:44 +11:00
parent a2d071e681
commit da39d6e9d6
5 changed files with 61 additions and 24 deletions

View File

@@ -35,6 +35,16 @@ pub struct ForkChoice<T: BeaconChainTypes> {
best_justified_checkpoint: RwLock<Checkpoint>,
}
impl<T: BeaconChainTypes> PartialEq for ForkChoice<T> {
/// This implementation ignores the `store`.
fn eq(&self, other: &Self) -> bool {
self.backend == other.backend
&& self.genesis_block_root == other.genesis_block_root
&& *self.justified_checkpoint.read() == *other.justified_checkpoint.read()
&& *self.best_justified_checkpoint.read() == *other.best_justified_checkpoint.read()
}
}
impl<T: BeaconChainTypes> ForkChoice<T> {
/// Instantiate a new fork chooser.
///

View File

@@ -3,7 +3,10 @@
#[macro_use]
extern crate lazy_static;
use beacon_chain::test_utils::{AttestationStrategy, BeaconChainHarness, BlockStrategy};
use beacon_chain::{
test_utils::{AttestationStrategy, BeaconChainHarness, BlockStrategy},
BeaconChain, BeaconChainTypes,
};
use sloggers::{null::NullLoggerBuilder, Build};
use std::sync::Arc;
use store::DiskStore;
@@ -55,15 +58,7 @@ fn finalizes_after_resuming_from_db() {
let latest_slot = harness.chain.slot().expect("should have a slot");
let original_head = harness.chain.head();
let original_heads = harness.chain.heads();
assert_eq!(
original_head.beacon_state.slot, first_half,
"head should be half way through test"
);
drop(harness);
harness.chain.persist().expect("should persist the chain");
let resumed_harness = BeaconChainHarness::resume_from_disk_store(
MinimalEthSpec,
@@ -71,6 +66,14 @@ fn finalizes_after_resuming_from_db() {
KEYPAIRS[0..validator_count].to_vec(),
);
assert_chains_pretty_much_the_same(&harness.chain, &resumed_harness.chain);
// Ensures we don't accidentally use it again.
//
// Note: this will persist the chain again, but that shouldn't matter since nothing has
// changed.
drop(harness);
// Set the slot clock of the resumed harness to be in the slot following the previous harness.
//
// This allows us to produce the block at the next slot.
@@ -79,18 +82,6 @@ fn finalizes_after_resuming_from_db() {
.slot_clock
.set_slot(latest_slot.as_u64() + 1);
assert_eq!(
original_head,
resumed_harness.chain.head(),
"resumed head should be same as previous head"
);
assert_eq!(
original_heads,
resumed_harness.chain.heads(),
"resumed heads should be same as previous heads"
);
resumed_harness.extend_chain(
(num_blocks_produced - first_half) as usize,
BlockStrategy::OnCanonicalHead,
@@ -118,3 +109,18 @@ fn finalizes_after_resuming_from_db() {
"the head should be finalized two behind the current epoch"
);
}
fn assert_chains_pretty_much_the_same<T: BeaconChainTypes>(a: &BeaconChain<T>, b: &BeaconChain<T>) {
assert_eq!(a.spec, b.spec, "spec should be equal");
assert_eq!(a.op_pool, b.op_pool, "op_pool should be equal");
assert_eq!(a.head(), b.head(), "head() should be equal");
assert_eq!(a.heads(), b.heads(), "heads() should be equal");
assert_eq!(
a.genesis_block_root, b.genesis_block_root,
"genesis_block_root should be equal"
);
assert!(
a.fork_choice == b.fork_choice,
"fork_choice should be equal"
);
}

View File

@@ -8,7 +8,9 @@ pub use reduced_tree::ThreadSafeReducedTree;
pub type Result<T> = std::result::Result<T, String>;
pub trait LmdGhost<S: Store, E: EthSpec>: Send + Sync + Sized {
// Note: the `PartialEq` bound is only required for testing. If it becomes a serious annoyance we
// can remove it.
pub trait LmdGhost<S: Store, E: EthSpec>: PartialEq + Send + Sync + Sized {
/// Create a new instance, with the given `store` and `finalized_root`.
fn new(store: Arc<S>, finalized_block: &BeaconBlock<E>, finalized_root: Hash256) -> Self;

View File

@@ -55,6 +55,13 @@ impl<T, E> fmt::Debug for ThreadSafeReducedTree<T, E> {
}
}
impl<T, E> PartialEq for ThreadSafeReducedTree<T, E> {
/// This implementation ignores the `store`.
fn eq(&self, other: &Self) -> bool {
*self.core.read() == *other.core.read()
}
}
impl<T, E> LmdGhost<T, E> for ThreadSafeReducedTree<T, E>
where
T: Store,
@@ -200,6 +207,15 @@ impl<T, E> fmt::Debug for ReducedTree<T, E> {
}
}
impl<T, E> PartialEq for ReducedTree<T, E> {
/// This implementation ignores the `store` field.
fn eq(&self, other: &Self) -> bool {
self.nodes == other.nodes
&& self.latest_votes == other.latest_votes
&& self.root == other.root
}
}
impl<T, E> ReducedTree<T, E>
where
T: Store,
@@ -918,7 +934,7 @@ pub struct Vote {
///
/// E.g., a `get` or `insert` to an out-of-bounds element will cause the Vec to grow (using
/// Default) to the smallest size required to fulfill the request.
#[derive(Default, Clone, Debug)]
#[derive(Default, Clone, Debug, PartialEq)]
pub struct ElasticList<T>(Vec<T>);
impl<T> ElasticList<T>

View File

@@ -1,3 +1,5 @@
// mod simulated_network;
use node_test_rig::{
environment::{Environment, EnvironmentBuilder, RuntimeContext},
testing_client_config, ClientConfig, ClientGenesis, LocalBeaconNode, LocalValidatorClient,
@@ -7,6 +9,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use types::EthSpec;
pub type BeaconNode<E> = LocalBeaconNode<ProductionClient<E>>;
pub type ValidatorClient<E> = LocalValidatorClient<E>;
fn main() {
let nodes = 4;