Add comments to new functions/structs.

This commit is contained in:
Paul Hauner 2019-03-12 18:26:41 +11:00
parent f949919b9b
commit 2be0373f01
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
11 changed files with 80 additions and 44 deletions

View File

@ -23,6 +23,8 @@ pub struct BeaconBlock {
impl BeaconBlock {
/// Produce the first block of the Beacon Chain.
///
/// Spec v0.4.0
pub fn genesis(state_root: Hash256, spec: &ChainSpec) -> BeaconBlock {
BeaconBlock {
slot: spec.genesis_slot,
@ -46,11 +48,15 @@ impl BeaconBlock {
}
/// Returns the `hash_tree_root` of the block.
///
/// Spec v0.4.0
pub fn canonical_root(&self) -> Hash256 {
Hash256::from_slice(&self.hash_tree_root()[..])
}
/// Returns an unsigned proposal for block.
///
/// Spec v0.4.0
pub fn proposal(&self, spec: &ChainSpec) -> Proposal {
Proposal {
slot: self.slot,

View File

@ -6,7 +6,6 @@ use honey_badger_split::SplitExt;
use int_to_bytes::int_to_bytes32;
use log::{debug, error, trace};
use rand::RngCore;
use rayon::prelude::*;
use serde_derive::Serialize;
use ssz::{hash, Decodable, DecodeError, Encodable, SignedRoot, SszStream, TreeHash};
use std::collections::HashMap;
@ -113,6 +112,11 @@ pub struct BeaconState {
impl BeaconState {
/// Produce the first state of the Beacon Chain.
///
/// This does not fully build a genesis beacon state, it omits processing of initial validator
/// deposits. To obtain a full genesis beacon state, use the `BeaconStateBuilder`.
///
/// Spec v0.4.0
pub fn genesis(genesis_time: u64, latest_eth1_data: Eth1Data, spec: &ChainSpec) -> BeaconState {
let initial_crosslink = Crosslink {
epoch: spec.genesis_epoch,
@ -185,44 +189,9 @@ impl BeaconState {
}
}
/// Produce the first state of the Beacon Chain.
pub fn process_initial_deposits(
&mut self,
initial_validator_deposits: Vec<Deposit>,
spec: &ChainSpec,
) -> Result<(), Error> {
debug!("Processing genesis deposits...");
let deposit_data = initial_validator_deposits
.par_iter()
.map(|deposit| &deposit.deposit_data)
.collect();
self.process_deposits(deposit_data, spec);
trace!("Processed genesis deposits.");
for validator_index in 0..self.validator_registry.len() {
if self.get_effective_balance(validator_index, spec) >= spec.max_deposit_amount {
self.activate_validator(validator_index, true, spec);
}
}
self.deposit_index = initial_validator_deposits.len() as u64;
let genesis_active_index_root = hash_tree_root(get_active_validator_indices(
&self.validator_registry,
spec.genesis_epoch,
));
self.latest_active_index_roots =
vec![genesis_active_index_root; spec.latest_active_index_roots_length];
self.current_shuffling_seed = self.generate_seed(spec.genesis_epoch, spec)?;
Ok(())
}
/// Returns the `hash_tree_root` of the state.
///
/// Spec v0.4.0
pub fn canonical_root(&self) -> Hash256 {
Hash256::from_slice(&self.hash_tree_root()[..])
}
@ -1129,10 +1098,6 @@ impl BeaconState {
}
}
fn hash_tree_root<T: TreeHash>(input: Vec<T>) -> Hash256 {
Hash256::from_slice(&input.hash_tree_root()[..])
}
impl Encodable for BeaconState {
fn ssz_append(&self, s: &mut SszStream) {
s.append(&self.slot);

View File

@ -12,12 +12,17 @@ pub const BATCH_SIZE: usize = 1_000; // ~15MB
pub const KEYPAIR_BYTES_LEN: usize = PUBLIC_KEY_BYTES_LEN + SECRET_KEY_BYTES_LEN;
pub const BATCH_BYTE_LEN: usize = KEYPAIR_BYTES_LEN * BATCH_SIZE;
/// Defines a trait that allows reading/writing a vec of `Keypair` from/to a file.
pub trait KeypairsFile {
/// Write to file, without guaranteeing interoperability with other clients.
fn to_raw_file(&self, path: &Path, keypairs: &[Keypair]) -> Result<(), Error>;
/// Read from file, without guaranteeing interoperability with other clients.
fn from_raw_file(path: &Path, count: usize) -> Result<Vec<Keypair>, Error>;
}
impl KeypairsFile for Vec<Keypair> {
/// Write the keypairs to file, using the fastest possible method without guaranteeing
/// interoperability with other clients.
fn to_raw_file(&self, path: &Path, keypairs: &[Keypair]) -> Result<(), Error> {
let mut keypairs_file = File::create(path)?;
@ -35,6 +40,8 @@ impl KeypairsFile for Vec<Keypair> {
Ok(())
}
/// Read the keypairs from file, using the fastest possible method without guaranteeing
/// interoperability with other clients.
fn from_raw_file(path: &Path, count: usize) -> Result<Vec<Keypair>, Error> {
let mut keypairs_file = File::open(path)?;

View File

@ -1,12 +1,16 @@
use crate::*;
use ssz::TreeHash;
/// Builds an attestation to be used for testing purposes.
///
/// This struct should **never be used for production purposes.**
pub struct TestingAttestationBuilder {
committee: Vec<usize>,
attestation: Attestation,
}
impl TestingAttestationBuilder {
/// Create a new attestation builder.
pub fn new(
state: &BeaconState,
committee: &[usize],
@ -70,6 +74,10 @@ impl TestingAttestationBuilder {
}
}
/// Signs the attestation with a subset (or all) committee members.
///
/// `secret_keys` must be supplied in the same order as `signing_validators`. I.e., the first
/// keypair must be that of the first signing validator.
pub fn sign(
&mut self,
signing_validators: &[usize],
@ -111,6 +119,7 @@ impl TestingAttestationBuilder {
}
}
/// Consume the builder and return the attestation.
pub fn build(self) -> Attestation {
self.attestation
}

View File

@ -2,6 +2,8 @@ use crate::*;
use ssz::TreeHash;
/// Builds an `AttesterSlashing`.
///
/// This struct should **never be used for production purposes.**
pub struct TestingAttesterSlashingBuilder();
impl TestingAttesterSlashingBuilder {

View File

@ -8,22 +8,29 @@ use crate::{
use rayon::prelude::*;
use ssz::{SignedRoot, TreeHash};
/// Builds a beacon block to be used for testing purposes.
///
/// This struct should **never be used for production purposes.**
pub struct TestingBeaconBlockBuilder {
block: BeaconBlock,
}
impl TestingBeaconBlockBuilder {
/// Create a new builder from genesis.
pub fn new(spec: &ChainSpec) -> Self {
Self {
block: BeaconBlock::genesis(spec.zero_hash, spec),
}
}
/// Set the slot of the block.
pub fn set_slot(&mut self, slot: Slot) {
self.block.slot = slot;
}
/// Signs the block.
///
/// Modifying the block after signing may invalidate the signature.
pub fn sign(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) {
let proposal = self.block.proposal(spec);
let message = proposal.signed_root();
@ -33,6 +40,8 @@ impl TestingBeaconBlockBuilder {
}
/// Sets the randao to be a signature across the blocks epoch.
///
/// Modifying the block's slot after signing may invalidate the signature.
pub fn set_randao_reveal(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) {
let epoch = self.block.slot.epoch(spec.slots_per_epoch);
let message = epoch.hash_tree_root();
@ -65,9 +74,15 @@ impl TestingBeaconBlockBuilder {
self.block.body.attester_slashings.push(attester_slashing);
}
/// Fills the block with as many attestations as possible.
/// Fills the block with `MAX_ATTESTATIONS` attestations.
///
/// Note: this will not perform well when `jepoch_committees_count % slots_per_epoch != 0`
/// It will first go and get each committee that is able to include an attestation in this
/// block. If there are enough committees, it will produce an attestation for each. If there
/// are _not_ enough committees, it will start splitting the committees in half until it
/// achieves the target. It will then produce separate attestations for each split committee.
///
/// Note: the signed messages of the split committees will be identical -- it would be possible
/// to aggregate these split attestations.
pub fn fill_with_attestations(
&mut self,
state: &BeaconState,

View File

@ -20,6 +20,9 @@ pub fn keypairs_path() -> PathBuf {
dir.join(KEYPAIRS_FILE)
}
/// Builds a beacon state to be used for testing purposes.
///
/// This struct should **never be used for production purposes.**
pub struct TestingBeaconStateBuilder {
state: BeaconState,
keypairs: Vec<Keypair>,

View File

@ -1,11 +1,15 @@
use crate::*;
use bls::get_withdrawal_credentials;
/// Builds an deposit to be used for testing purposes.
///
/// This struct should **never be used for production purposes.**
pub struct TestingDepositBuilder {
deposit: Deposit,
}
impl TestingDepositBuilder {
/// Instantiates a new builder.
pub fn new(amount: u64) -> Self {
let keypair = Keypair::random();
@ -26,10 +30,16 @@ impl TestingDepositBuilder {
Self { deposit }
}
/// Set the `deposit.index` value.
pub fn set_index(&mut self, index: u64) {
self.deposit.index = index;
}
/// Signs the deposit, also setting the following values:
///
/// - `pubkey` to the signing pubkey.
/// - `withdrawal_credentials` to the signing pubkey.
/// - `proof_of_possesssion`
pub fn sign(&mut self, keypair: &Keypair, state: &BeaconState, spec: &ChainSpec) {
let withdrawal_credentials = Hash256::from_slice(
&get_withdrawal_credentials(&keypair.pk, spec.bls_withdrawal_prefix_byte)[..],
@ -47,6 +57,7 @@ impl TestingDepositBuilder {
DepositInput::create_proof_of_possession(&keypair, &withdrawal_credentials, domain);
}
/// Builds the deposit, consuming the builder.
pub fn build(self) -> Deposit {
self.deposit
}

View File

@ -2,6 +2,8 @@ use crate::*;
use ssz::SignedRoot;
/// Builds a `ProposerSlashing`.
///
/// This struct should **never be used for production purposes.**
pub struct TestingProposerSlashingBuilder();
impl TestingProposerSlashingBuilder {

View File

@ -1,11 +1,15 @@
use crate::*;
use ssz::SignedRoot;
/// Builds a transfer to be used for testing purposes.
///
/// This struct should **never be used for production purposes.**
pub struct TestingTransferBuilder {
transfer: Transfer,
}
impl TestingTransferBuilder {
/// Instantiates a new builder.
pub fn new(from: u64, to: u64, amount: u64, slot: Slot) -> Self {
let keypair = Keypair::random();
@ -22,6 +26,9 @@ impl TestingTransferBuilder {
Self { transfer }
}
/// Signs the transfer.
///
/// The keypair must match that of the `from` validator index.
pub fn sign(&mut self, keypair: Keypair, fork: &Fork, spec: &ChainSpec) {
self.transfer.pubkey = keypair.pk;
let message = self.transfer.signed_root();
@ -31,6 +38,7 @@ impl TestingTransferBuilder {
self.transfer.signature = Signature::new(&message, domain, &keypair.sk);
}
/// Builds the transfer, consuming the builder.
pub fn build(self) -> Transfer {
self.transfer
}

View File

@ -1,11 +1,15 @@
use crate::*;
use ssz::SignedRoot;
/// Builds an exit to be used for testing purposes.
///
/// This struct should **never be used for production purposes.**
pub struct TestingVoluntaryExitBuilder {
exit: VoluntaryExit,
}
impl TestingVoluntaryExitBuilder {
/// Instantiates a new builder.
pub fn new(epoch: Epoch, validator_index: u64) -> Self {
let exit = VoluntaryExit {
epoch,
@ -16,6 +20,9 @@ impl TestingVoluntaryExitBuilder {
Self { exit }
}
/// Signs the exit.
///
/// The signing secret key must match that of the exiting validator.
pub fn sign(&mut self, secret_key: &SecretKey, fork: &Fork, spec: &ChainSpec) {
let message = self.exit.signed_root();
let domain = spec.get_domain(self.exit.epoch, Domain::Exit, fork);
@ -23,6 +30,7 @@ impl TestingVoluntaryExitBuilder {
self.exit.signature = Signature::new(&message, domain, secret_key);
}
/// Builds the exit, consuming the builder.
pub fn build(self) -> VoluntaryExit {
self.exit
}