mirror of
https://gitlab.com/pulsechaincom/lighthouse-pulse.git
synced 2025-01-01 00:41:20 +00:00
Add support for deposits to test_harness
This commit is contained in:
parent
c278c08e34
commit
b0403707eb
@ -7,10 +7,19 @@ test_cases:
|
|||||||
- config:
|
- config:
|
||||||
epoch_length: 64
|
epoch_length: 64
|
||||||
deposits_for_chain_start: 1000
|
deposits_for_chain_start: 1000
|
||||||
num_slots: 32 # Testing advancing state to slot < SlotsPerEpoch
|
num_slots: 65
|
||||||
skip_slots: [2, 3]
|
skip_slots: [2, 3]
|
||||||
|
deposits:
|
||||||
|
- slot: 1
|
||||||
|
amount: 32
|
||||||
|
merkle_index: 0
|
||||||
|
- slot: 3
|
||||||
|
amount: 32
|
||||||
|
merkle_index: 1
|
||||||
|
- slot: 5
|
||||||
|
amount: 32
|
||||||
|
merkle_index: 2
|
||||||
results:
|
results:
|
||||||
slot: 32
|
|
||||||
num_validators: 1000
|
num_validators: 1000
|
||||||
- config:
|
- config:
|
||||||
epoch_length: 64
|
epoch_length: 64
|
||||||
|
@ -15,10 +15,7 @@ use std::fs::File;
|
|||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use types::{
|
use types::*;
|
||||||
BeaconBlock, ChainSpec, Deposit, DepositData, DepositInput, Eth1Data, FreeAttestation, Hash256,
|
|
||||||
Keypair, Slot,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The beacon chain harness simulates a single beacon node with `validator_count` validators connected
|
/// The beacon chain harness simulates a single beacon node with `validator_count` validators connected
|
||||||
/// to it. Each validator is provided a borrow to the beacon chain, where it may read
|
/// to it. Each validator is provided a borrow to the beacon chain, where it may read
|
||||||
@ -245,6 +242,17 @@ impl BeaconChainHarness {
|
|||||||
debug!("Free attestations processed.");
|
debug!("Free attestations processed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn process_deposit(&mut self, deposit: Deposit, keypair: Option<Keypair>) {
|
||||||
|
self.beacon_chain.receive_deposit_for_inclusion(deposit);
|
||||||
|
|
||||||
|
// If a keypair is present, add a new `ValidatorHarness` to the rig.
|
||||||
|
if let Some(keypair) = keypair {
|
||||||
|
let validator =
|
||||||
|
ValidatorHarness::new(keypair, self.beacon_chain.clone(), self.spec.clone());
|
||||||
|
self.validators.push(validator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run_fork_choice(&mut self) {
|
pub fn run_fork_choice(&mut self) {
|
||||||
self.beacon_chain.fork_choice().unwrap()
|
self.beacon_chain.fork_choice().unwrap()
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use self::beacon_chain_harness::BeaconChainHarness;
|
use self::beacon_chain_harness::BeaconChainHarness;
|
||||||
use self::validator_harness::ValidatorHarness;
|
use self::validator_harness::ValidatorHarness;
|
||||||
use beacon_chain::CheckPoint;
|
use beacon_chain::CheckPoint;
|
||||||
|
use bls::create_proof_of_possession;
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use env_logger::{Builder, Env};
|
use env_logger::{Builder, Env};
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::{fs::File, io::prelude::*};
|
use std::{fs::File, io::prelude::*};
|
||||||
use types::*;
|
use types::*;
|
||||||
use yaml_rust::{Yaml, YamlLoader};
|
use yaml_rust::{Yaml, YamlLoader};
|
||||||
@ -73,7 +73,7 @@ impl Manifest {
|
|||||||
pub fn execute(&self) -> ExecutionResult {
|
pub fn execute(&self) -> ExecutionResult {
|
||||||
let spec = self.spec();
|
let spec = self.spec();
|
||||||
let validator_count = self.config.deposits_for_chain_start;
|
let validator_count = self.config.deposits_for_chain_start;
|
||||||
let slots = self.results.slot;
|
let slots = self.config.num_slots;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Building BeaconChainHarness with {} validators...",
|
"Building BeaconChainHarness with {} validators...",
|
||||||
@ -84,7 +84,18 @@ impl Manifest {
|
|||||||
|
|
||||||
info!("Starting simulation across {} slots...", slots);
|
info!("Starting simulation across {} slots...", slots);
|
||||||
|
|
||||||
for slot_height in 0..self.results.slot {
|
for slot_height in 0..slots {
|
||||||
|
// Include deposits
|
||||||
|
if let Some(ref deposits) = self.config.deposits {
|
||||||
|
for (slot, deposit, keypair) in deposits {
|
||||||
|
if *slot == slot_height {
|
||||||
|
info!("Including deposit at slot height {}.", slot_height);
|
||||||
|
harness.process_deposit(deposit.clone(), Some(keypair.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a block or skip a slot.
|
||||||
match self.config.skip_slots {
|
match self.config.skip_slots {
|
||||||
Some(ref skip_slots) if skip_slots.contains(&slot_height) => {
|
Some(ref skip_slots) if skip_slots.contains(&slot_height) => {
|
||||||
warn!("Skipping slot at height {}.", slot_height);
|
warn!("Skipping slot at height {}.", slot_height);
|
||||||
@ -109,8 +120,24 @@ impl Manifest {
|
|||||||
pub fn assert_result_valid(&self, result: ExecutionResult) {
|
pub fn assert_result_valid(&self, result: ExecutionResult) {
|
||||||
info!("Verifying test results...");
|
info!("Verifying test results...");
|
||||||
|
|
||||||
|
let skipped_slots = self
|
||||||
|
.config
|
||||||
|
.skip_slots
|
||||||
|
.clone()
|
||||||
|
.and_then(|slots| Some(slots.len()))
|
||||||
|
.unwrap_or_else(|| 0);
|
||||||
|
let expected_blocks = self.config.num_slots as usize + 1 - skipped_slots;
|
||||||
|
|
||||||
|
assert_eq!(result.chain.len(), expected_blocks);
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"OK: Chain length is {} ({} skipped slots).",
|
||||||
|
result.chain.len(),
|
||||||
|
skipped_slots
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(ref skip_slots) = self.config.skip_slots {
|
if let Some(ref skip_slots) = self.config.skip_slots {
|
||||||
for checkpoint in result.chain {
|
for checkpoint in &result.chain {
|
||||||
let block_slot = checkpoint.beacon_block.slot.as_u64();
|
let block_slot = checkpoint.beacon_block.slot.as_u64();
|
||||||
assert!(
|
assert!(
|
||||||
!skip_slots.contains(&block_slot),
|
!skip_slots.contains(&block_slot),
|
||||||
@ -118,17 +145,30 @@ impl Manifest {
|
|||||||
block_slot
|
block_slot
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
info!("OK: Skipped slots not present in chain.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ref deposits) = self.config.deposits {
|
||||||
|
let latest_state = &result.chain.last().expect("Empty chain.").beacon_state;
|
||||||
|
assert_eq!(
|
||||||
|
latest_state.validator_registry.len(),
|
||||||
|
self.config.deposits_for_chain_start + deposits.len()
|
||||||
|
);
|
||||||
|
info!(
|
||||||
|
"OK: Validator registry has {} more validators.",
|
||||||
|
deposits.len()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
info!("OK: Skipped slots not present in chain.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type DepositTuple = (u64, Deposit, Keypair);
|
||||||
|
|
||||||
struct ExecutionResult {
|
struct ExecutionResult {
|
||||||
pub chain: Vec<CheckPoint>,
|
pub chain: Vec<CheckPoint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Results {
|
struct Results {
|
||||||
pub slot: u64,
|
|
||||||
pub num_validators: Option<usize>,
|
pub num_validators: Option<usize>,
|
||||||
pub slashed_validators: Option<Vec<u64>>,
|
pub slashed_validators: Option<Vec<u64>>,
|
||||||
pub exited_validators: Option<Vec<u64>>,
|
pub exited_validators: Option<Vec<u64>>,
|
||||||
@ -137,7 +177,6 @@ struct Results {
|
|||||||
impl Results {
|
impl Results {
|
||||||
pub fn from_yaml(yaml: &Yaml) -> Self {
|
pub fn from_yaml(yaml: &Yaml) -> Self {
|
||||||
Self {
|
Self {
|
||||||
slot: as_u64(&yaml, "slot").expect("Must have end slot"),
|
|
||||||
num_validators: as_usize(&yaml, "num_validators"),
|
num_validators: as_usize(&yaml, "num_validators"),
|
||||||
slashed_validators: as_vec_u64(&yaml, "slashed_validators"),
|
slashed_validators: as_vec_u64(&yaml, "slashed_validators"),
|
||||||
exited_validators: as_vec_u64(&yaml, "exited_validators"),
|
exited_validators: as_vec_u64(&yaml, "exited_validators"),
|
||||||
@ -148,7 +187,9 @@ impl Results {
|
|||||||
struct Config {
|
struct Config {
|
||||||
pub deposits_for_chain_start: usize,
|
pub deposits_for_chain_start: usize,
|
||||||
pub epoch_length: Option<u64>,
|
pub epoch_length: Option<u64>,
|
||||||
|
pub num_slots: u64,
|
||||||
pub skip_slots: Option<Vec<u64>>,
|
pub skip_slots: Option<Vec<u64>>,
|
||||||
|
pub deposits: Option<Vec<DepositTuple>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@ -157,11 +198,41 @@ impl Config {
|
|||||||
deposits_for_chain_start: as_usize(&yaml, "deposits_for_chain_start")
|
deposits_for_chain_start: as_usize(&yaml, "deposits_for_chain_start")
|
||||||
.expect("Must specify validator count"),
|
.expect("Must specify validator count"),
|
||||||
epoch_length: as_u64(&yaml, "epoch_length"),
|
epoch_length: as_u64(&yaml, "epoch_length"),
|
||||||
|
num_slots: as_u64(&yaml, "num_slots").expect("Must specify `config.num_slots`"),
|
||||||
skip_slots: as_vec_u64(yaml, "skip_slots"),
|
skip_slots: as_vec_u64(yaml, "skip_slots"),
|
||||||
|
deposits: process_deposits(&yaml),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn process_deposits(yaml: &Yaml) -> Option<Vec<DepositTuple>> {
|
||||||
|
let mut deposits = vec![];
|
||||||
|
|
||||||
|
for deposit in yaml["deposits"].as_vec()? {
|
||||||
|
let keypair = Keypair::random();
|
||||||
|
let proof_of_possession = create_proof_of_possession(&keypair);
|
||||||
|
|
||||||
|
let slot = as_u64(deposit, "slot").expect("Incomplete deposit");
|
||||||
|
let deposit = Deposit {
|
||||||
|
branch: vec![],
|
||||||
|
index: as_u64(deposit, "merkle_index").unwrap(),
|
||||||
|
deposit_data: DepositData {
|
||||||
|
amount: 32_000_000_000,
|
||||||
|
timestamp: 1,
|
||||||
|
deposit_input: DepositInput {
|
||||||
|
pubkey: keypair.pk.clone(),
|
||||||
|
withdrawal_credentials: Hash256::zero(),
|
||||||
|
proof_of_possession,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
deposits.push((slot, deposit, keypair));
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(deposits)
|
||||||
|
}
|
||||||
|
|
||||||
fn as_usize(yaml: &Yaml, key: &str) -> Option<usize> {
|
fn as_usize(yaml: &Yaml, key: &str) -> Option<usize> {
|
||||||
yaml[key].as_i64().and_then(|n| Some(n as usize))
|
yaml[key].as_i64().and_then(|n| Some(n as usize))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user