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:
Michael Sproul
2022-01-27 01:06:02 +00:00
parent 013a3cc3e0
commit e70daaa3b6
14 changed files with 366 additions and 16 deletions

View File

@@ -9,6 +9,7 @@
#[cfg(feature = "lighthouse")]
pub mod lighthouse;
#[cfg(feature = "lighthouse")]
pub mod lighthouse_vc;
pub mod mixin;
pub mod types;
@@ -245,6 +246,7 @@ impl BeaconNodeHttpClient {
}
/// Perform a HTTP POST request, returning a JSON response.
#[cfg(feature = "lighthouse")]
async fn post_with_response<T: Serialize, U: IntoUrl, R: DeserializeOwned>(
&self,
url: U,

View File

@@ -1,5 +1,7 @@
//! This module contains endpoints that are non-standard and only available on Lighthouse servers.
mod block_rewards;
use crate::{
ok_or_error,
types::{BeaconState, ChainSpec, Epoch, EthSpec, GenericResponse, ValidatorId},
@@ -12,6 +14,7 @@ use ssz::four_byte_option_impl;
use ssz_derive::{Decode, Encode};
use store::{AnchorInfo, Split};
pub use block_rewards::{AttestationRewards, BlockReward, BlockRewardMeta, BlockRewardsQuery};
pub use lighthouse_network::{types::SyncState, PeerInfo};
// Define "legacy" implementations of `Option<T>` which use four bytes for encoding the union

View File

@@ -0,0 +1,54 @@
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use types::{Hash256, Slot};
/// Details about the rewards paid to a block proposer for proposing a block.
///
/// All rewards in GWei.
///
/// Presently this only counts attestation rewards, but in future should be expanded
/// to include information on slashings and sync committee aggregates too.
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct BlockReward {
/// Sum of all reward components.
pub total: u64,
/// Block root of the block that these rewards are for.
pub block_root: Hash256,
/// Metadata about the block, particularly reward-relevant metadata.
pub meta: BlockRewardMeta,
/// Rewards due to attestations.
pub attestation_rewards: AttestationRewards,
/// Sum of rewards due to sync committee signatures.
pub sync_committee_rewards: u64,
}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct BlockRewardMeta {
pub slot: Slot,
pub parent_slot: Slot,
pub proposer_index: u64,
pub graffiti: String,
}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct AttestationRewards {
/// Total block reward from attestations included.
pub total: u64,
/// Total rewards from previous epoch attestations.
pub prev_epoch_total: u64,
/// Total rewards from current epoch attestations.
pub curr_epoch_total: u64,
/// Vec of attestation rewards for each attestation included.
///
/// Each element of the vec is a map from validator index to reward.
pub per_attestation_rewards: Vec<HashMap<u64, u64>>,
}
/// Query parameters for the `/lighthouse/block_rewards` endpoint.
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct BlockRewardsQuery {
/// Lower slot limit for block rewards returned (inclusive).
pub start_slot: Slot,
/// Upper slot limit for block rewards returned (inclusive).
pub end_slot: Slot,
}

View File

@@ -10,6 +10,9 @@ use std::str::{from_utf8, FromStr};
use std::time::Duration;
pub use types::*;
#[cfg(feature = "lighthouse")]
use crate::lighthouse::BlockReward;
/// An API error serializable to JSON.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
@@ -839,6 +842,8 @@ pub enum EventKind<T: EthSpec> {
ChainReorg(SseChainReorg),
ContributionAndProof(Box<SignedContributionAndProof<T>>),
LateHead(SseLateHead),
#[cfg(feature = "lighthouse")]
BlockReward(BlockReward),
}
impl<T: EthSpec> EventKind<T> {
@@ -852,6 +857,8 @@ impl<T: EthSpec> EventKind<T> {
EventKind::ChainReorg(_) => "chain_reorg",
EventKind::ContributionAndProof(_) => "contribution_and_proof",
EventKind::LateHead(_) => "late_head",
#[cfg(feature = "lighthouse")]
EventKind::BlockReward(_) => "block_reward",
}
}
@@ -904,6 +911,10 @@ impl<T: EthSpec> EventKind<T> {
ServerError::InvalidServerSentEvent(format!("Contribution and Proof: {:?}", e))
})?,
))),
#[cfg(feature = "lighthouse")]
"block_reward" => Ok(EventKind::BlockReward(serde_json::from_str(data).map_err(
|e| ServerError::InvalidServerSentEvent(format!("Block Reward: {:?}", e)),
)?)),
_ => Err(ServerError::InvalidServerSentEvent(
"Could not parse event tag".to_string(),
)),
@@ -929,6 +940,8 @@ pub enum EventTopic {
ChainReorg,
ContributionAndProof,
LateHead,
#[cfg(feature = "lighthouse")]
BlockReward,
}
impl FromStr for EventTopic {
@@ -944,6 +957,8 @@ impl FromStr for EventTopic {
"chain_reorg" => Ok(EventTopic::ChainReorg),
"contribution_and_proof" => Ok(EventTopic::ContributionAndProof),
"late_head" => Ok(EventTopic::LateHead),
#[cfg(feature = "lighthouse")]
"block_reward" => Ok(EventTopic::BlockReward),
_ => Err("event topic cannot be parsed.".to_string()),
}
}
@@ -960,6 +975,8 @@ impl fmt::Display for EventTopic {
EventTopic::ChainReorg => write!(f, "chain_reorg"),
EventTopic::ContributionAndProof => write!(f, "contribution_and_proof"),
EventTopic::LateHead => write!(f, "late_head"),
#[cfg(feature = "lighthouse")]
EventTopic::BlockReward => write!(f, "block_reward"),
}
}
}