Fix bug with block production

This commit is contained in:
Paul Hauner 2019-08-30 11:04:15 +10:00
parent 31bbb0f573
commit 3365106340
No known key found for this signature in database
GPG Key ID: 5E2CFF9B75FA63DF
4 changed files with 35 additions and 24 deletions

View File

@ -466,6 +466,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
state.build_committee_cache(RelativeEpoch::Current, &self.spec)?; state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
} }
if epoch(state.as_ref().slot) != epoch(slot) {
return Err(Error::InvariantViolated(format!(
"Epochs in consistent in proposer lookup: state: {}, requested: {}",
epoch(state.as_ref().slot),
epoch(slot)
)));
}
state state
.as_ref() .as_ref()
.get_beacon_proposer_index(slot, RelativeEpoch::Current, &self.spec) .get_beacon_proposer_index(slot, RelativeEpoch::Current, &self.spec)
@ -494,6 +502,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
state.build_committee_cache(RelativeEpoch::Current, &self.spec)?; state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
} }
if as_epoch(state.as_ref().slot) != epoch {
return Err(Error::InvariantViolated(format!(
"Epochs in consistent in attestation duties lookup: state: {}, requested: {}",
as_epoch(state.as_ref().slot),
epoch
)));
}
if let Some(attestation_duty) = state if let Some(attestation_duty) = state
.as_ref() .as_ref()
.get_attestation_duties(validator_index, RelativeEpoch::Current)? .get_attestation_duties(validator_index, RelativeEpoch::Current)?
@ -1123,13 +1139,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
slot: Slot, slot: Slot,
) -> Result<(BeaconBlock<T::EthSpec>, BeaconState<T::EthSpec>), BlockProductionError> { ) -> Result<(BeaconBlock<T::EthSpec>, BeaconState<T::EthSpec>), BlockProductionError> {
let state = self let state = self
.state_at_slot(slot) .state_at_slot(slot - 1)
.map_err(|_| BlockProductionError::UnableToProduceAtSlot(slot))?; .map_err(|_| BlockProductionError::UnableToProduceAtSlot(slot))?;
let slot = self
.slot()
.map_err(|_| BlockProductionError::UnableToReadSlot)?;
self.produce_block_on_state(state.as_ref().clone(), slot, randao_reveal) self.produce_block_on_state(state.as_ref().clone(), slot, randao_reveal)
} }

View File

@ -37,6 +37,8 @@ pub enum BeaconChainError {
beacon_block_root: Hash256, beacon_block_root: Hash256,
}, },
AttestationValidationError(AttestationValidationError), AttestationValidationError(AttestationValidationError),
/// Returned when an internal check fails, indicating corrupt data.
InvariantViolated(String),
} }
easy_from_to!(SlotProcessingError, BeaconChainError); easy_from_to!(SlotProcessingError, BeaconChainError);

View File

@ -34,8 +34,7 @@ impl<T: BeaconChainTypes> BeaconBlockService for BeaconBlockServiceInstance<T> {
trace!(self.log, "Generating a beacon block"; "req" => format!("{:?}", req)); trace!(self.log, "Generating a beacon block"; "req" => format!("{:?}", req));
// decode the request // decode the request
// TODO: requested slot currently unused, see: https://github.com/sigp/lighthouse/issues/336 let requested_slot = Slot::from(req.get_slot());
let _requested_slot = Slot::from(req.get_slot());
let randao_reveal = match Signature::from_ssz_bytes(req.get_randao_reveal()) { let randao_reveal = match Signature::from_ssz_bytes(req.get_randao_reveal()) {
Ok(reveal) => reveal, Ok(reveal) => reveal,
Err(_) => { Err(_) => {
@ -51,22 +50,7 @@ impl<T: BeaconChainTypes> BeaconBlockService for BeaconBlockServiceInstance<T> {
} }
}; };
let slot = match self.chain.slot() { let produced_block = match self.chain.produce_block(randao_reveal, requested_slot) {
Ok(slot) => slot,
Err(_) => {
// decode error, incorrect signature
let log_clone = self.log.clone();
let f = sink
.fail(RpcStatus::new(
RpcStatusCode::InvalidArgument,
Some("No slot from chain".to_string()),
))
.map_err(move |e| warn!(log_clone, "failed to reply {:?}: {:?}", req, e));
return ctx.spawn(f);
}
};
let produced_block = match self.chain.produce_block(randao_reveal, slot) {
Ok((block, _state)) => block, Ok((block, _state)) => block,
Err(e) => { Err(e) => {
// could not produce a block // could not produce a block
@ -82,6 +66,11 @@ impl<T: BeaconChainTypes> BeaconBlockService for BeaconBlockServiceInstance<T> {
} }
}; };
assert_eq!(
produced_block.slot, requested_slot,
"should produce at the requested slot"
);
let mut block = BeaconBlockProto::new(); let mut block = BeaconBlockProto::new();
block.set_ssz(ssz_encode(&produced_block)); block.set_ssz(ssz_encode(&produced_block));

View File

@ -46,12 +46,20 @@ impl<T: BeaconChainTypes> ValidatorService for ValidatorServiceInstance<T> {
let _ = state.build_all_caches(&self.chain.spec); let _ = state.build_all_caches(&self.chain.spec);
assert_eq!(
state.current_epoch(),
epoch,
"Retrieved state should be from the same epoch"
);
let mut resp = GetDutiesResponse::new(); let mut resp = GetDutiesResponse::new();
let resp_validators = resp.mut_active_validators(); let resp_validators = resp.mut_active_validators();
let validator_proposers: Result<Vec<usize>, _> = epoch let validator_proposers: Result<Vec<usize>, _> = epoch
.slot_iter(T::EthSpec::slots_per_epoch()) .slot_iter(T::EthSpec::slots_per_epoch())
.map(|slot| self.chain.block_proposer(slot)) .map(|slot| {
state.get_beacon_proposer_index(slot, RelativeEpoch::Current, &self.chain.spec)
})
.collect(); .collect();
let validator_proposers = match validator_proposers { let validator_proposers = match validator_proposers {
Ok(v) => v, Ok(v) => v,