Skip to content

Commit

Permalink
add api logic
Browse files Browse the repository at this point in the history
  • Loading branch information
eserilev committed Aug 16, 2023
1 parent 5d984f0 commit 48661b4
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 11 deletions.
13 changes: 7 additions & 6 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,12 +452,11 @@ pub struct BeaconChain<T: BeaconChainTypes> {
}

pub enum BeaconBlockAndStateResponse<T: EthSpec> {
Full((BeaconBlock<T, FullPayload<T>>, BeaconState<T>)),
Blinded((BeaconBlock<T, BlindedPayload<T>>, BeaconState<T>)),
BeaconBlockError(),
Full(BeaconBlockAndState<T, FullPayload<T>>),
Blinded(BeaconBlockAndState<T, BlindedPayload<T>>),
}

type BeaconBlockAndState<T, Payload> = (BeaconBlock<T, Payload>, BeaconState<T>);
pub type BeaconBlockAndState<T, Payload> = (BeaconBlock<T, Payload>, BeaconState<T>);

impl FinalizationAndCanonicity {
pub fn is_finalized(self) -> bool {
Expand Down Expand Up @@ -4344,7 +4343,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
match block_contents_type {
BlockProposalContentsType::Full(block_contents) => {
let chain = self.clone();
let beacon_block_and_state = self.task_executor
let beacon_block_and_state = self
.task_executor
.spawn_blocking_handle(
move || {
chain.complete_partial_beacon_block_v3(
Expand All @@ -4363,7 +4363,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}
BlockProposalContentsType::Blinded(block_contents) => {
let chain = self.clone();
let beacon_block_and_state = self.task_executor
let beacon_block_and_state = self
.task_executor
.spawn_blocking_handle(
move || {
chain.complete_partial_beacon_block_v3(
Expand Down
7 changes: 4 additions & 3 deletions beacon_node/beacon_chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ pub mod validator_monitor;
pub mod validator_pubkey_cache;

pub use self::beacon_chain::{
AttestationProcessingOutcome, BeaconChain, BeaconChainTypes, BeaconStore, ChainSegmentResult,
ForkChoiceError, OverrideForkchoiceUpdate, ProduceBlockVerification, StateSkipConfig,
WhenSlotSkipped, INVALID_FINALIZED_MERGE_TRANSITION_BLOCK_SHUTDOWN_REASON,
AttestationProcessingOutcome, BeaconBlockAndStateResponse, BeaconChain, BeaconChainTypes,
BeaconStore, ChainSegmentResult, ForkChoiceError, OverrideForkchoiceUpdate,
ProduceBlockVerification, StateSkipConfig, WhenSlotSkipped,
INVALID_FINALIZED_MERGE_TRANSITION_BLOCK_SHUTDOWN_REASON,
INVALID_JUSTIFIED_PAYLOAD_SHUTDOWN_REASON,
};
pub use self::beacon_snapshot::BeaconSnapshot;
Expand Down
147 changes: 146 additions & 1 deletion beacon_node/http_api/src/validator.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes};
use types::*;

use std::sync::Arc;

use beacon_chain::{
BeaconBlockAndStateResponse, BeaconChain, BeaconChainError, BeaconChainTypes,
ProduceBlockVerification,
};
use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification};
use ssz::Encode;
use types::*;
use warp::{
hyper::{Body, Response},
Reply,
};

use crate::version::{
add_consensus_version_header, add_execution_payload_blinded_header,
add_execution_payload_value_header, fork_versioned_response, inconsistent_fork_rejection,
};
/// Uses the `chain.validator_pubkey_cache` to resolve a pubkey to a validator
/// index and then ensures that the validator exists in the given `state`.
pub fn pubkey_to_validator_index<T: BeaconChainTypes>(
Expand All @@ -19,3 +36,131 @@ pub fn pubkey_to_validator_index<T: BeaconChainTypes>(
.map(Result::Ok)
.transpose()
}

pub fn get_randao_verification(
query: &api_types::ValidatorBlocksQuery,
randao_reveal_infinity: bool,
) -> Result<ProduceBlockVerification, warp::Rejection> {
let randao_verification = if query.skip_randao_verification == SkipRandaoVerification::Yes {
if !randao_reveal_infinity {
return Err(warp_utils::reject::custom_bad_request(
"randao_reveal must be point-at-infinity if verification is skipped".into(),
));
}
ProduceBlockVerification::NoVerification
} else {
ProduceBlockVerification::VerifyRandao
};

Ok(randao_verification)
}

pub async fn determine_and_produce_block_json<T: BeaconChainTypes>(
endpoint_version: EndpointVersion,
chain: Arc<BeaconChain<T>>,
slot: Slot,
query: api_types::ValidatorBlocksQuery,
) -> Result<Response<Body>, warp::Rejection> {
let randao_reveal = query.randao_reveal.decompress().map_err(|e| {
warp_utils::reject::custom_bad_request(format!(
"randao reveal is not a valid BLS signature: {:?}",
e
))
})?;

let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?;

match chain
.determine_and_produce_block_with_verification(
randao_reveal,
slot,
query.graffiti.map(Into::into),
randao_verification,
)
.await
.unwrap()
{
BeaconBlockAndStateResponse::Full((block, state)) => {
let fork_name = block
.to_ref()
.fork_name(&chain.spec)
.map_err(inconsistent_fork_rejection)?;

fork_versioned_response(endpoint_version, fork_name, block)
.map(|response| warp::reply::json(&response).into_response())
.map(|res| add_consensus_version_header(res, fork_name))
.map(|res| add_execution_payload_blinded_header(res, true))
.map(|res: Response<Body>| add_execution_payload_value_header(res, 0))
// TODO
}
BeaconBlockAndStateResponse::Blinded((block, state)) => {
let fork_name = block
.to_ref()
.fork_name(&chain.spec)
.map_err(inconsistent_fork_rejection)?;

fork_versioned_response(endpoint_version, fork_name, block)
.map(|response| warp::reply::json(&response).into_response())
.map(|res| add_consensus_version_header(res, fork_name))
.map(|res| add_execution_payload_blinded_header(res, true))
.map(|res: Response<Body>| add_execution_payload_value_header(res, 0))
// TODO
}
}
}

pub async fn determine_and_produce_block_ssz<T: BeaconChainTypes>(
endpoint_version: EndpointVersion,
chain: Arc<BeaconChain<T>>,
slot: Slot,
query: api_types::ValidatorBlocksQuery,
) -> Result<Response<Body>, warp::Rejection> {
let randao_reveal = query.randao_reveal.decompress().map_err(|e| {
warp_utils::reject::custom_bad_request(format!(
"randao reveal is not a valid BLS signature: {:?}",
e
))
})?;

let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?;

// TODO: block value
let (block_ssz, fork_name, block_value) = match chain
.determine_and_produce_block_with_verification(
randao_reveal,
slot,
query.graffiti.map(Into::into),
randao_verification,
)
.await
.unwrap()
{
BeaconBlockAndStateResponse::Full((block, state)) => {
let fork_name = block
.to_ref()
.fork_name(&chain.spec)
.map_err(inconsistent_fork_rejection)?;

(block.as_ssz_bytes(), fork_name, 0)
}
BeaconBlockAndStateResponse::Blinded((block, state)) => {
let fork_name = block
.to_ref()
.fork_name(&chain.spec)
.map_err(inconsistent_fork_rejection)?;

(block.as_ssz_bytes(), fork_name, 0)
}
};

Response::builder()
.status(200)
.header("Content-Type", "application/ssz")
.body(block_ssz.into())
.map(|res: Response<Body>| add_consensus_version_header(res, fork_name))
.map(|res| add_execution_payload_blinded_header(res, blinded))
.map(|res: Response<Body>| add_execution_payload_value_header(res, block_value))
.map_err(|e| -> warp::Rejection {
warp_utils::reject::custom_server_error(format!("failed to create response: {}", e))
})
}
30 changes: 29 additions & 1 deletion beacon_node/http_api/src/version.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::api_types::fork_versioned_response::ExecutionOptimisticFinalizedForkVersionedResponse;
use crate::api_types::EndpointVersion;
use eth2::CONSENSUS_VERSION_HEADER;
use eth2::{
CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER, EXECUTION_PAYLOAD_VALUE_HEADER,
};
use serde::Serialize;
use types::{ForkName, ForkVersionedResponse, InconsistentFork};
use warp::reply::{self, Reply, Response};
Expand Down Expand Up @@ -53,6 +55,32 @@ pub fn add_consensus_version_header<T: Reply>(reply: T, fork_name: ForkName) ->
reply::with_header(reply, CONSENSUS_VERSION_HEADER, fork_name.to_string()).into_response()
}

/// Add the `Eth-Execution-Payload-Blinded` header to a response.
pub fn add_execution_payload_blinded_header<T: Reply>(
reply: T,
execution_payload_blinded: bool,
) -> Response {
reply::with_header(
reply,
EXECUTION_PAYLOAD_BLINDED_HEADER,
execution_payload_blinded.to_string(),
)
.into_response()
}

/// Add the `Eth-Execution-Payload-Value` header to a response.
pub fn add_execution_payload_value_header<T: Reply>(
reply: T,
execution_payload_value: u32,
) -> Response {
reply::with_header(
reply,
EXECUTION_PAYLOAD_VALUE_HEADER,
execution_payload_value.to_string(),
)
.into_response()
}

pub fn inconsistent_fork_rejection(error: InconsistentFork) -> warp::reject::Rejection {
warp_utils::reject::custom_server_error(format!("wrong fork: {:?}", error))
}
Expand Down
2 changes: 2 additions & 0 deletions common/eth2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub const V1: EndpointVersion = EndpointVersion(1);
pub const V2: EndpointVersion = EndpointVersion(2);

pub const CONSENSUS_VERSION_HEADER: &str = "Eth-Consensus-Version";
pub const EXECUTION_PAYLOAD_BLINDED_HEADER: &str = "Eth-Execution-Payload-Blinded";
pub const EXECUTION_PAYLOAD_VALUE_HEADER: &str = "Eth-Execution-Payload-Value";

#[derive(Debug)]
pub enum Error {
Expand Down

0 comments on commit 48661b4

Please sign in to comment.