Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 23 additions & 1 deletion crates/common/operation_pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,15 @@ impl OperationPool {
self.attester_slashings.read().iter().cloned().collect()
}

pub fn get_all_proposer_slahsings(&self) -> Vec<ProposerSlashing> {
pub fn get_all_proposer_slashings(&self) -> Vec<ProposerSlashing> {
self.proposer_slashings.read().iter().cloned().collect()
}

#[deprecated(note = "use `get_all_proposer_slashings` instead")]
pub fn get_all_proposer_slahsings(&self) -> Vec<ProposerSlashing> {
self.get_all_proposer_slashings()
}

pub fn insert_proposer_slashing(&self, slashing: ProposerSlashing) {
self.proposer_slashings.write().insert(slashing);
}
Expand Down Expand Up @@ -407,4 +412,21 @@ mod tests {
operation_pool.clean_proposer_preparations(103);
assert_eq!(operation_pool.get_proposer_preparation(1), None);
}

#[test]
#[allow(deprecated)]
fn test_proposer_slashings_retrieval() {
let operation_pool = OperationPool::default();
let slashing = ProposerSlashing {
signed_header_1: Default::default(),
signed_header_2: Default::default(),
};
operation_pool.insert_proposer_slashing(slashing.clone());

assert_eq!(
operation_pool.get_all_proposer_slashings(),
vec![slashing.clone()]
);
assert_eq!(operation_pool.get_all_proposer_slahsings(), vec![slashing]);
}
}
3 changes: 3 additions & 0 deletions crates/rpc/beacon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,8 @@ ream-storage.workspace = true
ream-sync-committee-pool.workspace = true
ream-validator-beacon.workspace = true

[dev-dependencies]
tempfile.workspace = true

[lints]
workspace = true
5 changes: 3 additions & 2 deletions crates/rpc/beacon/src/handlers/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,9 @@ pub async fn post_sync_committee_rewards(
Ok(HttpResponse::Ok().json(BeaconResponse::new(reward_data)))
}

#[get("/beacon/blind_block/{block_id}")]
pub async fn get_blind_block(
/// GET /eth/v1/beacon/blinded_blocks/{block_id}
#[get("/beacon/blinded_blocks/{block_id}")]
pub async fn get_blinded_block(
http_request: HttpRequest,
db: Data<BeaconDB>,
block_id: Path<ID>,
Expand Down
6 changes: 3 additions & 3 deletions crates/rpc/beacon/src/handlers/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,13 @@ pub async fn post_attester_slashings(
Ok(HttpResponse::Ok())
}

/// GET /eth/v2/beacon/pool/proposer_slashings
#[get("/beacon/pool/prposer_slashings")]
/// GET /eth/v1/beacon/pool/proposer_slashings
#[get("/beacon/pool/proposer_slashings")]
pub async fn get_proposer_slashings(
operation_pool: Data<Arc<OperationPool>>,
) -> Result<impl Responder, ApiError> {
Ok(HttpResponse::Ok().json(DataVersionedResponse::new(
operation_pool.get_all_proposer_slahsings(),
operation_pool.get_all_proposer_slashings(),
)))
}

Expand Down
4 changes: 2 additions & 2 deletions crates/rpc/beacon/src/handlers/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ pub async fn get_attestation_data(
/// For the initial stage, this endpoint returns a 501 as DVT support is not planned.
#[post("/validator/sync_committee_selections")]
pub async fn post_sync_committee_selections(
_selections: Json<SyncCommitteeSelection>,
_selections: Json<Vec<SyncCommitteeSelection>>,
) -> Result<impl Responder, ApiError> {
Ok(HttpResponse::NotImplemented())
}
Expand Down Expand Up @@ -1518,7 +1518,7 @@ pub async fn get_blocks_v3(
.await?;

let proposer_slashings: VariableList<ProposerSlashing, U16> = operation_pool
.get_all_proposer_slahsings()
.get_all_proposer_slashings()
.try_into()
.unwrap_or_default();
let attester_slashings: VariableList<AttesterSlashing, U1> = operation_pool
Expand Down
3 changes: 3 additions & 0 deletions crates/rpc/beacon/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
pub mod handlers;
pub mod routes;
pub mod server;

#[cfg(test)]
mod tests;
4 changes: 2 additions & 2 deletions crates/rpc/beacon/src/routes/beacon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::handlers::{
attestation::post_attestation_rewards,
blob_sidecar::get_blob_sidecars,
block::{
get_blind_block, get_block_attestations, get_block_from_id, get_block_rewards,
get_blinded_block, get_block_attestations, get_block_from_id, get_block_rewards,
get_block_root, get_genesis, post_beacon_block, post_blinded_beacon_block,
post_sync_committee_rewards,
},
Expand Down Expand Up @@ -67,7 +67,7 @@ pub fn register_beacon_routes(cfg: &mut ServiceConfig) {
.service(get_light_client_updates)
.service(get_light_client_finality_update)
.service(get_light_client_optimistic_update)
.service(get_blind_block)
.service(get_blinded_block)
.service(post_validator_liveness)
.service(get_proposer_slashings)
.service(post_proposer_slashings)
Expand Down
4 changes: 3 additions & 1 deletion crates/rpc/beacon/src/routes/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use crate::handlers::{
get_aggregate_attestation, get_attestation_data, get_blocks_v3,
get_sync_committee_contribution, post_aggregate_and_proofs_v2,
post_beacon_committee_selections, post_beacon_committee_subscriptions,
post_contribution_and_proofs, post_register_validator, post_sync_committee_subscriptions,
post_contribution_and_proofs, post_register_validator, post_sync_committee_selections,
post_sync_committee_subscriptions,
},
};

Expand All @@ -18,6 +19,7 @@ pub fn register_validator_routes_v1(config: &mut ServiceConfig) {
config.service(prepare_beacon_proposer);
config.service(get_attestation_data);
config.service(post_beacon_committee_selections);
config.service(post_sync_committee_selections);
config.service(get_sync_committee_contribution);
config.service(post_beacon_committee_subscriptions);
config.service(post_sync_committee_subscriptions);
Expand Down
77 changes: 77 additions & 0 deletions crates/rpc/beacon/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::sync::Arc;

use actix_web::{App, http::StatusCode, test, web::Data};
use ream_operation_pool::OperationPool;
use ream_storage::db::ReamDB;
use serde_json::json;

use crate::routes::register_routers;

#[actix_web::test]
async fn test_get_proposer_slashings_route_spec_compliance() {
let operation_pool = Arc::new(OperationPool::default());
let app = test::init_service(
App::new()
.app_data(Data::new(operation_pool))
.configure(register_routers),
)
.await;

// Spec-compliant route: GET /eth/v1/beacon/pool/proposer_slashings
let req = test::TestRequest::get()
.uri("/eth/v1/beacon/pool/proposer_slashings")
.to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.status(), StatusCode::OK);

// Old typo route should no longer be present
let req_typo = test::TestRequest::get()
.uri("/eth/v1/beacon/pool/prposer_slashings")
.to_request();
let resp_typo = test::call_service(&app, req_typo).await;
assert_eq!(resp_typo.status(), StatusCode::NOT_FOUND);
}

#[actix_web::test]
async fn test_post_sync_committee_selections_registered_and_vector_payload() {
let app = test::init_service(App::new().configure(register_routers)).await;

// Spec-compliant route: POST /eth/v1/validator/sync_committee_selections
// Takes a list of SyncCommitteeSelection and returns 501 Not Implemented (DVT not yet
// supported)
let req = test::TestRequest::post()
.uri("/eth/v1/validator/sync_committee_selections")
.set_json(json!([]))
.to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.status(), StatusCode::NOT_IMPLEMENTED);
}

#[actix_web::test]
async fn test_get_blinded_blocks_route_spec_compliance() {
let temp_dir = tempfile::tempdir().expect("failed to create temp dir");
let ream_db = ReamDB::new(temp_dir.path().to_path_buf()).expect("failed to init ream db");
let db = ream_db.init_beacon_db().expect("failed to init beacon db");

let app = test::init_service(
App::new()
.app_data(Data::new(db))
.configure(register_routers),
)
.await;

// Spec-compliant route: GET /eth/v1/beacon/blinded_blocks/{block_id}
let req = test::TestRequest::get()
.uri("/eth/v1/beacon/blinded_blocks/head")
.to_request();
let resp = test::call_service(&app, req).await;
// The route matches and reaches the handler (which returns 404 block not found for empty db)
assert_eq!(resp.status(), StatusCode::NOT_FOUND);

// Old non-spec route: /eth/v1/beacon/blind_block/{block_id} should not be registered
let req_old = test::TestRequest::get()
.uri("/eth/v1/beacon/blind_block/head")
.to_request();
let resp_old = test::call_service(&app, req_old).await;
assert_eq!(resp_old.status(), StatusCode::NOT_FOUND);
}