Update to spec v0.9.0

This commit is contained in:
Michael Sproul
2019-11-11 15:00:10 +11:00
parent 613fdbeda6
commit aaa5f2042f
93 changed files with 651 additions and 2203 deletions

View File

@@ -16,7 +16,7 @@ use ssz::Encode;
use state_processing::per_block_processing::{
errors::{
AttestationValidationError, AttesterSlashingValidationError, DepositValidationError,
ExitValidationError, ProposerSlashingValidationError, TransferValidationError,
ExitValidationError, ProposerSlashingValidationError,
},
verify_attestation_for_state, VerifySignatures,
};
@@ -493,15 +493,15 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}
state
.get_beacon_proposer_index(slot, RelativeEpoch::Current, &self.spec)
.get_beacon_proposer_index(slot, &self.spec)
.map_err(Into::into)
}
/// Returns the attestation slot and shard for a given validator index.
/// Returns the attestation slot and committee index for a given validator index.
///
/// Information is read from the current state, so only information from the present and prior
/// epoch is available.
pub fn validator_attestation_slot_and_shard(
pub fn validator_attestation_slot_and_index(
&self,
validator_index: usize,
epoch: Epoch,
@@ -528,25 +528,25 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
if let Some(attestation_duty) =
state.get_attestation_duties(validator_index, RelativeEpoch::Current)?
{
Ok(Some((attestation_duty.slot, attestation_duty.shard)))
Ok(Some((attestation_duty.slot, attestation_duty.index)))
} else {
Ok(None)
}
}
/// Produce an `AttestationData` that is valid for the given `slot` `shard`.
/// Produce an `AttestationData` that is valid for the given `slot`, `index`.
///
/// Always attests to the canonical chain.
pub fn produce_attestation_data(
&self,
shard: u64,
slot: Slot,
index: CommitteeIndex,
) -> Result<AttestationData, Error> {
let state = self.state_at_slot(slot)?;
let head = self.head();
self.produce_attestation_data_for_block(
shard,
index,
head.beacon_block_root,
head.beacon_block.slot,
&state,
@@ -559,7 +559,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// function should be used as it attests to the canonical chain.
pub fn produce_attestation_data_for_block(
&self,
shard: u64,
index: CommitteeIndex,
head_block_root: Hash256,
head_block_slot: Slot,
state: &BeaconState<T::EthSpec>,
@@ -600,18 +600,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
root: target_root,
};
let parent_crosslink = state.get_current_crosslink(shard)?;
let crosslink = Crosslink {
shard,
parent_root: Hash256::from_slice(&parent_crosslink.tree_hash_root()),
start_epoch: parent_crosslink.end_epoch,
end_epoch: std::cmp::min(
target.epoch,
parent_crosslink.end_epoch + self.spec.max_epochs_per_crosslink,
),
data_root: Hash256::zero(),
};
// Collect some metrics.
metrics::inc_counter(&metrics::ATTESTATION_PRODUCTION_SUCCESSES);
metrics::stop_timer(timer);
@@ -620,15 +608,16 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
self.log,
"Produced beacon attestation data";
"beacon_block_root" => format!("{}", head_block_root),
"shard" => shard,
"slot" => state.slot
"slot" => state.slot,
"index" => index
);
Ok(AttestationData {
slot: state.slot,
index,
beacon_block_root: head_block_root,
source: state.current_justified_checkpoint.clone(),
target,
crosslink,
})
}
@@ -657,7 +646,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
self.log,
"Beacon attestation imported";
"target_epoch" => attestation.data.target.epoch,
"shard" => attestation.data.crosslink.shard,
"index" => attestation.data.index,
);
let _ = self
.event_handler
@@ -776,16 +765,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
let attestation_slot = state.get_attestation_data_slot(&attestation.data)?;
// Reject any attestation where the `state` loaded from `data.beacon_block_root`
// has a higher slot than the attestation.
//
// Permitting this would allow for attesters to vote on _future_ slots.
if state.slot > attestation_slot {
if state.slot > attestation.data.slot {
Ok(AttestationProcessingOutcome::AttestsToFutureState {
state: state.slot,
attestation: attestation_slot,
attestation: attestation.data.slot,
})
} else {
self.process_attestation_for_state_and_block(
@@ -937,22 +924,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}
}
/// Accept some transfer and queue it for inclusion in an appropriate block.
pub fn process_transfer(&self, transfer: Transfer) -> Result<(), TransferValidationError> {
match self.wall_clock_state() {
Ok(state) => self.op_pool.insert_transfer(transfer, &state, &self.spec),
Err(e) => {
error!(
&self.log,
"Unable to process transfer";
"error" => format!("{:?}", e),
"reason" => "no state"
);
Ok(())
}
}
}
/// Accept some proposer slashing and queue it for inclusion in an appropriate block.
pub fn process_proposer_slashing(
&self,
@@ -1331,7 +1302,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
attestations: self.op_pool.get_attestations(&state, &self.spec).into(),
deposits: self.eth1_chain.deposits_for_block_inclusion(&state)?.into(),
voluntary_exits: self.op_pool.get_voluntary_exits(&state, &self.spec).into(),
transfers: self.op_pool.get_transfers(&state, &self.spec).into(),
},
};

View File

@@ -27,7 +27,7 @@ pub use parking_lot;
pub use slot_clock;
pub use state_processing::per_block_processing::errors::{
AttestationValidationError, AttesterSlashingValidationError, DepositValidationError,
ExitValidationError, ProposerSlashingValidationError, TransferValidationError,
ExitValidationError, ProposerSlashingValidationError,
};
pub use store;
pub use types;

View File

@@ -172,8 +172,6 @@ lazy_static! {
try_create_int_gauge("beacon_head_state_finalized_root", "Finalized root at the head of the chain");
pub static ref HEAD_STATE_FINALIZED_EPOCH: Result<IntGauge> =
try_create_int_gauge("beacon_head_state_finalized_epoch", "Finalized epoch at the head of the chain");
pub static ref HEAD_STATE_SHARDS: Result<IntGauge> =
try_create_int_gauge("beacon_head_state_shard_total", "Count of shards in the beacon chain");
pub static ref HEAD_STATE_TOTAL_VALIDATORS: Result<IntGauge> =
try_create_int_gauge("beacon_head_state_total_validators_total", "Count of validators at the head of the chain");
pub static ref HEAD_STATE_ACTIVE_VALIDATORS: Result<IntGauge> =
@@ -226,7 +224,6 @@ fn scrape_head_state<T: BeaconChainTypes>(state: &BeaconState<T::EthSpec>, state
&HEAD_STATE_FINALIZED_EPOCH,
state.finalized_checkpoint.epoch,
);
set_gauge_by_usize(&HEAD_STATE_SHARDS, state.previous_crosslinks.len());
set_gauge_by_usize(&HEAD_STATE_TOTAL_VALIDATORS, state.validators.len());
set_gauge_by_u64(&HEAD_STATE_VALIDATOR_BALANCES, state.balances.iter().sum());
set_gauge_by_usize(

View File

@@ -13,8 +13,7 @@ use store::MemoryStore;
use tree_hash::{SignedRoot, TreeHash};
use types::{
AggregateSignature, Attestation, AttestationDataAndCustodyBit, BeaconBlock, BeaconState,
BitList, ChainSpec, Domain, EthSpec, Hash256, Keypair, RelativeEpoch, SecretKey, Signature,
Slot,
BitList, ChainSpec, Domain, EthSpec, Hash256, Keypair, SecretKey, Signature, Slot,
};
pub use types::test_utils::generate_deterministic_keypairs;
@@ -216,7 +215,7 @@ where
.block_proposer(slot)
.expect("should get block proposer from chain"),
_ => state
.get_beacon_proposer_index(slot, RelativeEpoch::Current, &self.spec)
.get_beacon_proposer_index(slot, &self.spec)
.expect("should get block proposer from state"),
};
@@ -293,13 +292,13 @@ where
let mut attestations = vec![];
state
.get_crosslink_committees_at_slot(state.slot)
.get_beacon_committees_at_slot(state.slot)
.expect("should get committees")
.iter()
.for_each(|cc| {
let committee_size = cc.committee.len();
.for_each(|bc| {
let committee_size = bc.committee.len();
let mut local_attestations: Vec<Attestation<E>> = cc
let mut local_attestations: Vec<Attestation<E>> = bc
.committee
.par_iter()
.enumerate()
@@ -310,7 +309,7 @@ where
let data = self
.chain
.produce_attestation_data_for_block(
cc.shard,
bc.index,
head_block_root,
head_block_slot,
state,
@@ -332,8 +331,11 @@ where
}
.tree_hash_root();
let domain =
spec.get_domain(data.target.epoch, Domain::Attestation, fork);
let domain = spec.get_domain(
data.target.epoch,
Domain::BeaconAttester,
fork,
);
let mut agg_sig = AggregateSignature::new();
agg_sig.add(&Signature::new(

View File

@@ -17,7 +17,7 @@ use std::sync::Arc;
use tokio;
use tokio::sync::mpsc;
use types::beacon_state::EthSpec;
use types::{Attestation, BeaconBlock, BitList, Epoch, RelativeEpoch, Shard, Slot};
use types::{Attestation, BeaconBlock, BitList, CommitteeIndex, Epoch, RelativeEpoch, Slot};
#[derive(Debug, Serialize, Deserialize)]
pub struct ValidatorDuty {
@@ -25,8 +25,8 @@ pub struct ValidatorDuty {
pub validator_pubkey: String,
/// The slot at which the validator must attest.
pub attestation_slot: Option<Slot>,
/// The shard in which the validator must attest.
pub attestation_shard: Option<Shard>,
/// The index of the committee within `slot` of which the validator is a member.
pub attestation_committee_index: Option<CommitteeIndex>,
/// The slot in which a validator must propose a block, or `null` if block production is not required.
pub block_proposal_slot: Option<Slot>,
}
@@ -36,7 +36,7 @@ impl ValidatorDuty {
ValidatorDuty {
validator_pubkey: "".to_string(),
attestation_slot: None,
attestation_shard: None,
attestation_committee_index: None,
block_proposal_slot: None,
}
}
@@ -90,7 +90,7 @@ pub fn get_validator_duties<T: BeaconChainTypes + 'static>(req: Request<Body>) -
.slot_iter(T::EthSpec::slots_per_epoch())
.map(|slot| {
head_state
.get_beacon_proposer_index(slot, relative_epoch, &beacon_chain.spec)
.get_beacon_proposer_index(slot, &beacon_chain.spec)
.map_err(|e| {
ApiError::ServerError(format!(
"Unable to get proposer index for validator: {:?}",
@@ -125,7 +125,7 @@ pub fn get_validator_duties<T: BeaconChainTypes + 'static>(req: Request<Body>) -
match head_state.get_attestation_duties(val_index, relative_epoch) {
Ok(Some(d)) => {
duty.attestation_slot = Some(d.slot);
duty.attestation_shard = Some(d.shard);
duty.attestation_committee_index = Some(d.index);
}
Ok(None) => {}
Err(e) => {
@@ -311,7 +311,7 @@ pub fn get_new_attestation<T: BeaconChainTypes + 'static>(req: Request<Body>) ->
let mut aggregation_bits = BitList::with_capacity(val_duty.committee_len)
.expect("An empty BitList should always be created, or we have bigger problems.");
aggregation_bits
.set(val_duty.committee_index, poc_bit)
.set(val_duty.committee_position, poc_bit)
.map_err(|e| {
ApiError::ServerError(format!(
"Unable to set aggregation bits for the attestation: {:?}",
@@ -334,14 +334,14 @@ pub fn get_new_attestation<T: BeaconChainTypes + 'static>(req: Request<Body>) ->
return Err(ApiError::BadRequest(format!("Attestation data can only be requested for the current slot ({:?}), not your requested slot ({:?})", current_slot, requested_slot)));
}
let shard = query
.first_of(&["shard"])
let index = query
.first_of(&["index"])
.map(|(_key, value)| value)?
.parse::<u64>()
.map_err(|e| ApiError::BadRequest(format!("Shard is not a valid u64 value: {:?}", e)))?;
.map_err(|e| ApiError::BadRequest(format!("Index is not a valid u64 value: {:?}", e)))?;
let attestation_data = beacon_chain
.produce_attestation_data(shard, current_slot.into())
.produce_attestation_data(current_slot.into(), index)
.map_err(|e| ApiError::ServerError(format!("Could not produce an attestation: {:?}", e)))?;
let attestation: Attestation<T::EthSpec> = Attestation {

View File

@@ -38,11 +38,12 @@ impl<T: BeaconChainTypes> AttestationService for AttestationServiceInstance<T> {
);
// Then get the AttestationData from the beacon chain
// NOTE(v0.9): shard is incorrectly named, all this should be deleted
let shard = req.get_shard();
let slot_requested = req.get_slot();
let attestation_data = match self
.chain
.produce_attestation_data(shard, Slot::from(slot_requested))
.produce_attestation_data(Slot::from(slot_requested), shard)
{
Ok(v) => v,
Err(e) => {
@@ -105,7 +106,7 @@ impl<T: BeaconChainTypes> AttestationService for AttestationServiceInstance<T> {
self.log,
"Valid attestation from RPC";
"target_epoch" => attestation.data.target.epoch,
"shard" => attestation.data.crosslink.shard,
"index" => attestation.data.index,
);
// valid attestation, propagate to the network

View File

@@ -57,9 +57,7 @@ impl<T: BeaconChainTypes> ValidatorService for ValidatorServiceInstance<T> {
let validator_proposers: Result<Vec<usize>, _> = epoch
.slot_iter(T::EthSpec::slots_per_epoch())
.map(|slot| {
state.get_beacon_proposer_index(slot, RelativeEpoch::Current, &self.chain.spec)
})
.map(|slot| state.get_beacon_proposer_index(slot, &self.chain.spec))
.collect();
let validator_proposers = match validator_proposers {
Ok(v) => v,
@@ -161,9 +159,9 @@ impl<T: BeaconChainTypes> ValidatorService for ValidatorServiceInstance<T> {
duty.set_none(false)
}
duty.set_committee_index(attestation_duties.committee_index as u64);
duty.set_committee_index(attestation_duties.committee_position as u64);
duty.set_attestation_slot(attestation_duties.slot.as_u64());
duty.set_attestation_shard(attestation_duties.shard);
duty.set_attestation_shard(attestation_duties.index);
duty.set_committee_len(attestation_duties.committee_len as u64);
active_validator.set_duty(duty);