# Dev Update #7 Hi, In my [last update](https://hackmd.io/@lODlsf2CR9uWlyIyEdjjPQ/rkNsMdm8j), our [`beacon-APIs`](https://github.com/ethereum/beacon-APIs) endpoints merged; you can check them out in the [API browser](https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Experimental). Since then, the priority has been on the following three things: - I got [my guide](https://github.com/sigp/lighthouse/pull/3681) merged on how to run a beacon node on Lighthouse. - Worked my way through the [Rust book](https://doc.rust-lang.org/book/) :crab:. - Had the [kickoff meeting](https://hackmd.io/@sproul/consensus-rewards-m1) for the endpoints implementation into Lighthouse, with [NC](https://github.com/naviechan) and [sproul](https://github.com/michaelsproul). We decided to start with the implementation of `sync_committee_rewards`because it is the most straightforward API. The implementation can be roughly divided into the following parts: 1. API handler - `compute_sync_committe_rewards` 2. Load *data* using `chain` from `BeaconChain<T>` 2.1 Load a *block* with `chain.get_blinded_block(block_root)` 2.2 Load a *state* with `chain.get_state(state_root, None)` 2.3 Convert a *slot* into the canonical *block root* from that slot with `block_id.root(&chain)` 3. Compute rewards by calling functions from `consensus/state_processing` Next, we will examine how these three parts could be implemented. The following sections are the first draft and could be changed massively in the next dev updates. ## API handler ```rust pub fn compute_sync_committee_rewards<T: BeaconChainTypes>( chain: &BeaconChain<T>, state: BeaconState<T::EthSpec>, block: SignedBlindedBeaconBlock<T::EthSpec>, ) -> Result<SyncCommitteeRewards, Error> { let get_lighthouse_sync_committee_rewards = warp::path("lighthouse") .and(warp::path("analysis")) .and(warp::path("sync_committee_rewards")) .and(warp::query::<eth2::lighthouse::SyncCommitteeRewardsQuery>()) .and(warp::path::end()) .and(chain_filter.clone()) .and(log_filter.clone()) .and_then(|query, chain, log| { blocking_json_task(move || sync_committee_rewards::get_sync_committee_rewards(query, chain, log)) }); } ``` ## Load data This section consists of three subsections, to load a block, to load a state, and to convert a slot into the canonical block root. ### Load a block ```rust pub fn get_blinded_block( &self, block_root: &Hash256, ) -> Result<Option<SignedBlindedBeaconBlock<T::EthSpec>>, Error> { Ok(self.store.get_blinded_block(block_root)?) } ``` ### Load a slot ```rust pub fn get_state( &self, state_root: &Hash256, slot: Option<Slot>, ) -> Result<Option<BeaconState<T::EthSpec>>, Error> { Ok(self.store.get_state(state_root, slot)?) } ``` ### Convert a slot into the canonical block root ```rust // TBD ``` ## Compute rewards ```rust pub fn compute_sync_aggregate_rewards<T: EthSpec>( state: &BeaconState<T>, spec: &ChainSpec, ) -> Result<(u64, u64), BlockProcessingError> { let total_active_balance = state.get_total_active_balance()?; let total_active_increments = total_active_balance.safe_div(spec.effective_balance_increment)?; let total_base_rewards = BaseRewardPerIncrement::new(total_active_balance, spec)? .as_u64() .safe_mul(total_active_increments)?; let max_participant_rewards = total_base_rewards .safe_mul(SYNC_REWARD_WEIGHT)? .safe_div(WEIGHT_DENOMINATOR)? .safe_div(T::slots_per_epoch())?; let participant_reward = max_participant_rewards.safe_div(T::SyncCommitteeSize::to_u64())?; let proposer_reward = participant_reward .safe_mul(PROPOSER_WEIGHT)? .safe_div(WEIGHT_DENOMINATOR.safe_sub(PROPOSER_WEIGHT)?)?; Ok((participant_reward, proposer_reward)) } ``` ## Next steps `Sync_committee_rewards` includes some back and forth with sproul to fully get the implementation right. Once approved, we can move on to either the `block_rewards`or `attestation_rewards`.