Allow HTTP API to return SSZ blocks (#2209)
## Issue Addressed Implements https://github.com/ethereum/eth2.0-APIs/pull/125 ## Proposed Changes Optionally return SSZ bytes from the `beacon/blocks` endpoint.
This commit is contained in:
parent
5bc93869c8
commit
2f077b11fe
@ -872,11 +872,35 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.and(chain_filter.clone());
|
.and(chain_filter.clone());
|
||||||
|
|
||||||
// GET beacon/blocks/{block_id}
|
// GET beacon/blocks/{block_id}
|
||||||
let get_beacon_block = beacon_blocks_path.clone().and(warp::path::end()).and_then(
|
let get_beacon_block = beacon_blocks_path
|
||||||
|block_id: BlockId, chain: Arc<BeaconChain<T>>| {
|
.clone()
|
||||||
blocking_json_task(move || block_id.block(&chain).map(api_types::GenericResponse::from))
|
.and(warp::path::end())
|
||||||
},
|
.and(warp::header::optional::<api_types::Accept>("accept"))
|
||||||
);
|
.and_then(
|
||||||
|
|block_id: BlockId,
|
||||||
|
chain: Arc<BeaconChain<T>>,
|
||||||
|
accept_header: Option<api_types::Accept>| {
|
||||||
|
blocking_task(move || {
|
||||||
|
let block = block_id.block(&chain)?;
|
||||||
|
match accept_header {
|
||||||
|
Some(api_types::Accept::Ssz) => Response::builder()
|
||||||
|
.status(200)
|
||||||
|
.header("Content-Type", "application/octet-stream")
|
||||||
|
.body(block.as_ssz_bytes().into())
|
||||||
|
.map_err(|e| {
|
||||||
|
warp_utils::reject::custom_server_error(format!(
|
||||||
|
"failed to create response: {}",
|
||||||
|
e
|
||||||
|
))
|
||||||
|
}),
|
||||||
|
_ => Ok(
|
||||||
|
warp::reply::json(&api_types::GenericResponseRef::from(&block))
|
||||||
|
.into_response(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// GET beacon/blocks/{block_id}/root
|
// GET beacon/blocks/{block_id}/root
|
||||||
let get_beacon_block_root = beacon_blocks_path
|
let get_beacon_block_root = beacon_blocks_path
|
||||||
|
@ -955,16 +955,18 @@ impl ApiTester {
|
|||||||
|
|
||||||
pub async fn test_beacon_blocks(self) -> Self {
|
pub async fn test_beacon_blocks(self) -> Self {
|
||||||
for block_id in self.interesting_block_ids() {
|
for block_id in self.interesting_block_ids() {
|
||||||
let result = self
|
let expected = self.get_block(block_id);
|
||||||
|
|
||||||
|
let json_result = self
|
||||||
.client
|
.client
|
||||||
.get_beacon_blocks(block_id)
|
.get_beacon_blocks(block_id)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|res| res.data);
|
.map(|res| res.data);
|
||||||
|
assert_eq!(json_result, expected, "{:?}", block_id);
|
||||||
|
|
||||||
let expected = self.get_block(block_id);
|
let ssz_result = self.client.get_beacon_blocks_ssz(block_id).await.unwrap();
|
||||||
|
assert_eq!(ssz_result, expected, "{:?}", block_id);
|
||||||
assert_eq!(result, expected, "{:?}", block_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
|
@ -491,6 +491,27 @@ impl BeaconNodeHttpClient {
|
|||||||
self.get_opt(path).await
|
self.get_opt(path).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `GET beacon/blocks` as SSZ
|
||||||
|
///
|
||||||
|
/// Returns `Ok(None)` on a 404 error.
|
||||||
|
pub async fn get_beacon_blocks_ssz<T: EthSpec>(
|
||||||
|
&self,
|
||||||
|
block_id: BlockId,
|
||||||
|
) -> Result<Option<SignedBeaconBlock<T>>, Error> {
|
||||||
|
let mut path = self.eth_path()?;
|
||||||
|
|
||||||
|
path.path_segments_mut()
|
||||||
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
||||||
|
.push("beacon")
|
||||||
|
.push("blocks")
|
||||||
|
.push(&block_id.to_string());
|
||||||
|
|
||||||
|
self.get_bytes_opt_accept_header(path, Accept::Ssz)
|
||||||
|
.await?
|
||||||
|
.map(|bytes| SignedBeaconBlock::from_ssz_bytes(&bytes).map_err(Error::InvalidSsz))
|
||||||
|
.transpose()
|
||||||
|
}
|
||||||
|
|
||||||
/// `GET beacon/blocks/{block_id}/root`
|
/// `GET beacon/blocks/{block_id}/root`
|
||||||
///
|
///
|
||||||
/// Returns `Ok(None)` on a 404 error.
|
/// Returns `Ok(None)` on a 404 error.
|
||||||
|
Loading…
Reference in New Issue
Block a user