Skip to content

Commit 7534f57

Browse files
authored
Add pending_consolidations Beacon API endpoint (#7290)
#7282 Adds the missing `beacon/states/{state_id}/pending_consolidations` Beacon API endpoint along with related tests.
1 parent ec64384 commit 7534f57

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

beacon_node/http_api/src/lib.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,39 @@ pub fn serve<T: BeaconChainTypes>(
11861186
},
11871187
);
11881188

1189+
// GET beacon/states/{state_id}/pending_consolidations
1190+
let get_beacon_state_pending_consolidations = beacon_states_path
1191+
.clone()
1192+
.and(warp::path("pending_consolidations"))
1193+
.and(warp::path::end())
1194+
.then(
1195+
|state_id: StateId,
1196+
task_spawner: TaskSpawner<T::EthSpec>,
1197+
chain: Arc<BeaconChain<T>>| {
1198+
task_spawner.blocking_json_task(Priority::P1, move || {
1199+
let (data, execution_optimistic, finalized) = state_id
1200+
.map_state_and_execution_optimistic_and_finalized(
1201+
&chain,
1202+
|state, execution_optimistic, finalized| {
1203+
let Ok(consolidations) = state.pending_consolidations() else {
1204+
return Err(warp_utils::reject::custom_bad_request(
1205+
"Pending consolidations not found".to_string(),
1206+
));
1207+
};
1208+
1209+
Ok((consolidations.clone(), execution_optimistic, finalized))
1210+
},
1211+
)?;
1212+
1213+
Ok(api_types::ExecutionOptimisticFinalizedResponse {
1214+
data,
1215+
execution_optimistic: Some(execution_optimistic),
1216+
finalized: Some(finalized),
1217+
})
1218+
})
1219+
},
1220+
);
1221+
11891222
// GET beacon/headers
11901223
//
11911224
// Note: this endpoint only returns information about blocks in the canonical chain. Given that
@@ -4853,6 +4886,7 @@ pub fn serve<T: BeaconChainTypes>(
48534886
.uor(get_beacon_state_randao)
48544887
.uor(get_beacon_state_pending_deposits)
48554888
.uor(get_beacon_state_pending_partial_withdrawals)
4889+
.uor(get_beacon_state_pending_consolidations)
48564890
.uor(get_beacon_headers)
48574891
.uor(get_beacon_headers_block_id)
48584892
.uor(get_beacon_block)

beacon_node/http_api/tests/tests.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,33 @@ impl ApiTester {
12461246
self
12471247
}
12481248

1249+
pub async fn test_beacon_states_pending_consolidations(self) -> Self {
1250+
for state_id in self.interesting_state_ids() {
1251+
let mut state_opt = state_id
1252+
.state(&self.chain)
1253+
.ok()
1254+
.map(|(state, _execution_optimistic, _finalized)| state);
1255+
1256+
let result = self
1257+
.client
1258+
.get_beacon_states_pending_consolidations(state_id.0)
1259+
.await
1260+
.unwrap()
1261+
.map(|res| res.data);
1262+
1263+
if result.is_none() && state_opt.is_none() {
1264+
continue;
1265+
}
1266+
1267+
let state = state_opt.as_mut().expect("result should be none");
1268+
let expected = state.pending_consolidations().unwrap();
1269+
1270+
assert_eq!(result.unwrap(), expected.to_vec());
1271+
}
1272+
1273+
self
1274+
}
1275+
12491276
pub async fn test_beacon_headers_all_slots(self) -> Self {
12501277
for slot in 0..CHAIN_LENGTH {
12511278
let slot = Slot::from(slot);
@@ -6404,6 +6431,8 @@ async fn beacon_get_state_info_electra() {
64046431
.test_beacon_states_pending_deposits()
64056432
.await
64066433
.test_beacon_states_pending_partial_withdrawals()
6434+
.await
6435+
.test_beacon_states_pending_consolidations()
64076436
.await;
64086437
}
64096438

common/eth2/src/lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,26 @@ impl BeaconNodeHttpClient {
821821
self.get_opt(path).await
822822
}
823823

824+
/// `GET beacon/states/{state_id}/pending_consolidations`
825+
///
826+
/// Returns `Ok(None)` on a 404 error.
827+
pub async fn get_beacon_states_pending_consolidations(
828+
&self,
829+
state_id: StateId,
830+
) -> Result<Option<ExecutionOptimisticFinalizedResponse<Vec<PendingConsolidation>>>, Error>
831+
{
832+
let mut path = self.eth_path(V1)?;
833+
834+
path.path_segments_mut()
835+
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
836+
.push("beacon")
837+
.push("states")
838+
.push(&state_id.to_string())
839+
.push("pending_consolidations");
840+
841+
self.get_opt(path).await
842+
}
843+
824844
/// `GET beacon/light_client/updates`
825845
///
826846
/// Returns `Ok(None)` on a 404 error.

0 commit comments

Comments
 (0)