Change validator/duties endpoint

This commit is contained in:
Paul Hauner
2019-11-27 17:30:44 +11:00
parent 97aa8b75b8
commit dcd889f6ba
2 changed files with 44 additions and 23 deletions

View File

@@ -93,31 +93,31 @@ fn return_validator_duties<T: BeaconChainTypes>(
epoch: Epoch, epoch: Epoch,
validator_pubkeys: Vec<PublicKey>, validator_pubkeys: Vec<PublicKey>,
) -> Result<Vec<ValidatorDuty>, ApiError> { ) -> Result<Vec<ValidatorDuty>, ApiError> {
let head_state = beacon_chain.head().beacon_state; let slots_per_epoch = T::EthSpec::slots_per_epoch();
let head_epoch = head_state.current_epoch(); let head_epoch = beacon_chain.head().beacon_state.current_epoch();
let relative_epoch = RelativeEpoch::from_epoch(head_epoch, epoch); let mut state = if RelativeEpoch::from_epoch(head_epoch, epoch).is_ok() {
let mut state = if relative_epoch.is_err() { beacon_chain.head().beacon_state
head_state
} else { } else {
match beacon_chain.state_at_slot(epoch.start_slot(T::EthSpec::slots_per_epoch())) { let slot = if epoch > head_epoch {
Ok(state) => state, // Move to the first slot of the epoch prior to the request.
Err(e) => { //
return Err(ApiError::ServerError(format!( // Taking advantage of saturating epoch subtraction.
"Unable to load state for epoch {}: {:?}", (epoch - 1).start_slot(slots_per_epoch)
epoch, e } else {
))) // Move to the end of the epoch following the target.
} //
} // Taking advantage of saturating epoch subtraction.
(epoch + 2).start_slot(slots_per_epoch) - 1
};
beacon_chain.state_at_slot(slot).map_err(|e| {
ApiError::ServerError(format!("Unable to load state for epoch {}: {:?}", epoch, e))
})?
}; };
let relative_epoch = relative_epoch.or_else(|_| { let relative_epoch = RelativeEpoch::from_epoch(state.current_epoch(), epoch)
RelativeEpoch::from_epoch(state.current_epoch(), epoch).map_err(|_| { .map_err(|_| ApiError::ServerError(String::from("Loaded state is in the wrong epoch")))?;
ApiError::BadRequest(String::from(
"Epoch must be within one epoch of the current epoch",
))
})
})?;
state state
.build_committee_cache(relative_epoch, &beacon_chain.spec) .build_committee_cache(relative_epoch, &beacon_chain.spec)

View File

@@ -205,7 +205,7 @@ fn validator_duties() {
.beacon_chain() .beacon_chain()
.expect("client should have beacon chain"); .expect("client should have beacon chain");
let epoch = Epoch::new(0); let mut epoch = Epoch::new(0);
let validators = beacon_chain let validators = beacon_chain
.head() .head()
@@ -220,7 +220,26 @@ fn validator_duties() {
.block_on(remote_node.http.validator().get_duties(epoch, &validators)) .block_on(remote_node.http.validator().get_duties(epoch, &validators))
.expect("should fetch duties from http api"); .expect("should fetch duties from http api");
// 1. Check at the current epoch.
check_duties(
duties,
epoch,
validators.clone(),
beacon_chain.clone(),
spec,
);
epoch += 4;
let duties = env
.runtime()
.block_on(remote_node.http.validator().get_duties(epoch, &validators))
.expect("should fetch duties from http api");
// 2. Check with a long skip forward.
check_duties(duties, epoch, validators, beacon_chain, spec); check_duties(duties, epoch, validators, beacon_chain, spec);
// TODO: test an epoch in the past. Blocked because the `LocalBeaconNode` cannot produce a
// chain, yet.
} }
fn check_duties<T: BeaconChainTypes>( fn check_duties<T: BeaconChainTypes>(
@@ -236,7 +255,9 @@ fn check_duties<T: BeaconChainTypes>(
"there should be a duty for each validator" "there should be a duty for each validator"
); );
let state = beacon_chain.head().beacon_state.clone(); let state = beacon_chain
.state_at_slot(epoch.start_slot(T::EthSpec::slots_per_epoch()))
.expect("should get state at slot");
validators validators
.iter() .iter()