First compiling version of per-block-proc refactor

This commit is contained in:
Paul Hauner
2019-03-06 15:22:45 +11:00
parent a15ed0acd3
commit 40f74c9b26
20 changed files with 907 additions and 586 deletions

View File

@@ -12,7 +12,7 @@ impl AttesterSlashingBuilder {
/// - `validator_index: u64`
/// - `message: &[u8]`
/// - `epoch: Epoch`
/// - `domain: u64`
/// - `domain: Domain`
///
/// Where domain is a domain "constant" (e.g., `spec.domain_attestation`).
pub fn double_vote<F>(
@@ -21,7 +21,7 @@ impl AttesterSlashingBuilder {
spec: &ChainSpec,
) -> AttesterSlashing
where
F: Fn(u64, &[u8], Epoch, u64) -> Signature,
F: Fn(u64, &[u8], Epoch, Domain) -> Signature,
{
let double_voted_slot = Slot::new(0);
let shard = 0;
@@ -75,12 +75,7 @@ impl AttesterSlashingBuilder {
custody_bit: attestation.custody_bitfield.get(i).unwrap(),
};
let message = attestation_data_and_custody_bit.hash_tree_root();
let signature = signer(
*validator_index,
&message[..],
epoch,
spec.domain_attestation,
);
let signature = signer(*validator_index, &message[..], epoch, Domain::Attestation);
attestation.aggregate_signature.add(&signature);
}
};

View File

@@ -112,6 +112,7 @@ pub struct BeaconState {
// Ethereum 1.0 chain data
pub latest_eth1_data: Eth1Data,
pub eth1_data_votes: Vec<Eth1DataVote>,
pub deposit_index: u64,
// Caching (not in the spec)
pub cache_index_offset: usize,
@@ -187,6 +188,7 @@ impl BeaconState {
*/
latest_eth1_data,
eth1_data_votes: vec![],
deposit_index: 0,
/*
* Caching (not in spec)
@@ -224,6 +226,8 @@ impl BeaconState {
}
}
genesis_state.deposit_index = initial_validator_deposits.len() as u64;
let genesis_active_index_root = hash_tree_root(get_active_validator_indices(
&genesis_state.validator_registry,
spec.genesis_epoch,
@@ -566,92 +570,6 @@ impl BeaconState {
.fold(0, |acc, i| acc + self.get_effective_balance(*i, spec))
}
/// Verify validity of ``slashable_attestation`` fields.
///
/// Spec v0.4.0
pub fn verify_slashable_attestation(
&self,
slashable_attestation: &SlashableAttestation,
spec: &ChainSpec,
) -> bool {
if slashable_attestation.custody_bitfield.num_set_bits() > 0 {
return false;
}
if slashable_attestation.validator_indices.is_empty() {
return false;
}
for i in 0..(slashable_attestation.validator_indices.len() - 1) {
if slashable_attestation.validator_indices[i]
>= slashable_attestation.validator_indices[i + 1]
{
return false;
}
}
if !verify_bitfield_length(
&slashable_attestation.custody_bitfield,
slashable_attestation.validator_indices.len(),
) {
return false;
}
if slashable_attestation.validator_indices.len()
> spec.max_indices_per_slashable_vote as usize
{
return false;
}
let mut aggregate_pubs = vec![AggregatePublicKey::new(); 2];
let mut message_exists = vec![false; 2];
for (i, v) in slashable_attestation.validator_indices.iter().enumerate() {
let custody_bit = match slashable_attestation.custody_bitfield.get(i) {
Ok(bit) => bit,
Err(_) => unreachable!(),
};
message_exists[custody_bit as usize] = true;
match self.validator_registry.get(*v as usize) {
Some(validator) => {
aggregate_pubs[custody_bit as usize].add(&validator.pubkey);
}
None => return false,
};
}
let message_0 = AttestationDataAndCustodyBit {
data: slashable_attestation.data.clone(),
custody_bit: false,
}
.hash_tree_root();
let message_1 = AttestationDataAndCustodyBit {
data: slashable_attestation.data.clone(),
custody_bit: true,
}
.hash_tree_root();
let mut messages = vec![];
let mut keys = vec![];
if message_exists[0] {
messages.push(&message_0[..]);
keys.push(&aggregate_pubs[0]);
}
if message_exists[1] {
messages.push(&message_1[..]);
keys.push(&aggregate_pubs[1]);
}
slashable_attestation.aggregate_signature.verify_multiple(
&messages[..],
spec.domain_attestation,
&keys[..],
)
}
/// Return the epoch at which an activation or exit triggered in ``epoch`` takes effect.
///
/// Spec v0.4.0
@@ -1163,8 +1081,11 @@ impl BeaconState {
proof_of_possession.verify(
&proof_of_possession_data.hash_tree_root(),
self.fork
.get_domain(self.slot.epoch(spec.slots_per_epoch), spec.domain_deposit),
spec.get_domain(
self.slot.epoch(spec.slots_per_epoch),
Domain::Deposit,
&self.fork,
),
&pubkey,
)
}
@@ -1338,6 +1259,7 @@ impl Encodable for BeaconState {
s.append(&self.batched_block_roots);
s.append(&self.latest_eth1_data);
s.append(&self.eth1_data_votes);
s.append(&self.deposit_index);
}
}
@@ -1368,6 +1290,7 @@ impl Decodable for BeaconState {
let (batched_block_roots, i) = <_>::ssz_decode(bytes, i)?;
let (latest_eth1_data, i) = <_>::ssz_decode(bytes, i)?;
let (eth1_data_votes, i) = <_>::ssz_decode(bytes, i)?;
let (deposit_index, i) = <_>::ssz_decode(bytes, i)?;
Ok((
Self {
@@ -1396,6 +1319,7 @@ impl Decodable for BeaconState {
batched_block_roots,
latest_eth1_data,
eth1_data_votes,
deposit_index,
cache_index_offset: 0,
caches: vec![EpochCache::empty(); CACHED_EPOCHS],
},
@@ -1440,6 +1364,7 @@ impl TreeHash for BeaconState {
result.append(&mut self.batched_block_roots.hash_tree_root_internal());
result.append(&mut self.latest_eth1_data.hash_tree_root_internal());
result.append(&mut self.eth1_data_votes.hash_tree_root_internal());
result.append(&mut self.deposit_index.hash_tree_root_internal());
hash(&result)
}
}
@@ -1472,6 +1397,7 @@ impl<T: RngCore> TestRandom<T> for BeaconState {
batched_block_roots: <_>::random_for_test(rng),
latest_eth1_data: <_>::random_for_test(rng),
eth1_data_votes: <_>::random_for_test(rng),
deposit_index: <_>::random_for_test(rng),
cache_index_offset: 0,
caches: vec![EpochCache::empty(); CACHED_EPOCHS],
}

View File

@@ -1,8 +1,17 @@
use crate::{Address, Epoch, Hash256, Slot};
use crate::{Address, Epoch, Fork, Hash256, Slot};
use bls::Signature;
const GWEI: u64 = 1_000_000_000;
pub enum Domain {
Deposit,
Attestation,
Proposal,
Exit,
Randao,
Transfer,
}
/// Holds all the "constants" for a BeaconChain.
///
/// Spec v0.4.0
@@ -85,14 +94,20 @@ pub struct ChainSpec {
/*
* Signature domains
*
* Fields should be private to prevent accessing a domain that hasn't been modified to suit
* some `Fork`.
*
* Use `ChainSpec::get_domain(..)` to access these values.
*/
pub domain_deposit: u64,
pub domain_attestation: u64,
pub domain_proposal: u64,
pub domain_exit: u64,
pub domain_randao: u64,
pub domain_transfer: u64,
domain_deposit: u64,
domain_attestation: u64,
domain_proposal: u64,
domain_exit: u64,
domain_randao: u64,
domain_transfer: u64,
}
impl ChainSpec {
/// Return the number of committees in one epoch.
///
@@ -107,6 +122,23 @@ impl ChainSpec {
) * self.slots_per_epoch
}
/// Get the domain number that represents the fork meta and signature domain.
///
/// Spec v0.4.0
pub fn get_domain(&self, epoch: Epoch, domain: Domain, fork: &Fork) -> u64 {
let domain_constant = match domain {
Domain::Deposit => self.domain_deposit,
Domain::Attestation => self.domain_attestation,
Domain::Proposal => self.domain_proposal,
Domain::Exit => self.domain_exit,
Domain::Randao => self.domain_randao,
Domain::Transfer => self.domain_transfer,
};
let fork_version = fork.get_fork_version(epoch);
fork_version * u64::pow(2, 32) + domain_constant
}
/// Returns a `ChainSpec` compatible with the Ethereum Foundation specification.
///
/// Spec v0.4.0

View File

@@ -24,14 +24,6 @@ impl Fork {
}
self.current_version
}
/// Get the domain number that represents the fork meta and signature domain.
///
/// Spec v0.4.0
pub fn get_domain(&self, epoch: Epoch, domain_type: u64) -> u64 {
let fork_version = self.get_fork_version(epoch);
fork_version * u64::pow(2, 32) + domain_type
}
}
#[cfg(test)]

View File

@@ -43,7 +43,7 @@ pub use crate::beacon_block_body::BeaconBlockBody;
pub use crate::beacon_state::{
BeaconState, Error as BeaconStateError, InclusionError, RelativeEpoch,
};
pub use crate::chain_spec::ChainSpec;
pub use crate::chain_spec::{ChainSpec, Domain};
pub use crate::crosslink::Crosslink;
pub use crate::deposit::Deposit;
pub use crate::deposit_data::DepositData;

View File

@@ -12,12 +12,12 @@ impl ProposerSlashingBuilder {
/// - `validator_index: u64`
/// - `message: &[u8]`
/// - `epoch: Epoch`
/// - `domain: u64`
/// - `domain: Domain`
///
/// Where domain is a domain "constant" (e.g., `spec.domain_attestation`).
pub fn double_vote<F>(proposer_index: u64, signer: F, spec: &ChainSpec) -> ProposerSlashing
where
F: Fn(u64, &[u8], Epoch, u64) -> Signature,
F: Fn(u64, &[u8], Epoch, Domain) -> Signature,
{
let slot = Slot::new(0);
let shard = 0;
@@ -39,15 +39,13 @@ impl ProposerSlashingBuilder {
proposal_1.signature = {
let message = proposal_1.signed_root();
let epoch = slot.epoch(spec.slots_per_epoch);
let domain = spec.domain_proposal;
signer(proposer_index, &message[..], epoch, domain)
signer(proposer_index, &message[..], epoch, Domain::Proposal)
};
proposal_2.signature = {
let message = proposal_2.signed_root();
let epoch = slot.epoch(spec.slots_per_epoch);
let domain = spec.domain_proposal;
signer(proposer_index, &message[..], epoch, domain)
signer(proposer_index, &message[..], epoch, Domain::Proposal)
};
ProposerSlashing {