Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Standard beacon api updates #1831

Closed
Closed
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8ae2364
add validator index to proposer data
realbigsean Oct 23, 2020
099707f
update state id serialization error
realbigsean Oct 26, 2020
74d81e6
test logging ahead of error handling in beacon api
realbigsean Oct 26, 2020
8473a29
add validator balances endpoint
realbigsean Oct 26, 2020
e266ceb
fix error codes in beacon api
realbigsean Oct 27, 2020
32299c4
remove unstable `future::ready`
realbigsean Oct 28, 2020
e437ce5
update aggregate and proof endpoint to accept arrays
realbigsean Oct 28, 2020
acde786
update attester duties endpoint to a POST, only query for proposer du…
realbigsean Oct 28, 2020
8060538
cargo clippy
realbigsean Oct 28, 2020
c734834
cargo clippy
realbigsean Oct 28, 2020
5bba1d8
check for known validator indices before querying the beacon node
realbigsean Oct 29, 2020
d31ee87
revert change to `StateId`'s `FromStr`
realbigsean Oct 29, 2020
dd0f0ba
Merge branch 'master' of https://github.com/sigp/lighthouse into stan…
realbigsean Oct 29, 2020
1ada0de
Merge branch 'master' of https://github.com/sigp/lighthouse into stan…
realbigsean Oct 30, 2020
493361c
add historical lookups for proposer duties
realbigsean Oct 30, 2020
6c563e8
Merge branch 'master' of https://github.com/sigp/lighthouse into stan…
realbigsean Nov 2, 2020
192d9de
Merge branch 'historical-data-api' of https://github.com/realbigsean/…
realbigsean Nov 3, 2020
ef25484
remove comment
realbigsean Nov 3, 2020
59ef923
appease clippy
realbigsean Nov 3, 2020
81d3ffc
aggregate and proofs endpoint error handling update
realbigsean Nov 6, 2020
e4a6f9b
validator duties download refactor
realbigsean Nov 7, 2020
016c105
fix test compile error
realbigsean Nov 7, 2020
9cacac5
fix indexed error deserialization
realbigsean Nov 8, 2020
7895c50
log updates
realbigsean Nov 9, 2020
28d159d
Change duties endpoint
paulhauner Nov 9, 2020
8849293
remove index check
realbigsean Nov 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,9 +984,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
///
/// - `VerifiedUnaggregatedAttestation`
/// - `VerifiedAggregatedAttestation`
pub fn apply_attestation_to_fork_choice<'a>(
pub fn apply_attestation_to_fork_choice(
&self,
verified: &'a impl SignatureVerifiedAttestation<T>,
verified: &impl SignatureVerifiedAttestation<T>,
) -> Result<(), Error> {
let _timer = metrics::start_timer(&metrics::FORK_CHOICE_PROCESS_ATTESTATION_TIMES);

Expand Down
1 change: 1 addition & 0 deletions beacon_node/http_api/src/beacon_proposer_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ impl BeaconProposerCache {

Ok(ProposerData {
pubkey: PublicKeyBytes::from(pubkey),
validator_index: i as u64,
slot,
})
})
Expand Down
412 changes: 252 additions & 160 deletions beacon_node/http_api/src/lib.rs

Large diffs are not rendered by default.

101 changes: 86 additions & 15 deletions beacon_node/http_api/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,73 @@ impl ApiTester {
self
}

pub async fn test_beacon_states_validator_balances(self) -> Self {
for state_id in self.interesting_state_ids() {
for validator_indices in self.interesting_validator_indices() {
let state_opt = self.get_state(state_id);
let validators: Vec<Validator> = match state_opt.as_ref() {
Some(state) => state.validators.clone().into(),
None => vec![],
};
let validator_index_ids = validator_indices
.iter()
.cloned()
.map(|i| ValidatorId::Index(i))
.collect::<Vec<ValidatorId>>();
let validator_pubkey_ids = validator_indices
.iter()
.cloned()
.map(|i| {
ValidatorId::PublicKey(
validators
.get(i as usize)
.map_or(PublicKeyBytes::empty(), |val| val.pubkey.clone()),
)
})
.collect::<Vec<ValidatorId>>();

let result_index_ids = self
.client
.get_beacon_states_validator_balances(
state_id,
Some(validator_index_ids.as_slice()),
)
.await
.unwrap()
.map(|res| res.data);
let result_pubkey_ids = self
.client
.get_beacon_states_validator_balances(
state_id,
Some(validator_pubkey_ids.as_slice()),
)
.await
.unwrap()
.map(|res| res.data);

let expected = state_opt.map(|state| {
let mut validators = Vec::with_capacity(validator_indices.len());

for i in validator_indices {
if i < state.balances.len() as u64 {
validators.push(ValidatorBalanceData {
index: i as u64,
balance: state.balances[i as usize],
});
}
}

validators
});

assert_eq!(result_index_ids, expected, "{:?}", state_id);
assert_eq!(result_pubkey_ids, expected, "{:?}", state_id);
}
}

self
}

pub async fn test_beacon_states_validators(self) -> Self {
for state_id in self.interesting_state_ids() {
for statuses in self.interesting_validator_statuses() {
Expand Down Expand Up @@ -1239,7 +1306,7 @@ impl ApiTester {
if epoch > current_epoch + 1 {
assert_eq!(
self.client
.get_validator_duties_attester(epoch, Some(&indices))
.post_validator_duties_attester(epoch, indices)
.await
.unwrap_err()
.status()
Expand All @@ -1251,7 +1318,7 @@ impl ApiTester {

let results = self
.client
.get_validator_duties_attester(epoch, Some(&indices))
.post_validator_duties_attester(epoch, indices.clone())
.await
.unwrap()
.data;
Expand Down Expand Up @@ -1340,7 +1407,11 @@ impl ApiTester {
.unwrap();
let pubkey = state.validators[index].pubkey.clone().into();

ProposerData { pubkey, slot }
ProposerData {
pubkey,
validator_index: index as u64,
slot,
}
})
.collect::<Vec<_>>();

Expand Down Expand Up @@ -1477,17 +1548,15 @@ impl ApiTester {
let fork = head.beacon_state.fork;
let genesis_validators_root = self.chain.genesis_validators_root;

let mut duties = vec![];
for i in 0..self.validator_keypairs.len() {
duties.push(
self.client
.get_validator_duties_attester(epoch, Some(&[i as u64]))
.await
.unwrap()
.data[0]
.clone(),
let duties = self
.client
.post_validator_duties_attester(
epoch,
(0..self.validator_keypairs.len() as u64).collect(),
)
}
.await
.unwrap()
.data;

let (i, kp, duty, proof) = self
.validator_keypairs
Expand Down Expand Up @@ -1558,7 +1627,7 @@ impl ApiTester {
let aggregate = self.get_aggregate().await;

self.client
.post_validator_aggregate_and_proof::<E>(&aggregate)
.post_validator_aggregate_and_proof::<E>(vec![aggregate])
.await
.unwrap();

Expand All @@ -1573,7 +1642,7 @@ impl ApiTester {
aggregate.message.aggregate.data.slot += 1;

self.client
.post_validator_aggregate_and_proof::<E>(&aggregate)
.post_validator_aggregate_and_proof::<E>(vec![aggregate])
.await
.unwrap_err();

Expand Down Expand Up @@ -1704,6 +1773,8 @@ async fn beacon_get() {
.await
.test_beacon_states_validators()
.await
.test_beacon_states_validator_balances()
.await
.test_beacon_states_committees()
.await
.test_beacon_states_validator_id()
Expand Down
102 changes: 69 additions & 33 deletions common/eth2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,26 @@ impl BeaconNodeHttpClient {
Ok(())
}

/// Perform a HTTP POST request, returning a JSON response.
async fn post_with_response<T: DeserializeOwned, U: IntoUrl, V: Serialize>(
&self,
url: U,
body: &V,
) -> Result<T, Error> {
let response = self
.client
.post(url)
.json(body)
.send()
.await
.map_err(Error::Reqwest)?;
ok_or_error(response)
.await?
.json()
.await
.map_err(Error::Reqwest)
}

/// `GET beacon/genesis`
///
/// ## Errors
Expand Down Expand Up @@ -210,6 +230,35 @@ impl BeaconNodeHttpClient {
self.get_opt(path).await
}

/// `GET beacon/states/{state_id}/validator_balances?id`
///
/// Returns `Ok(None)` on a 404 error.
pub async fn get_beacon_states_validator_balances(
&self,
state_id: StateId,
ids: Option<&[ValidatorId]>,
) -> Result<Option<GenericResponse<Vec<ValidatorBalanceData>>>, Error> {
let mut path = self.eth_path()?;

path.path_segments_mut()
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
.push("beacon")
.push("states")
.push(&state_id.to_string())
.push("validator_balances");

if let Some(ids) = ids {
let id_string = ids
.iter()
.map(|i| i.to_string())
.collect::<Vec<_>>()
.join(",");
path.query_pairs_mut().append_pair("id", &id_string);
}

self.get_opt(path).await
}

/// `GET beacon/states/{state_id}/validators?id,status`
///
/// Returns `Ok(None)` on a 404 error.
Expand Down Expand Up @@ -713,37 +762,6 @@ impl BeaconNodeHttpClient {
self.get(path).await
}

/// `GET validator/duties/attester/{epoch}?index`
///
/// ## Note
///
/// The `index` query parameter accepts a list of validator indices.
pub async fn get_validator_duties_attester(
&self,
epoch: Epoch,
index: Option<&[u64]>,
) -> Result<GenericResponse<Vec<AttesterData>>, Error> {
let mut path = self.eth_path()?;

path.path_segments_mut()
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
.push("validator")
.push("duties")
.push("attester")
.push(&epoch.to_string());

if let Some(index) = index {
let string = index
.iter()
.map(|i| i.to_string())
.collect::<Vec<_>>()
.join(",");
path.query_pairs_mut().append_pair("index", &string);
}

self.get(path).await
}

/// `GET validator/duties/proposer/{epoch}`
pub async fn get_validator_duties_proposer(
&self,
Expand Down Expand Up @@ -834,10 +852,28 @@ impl BeaconNodeHttpClient {
self.get_opt(path).await
}

/// `POST validator/duties/attester/{epoch}`
pub async fn post_validator_duties_attester(
&self,
epoch: Epoch,
indices: Vec<u64>,
paulhauner marked this conversation as resolved.
Show resolved Hide resolved
) -> Result<GenericResponse<Vec<AttesterData>>, Error> {
let mut path = self.eth_path()?;

path.path_segments_mut()
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
.push("validator")
.push("duties")
.push("attester")
.push(&epoch.to_string());

self.post_with_response(path, &indices).await
}

/// `POST validator/aggregate_and_proofs`
pub async fn post_validator_aggregate_and_proof<T: EthSpec>(
&self,
aggregate: &SignedAggregateAndProof<T>,
aggregates: Vec<SignedAggregateAndProof<T>>,
paulhauner marked this conversation as resolved.
Show resolved Hide resolved
) -> Result<(), Error> {
let mut path = self.eth_path()?;

Expand All @@ -846,7 +882,7 @@ impl BeaconNodeHttpClient {
.push("validator")
.push("aggregate_and_proofs");

self.post(path, aggregate).await?;
self.post(path, &aggregates).await?;

Ok(())
}
Expand Down
18 changes: 16 additions & 2 deletions common/eth2/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ pub struct ValidatorData {
pub validator: Validator,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ValidatorBalanceData {
#[serde(with = "serde_utils::quoted_u64")]
pub index: u64,
#[serde(with = "serde_utils::quoted_u64")]
pub balance: u64,
}

// TODO: This does not currently match the spec, but I'm going to try and change the spec using
// this proposal:
//
Expand Down Expand Up @@ -415,10 +423,14 @@ impl<T: FromStr> TryFrom<String> for QueryVec<T> {
}

#[derive(Clone, Deserialize)]
pub struct ValidatorDutiesQuery {
pub index: Option<QueryVec<u64>>,
pub struct ValidatorBalancesQuery {
pub id: Option<QueryVec<ValidatorId>>,
}

#[derive(Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct ValidatorIndexData(#[serde(with = "serde_utils::quoted_u64_vec")] pub Vec<u64>);

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AttesterData {
pub pubkey: PublicKeyBytes,
Expand All @@ -438,6 +450,8 @@ pub struct AttesterData {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ProposerData {
pub pubkey: PublicKeyBytes,
#[serde(with = "serde_utils::quoted_u64")]
pub validator_index: u64,
pub slot: Slot,
}

Expand Down
Loading