mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 11:41:51 +00:00
Implement API for block rewards (#2628)
## Proposed Changes Add an API endpoint for retrieving detailed information about block rewards. For information on usage see [the docs](https://github.com/sigp/lighthouse/blob/block-rewards-api/book/src/api-lighthouse.md#lighthouseblock_rewards), and the source.
This commit is contained in:
80
beacon_node/http_api/src/block_rewards.rs
Normal file
80
beacon_node/http_api/src/block_rewards.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes, WhenSlotSkipped};
|
||||
use eth2::lighthouse::{BlockReward, BlockRewardsQuery};
|
||||
use slog::{warn, Logger};
|
||||
use state_processing::BlockReplayer;
|
||||
use std::sync::Arc;
|
||||
use warp_utils::reject::{beacon_chain_error, beacon_state_error, custom_bad_request};
|
||||
|
||||
pub fn get_block_rewards<T: BeaconChainTypes>(
|
||||
query: BlockRewardsQuery,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
log: Logger,
|
||||
) -> Result<Vec<BlockReward>, warp::Rejection> {
|
||||
let start_slot = query.start_slot;
|
||||
let end_slot = query.end_slot;
|
||||
let prior_slot = start_slot - 1;
|
||||
|
||||
if start_slot > end_slot || start_slot == 0 {
|
||||
return Err(custom_bad_request(format!(
|
||||
"invalid start and end: {}, {}",
|
||||
start_slot, end_slot
|
||||
)));
|
||||
}
|
||||
|
||||
let end_block_root = chain
|
||||
.block_root_at_slot(end_slot, WhenSlotSkipped::Prev)
|
||||
.map_err(beacon_chain_error)?
|
||||
.ok_or_else(|| custom_bad_request(format!("block at end slot {} unknown", end_slot)))?;
|
||||
|
||||
let blocks = chain
|
||||
.store
|
||||
.load_blocks_to_replay(start_slot, end_slot, end_block_root)
|
||||
.map_err(|e| beacon_chain_error(e.into()))?;
|
||||
|
||||
let state_root = chain
|
||||
.state_root_at_slot(prior_slot)
|
||||
.map_err(beacon_chain_error)?
|
||||
.ok_or_else(|| custom_bad_request(format!("prior state at slot {} unknown", prior_slot)))?;
|
||||
|
||||
let mut state = chain
|
||||
.get_state(&state_root, Some(prior_slot))
|
||||
.and_then(|maybe_state| maybe_state.ok_or(BeaconChainError::MissingBeaconState(state_root)))
|
||||
.map_err(beacon_chain_error)?;
|
||||
|
||||
state
|
||||
.build_all_caches(&chain.spec)
|
||||
.map_err(beacon_state_error)?;
|
||||
|
||||
let mut block_rewards = Vec::with_capacity(blocks.len());
|
||||
|
||||
let block_replayer = BlockReplayer::new(state, &chain.spec)
|
||||
.pre_block_hook(Box::new(|state, block| {
|
||||
// Compute block reward.
|
||||
let block_reward =
|
||||
chain.compute_block_reward(block.message(), block.canonical_root(), state)?;
|
||||
block_rewards.push(block_reward);
|
||||
Ok(())
|
||||
}))
|
||||
.state_root_iter(
|
||||
chain
|
||||
.forwards_iter_state_roots_until(prior_slot, end_slot)
|
||||
.map_err(beacon_chain_error)?,
|
||||
)
|
||||
.no_signature_verification()
|
||||
.minimal_block_root_verification()
|
||||
.apply_blocks(blocks, None)
|
||||
.map_err(beacon_chain_error)?;
|
||||
|
||||
if block_replayer.state_root_miss() {
|
||||
warn!(
|
||||
log,
|
||||
"Block reward state root miss";
|
||||
"start_slot" => start_slot,
|
||||
"end_slot" => end_slot,
|
||||
);
|
||||
}
|
||||
|
||||
drop(block_replayer);
|
||||
|
||||
Ok(block_rewards)
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
mod attester_duties;
|
||||
mod block_id;
|
||||
mod block_rewards;
|
||||
mod database;
|
||||
mod metrics;
|
||||
mod proposer_duties;
|
||||
@@ -2540,6 +2541,16 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
},
|
||||
);
|
||||
|
||||
let get_lighthouse_block_rewards = warp::path("lighthouse")
|
||||
.and(warp::path("block_rewards"))
|
||||
.and(warp::query::<eth2::lighthouse::BlockRewardsQuery>())
|
||||
.and(warp::path::end())
|
||||
.and(chain_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.and_then(|query, chain, log| {
|
||||
blocking_json_task(move || block_rewards::get_block_rewards(query, chain, log))
|
||||
});
|
||||
|
||||
let get_events = eth1_v1
|
||||
.and(warp::path("events"))
|
||||
.and(warp::path::end())
|
||||
@@ -2576,6 +2587,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
api_types::EventTopic::LateHead => {
|
||||
event_handler.subscribe_late_head()
|
||||
}
|
||||
api_types::EventTopic::BlockReward => {
|
||||
event_handler.subscribe_block_reward()
|
||||
}
|
||||
};
|
||||
|
||||
receivers.push(BroadcastStream::new(receiver).map(|msg| {
|
||||
@@ -2661,6 +2675,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.or(get_lighthouse_beacon_states_ssz.boxed())
|
||||
.or(get_lighthouse_staking.boxed())
|
||||
.or(get_lighthouse_database_info.boxed())
|
||||
.or(get_lighthouse_block_rewards.boxed())
|
||||
.or(get_events.boxed()),
|
||||
)
|
||||
.or(warp::post().and(
|
||||
|
||||
Reference in New Issue
Block a user