mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-17 21:08:32 +00:00
First compiling version of per-block-proc refactor
This commit is contained in:
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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],
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user