From 91cf782f8fc00482a93f7b5d9d4651b788a0c581 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Fri, 29 Nov 2019 17:27:08 +1100 Subject: [PATCH] Add the /beacon/heads API endpoint --- beacon_node/beacon_chain/src/beacon_chain.rs | 11 ++++++++-- beacon_node/rest_api/src/beacon.rs | 23 ++++++++++++++++++++ beacon_node/rest_api/src/router.rs | 3 +++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 7437253491..9b2d670233 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -336,10 +336,17 @@ impl BeaconChain { self.canonical_head.read().clone() } + /// Returns the current heads of the `BeaconChain`. For the canonical head, see `Self::head`. + /// + /// Returns `(block_root, block_slot)`. + pub fn heads(&self) -> Vec<(Hash256, Slot)> { + self.head_tracker.heads() + } + /// Returns the `BeaconState` at the given slot. /// - /// Returns `None` when the state is not found in the database or there is an error skipping - /// to a future state. + /// Returns `None` when the state is not found in the database or there is an error skipping + /// to a future state. pub fn state_at_slot(&self, slot: Slot) -> Result, Error> { let head_state = self.head().beacon_state; diff --git a/beacon_node/rest_api/src/beacon.rs b/beacon_node/rest_api/src/beacon.rs index 9621dce459..a73ade89b6 100644 --- a/beacon_node/rest_api/src/beacon.rs +++ b/beacon_node/rest_api/src/beacon.rs @@ -56,6 +56,29 @@ pub fn get_head( ResponseBuilder::new(&req)?.body(&head) } +#[derive(Serialize, Deserialize, Encode)] +pub struct HeadBeaconBlock { + beacon_block_root: Hash256, + beacon_block_slot: Slot, +} + +/// HTTP handler to return a list of head BeaconBlocks. +pub fn get_heads( + req: Request, + beacon_chain: Arc>, +) -> ApiResult { + let heads = beacon_chain + .heads() + .into_iter() + .map(|(beacon_block_root, beacon_block_slot)| HeadBeaconBlock { + beacon_block_root, + beacon_block_slot, + }) + .collect::>(); + + ResponseBuilder::new(&req)?.body(&heads) +} + #[derive(Serialize, Encode)] #[serde(bound = "T: EthSpec")] pub struct BlockResponse { diff --git a/beacon_node/rest_api/src/router.rs b/beacon_node/rest_api/src/router.rs index ada832f089..03cc35f959 100644 --- a/beacon_node/rest_api/src/router.rs +++ b/beacon_node/rest_api/src/router.rs @@ -64,6 +64,9 @@ pub fn route( // Methods for Beacon Node (&Method::GET, "/beacon/head") => into_boxfut(beacon::get_head::(req, beacon_chain)), + (&Method::GET, "/beacon/heads") => { + into_boxfut(beacon::get_heads::(req, beacon_chain)) + } (&Method::GET, "/beacon/block") => { into_boxfut(beacon::get_block::(req, beacon_chain)) }