From 039173d1b8f724e6a3db6bd748d1c16813d7ab82 Mon Sep 17 00:00:00 2001 From: navie Date: Thu, 1 Dec 2022 22:46:59 +0800 Subject: [PATCH 01/38] Added sync committee reward api blueprint --- .idea/.gitignore | 3 + .idea/compiler.xml | 6 ++ .idea/libraries/genesis_ssz.xml | 9 +++ .idea/libraries/genesis_ssz1.xml | 9 +++ .idea/libraries/genesis_ssz2.xml | 9 +++ .idea/libraries/genesis_ssz3.xml | 9 +++ .idea/libraries/genesis_ssz4.xml | 9 +++ .idea/libraries/genesis_ssz5.xml | 9 +++ .idea/lighthouse.iml | 118 +++++++++++++++++++++++++++++++ .idea/misc.xml | 6 ++ .idea/modules.xml | 8 +++ .idea/vcs.xml | 6 ++ beacon_node/http_api/src/lib.rs | 26 +++++++ 13 files changed, 227 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/libraries/genesis_ssz.xml create mode 100644 .idea/libraries/genesis_ssz1.xml create mode 100644 .idea/libraries/genesis_ssz2.xml create mode 100644 .idea/libraries/genesis_ssz3.xml create mode 100644 .idea/libraries/genesis_ssz4.xml create mode 100644 .idea/libraries/genesis_ssz5.xml create mode 100644 .idea/lighthouse.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000000..26d33521af1 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000000..2de20b74fda --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz.xml b/.idea/libraries/genesis_ssz.xml new file mode 100644 index 00000000000..2c8b15be86b --- /dev/null +++ b/.idea/libraries/genesis_ssz.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz1.xml b/.idea/libraries/genesis_ssz1.xml new file mode 100644 index 00000000000..9ba84627d56 --- /dev/null +++ b/.idea/libraries/genesis_ssz1.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz2.xml b/.idea/libraries/genesis_ssz2.xml new file mode 100644 index 00000000000..b523d63a4e4 --- /dev/null +++ b/.idea/libraries/genesis_ssz2.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz3.xml b/.idea/libraries/genesis_ssz3.xml new file mode 100644 index 00000000000..c0e7d1d65e9 --- /dev/null +++ b/.idea/libraries/genesis_ssz3.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz4.xml b/.idea/libraries/genesis_ssz4.xml new file mode 100644 index 00000000000..fa115368c1f --- /dev/null +++ b/.idea/libraries/genesis_ssz4.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz5.xml b/.idea/libraries/genesis_ssz5.xml new file mode 100644 index 00000000000..c216b508a11 --- /dev/null +++ b/.idea/libraries/genesis_ssz5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/lighthouse.iml b/.idea/lighthouse.iml new file mode 100644 index 00000000000..c3ecc51ecbf --- /dev/null +++ b/.idea/lighthouse.iml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000000..cc6eae03c93 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000000..dbb00009272 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000000..35eb1ddfbbc --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 7f6852f364b..2ae9f91e4e2 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1698,6 +1698,32 @@ pub fn serve( }, ); + /* + * beacon/rewards + */ + + let beacon_rewards_path = eth_v1 + .and(warp::path("beacon")) + .and(warp::path("rewards")) + .and(chain_filter.clone()); + + // TODO: POST beacon/rewards/sync_committee/{block_id} + let post_beacon_rewards_sync_committee = beacon_rewards_path + .clone() + .and(warp::path("sync_committee")) + .and(block_id_or_err) + .and(warp::path::end()) + .and(warp::body::json()) + .and(log_filter.clone()) + .and_then( + |chain: Arc>, + block_id: BlockId, + validators: Vec, + log: Logger| { + // Do something here + blocking_json_task(move) + }); + /* * config */ From e8ef118b2df69528d6b714717bd8eed30124c017 Mon Sep 17 00:00:00 2001 From: navie Date: Thu, 1 Dec 2022 22:48:53 +0800 Subject: [PATCH 02/38] Added sync committee reward api blueprint --- .idea/.gitignore | 3 - .idea/compiler.xml | 6 -- .idea/libraries/genesis_ssz.xml | 9 --- .idea/libraries/genesis_ssz1.xml | 9 --- .idea/libraries/genesis_ssz2.xml | 9 --- .idea/libraries/genesis_ssz3.xml | 9 --- .idea/libraries/genesis_ssz4.xml | 9 --- .idea/libraries/genesis_ssz5.xml | 9 --- .idea/lighthouse.iml | 118 ------------------------------- .idea/misc.xml | 6 -- .idea/modules.xml | 8 --- .idea/vcs.xml | 6 -- beacon_node/http_api/src/lib.rs | 2 +- 13 files changed, 1 insertion(+), 202 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/libraries/genesis_ssz.xml delete mode 100644 .idea/libraries/genesis_ssz1.xml delete mode 100644 .idea/libraries/genesis_ssz2.xml delete mode 100644 .idea/libraries/genesis_ssz3.xml delete mode 100644 .idea/libraries/genesis_ssz4.xml delete mode 100644 .idea/libraries/genesis_ssz5.xml delete mode 100644 .idea/lighthouse.iml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d33521af1..00000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 2de20b74fda..00000000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz.xml b/.idea/libraries/genesis_ssz.xml deleted file mode 100644 index 2c8b15be86b..00000000000 --- a/.idea/libraries/genesis_ssz.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz1.xml b/.idea/libraries/genesis_ssz1.xml deleted file mode 100644 index 9ba84627d56..00000000000 --- a/.idea/libraries/genesis_ssz1.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz2.xml b/.idea/libraries/genesis_ssz2.xml deleted file mode 100644 index b523d63a4e4..00000000000 --- a/.idea/libraries/genesis_ssz2.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz3.xml b/.idea/libraries/genesis_ssz3.xml deleted file mode 100644 index c0e7d1d65e9..00000000000 --- a/.idea/libraries/genesis_ssz3.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz4.xml b/.idea/libraries/genesis_ssz4.xml deleted file mode 100644 index fa115368c1f..00000000000 --- a/.idea/libraries/genesis_ssz4.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/genesis_ssz5.xml b/.idea/libraries/genesis_ssz5.xml deleted file mode 100644 index c216b508a11..00000000000 --- a/.idea/libraries/genesis_ssz5.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/lighthouse.iml b/.idea/lighthouse.iml deleted file mode 100644 index c3ecc51ecbf..00000000000 --- a/.idea/lighthouse.iml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index cc6eae03c93..00000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index dbb00009272..00000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddfbbc..00000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 2ae9f91e4e2..4f6263e0acf 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1721,7 +1721,7 @@ pub fn serve( validators: Vec, log: Logger| { // Do something here - blocking_json_task(move) + blocking_json_task(move || Ok(true)) }); /* From 5bbdd46272391427a6b4b5f22bb8c295ad455fa5 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 1 Dec 2022 17:30:49 +0100 Subject: [PATCH 03/38] lib.rs modification + add sync_committee_rewards --- beacon_node/http_api/src/lib.rs | 3 + .../http_api/src/sync_committee_rewards.rs | 81 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 beacon_node/http_api/src/sync_committee_rewards.rs diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 4f6263e0acf..67a75fc3803 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -17,6 +17,7 @@ mod proposer_duties; mod publish_blocks; mod state_id; mod sync_committees; +mod sync_committee_rewards; mod validator_inclusion; mod version; @@ -3391,6 +3392,8 @@ pub fn serve( .or(post_beacon_pool_proposer_slashings.boxed()) .or(post_beacon_pool_voluntary_exits.boxed()) .or(post_beacon_pool_sync_committees.boxed()) + //Right place for it? + .or(post_beacon_rewards_sync_committee.boxed()) .or(post_validator_duties_attester.boxed()) .or(post_validator_duties_sync.boxed()) .or(post_validator_aggregate_and_proofs.boxed()) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs new file mode 100644 index 00000000000..54e19787fca --- /dev/null +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -0,0 +1,81 @@ +/* +1. API handler `compute_sync_committe_rewards` +2. Load data using `chain` from `BeaconChain` + 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: block_id.root(&chain) +3. Compute rewards by calling functions from `consensus/state_processing` +*/ + +// ---1--- +// Copy the structure of an existing API handler, e.g. get_lighthouse_block_rewards. +pub fn get_sync_committee_rewards( + chain: &BeaconChain, + state: BeaconState, + block: SignedBlindedBeaconBlock, +) -> Result { + + let get_lighthouse_sync_committee_rewards = warp::path("lighthouse") + .and(warp::path("analysis")) + .and(warp::path("sync_committee_rewards")) + .and(warp::query::()) + .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)) + }); +} + +// ---2--- +// ---2.1--- +// Load a block with chain.get_blinded_block(block_root). +pub fn get_blinded_block( + &self, + block_root: &Hash256, +) -> Result>, Error> { + Ok(self.store.get_blinded_block(block_root)?) +} + +// ---2.2--- +// Load a state with chain.get_state(state_root, None) +pub fn get_state( + &self, + state_root: &Hash256, + slot: Option, +) -> Result>, Error> { + Ok(self.store.get_state(state_root, slot)?) +} + +// ---2.3--- +// Convert a slot into the canonical block root from that slot: block_id.root(&chain). +/* +let canonical = chain + .block_root_at_slot(block.slot(), WhenSlotSkipped::None) + .map_err(warp_utils::reject::beacon_chain_error)? + .map_or(false, |canonical| root == canonical); +*/ + +// ---3--- +// Once we have the block(s) and state that we need, we can compute the rewards using snippets of logic extracted from consensus/state_processing. +// Call this function +pub fn compute_sync_committee_rewards( + state: &BeaconState, + 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)) +} \ No newline at end of file From 09705bd88d69438dc728be699c9a2b8a206ec641 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 1 Dec 2022 17:38:27 +0100 Subject: [PATCH 04/38] change order --- beacon_node/http_api/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 67a75fc3803..87b85efe641 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -16,8 +16,8 @@ mod metrics; mod proposer_duties; mod publish_blocks; mod state_id; -mod sync_committees; mod sync_committee_rewards; +mod sync_committees; mod validator_inclusion; mod version; From 4cc09c6db0088b9dd0c27b952237e77d8e2beee4 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 2 Dec 2022 14:39:01 +0100 Subject: [PATCH 05/38] add types and function to lib.rs --- beacon_node/http_api/src/lib.rs | 3 +- .../http_api/src/sync_committee_rewards.rs | 87 +++---------------- 2 files changed, 15 insertions(+), 75 deletions(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 87b85efe641..463221c186a 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1722,7 +1722,8 @@ pub fn serve( validators: Vec, log: Logger| { // Do something here - blocking_json_task(move || Ok(true)) + blocking_json_task(move || sync_committee_rewards::compute_sync_committee_rewards( + chain, block_id, validators, log)) }); /* diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 54e19787fca..9770a187381 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,81 +1,20 @@ /* -1. API handler `compute_sync_committe_rewards` -2. Load data using `chain` from `BeaconChain` - 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: block_id.root(&chain) -3. Compute rewards by calling functions from `consensus/state_processing` -*/ +use beacon_chain::{BeaconChain, BeaconChainTypes}; +use eth2::types::{BlockId, ValidatorId}; +use slog::{Logger}; -// ---1--- -// Copy the structure of an existing API handler, e.g. get_lighthouse_block_rewards. -pub fn get_sync_committee_rewards( - chain: &BeaconChain, - state: BeaconState, - block: SignedBlindedBeaconBlock, +pub fn compute_sync_committee_rewards( + chain: Arc>, + block_id: BlockId, + validators: Vec, + log: Logger ) -> Result { - let get_lighthouse_sync_committee_rewards = warp::path("lighthouse") - .and(warp::path("analysis")) - .and(warp::path("sync_committee_rewards")) - .and(warp::query::()) - .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)) - }); -} - -// ---2--- -// ---2.1--- -// Load a block with chain.get_blinded_block(block_root). -pub fn get_blinded_block( - &self, - block_root: &Hash256, -) -> Result>, Error> { - Ok(self.store.get_blinded_block(block_root)?) -} + - Get block from block_id + - Get state from chain + - Call compute_sync_aggregate_reward + - Stuff things into SyncCommitteeRewards -// ---2.2--- -// Load a state with chain.get_state(state_root, None) -pub fn get_state( - &self, - state_root: &Hash256, - slot: Option, -) -> Result>, Error> { - Ok(self.store.get_state(state_root, slot)?) } -// ---2.3--- -// Convert a slot into the canonical block root from that slot: block_id.root(&chain). -/* -let canonical = chain - .block_root_at_slot(block.slot(), WhenSlotSkipped::None) - .map_err(warp_utils::reject::beacon_chain_error)? - .map_or(false, |canonical| root == canonical); -*/ - -// ---3--- -// Once we have the block(s) and state that we need, we can compute the rewards using snippets of logic extracted from consensus/state_processing. -// Call this function -pub fn compute_sync_committee_rewards( - state: &BeaconState, - 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)) -} \ No newline at end of file +*/ \ No newline at end of file From 73ba07b1c167dfe83cc9adaab40074185f975c7c Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 2 Dec 2022 16:30:27 +0100 Subject: [PATCH 06/38] use declarations --- beacon_node/http_api/src/sync_committee_rewards.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 9770a187381..94394da4258 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,6 +1,6 @@ -/* +use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes}; -use eth2::types::{BlockId, ValidatorId}; +use eth2::{types::{BlockId, ValidatorId}, Error}; use slog::{Logger}; pub fn compute_sync_committee_rewards( @@ -10,11 +10,11 @@ pub fn compute_sync_committee_rewards( log: Logger ) -> Result { + /* - Get block from block_id - Get state from chain - Call compute_sync_aggregate_reward - Stuff things into SyncCommitteeRewards + */ -} - -*/ \ No newline at end of file +} \ No newline at end of file From 6f3a7e61f99385f596471d26b3ea2c53771953b6 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Sat, 3 Dec 2022 10:33:15 +0100 Subject: [PATCH 07/38] change use declaration of BlockId --- beacon_node/http_api/src/lib.rs | 4 ++-- .../http_api/src/sync_committee_rewards.rs | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 463221c186a..811d8d02dc0 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1722,8 +1722,8 @@ pub fn serve( validators: Vec, log: Logger| { // Do something here - blocking_json_task(move || sync_committee_rewards::compute_sync_committee_rewards( - chain, block_id, validators, log)) + blocking_json_task(move || Ok(sync_committee_rewards::compute_sync_committee_rewards( + chain, block_id, validators, log))) }); /* diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 94394da4258..6c5611132b4 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,7 +1,8 @@ use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes}; -use eth2::{types::{BlockId, ValidatorId}, Error}; +use eth2::{types::{ValidatorId}, Error}; use slog::{Logger}; +use crate::BlockId; pub fn compute_sync_committee_rewards( chain: Arc>, @@ -10,11 +11,12 @@ pub fn compute_sync_committee_rewards( log: Logger ) -> Result { - /* - - Get block from block_id - - Get state from chain - - Call compute_sync_aggregate_reward - - Stuff things into SyncCommitteeRewards - */ + // Get block_id with full_block() + + // Get state from chain + + // Call compute_sync_aggregate_reward + + // Stuff things into SyncCommitteeRewards } \ No newline at end of file From c3c4c33cc656c4e163e2580a3f99915394f06d8f Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Sat, 3 Dec 2022 11:01:40 +0100 Subject: [PATCH 08/38] get block, get state, convert slot, compute reward --- .../http_api/src/sync_committee_rewards.rs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 6c5611132b4..ca41633ffb3 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -9,14 +9,28 @@ pub fn compute_sync_committee_rewards( block_id: BlockId, validators: Vec, log: Logger -) -> Result { +) -> Result Ok({ // Get block_id with full_block() + let block = chain + .get_block(block_id)? + .ok_or(Error::UnknownBlock(block_id))? + .full_block()?; // Get state from chain + let state = chain + .get_state(&block.state_root(), Some(block.slot()))? + .ok_or(Error::UnknownState(block.state_root()))?; + + // Convert a slot into the canonical block root from that slot: block_id.root(&chain). + let block_root = block_id.root(&chain)?; // Call compute_sync_aggregate_reward + let rewards = state.compute_sync_aggregate_reward(&block_root, &validators, &log)?; - // Stuff things into SyncCommitteeRewards - -} \ No newline at end of file + // Create SyncCommitteeRewards with calculated rewards + Ok(SyncCommitteeRewards { + rewards, + }) + +}); From a8204519b756a09ceea275ee4826a24cf99bf746 Mon Sep 17 00:00:00 2001 From: navie Date: Sun, 4 Dec 2022 01:24:40 +0800 Subject: [PATCH 09/38] Added sync_committee_attestation_rewards --- .../http_api/src/sync_committee_rewards.rs | 15 ++++++---- common/eth2/src/lighthouse.rs | 2 ++ .../sync_committee_attestation_rewards.rs | 28 +++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index ca41633ffb3..2b3035ebd4b 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,7 +1,8 @@ use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes}; -use eth2::{types::{ValidatorId}, Error}; -use slog::{Logger}; +use eth2::{types::ValidatorId, Error}; +use eth2::lighthouse::SyncCommitteeAttestationRewards; +use slog::Logger; use crate::BlockId; pub fn compute_sync_committee_rewards( @@ -9,7 +10,7 @@ pub fn compute_sync_committee_rewards( block_id: BlockId, validators: Vec, log: Logger -) -> Result Ok({ +) -> Result { // Get block_id with full_block() let block = chain @@ -29,8 +30,10 @@ pub fn compute_sync_committee_rewards( let rewards = state.compute_sync_aggregate_reward(&block_root, &validators, &log)?; // Create SyncCommitteeRewards with calculated rewards - Ok(SyncCommitteeRewards { - rewards, + Ok(SyncCommitteeAttestationRewards{ + execution_optimistic: false, + finalized: false, + data: Vec::new(), }) -}); +} diff --git a/common/eth2/src/lighthouse.rs b/common/eth2/src/lighthouse.rs index 2dced1c449a..b5bb2f768cc 100644 --- a/common/eth2/src/lighthouse.rs +++ b/common/eth2/src/lighthouse.rs @@ -3,6 +3,7 @@ mod attestation_performance; mod block_packing_efficiency; mod block_rewards; +mod sync_committee_attestation_rewards; use crate::{ ok_or_error, @@ -26,6 +27,7 @@ pub use block_packing_efficiency::{ BlockPackingEfficiency, BlockPackingEfficiencyQuery, ProposerInfo, UniqueAttestation, }; pub use block_rewards::{AttestationRewards, BlockReward, BlockRewardMeta, BlockRewardsQuery}; +pub use sync_committee_attestation_rewards::SyncCommitteeAttestationRewards; pub use lighthouse_network::{types::SyncState, PeerInfo}; // Define "legacy" implementations of `Option` which use four bytes for encoding the union diff --git a/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs b/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs new file mode 100644 index 00000000000..1fc3a68aee5 --- /dev/null +++ b/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs @@ -0,0 +1,28 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use types::{AttestationData, Hash256, Slot}; + +/// Details about the rewards paid to sync committee members for attesting headers +/// +/// 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 SyncCommitteeAttestationRewards { + + pub execution_optimistic: bool, + + pub finalized: bool, + + pub data: Vec, +} + +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +pub struct SyncCommitteeAttestationReward { + + pub validator_index: u8, + + pub reward: u64, + +} From dda4c27e2700e45abadd3d18e495942efdcf648e Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 6 Dec 2022 01:00:37 +0800 Subject: [PATCH 10/38] Partial implementation on sync committee reward api --- .../http_api/src/sync_committee_rewards.rs | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 2b3035ebd4b..9749031f4fa 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,8 +1,10 @@ use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes}; -use eth2::{types::ValidatorId, Error}; +use eth2::types::ValidatorId; use eth2::lighthouse::SyncCommitteeAttestationRewards; use slog::Logger; +use state_processing::per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards; +use types::{ChainSpec, Slot}; use crate::BlockId; pub fn compute_sync_committee_rewards( @@ -10,24 +12,20 @@ pub fn compute_sync_committee_rewards( block_id: BlockId, validators: Vec, log: Logger -) -> Result { - - // Get block_id with full_block() - let block = chain - .get_block(block_id)? - .ok_or(Error::UnknownBlock(block_id))? - .full_block()?; - - // Get state from chain - let state = chain - .get_state(&block.state_root(), Some(block.slot()))? - .ok_or(Error::UnknownState(block.state_root()))?; - - // Convert a slot into the canonical block root from that slot: block_id.root(&chain). - let block_root = block_id.root(&chain)?; - - // Call compute_sync_aggregate_reward - let rewards = state.compute_sync_aggregate_reward(&block_root, &validators, &log)?; +) -> Result { + + let spec: ChainSpec = chain.spec; + + let (block, execution_optimistic) = block_id.blinded_block(&chain)?; + + let slot: Slot = block.message().slot(); + + let state_root = chain.state_root_at_slot(slot)?.unwrap(); + + let state = chain.get_state(&state_root, Some(slot))?.unwrap(); + + let (_, rewards) = compute_sync_aggregate_rewards(&state, &spec)?; + // Create SyncCommitteeRewards with calculated rewards Ok(SyncCommitteeAttestationRewards{ From 0b5d6ad5ec5425e8abaf5be486286ce2dc8dce79 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Wed, 7 Dec 2022 10:55:19 +0100 Subject: [PATCH 11/38] delete imports, change comments --- .../sync_committee_attestation_rewards.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs b/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs index 1fc3a68aee5..229c3b6212e 100644 --- a/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs +++ b/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs @@ -1,13 +1,8 @@ use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -use types::{AttestationData, Hash256, Slot}; - -/// Details about the rewards paid to sync committee members for attesting headers -/// -/// 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. + +// Details about the rewards paid to sync committee members for attesting headers +// All rewards in GWei + #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct SyncCommitteeAttestationRewards { @@ -22,7 +17,7 @@ pub struct SyncCommitteeAttestationRewards { pub struct SyncCommitteeAttestationReward { pub validator_index: u8, - + // sync committee reward in gwei for the validator pub reward: u64, } From 4994c271b6b6ebf4c759b5b51819679e55ea6be5 Mon Sep 17 00:00:00 2001 From: navie Date: Thu, 8 Dec 2022 22:57:48 +0800 Subject: [PATCH 12/38] Updated logic to grab rewards --- .../http_api/src/sync_committee_rewards.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 9749031f4fa..b710900afd5 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -3,8 +3,7 @@ use beacon_chain::{BeaconChain, BeaconChainTypes}; use eth2::types::ValidatorId; use eth2::lighthouse::SyncCommitteeAttestationRewards; use slog::Logger; -use state_processing::per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards; -use types::{ChainSpec, Slot}; +use state_processing::{per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards, BlockReplayer}; use crate::BlockId; pub fn compute_sync_committee_rewards( @@ -14,18 +13,22 @@ pub fn compute_sync_committee_rewards( log: Logger ) -> Result { - let spec: ChainSpec = chain.spec; + let spec = chain.spec; let (block, execution_optimistic) = block_id.blinded_block(&chain)?; - let slot: Slot = block.message().slot(); + let slot = block.slot(); - let state_root = chain.state_root_at_slot(slot)?.unwrap(); + let state_root = block.state_root(); - let state = chain.get_state(&state_root, Some(slot))?.unwrap(); + let state = chain.get_state(&state_root, Some(slot))?.unwrap(); // Some comments here to + // indicate this is not the + // exact state but close + // enough let (_, rewards) = compute_sync_aggregate_rewards(&state, &spec)?; + // Create SyncCommitteeRewards with calculated rewards Ok(SyncCommitteeAttestationRewards{ From 29d18223ff8c9cbebed7a93285f9768f3f1ba27a Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Fri, 9 Dec 2022 11:08:48 +0100 Subject: [PATCH 13/38] fix imports, add comment --- beacon_node/http_api/src/sync_committee_rewards.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index b710900afd5..2b2f6fad30f 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -3,7 +3,7 @@ use beacon_chain::{BeaconChain, BeaconChainTypes}; use eth2::types::ValidatorId; use eth2::lighthouse::SyncCommitteeAttestationRewards; use slog::Logger; -use state_processing::{per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards, BlockReplayer}; +use state_processing::{per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards}; use crate::BlockId; pub fn compute_sync_committee_rewards( @@ -11,7 +11,7 @@ pub fn compute_sync_committee_rewards( block_id: BlockId, validators: Vec, log: Logger -) -> Result { +) -> Result { let spec = chain.spec; @@ -21,14 +21,12 @@ pub fn compute_sync_committee_rewards( let state_root = block.state_root(); - let state = chain.get_state(&state_root, Some(slot))?.unwrap(); // Some comments here to - // indicate this is not the - // exact state but close - // enough + // Technically we should use the pre-block state, but it won't matter because + // compute_sync_aggregate_rewards() only uses state.get_total_active_balance() which only changes on epoch boundaries. + // So, the "wrong" state will still give the same result. + let state = chain.get_state(&state_root, Some(slot))?.unwrap(); let (_, rewards) = compute_sync_aggregate_rewards(&state, &spec)?; - - // Create SyncCommitteeRewards with calculated rewards Ok(SyncCommitteeAttestationRewards{ From afefce884021c2912426e93e4b10bd05bbdf80eb Mon Sep 17 00:00:00 2001 From: navie Date: Fri, 9 Dec 2022 18:55:30 +0800 Subject: [PATCH 14/38] Changed fields to optional in sync_committee_attestation_rewards --- beacon_node/http_api/src/lib.rs | 5 ++-- .../http_api/src/sync_committee_rewards.rs | 28 ++++++++++++++++--- .../sync_committee_attestation_rewards.rs | 6 ++-- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 811d8d02dc0..84014eaa84e 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1721,9 +1721,8 @@ pub fn serve( block_id: BlockId, validators: Vec, log: Logger| { - // Do something here - blocking_json_task(move || Ok(sync_committee_rewards::compute_sync_committee_rewards( - chain, block_id, validators, log))) + blocking_json_task(move || sync_committee_rewards::compute_sync_committee_rewards( + chain, block_id, validators, log)) }); /* diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 2b2f6fad30f..c5e2dd8ce0a 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -4,6 +4,10 @@ use eth2::types::ValidatorId; use eth2::lighthouse::SyncCommitteeAttestationRewards; use slog::Logger; use state_processing::{per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards}; +<<<<<<< HEAD +======= +use warp_utils::reject::{beacon_chain_error, custom_bad_request}; +>>>>>>> 0f352220 (Changed fields to optional in sync_committee_attestation_rewards) use crate::BlockId; pub fn compute_sync_committee_rewards( @@ -11,9 +15,13 @@ pub fn compute_sync_committee_rewards( block_id: BlockId, validators: Vec, log: Logger +<<<<<<< HEAD ) -> Result { +======= +) -> Result { +>>>>>>> 0f352220 (Changed fields to optional in sync_committee_attestation_rewards) - let spec = chain.spec; + let spec = &chain.spec; let (block, execution_optimistic) = block_id.blinded_block(&chain)?; @@ -21,18 +29,30 @@ pub fn compute_sync_committee_rewards( let state_root = block.state_root(); +<<<<<<< HEAD // Technically we should use the pre-block state, but it won't matter because // compute_sync_aggregate_rewards() only uses state.get_total_active_balance() which only changes on epoch boundaries. // So, the "wrong" state will still give the same result. let state = chain.get_state(&state_root, Some(slot))?.unwrap(); let (_, rewards) = compute_sync_aggregate_rewards(&state, &spec)?; +======= + let state = chain + .get_state(&state_root, Some(slot)) + .map_err(beacon_chain_error)? + .ok_or_else(|| custom_bad_request(String::from("Unable to get state")))?; + + let (participant_reward, _) = compute_sync_aggregate_rewards(&state, spec) + .map_err(|_| custom_bad_request(String::from("Unable to get rewards")))?; + + +>>>>>>> 0f352220 (Changed fields to optional in sync_committee_attestation_rewards) // Create SyncCommitteeRewards with calculated rewards Ok(SyncCommitteeAttestationRewards{ - execution_optimistic: false, - finalized: false, - data: Vec::new(), + execution_optimistic: None, + finalized: None, + data: Some(vec![]) }) } diff --git a/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs b/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs index 229c3b6212e..38355bdd9de 100644 --- a/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs +++ b/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs @@ -6,11 +6,11 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct SyncCommitteeAttestationRewards { - pub execution_optimistic: bool, + pub execution_optimistic: Option, - pub finalized: bool, + pub finalized: Option, - pub data: Vec, + pub data: Option> } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] From 9cb4fb0e035463f3e45fae9b0cdd342f8b10952e Mon Sep 17 00:00:00 2001 From: navie Date: Fri, 9 Dec 2022 19:01:18 +0800 Subject: [PATCH 15/38] Fixed conflict --- beacon_node/http_api/src/sync_committee_rewards.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index c5e2dd8ce0a..f557864549e 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -4,10 +4,7 @@ use eth2::types::ValidatorId; use eth2::lighthouse::SyncCommitteeAttestationRewards; use slog::Logger; use state_processing::{per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards}; -<<<<<<< HEAD -======= use warp_utils::reject::{beacon_chain_error, custom_bad_request}; ->>>>>>> 0f352220 (Changed fields to optional in sync_committee_attestation_rewards) use crate::BlockId; pub fn compute_sync_committee_rewards( @@ -15,11 +12,7 @@ pub fn compute_sync_committee_rewards( block_id: BlockId, validators: Vec, log: Logger -<<<<<<< HEAD -) -> Result { -======= ) -> Result { ->>>>>>> 0f352220 (Changed fields to optional in sync_committee_attestation_rewards) let spec = &chain.spec; @@ -29,14 +22,9 @@ pub fn compute_sync_committee_rewards( let state_root = block.state_root(); -<<<<<<< HEAD // Technically we should use the pre-block state, but it won't matter because // compute_sync_aggregate_rewards() only uses state.get_total_active_balance() which only changes on epoch boundaries. // So, the "wrong" state will still give the same result. - let state = chain.get_state(&state_root, Some(slot))?.unwrap(); - - let (_, rewards) = compute_sync_aggregate_rewards(&state, &spec)?; -======= let state = chain .get_state(&state_root, Some(slot)) .map_err(beacon_chain_error)? @@ -45,8 +33,6 @@ pub fn compute_sync_committee_rewards( let (participant_reward, _) = compute_sync_aggregate_rewards(&state, spec) .map_err(|_| custom_bad_request(String::from("Unable to get rewards")))?; - ->>>>>>> 0f352220 (Changed fields to optional in sync_committee_attestation_rewards) // Create SyncCommitteeRewards with calculated rewards Ok(SyncCommitteeAttestationRewards{ From 552581b9983b269aaaf9716acc5185d1113d7235 Mon Sep 17 00:00:00 2001 From: navie Date: Sat, 10 Dec 2022 16:44:10 +0800 Subject: [PATCH 16/38] Populate reward content in sync_committee_rewards --- .../http_api/src/sync_committee_rewards.rs | 52 +++++++++++++++++-- common/eth2/src/lighthouse.rs | 2 +- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index f557864549e..da2b7d68bc0 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes}; use eth2::types::ValidatorId; -use eth2::lighthouse::SyncCommitteeAttestationRewards; +use eth2::lighthouse::{SyncCommitteeAttestationRewards, SyncCommitteeAttestationReward}; use slog::Logger; use state_processing::{per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards}; use warp_utils::reject::{beacon_chain_error, custom_bad_request}; @@ -25,20 +25,64 @@ pub fn compute_sync_committee_rewards( // Technically we should use the pre-block state, but it won't matter because // compute_sync_aggregate_rewards() only uses state.get_total_active_balance() which only changes on epoch boundaries. // So, the "wrong" state will still give the same result. - let state = chain + let mut state = chain .get_state(&state_root, Some(slot)) .map_err(beacon_chain_error)? .ok_or_else(|| custom_bad_request(String::from("Unable to get state")))?; - let (participant_reward, _) = compute_sync_aggregate_rewards(&state, spec) + let (participant_reward_value, _) = compute_sync_aggregate_rewards(&state, spec) .map_err(|_| custom_bad_request(String::from("Unable to get rewards")))?; + + let current_sync_committee = state + .current_sync_committee() + .map_err(|_| custom_bad_request(String::from("Unable to get participants")))? + .pubkeys + .clone(); + + let data = if current_sync_committee.is_empty() { + None + } else { + Some( + current_sync_committee + .iter() + .map(|sync_committee_pubkey| { + let sync_committee_validator_index = match state.get_validator_index(sync_committee_pubkey) { + Ok(validator_index) => validator_index, + _ => Some(0) + }.unwrap(); + (sync_committee_pubkey, sync_committee_validator_index) + }) + .filter(|(sync_committee_pubkey, sync_committee_validator_index)| { + validators + .iter() + .any(|validator| match validator { + ValidatorId::PublicKey(pubkey) => { + *sync_committee_pubkey == pubkey + } + ValidatorId::Index(i) => { + *sync_committee_validator_index as u64 == *i + } + }) + }) + .map(|(_sync_committee_pubkey, sync_committee_validator_index)| { + SyncCommitteeAttestationReward { + validator_index: sync_committee_validator_index as u8, + reward: participant_reward_value + } + }) + .collect::>() + ) + }; + + + // Create SyncCommitteeRewards with calculated rewards Ok(SyncCommitteeAttestationRewards{ execution_optimistic: None, finalized: None, - data: Some(vec![]) + data }) } diff --git a/common/eth2/src/lighthouse.rs b/common/eth2/src/lighthouse.rs index b5bb2f768cc..db29fa89e38 100644 --- a/common/eth2/src/lighthouse.rs +++ b/common/eth2/src/lighthouse.rs @@ -27,7 +27,7 @@ pub use block_packing_efficiency::{ BlockPackingEfficiency, BlockPackingEfficiencyQuery, ProposerInfo, UniqueAttestation, }; pub use block_rewards::{AttestationRewards, BlockReward, BlockRewardMeta, BlockRewardsQuery}; -pub use sync_committee_attestation_rewards::SyncCommitteeAttestationRewards; +pub use sync_committee_attestation_rewards::{SyncCommitteeAttestationRewards, SyncCommitteeAttestationReward}; pub use lighthouse_network::{types::SyncState, PeerInfo}; // Define "legacy" implementations of `Option` which use four bytes for encoding the union From 7d5ae25f8d789770790919a244981f7d3d0d04dd Mon Sep 17 00:00:00 2001 From: navie Date: Sat, 10 Dec 2022 16:47:43 +0800 Subject: [PATCH 17/38] Handle case where validators is empty in sync_committee_rewards --- beacon_node/http_api/src/sync_committee_rewards.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index da2b7d68bc0..0a9a03e13eb 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -54,6 +54,8 @@ pub fn compute_sync_committee_rewards( (sync_committee_pubkey, sync_committee_validator_index) }) .filter(|(sync_committee_pubkey, sync_committee_validator_index)| { + validators.is_empty() + || validators .iter() .any(|validator| match validator { From 511f96b78d8a34604ada803090656da9556aa332 Mon Sep 17 00:00:00 2001 From: navie Date: Sat, 10 Dec 2022 23:30:19 +0800 Subject: [PATCH 18/38] Added debug messages --- .../http_api/src/sync_committee_rewards.rs | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 0a9a03e13eb..9e714877cae 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes}; use eth2::types::ValidatorId; use eth2::lighthouse::{SyncCommitteeAttestationRewards, SyncCommitteeAttestationReward}; -use slog::Logger; +use slog::{debug, warn, Logger}; use state_processing::{per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards}; use warp_utils::reject::{beacon_chain_error, custom_bad_request}; use crate::BlockId; @@ -30,8 +30,15 @@ pub fn compute_sync_committee_rewards( .map_err(beacon_chain_error)? .ok_or_else(|| custom_bad_request(String::from("Unable to get state")))?; + debug!( + log, + "Retrieving sync committee attestation rewards"; + "state_root" => ?state_root, + "slot" => slot, + ); + let (participant_reward_value, _) = compute_sync_aggregate_rewards(&state, spec) - .map_err(|_| custom_bad_request(String::from("Unable to get rewards")))?; + .map_err(|_| custom_bad_request(format!("Unable to get sync aggregate rewards at state root {:?}", state_root)))?; let current_sync_committee = state @@ -39,6 +46,13 @@ pub fn compute_sync_committee_rewards( .map_err(|_| custom_bad_request(String::from("Unable to get participants")))? .pubkeys .clone(); + + debug!( + log, + "Retrived sync committee attestation reward value"; + "reward_value" => participant_reward_value, + "sync_committee_participant_size" => current_sync_committee.len() + ); let data = if current_sync_committee.is_empty() { None @@ -77,10 +91,6 @@ pub fn compute_sync_committee_rewards( ) }; - - - - // Create SyncCommitteeRewards with calculated rewards Ok(SyncCommitteeAttestationRewards{ execution_optimistic: None, finalized: None, From 46b3624e49e5f7a1c18e2495c10792118c3da4d9 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Mon, 12 Dec 2022 11:12:19 +0100 Subject: [PATCH 19/38] change data types + delete comment --- beacon_node/http_api/src/lib.rs | 1 - beacon_node/http_api/src/sync_committee_rewards.rs | 4 ++-- .../eth2/src/lighthouse/sync_committee_attestation_rewards.rs | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 84014eaa84e..c5ad1c2c8f4 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -3392,7 +3392,6 @@ pub fn serve( .or(post_beacon_pool_proposer_slashings.boxed()) .or(post_beacon_pool_voluntary_exits.boxed()) .or(post_beacon_pool_sync_committees.boxed()) - //Right place for it? .or(post_beacon_rewards_sync_committee.boxed()) .or(post_validator_duties_attester.boxed()) .or(post_validator_duties_sync.boxed()) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 9e714877cae..4947dcec875 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -83,8 +83,8 @@ pub fn compute_sync_committee_rewards( }) .map(|(_sync_committee_pubkey, sync_committee_validator_index)| { SyncCommitteeAttestationReward { - validator_index: sync_committee_validator_index as u8, - reward: participant_reward_value + validator_index: sync_committee_validator_index as u64, + reward: participant_reward_value as i64 } }) .collect::>() diff --git a/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs b/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs index 38355bdd9de..3dd4b4cdf1c 100644 --- a/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs +++ b/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs @@ -16,8 +16,8 @@ pub struct SyncCommitteeAttestationRewards { #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct SyncCommitteeAttestationReward { - pub validator_index: u8, + pub validator_index: u64, // sync committee reward in gwei for the validator - pub reward: u64, + pub reward: i64, } From 37e87290dfaa294a142f26648a8c9bc865128faf Mon Sep 17 00:00:00 2001 From: navie Date: Wed, 14 Dec 2022 23:29:04 +0800 Subject: [PATCH 20/38] Handle case where participants are penalized --- .../http_api/src/sync_committee_rewards.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 4947dcec875..07d92e5218a 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -22,6 +22,12 @@ pub fn compute_sync_committee_rewards( let state_root = block.state_root(); + let sync_aggregate = block + .message() + .body() + .sync_aggregate() + .map_err(|_| custom_bad_request(String::from("Unable to get sync aggregate")))?; + // Technically we should use the pre-block state, but it won't matter because // compute_sync_aggregate_rewards() only uses state.get_total_active_balance() which only changes on epoch boundaries. // So, the "wrong" state will still give the same result. @@ -60,14 +66,15 @@ pub fn compute_sync_committee_rewards( Some( current_sync_committee .iter() - .map(|sync_committee_pubkey| { + .zip(sync_aggregate.sync_committee_bits.iter()) + .map(|(sync_committee_pubkey, participation_bit)| { let sync_committee_validator_index = match state.get_validator_index(sync_committee_pubkey) { Ok(validator_index) => validator_index, _ => Some(0) }.unwrap(); - (sync_committee_pubkey, sync_committee_validator_index) + (sync_committee_pubkey, sync_committee_validator_index, participation_bit) }) - .filter(|(sync_committee_pubkey, sync_committee_validator_index)| { + .filter(|(sync_committee_pubkey, sync_committee_validator_index, participation_bit)| { validators.is_empty() || validators @@ -81,10 +88,11 @@ pub fn compute_sync_committee_rewards( } }) }) - .map(|(_sync_committee_pubkey, sync_committee_validator_index)| { + .map(|(_sync_committee_pubkey, sync_committee_validator_index, participation_bit)| { SyncCommitteeAttestationReward { validator_index: sync_committee_validator_index as u64, - reward: participant_reward_value as i64 + reward: if participation_bit { participant_reward_value as i64 } + else { participant_reward_value as i64 * -1 } } }) .collect::>() From aeaded798a7f55936ee60c236e4a00359cf9a8b2 Mon Sep 17 00:00:00 2001 From: kevinbogner Date: Thu, 15 Dec 2022 10:55:04 +0100 Subject: [PATCH 21/38] add endpoint to common/eth2/src/lib.rs --- common/eth2/src/lib.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index 58b4c88b3c7..d7350646580 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -1026,6 +1026,24 @@ impl BeaconNodeHttpClient { .transpose() } + /// `POST beacon/rewards/sync_committee` + pub async fn post_beacon_rewards_sync_committee( + &self, + rewards: &[Option>], + ) -> Result<(), Error> { + let mut path = self.eth_path(V1)?; + + path.path_segments_mut() + .map_err(|()| Error::InvalidUrl(self.server.clone()))? + .push("beacon") + .push("rewards") + .push("sync_committee"); + + self.post(path, &rewards).await?; + + Ok(()) + } + /// `POST validator/contribution_and_proofs` pub async fn post_validator_contribution_and_proofs( &self, From 9b29113a4ae19ac894588be12a7abf15b0b9c9b7 Mon Sep 17 00:00:00 2001 From: navie Date: Fri, 16 Dec 2022 00:32:34 +0800 Subject: [PATCH 22/38] Rewrite logic for sync_committee_rewards --- .../http_api/src/sync_committee_rewards.rs | 82 +++++++++---------- 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 07d92e5218a..185882c6dc4 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,9 +1,10 @@ +use std::collections::HashMap; use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes}; use eth2::types::ValidatorId; use eth2::lighthouse::{SyncCommitteeAttestationRewards, SyncCommitteeAttestationReward}; -use slog::{debug, warn, Logger}; -use state_processing::{per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards}; +use slog::{debug, Logger}; +use state_processing::per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards; use warp_utils::reject::{beacon_chain_error, custom_bad_request}; use crate::BlockId; @@ -36,6 +37,15 @@ pub fn compute_sync_committee_rewards( .map_err(beacon_chain_error)? .ok_or_else(|| custom_bad_request(String::from("Unable to get state")))?; + let sync_committee = state + .clone() + .current_sync_committee() + .map_err(|_| custom_bad_request(String::from("Unable to get participants")))?; + + let sync_committee_indices = state + .get_sync_committee_indices(sync_committee) + .map_err(|_| custom_bad_request(String::from("Unable to get participant indices")))?; + debug!( log, "Retrieving sync committee attestation rewards"; @@ -46,56 +56,42 @@ pub fn compute_sync_committee_rewards( let (participant_reward_value, _) = compute_sync_aggregate_rewards(&state, spec) .map_err(|_| custom_bad_request(format!("Unable to get sync aggregate rewards at state root {:?}", state_root)))?; - - let current_sync_committee = state - .current_sync_committee() - .map_err(|_| custom_bad_request(String::from("Unable to get participants")))? - .pubkeys - .clone(); - debug!( log, "Retrived sync committee attestation reward value"; - "reward_value" => participant_reward_value, - "sync_committee_participant_size" => current_sync_committee.len() + "reward_value" => participant_reward_value ); - - let data = if current_sync_committee.is_empty() { - None + + + let mut balances = sync_committee_indices + .iter() + .map(|i| (*i, state.balances()[*i])) + .collect::>(); + + let mut total_proposer_rewards = 0; + + for (validator_index, participant_bit) in sync_committee_indices.iter().zip(sync_aggregate.sync_committee_bits.iter()) { + let mut participant_balance = balances.get_mut(validator_index); + if participant_bit { + participant_balance.get_or_insert(&mut 0).saturating_add(participant_reward_value); + // TODO: Update proposer reward at proposer_index + } else { + participant_balance.get_or_insert(&mut 0).saturating_sub(participant_reward_value); + } + } + + let data = if sync_committee.pubkeys.is_empty() { + None } else { Some( - current_sync_committee - .iter() - .zip(sync_aggregate.sync_committee_bits.iter()) - .map(|(sync_committee_pubkey, participation_bit)| { - let sync_committee_validator_index = match state.get_validator_index(sync_committee_pubkey) { - Ok(validator_index) => validator_index, - _ => Some(0) - }.unwrap(); - (sync_committee_pubkey, sync_committee_validator_index, participation_bit) - }) - .filter(|(sync_committee_pubkey, sync_committee_validator_index, participation_bit)| { - validators.is_empty() - || - validators - .iter() - .any(|validator| match validator { - ValidatorId::PublicKey(pubkey) => { - *sync_committee_pubkey == pubkey - } - ValidatorId::Index(i) => { - *sync_committee_validator_index as u64 == *i - } - }) - }) - .map(|(_sync_committee_pubkey, sync_committee_validator_index, participation_bit)| { + balances.iter().map(|(i, new_balance)| { + let reward = *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards; SyncCommitteeAttestationReward { - validator_index: sync_committee_validator_index as u64, - reward: if participation_bit { participant_reward_value as i64 } - else { participant_reward_value as i64 * -1 } + validator_index: *i as u64, + reward } }) - .collect::>() + .collect() ) }; From 04f9768cd1db402a7943b3d0195d12a40f6c889f Mon Sep 17 00:00:00 2001 From: navie Date: Fri, 16 Dec 2022 01:11:00 +0800 Subject: [PATCH 23/38] Rewrite logic for sync_committee_rewards --- beacon_node/http_api/src/sync_committee_rewards.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 185882c6dc4..c8d299d0beb 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -38,12 +38,12 @@ pub fn compute_sync_committee_rewards( .ok_or_else(|| custom_bad_request(String::from("Unable to get state")))?; let sync_committee = state - .clone() .current_sync_committee() - .map_err(|_| custom_bad_request(String::from("Unable to get participants")))?; + .map_err(|_| custom_bad_request(String::from("Unable to get participants")))? + .clone(); - let sync_committee_indices = state - .get_sync_committee_indices(sync_committee) + let sync_committee_indices = state + .get_sync_committee_indices(&sync_committee) .map_err(|_| custom_bad_request(String::from("Unable to get participant indices")))?; debug!( From 93bdc09359f025250a737d0ed15ae8c6a6473680 Mon Sep 17 00:00:00 2001 From: navie Date: Sat, 17 Dec 2022 01:22:09 +0800 Subject: [PATCH 24/38] Apply rewards to proposer balance --- .../http_api/src/sync_committee_rewards.rs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index c8d299d0beb..ec9bc19ada2 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -53,7 +53,7 @@ pub fn compute_sync_committee_rewards( "slot" => slot, ); - let (participant_reward_value, _) = compute_sync_aggregate_rewards(&state, spec) + let (participant_reward_value, proposer_reward_per_bit) = compute_sync_aggregate_rewards(&state, spec) .map_err(|_| custom_bad_request(format!("Unable to get sync aggregate rewards at state root {:?}", state_root)))?; debug!( @@ -69,23 +69,36 @@ pub fn compute_sync_committee_rewards( .collect::>(); let mut total_proposer_rewards = 0; + let proposer_index = state.get_beacon_proposer_index(slot, spec) + .map_err(|_| custom_bad_request(String::from("placeholder")))?; + // Apply rewards to participant balances. Keep track of proposer rewards for (validator_index, participant_bit) in sync_committee_indices.iter().zip(sync_aggregate.sync_committee_bits.iter()) { - let mut participant_balance = balances.get_mut(validator_index); + let participant_balance = balances.get(validator_index); + if participant_bit { - participant_balance.get_or_insert(&mut 0).saturating_add(participant_reward_value); - // TODO: Update proposer reward at proposer_index + if let Some(balance_value) = participant_balance { + balances.insert(*validator_index, balance_value + participant_reward_value); + } + total_proposer_rewards += proposer_reward_per_bit; } else { - participant_balance.get_or_insert(&mut 0).saturating_sub(participant_reward_value); + if let Some(balance_value) = participant_balance { + balances.insert(*validator_index, balance_value.saturating_sub(participant_reward_value)); + } } } + // Update proposer balance + balances.insert(proposer_index, total_proposer_rewards + + if balances.contains_key(&proposer_index) { balances[&proposer_index] } + else { 0 }); + let data = if sync_committee.pubkeys.is_empty() { None } else { Some( balances.iter().map(|(i, new_balance)| { - let reward = *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards; + let reward = *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards as i64; SyncCommitteeAttestationReward { validator_index: *i as u64, reward From 662d72323e294e6e1972481d40a2ebf7ac7dfb53 Mon Sep 17 00:00:00 2001 From: navie Date: Fri, 23 Dec 2022 01:31:44 +0800 Subject: [PATCH 25/38] Add sync committee rewards to beacon chain trait --- beacon_node/beacon_chain/src/errors.rs | 1 + beacon_node/beacon_chain/src/lib.rs | 1 + .../src/sync_committee_rewards.rs | 79 ++++++++++++++++ .../http_api/src/sync_committee_rewards.rs | 89 ++----------------- 4 files changed, 88 insertions(+), 82 deletions(-) create mode 100644 beacon_node/beacon_chain/src/sync_committee_rewards.rs diff --git a/beacon_node/beacon_chain/src/errors.rs b/beacon_node/beacon_chain/src/errors.rs index 704cba489d2..8fc109bc70e 100644 --- a/beacon_node/beacon_chain/src/errors.rs +++ b/beacon_node/beacon_chain/src/errors.rs @@ -160,6 +160,7 @@ pub enum BeaconChainError { BlockRewardSlotError, BlockRewardAttestationError, BlockRewardSyncError, + SyncCommitteeRewardsSyncError, HeadMissingFromForkChoice(Hash256), FinalizedBlockMissingFromForkChoice(Hash256), HeadBlockMissingFromForkChoice(Hash256), diff --git a/beacon_node/beacon_chain/src/lib.rs b/beacon_node/beacon_chain/src/lib.rs index 5ead5311e59..fb94768601d 100644 --- a/beacon_node/beacon_chain/src/lib.rs +++ b/beacon_node/beacon_chain/src/lib.rs @@ -6,6 +6,7 @@ mod beacon_fork_choice_store; pub mod beacon_proposer_cache; mod beacon_snapshot; pub mod block_reward; +pub mod sync_committee_rewards; mod block_times_cache; mod block_verification; pub mod builder; diff --git a/beacon_node/beacon_chain/src/sync_committee_rewards.rs b/beacon_node/beacon_chain/src/sync_committee_rewards.rs new file mode 100644 index 00000000000..ae2365097ba --- /dev/null +++ b/beacon_node/beacon_chain/src/sync_committee_rewards.rs @@ -0,0 +1,79 @@ +use crate::{BeaconChain, BeaconChainError, BeaconChainTypes}; + +use eth2::lighthouse::SyncCommitteeAttestationReward; +use state_processing::per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards; +use types::{BeaconBlockRef, BeaconState, ExecPayload}; +use std::collections::HashMap; + +impl BeaconChain { + pub fn compute_sync_committee_rewards>( + &self, + block: BeaconBlockRef<'_, T::EthSpec, Payload>, + state: &mut BeaconState, + ) -> Result, BeaconChainError> { + if block.slot() != state.slot() { + return Err(BeaconChainError::BlockRewardSlotError); + } + + let spec = &self.spec; + + let sync_aggregate = block + .body() + .sync_aggregate()?; + + let sync_committee = state + .current_sync_committee()? + .clone(); + + let sync_committee_indices = state + .get_sync_committee_indices(&sync_committee)?; + + + let (participant_reward_value, proposer_reward_per_bit) = compute_sync_aggregate_rewards(&state, spec) + .map_err(|_| BeaconChainError::SyncCommitteeRewardsSyncError)?; + + let mut balances = sync_committee_indices + .iter() + .map(|i| (*i, state.balances()[*i])) + .collect::>(); + + let mut total_proposer_rewards = 0; + let proposer_index = state.get_beacon_proposer_index(block.slot(), spec)?; + + // Apply rewards to participant balances. Keep track of proposer rewards + for (validator_index, participant_bit) in sync_committee_indices.iter().zip(sync_aggregate.sync_committee_bits.iter()) { + let participant_balance = balances.get(validator_index); + + if participant_bit { + if let Some(balance_value) = participant_balance { + balances.insert(*validator_index, balance_value + participant_reward_value); + } + total_proposer_rewards += proposer_reward_per_bit; + } else { + if let Some(balance_value) = participant_balance { + balances.insert(*validator_index, balance_value.saturating_sub(participant_reward_value)); + } + } + } + + // Update proposer balance + balances.insert(proposer_index, total_proposer_rewards + + if balances.contains_key(&proposer_index) { balances[&proposer_index] } + else { 0 }); + + if sync_committee.pubkeys.is_empty() { + Ok(Vec::new()) + } else { + Ok( + balances.iter().map(|(i, new_balance)| { + let reward = *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards as i64; + SyncCommitteeAttestationReward { + validator_index: *i as u64, + reward + } + }) + .collect() + ) + } + } +} diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index ec9bc19ada2..5a197f21fc6 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,10 +1,8 @@ -use std::collections::HashMap; use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes}; use eth2::types::ValidatorId; use eth2::lighthouse::{SyncCommitteeAttestationRewards, SyncCommitteeAttestationReward}; use slog::{debug, Logger}; -use state_processing::per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards; use warp_utils::reject::{beacon_chain_error, custom_bad_request}; use crate::BlockId; @@ -23,95 +21,22 @@ pub fn compute_sync_committee_rewards( let state_root = block.state_root(); - let sync_aggregate = block - .message() - .body() - .sync_aggregate() - .map_err(|_| custom_bad_request(String::from("Unable to get sync aggregate")))?; - - // Technically we should use the pre-block state, but it won't matter because - // compute_sync_aggregate_rewards() only uses state.get_total_active_balance() which only changes on epoch boundaries. - // So, the "wrong" state will still give the same result. + // TODO: retrieve post state here let mut state = chain .get_state(&state_root, Some(slot)) .map_err(beacon_chain_error)? .ok_or_else(|| custom_bad_request(String::from("Unable to get state")))?; - let sync_committee = state - .current_sync_committee() - .map_err(|_| custom_bad_request(String::from("Unable to get participants")))? - .clone(); - - let sync_committee_indices = state - .get_sync_committee_indices(&sync_committee) - .map_err(|_| custom_bad_request(String::from("Unable to get participant indices")))?; - - debug!( - log, - "Retrieving sync committee attestation rewards"; - "state_root" => ?state_root, - "slot" => slot, - ); - - let (participant_reward_value, proposer_reward_per_bit) = compute_sync_aggregate_rewards(&state, spec) - .map_err(|_| custom_bad_request(format!("Unable to get sync aggregate rewards at state root {:?}", state_root)))?; - - debug!( - log, - "Retrived sync committee attestation reward value"; - "reward_value" => participant_reward_value - ); - - - let mut balances = sync_committee_indices - .iter() - .map(|i| (*i, state.balances()[*i])) - .collect::>(); - - let mut total_proposer_rewards = 0; - let proposer_index = state.get_beacon_proposer_index(slot, spec) - .map_err(|_| custom_bad_request(String::from("placeholder")))?; - - // Apply rewards to participant balances. Keep track of proposer rewards - for (validator_index, participant_bit) in sync_committee_indices.iter().zip(sync_aggregate.sync_committee_bits.iter()) { - let participant_balance = balances.get(validator_index); - - if participant_bit { - if let Some(balance_value) = participant_balance { - balances.insert(*validator_index, balance_value + participant_reward_value); - } - total_proposer_rewards += proposer_reward_per_bit; - } else { - if let Some(balance_value) = participant_balance { - balances.insert(*validator_index, balance_value.saturating_sub(participant_reward_value)); - } - } - } - - // Update proposer balance - balances.insert(proposer_index, total_proposer_rewards + - if balances.contains_key(&proposer_index) { balances[&proposer_index] } - else { 0 }); - - let data = if sync_committee.pubkeys.is_empty() { - None - } else { - Some( - balances.iter().map(|(i, new_balance)| { - let reward = *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards as i64; - SyncCommitteeAttestationReward { - validator_index: *i as u64, - reward - } - }) - .collect() - ) - }; + // TODO: filter payload by vlaidators + let reward_payload = chain + .compute_sync_committee_rewards(block.message(), &mut state) + .map_err(beacon_chain_error)?; Ok(SyncCommitteeAttestationRewards{ execution_optimistic: None, finalized: None, - data + data: if reward_payload.is_empty() { None } else { Some(reward_payload) } }) + } From 70a5cf3ea31bff8bd7f992cd13bd0b6af69ca1a2 Mon Sep 17 00:00:00 2001 From: navie Date: Mon, 26 Dec 2022 12:12:37 +0800 Subject: [PATCH 26/38] Filter reward_payload by validators --- .../http_api/src/sync_committee_rewards.rs | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 5a197f21fc6..10b103479f7 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -27,15 +27,42 @@ pub fn compute_sync_committee_rewards( .map_err(beacon_chain_error)? .ok_or_else(|| custom_bad_request(String::from("Unable to get state")))?; - // TODO: filter payload by vlaidators let reward_payload = chain .compute_sync_committee_rewards(block.message(), &mut state) .map_err(beacon_chain_error)?; + let data = if reward_payload.is_empty() { + None + } else if validators.is_empty() { + Some(reward_payload) + } else { + Some( + reward_payload + .into_iter() + .filter(|reward| { + validators + .iter() + .any(|validator| match validator { + ValidatorId::Index(i) => { + reward.validator_index == *i + } + ValidatorId::PublicKey(pubkey) => { + match state.get_validator_index(pubkey) { + Ok(Some(i)) => { reward.validator_index == i as u64 } + _ => { false } + } + } + }) + }) + .collect::>() + ) + }; + + Ok(SyncCommitteeAttestationRewards{ execution_optimistic: None, finalized: None, - data: if reward_payload.is_empty() { None } else { Some(reward_payload) } + data }) From 3a715797b45ede6fb3f789812e1b744394778d1f Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 27 Dec 2022 17:08:07 +0800 Subject: [PATCH 27/38] Added initial ver of unit test for sync committee rewards --- beacon_node/beacon_chain/tests/main.rs | 1 + beacon_node/beacon_chain/tests/rewards.rs | 57 +++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 beacon_node/beacon_chain/tests/rewards.rs diff --git a/beacon_node/beacon_chain/tests/main.rs b/beacon_node/beacon_chain/tests/main.rs index 1c61e9927fc..b9845f5ca18 100644 --- a/beacon_node/beacon_chain/tests/main.rs +++ b/beacon_node/beacon_chain/tests/main.rs @@ -7,3 +7,4 @@ mod payload_invalidation; mod store_tests; mod sync_committee_verification; mod tests; +mod rewards; diff --git a/beacon_node/beacon_chain/tests/rewards.rs b/beacon_node/beacon_chain/tests/rewards.rs new file mode 100644 index 00000000000..77b8e8e07af --- /dev/null +++ b/beacon_node/beacon_chain/tests/rewards.rs @@ -0,0 +1,57 @@ +#![cfg(test)] + +use lazy_static::lazy_static; +use beacon_chain::types::{ + test_utils::TestRandom, BeaconState, BeaconStateAltair, BeaconStateBase, BeaconStateError, + ChainSpec, CloneConfig, Domain, Epoch, EthSpec, FixedVector, Hash256, Keypair, MainnetEthSpec, + MinimalEthSpec, RelativeEpoch, Slot +}; +use eth2::lighthouse::SyncCommitteeAttestationReward; +use beacon_chain::test_utils::{EphemeralHarnessType, BeaconChainHarness, generate_deterministic_keypairs}; + +pub const SLOT: Slot = Slot::new(12); +lazy_static! { + static ref KEYPAIRS: Vec = generate_deterministic_keypairs(8); +} + +fn get_harness() -> BeaconChainHarness> { + let harness = BeaconChainHarness::builder(E::default()) + .default_spec() + .keypairs(KEYPAIRS.to_vec()) + .fresh_ephemeral_store() + .build(); + + let state = harness.get_current_state(); + let target_slot = SLOT; + + harness + .add_attested_blocks_at_slots( + state, + Hash256::zero(), + (1..target_slot.as_u64()) + .map(Slot::new) + .collect::>() + .as_slice(), + (0..12).collect::>().as_slice(), + ); + + harness +} + +#[tokio::test] +async fn test_sync_committee_rewards() { + let harness = get_harness::(); + let chain = harness.chain.clone(); + + let block = chain.block_at_slot(SLOT, beacon_chain::WhenSlotSkipped::None).unwrap().unwrap(); + + let mut state = harness.get_current_state(); + + let reward_payload = chain + .compute_sync_committee_rewards(block.message(), &mut state) + .unwrap(); + + assert_eq!(reward_payload.len(), 8); + + +} From 3d3f71c8544026dbd6ee2345b470cde092f62ab0 Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 27 Dec 2022 19:10:16 +0800 Subject: [PATCH 28/38] Use post state for sync committee rewards --- .../http_api/src/sync_committee_rewards.rs | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 10b103479f7..8ed9d6253f7 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,9 +1,11 @@ use std::sync::Arc; -use beacon_chain::{BeaconChain, BeaconChainTypes}; +use beacon_chain::{BeaconChain, BeaconChainTypes, BeaconChainError}; use eth2::types::ValidatorId; use eth2::lighthouse::{SyncCommitteeAttestationRewards, SyncCommitteeAttestationReward}; use slog::{debug, Logger}; -use warp_utils::reject::{beacon_chain_error, custom_bad_request}; +use state_processing::BlockReplayer; +use types::{BeaconState, SignedBlindedBeaconBlock}; +use warp_utils::reject::beacon_chain_error; use crate::BlockId; pub fn compute_sync_committee_rewards( @@ -13,19 +15,11 @@ pub fn compute_sync_committee_rewards( log: Logger ) -> Result { - let spec = &chain.spec; - let (block, execution_optimistic) = block_id.blinded_block(&chain)?; + let (block, _) = block_id.blinded_block(&chain)?; - let slot = block.slot(); - - let state_root = block.state_root(); - - // TODO: retrieve post state here - let mut state = chain - .get_state(&state_root, Some(slot)) - .map_err(beacon_chain_error)? - .ok_or_else(|| custom_bad_request(String::from("Unable to get state")))?; + let mut state = get_state_before_applying_block(chain.clone(), block.clone()) + .map_err(beacon_chain_error)?; let reward_payload = chain .compute_sync_committee_rewards(block.message(), &mut state) @@ -67,3 +61,27 @@ pub fn compute_sync_committee_rewards( } + +fn get_state_before_applying_block( + chain: Arc>, + block: SignedBlindedBeaconBlock +) -> Result, BeaconChainError> { + + let parent_block: SignedBlindedBeaconBlock = chain + .get_blinded_block(&block.parent_root())? + .ok_or_else(|| BeaconChainError::SyncCommitteeRewardsSyncError)?; + + + let parent_state = chain + .get_state(&parent_block.state_root(), Some(parent_block.slot()))? + .ok_or_else(|| BeaconChainError::SyncCommitteeRewardsSyncError)?; + + let replayer = BlockReplayer::new(parent_state, &chain.spec) + .no_signature_verification() + .state_root_iter([Ok((parent_block.state_root(), parent_block.slot()))].into_iter()) + .minimal_block_root_verification() + .apply_blocks(vec![], Some(block.slot())) + .map_err(|_: BeaconChainError| BeaconChainError::SyncCommitteeRewardsSyncError)?; + + Ok(replayer.into_state()) +} From 5627e5fde2e77f7203a226fc2d3ad1f277b296a3 Mon Sep 17 00:00:00 2001 From: navie Date: Sun, 8 Jan 2023 00:50:49 +0800 Subject: [PATCH 29/38] Added unit test for sync committee rewards --- .../src/sync_committee_rewards.rs | 22 ++-- beacon_node/beacon_chain/src/test_utils.rs | 35 +++++- beacon_node/beacon_chain/tests/rewards.rs | 109 +++++++++++++----- .../altair/sync_committee.rs | 3 +- .../types/src/sync_committee_contribution.rs | 1 + 5 files changed, 130 insertions(+), 40 deletions(-) diff --git a/beacon_node/beacon_chain/src/sync_committee_rewards.rs b/beacon_node/beacon_chain/src/sync_committee_rewards.rs index ae2365097ba..99b717ac7f2 100644 --- a/beacon_node/beacon_chain/src/sync_committee_rewards.rs +++ b/beacon_node/beacon_chain/src/sync_committee_rewards.rs @@ -28,7 +28,6 @@ impl BeaconChain { let sync_committee_indices = state .get_sync_committee_indices(&sync_committee)?; - let (participant_reward_value, proposer_reward_per_bit) = compute_sync_aggregate_rewards(&state, spec) .map_err(|_| BeaconChainError::SyncCommitteeRewardsSyncError)?; @@ -39,6 +38,7 @@ impl BeaconChain { let mut total_proposer_rewards = 0; let proposer_index = state.get_beacon_proposer_index(block.slot(), spec)?; + balances.insert(proposer_index, state.balances()[proposer_index]); // Apply rewards to participant balances. Keep track of proposer rewards for (validator_index, participant_bit) in sync_committee_indices.iter().zip(sync_aggregate.sync_committee_bits.iter()) { @@ -48,6 +48,7 @@ impl BeaconChain { if let Some(balance_value) = participant_balance { balances.insert(*validator_index, balance_value + participant_reward_value); } + *balances.get_mut(&proposer_index).unwrap() += proposer_reward_per_bit; total_proposer_rewards += proposer_reward_per_bit; } else { if let Some(balance_value) = participant_balance { @@ -56,21 +57,20 @@ impl BeaconChain { } } - // Update proposer balance - balances.insert(proposer_index, total_proposer_rewards + - if balances.contains_key(&proposer_index) { balances[&proposer_index] } - else { 0 }); - if sync_committee.pubkeys.is_empty() { Ok(Vec::new()) } else { Ok( balances.iter().map(|(i, new_balance)| { - let reward = *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards as i64; - SyncCommitteeAttestationReward { - validator_index: *i as u64, - reward - } + let reward = if *i != proposer_index { + *new_balance as i64 - state.balances()[*i] as i64 + } else { + *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards as i64 + }; + SyncCommitteeAttestationReward { + validator_index: *i as u64, + reward + } }) .collect() ) diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index a1c7acf173a..2693c96aecb 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -2,7 +2,8 @@ pub use crate::persisted_beacon_chain::PersistedBeaconChain; pub use crate::{ beacon_chain::{BEACON_CHAIN_DB_KEY, ETH1_CACHE_DB_KEY, FORK_CHOICE_DB_KEY, OP_POOL_DB_KEY}, migrate::MigratorConfig, - BeaconChainError, ProduceBlockVerification, + sync_committee_verification::Error as SyncCommitteeError, + BeaconChainError, ProduceBlockVerification }; use crate::{ builder::{BeaconChainBuilder, Witness}, @@ -48,6 +49,7 @@ use store::{config::StoreConfig, HotColdDB, ItemStore, LevelDB, MemoryStore}; use task_executor::{test_utils::TestRuntime, ShutdownReason}; use tree_hash::TreeHash; use types::sync_selection_proof::SyncSelectionProof; +use types::sync_committee_contribution::Error as ContributionError; pub use types::test_utils::generate_deterministic_keypairs; use types::{typenum::U4294967296, *}; @@ -1878,6 +1880,37 @@ where (honest_head, faulty_head) } + + pub fn process_sync_contributions( + &self, + sync_contributions: HarnessSyncContributions + ) -> Result<(), SyncCommitteeError> { + + let mut verified_contributions = Vec::with_capacity(sync_contributions.len()); + + for (_, contribution_and_proof) in sync_contributions { + if let Some(signed_contribution_and_proof) = contribution_and_proof { + let verified_contribution = self + .chain + .verify_sync_contribution_for_gossip(signed_contribution_and_proof)?; + + verified_contributions.push(verified_contribution); + + } else { + return Err(SyncCommitteeError::ContributionError(ContributionError::VerificationFail)); + } + } + + for verified_contribution in verified_contributions { + self + .chain + .add_contribution_to_block_inclusion_pool(verified_contribution)?; + } + + Ok(()) + + } + } // Junk `Debug` impl to satistfy certain trait bounds during testing. diff --git a/beacon_node/beacon_chain/tests/rewards.rs b/beacon_node/beacon_chain/tests/rewards.rs index 77b8e8e07af..a0220c6de65 100644 --- a/beacon_node/beacon_chain/tests/rewards.rs +++ b/beacon_node/beacon_chain/tests/rewards.rs @@ -1,57 +1,112 @@ #![cfg(test)] +use std::collections::HashMap; + use lazy_static::lazy_static; -use beacon_chain::types::{ - test_utils::TestRandom, BeaconState, BeaconStateAltair, BeaconStateBase, BeaconStateError, - ChainSpec, CloneConfig, Domain, Epoch, EthSpec, FixedVector, Hash256, Keypair, MainnetEthSpec, - MinimalEthSpec, RelativeEpoch, Slot -}; -use eth2::lighthouse::SyncCommitteeAttestationReward; +use beacon_chain::{types::{ + Epoch, EthSpec, Keypair, + MinimalEthSpec +}, test_utils::{BlockStrategy, AttestationStrategy, RelativeSyncCommittee}}; use beacon_chain::test_utils::{EphemeralHarnessType, BeaconChainHarness, generate_deterministic_keypairs}; -pub const SLOT: Slot = Slot::new(12); +pub const VALIDATOR_COUNT: usize = 64; + lazy_static! { - static ref KEYPAIRS: Vec = generate_deterministic_keypairs(8); + static ref KEYPAIRS: Vec = generate_deterministic_keypairs(VALIDATOR_COUNT); } fn get_harness() -> BeaconChainHarness> { + let mut spec = E::default_spec(); + + spec.altair_fork_epoch = Some(Epoch::new(0)); // We use altair for all tests + let harness = BeaconChainHarness::builder(E::default()) - .default_spec() + .spec(spec) .keypairs(KEYPAIRS.to_vec()) .fresh_ephemeral_store() .build(); - let state = harness.get_current_state(); - let target_slot = SLOT; - - harness - .add_attested_blocks_at_slots( - state, - Hash256::zero(), - (1..target_slot.as_u64()) - .map(Slot::new) - .collect::>() - .as_slice(), - (0..12).collect::>().as_slice(), - ); + harness.advance_slot(); harness } #[tokio::test] async fn test_sync_committee_rewards() { - let harness = get_harness::(); - let chain = harness.chain.clone(); + let num_block_produced = MinimalEthSpec::slots_per_epoch() * 5 + 2; // Avoid latest block at + // boundary + let harness = get_harness::(); + + let latest_block_root = harness + .extend_chain(num_block_produced as usize, BlockStrategy::OnCanonicalHead, AttestationStrategy::AllValidators) + .await; + + // Create and add sync committee message to op_pool + let sync_contributions = harness + .make_sync_contributions( + &harness.get_current_state(), + latest_block_root, + harness.get_current_slot(), + RelativeSyncCommittee::Current + ); + + harness + .process_sync_contributions(sync_contributions) + .unwrap(); - let block = chain.block_at_slot(SLOT, beacon_chain::WhenSlotSkipped::None).unwrap().unwrap(); + // Add block + let chain = &harness.chain; + let (head_state, head_state_root) = harness.get_current_state_and_root(); + let target_slot = harness.get_current_slot() + 1; - let mut state = harness.get_current_state(); + let (block_root, mut state) = harness + .add_attested_block_at_slot(target_slot, head_state, head_state_root, &[]) + .await + .unwrap(); + let block = harness.get_block(block_root).unwrap(); + let parent_block = chain + .get_blinded_block(&block.parent_root()) + .unwrap() + .unwrap(); + let parent_state = chain + .get_state(&parent_block.state_root(), Some(parent_block.slot())) + .unwrap() + .unwrap(); + let reward_payload = chain .compute_sync_committee_rewards(block.message(), &mut state) .unwrap(); - assert_eq!(reward_payload.len(), 8); + let rewards = reward_payload + .iter() + .map(|reward| (reward.validator_index, reward.reward)) + .collect::>(); + + let proposer_index = state.get_beacon_proposer_index(target_slot, &MinimalEthSpec::default_spec()).unwrap(); + + let mut mismatches = vec![]; + + for validator in state.validators() { + let validator_index = state.clone().get_validator_index(&validator.pubkey).unwrap().unwrap(); + let pre_state_balance = parent_state.balances()[validator_index]; + let post_state_balance = state.balances()[validator_index]; + let sync_committee_reward = rewards.get(&(validator_index as u64)).unwrap_or_else(|| &0); + + if validator_index == proposer_index { + continue; // Ignore proposer + } + + if pre_state_balance as i64 + *sync_committee_reward != post_state_balance as i64 { + mismatches.push(validator_index.to_string()); + } + } + + assert_eq!(mismatches.len(), + 0, + "{}", + format!("Expect 0 mismatches, but these validators have mismatches on balances: {} ", mismatches.join(",")) + ); } diff --git a/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs b/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs index 306e86714c6..dbfe395d9b7 100644 --- a/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs +++ b/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs @@ -4,7 +4,7 @@ use crate::{signature_sets::sync_aggregate_signature_set, VerifySignatures}; use safe_arith::SafeArith; use std::borrow::Cow; use types::consts::altair::{PROPOSER_WEIGHT, SYNC_REWARD_WEIGHT, WEIGHT_DENOMINATOR}; -use types::{BeaconState, ChainSpec, EthSpec, PublicKeyBytes, SyncAggregate, Unsigned}; +use types::{BeaconState, ChainSpec, EthSpec, PublicKeyBytes, SyncAggregate, Unsigned, Slot}; pub fn process_sync_aggregate( state: &mut BeaconState, @@ -69,6 +69,7 @@ pub fn compute_sync_aggregate_rewards( state: &BeaconState, 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)?; diff --git a/consensus/types/src/sync_committee_contribution.rs b/consensus/types/src/sync_committee_contribution.rs index c79ceb92fbb..ada0345b803 100644 --- a/consensus/types/src/sync_committee_contribution.rs +++ b/consensus/types/src/sync_committee_contribution.rs @@ -12,6 +12,7 @@ pub enum Error { SszTypesError(ssz_types::Error), AlreadySigned(usize), SubnetCountIsZero(ArithError), + VerificationFail, } /// An aggregation of `SyncCommitteeMessage`s, used in creating a `SignedContributionAndProof`. From 992b56d43cffb9f818925ca32e83421680792c97 Mon Sep 17 00:00:00 2001 From: navie Date: Sun, 8 Jan 2023 01:18:34 +0800 Subject: [PATCH 30/38] Clean up some of the code --- beacon_node/beacon_chain/tests/rewards.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon_node/beacon_chain/tests/rewards.rs b/beacon_node/beacon_chain/tests/rewards.rs index a0220c6de65..6827b343031 100644 --- a/beacon_node/beacon_chain/tests/rewards.rs +++ b/beacon_node/beacon_chain/tests/rewards.rs @@ -105,8 +105,8 @@ async fn test_sync_committee_rewards() { assert_eq!(mismatches.len(), 0, - "{}", - format!("Expect 0 mismatches, but these validators have mismatches on balances: {} ", mismatches.join(",")) + "Expect 0 mismatches, but these validators have mismatches on balance: {} ", + mismatches.join(",") ); } From 968fa24c1f5d625009a72d2740a1bd3a39f83482 Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 10 Jan 2023 00:06:37 +0800 Subject: [PATCH 31/38] Added log --- beacon_node/http_api/src/lib.rs | 2 +- beacon_node/http_api/src/sync_committee_rewards.rs | 1 + .../src/per_block_processing/altair/sync_committee.rs | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index c5ad1c2c8f4..e557294b284 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1708,7 +1708,7 @@ pub fn serve( .and(warp::path("rewards")) .and(chain_filter.clone()); - // TODO: POST beacon/rewards/sync_committee/{block_id} + // POST beacon/rewards/sync_committee/{block_id} let post_beacon_rewards_sync_committee = beacon_rewards_path .clone() .and(warp::path("sync_committee")) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 8ed9d6253f7..9c93692b99a 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -26,6 +26,7 @@ pub fn compute_sync_committee_rewards( .map_err(beacon_chain_error)?; let data = if reward_payload.is_empty() { + debug!(log, "compute_sync_committee_rewards returned empty"); None } else if validators.is_empty() { Some(reward_payload) diff --git a/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs b/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs index dbfe395d9b7..fb86a1bf2a3 100644 --- a/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs +++ b/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs @@ -4,7 +4,7 @@ use crate::{signature_sets::sync_aggregate_signature_set, VerifySignatures}; use safe_arith::SafeArith; use std::borrow::Cow; use types::consts::altair::{PROPOSER_WEIGHT, SYNC_REWARD_WEIGHT, WEIGHT_DENOMINATOR}; -use types::{BeaconState, ChainSpec, EthSpec, PublicKeyBytes, SyncAggregate, Unsigned, Slot}; +use types::{BeaconState, ChainSpec, EthSpec, PublicKeyBytes, SyncAggregate, Unsigned}; pub fn process_sync_aggregate( state: &mut BeaconState, From e29604b631fe064cc4d46ca71510c86e87ff2507 Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 10 Jan 2023 01:02:32 +0800 Subject: [PATCH 32/38] Refactored naming --- beacon_node/beacon_chain/src/sync_committee_rewards.rs | 6 +++--- beacon_node/http_api/src/sync_committee_rewards.rs | 8 ++++---- common/eth2/src/lib.rs | 2 +- common/eth2/src/lighthouse.rs | 4 ++-- ...e_attestation_rewards.rs => sync_committee_rewards.rs} | 6 +++--- .../src/per_block_processing/altair/sync_committee.rs | 1 - 6 files changed, 13 insertions(+), 14 deletions(-) rename common/eth2/src/lighthouse/{sync_committee_attestation_rewards.rs => sync_committee_rewards.rs} (75%) diff --git a/beacon_node/beacon_chain/src/sync_committee_rewards.rs b/beacon_node/beacon_chain/src/sync_committee_rewards.rs index 99b717ac7f2..a0ed0a6526a 100644 --- a/beacon_node/beacon_chain/src/sync_committee_rewards.rs +++ b/beacon_node/beacon_chain/src/sync_committee_rewards.rs @@ -1,6 +1,6 @@ use crate::{BeaconChain, BeaconChainError, BeaconChainTypes}; -use eth2::lighthouse::SyncCommitteeAttestationReward; +use eth2::lighthouse::SyncCommitteeReward; use state_processing::per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards; use types::{BeaconBlockRef, BeaconState, ExecPayload}; use std::collections::HashMap; @@ -10,7 +10,7 @@ impl BeaconChain { &self, block: BeaconBlockRef<'_, T::EthSpec, Payload>, state: &mut BeaconState, - ) -> Result, BeaconChainError> { + ) -> Result, BeaconChainError> { if block.slot() != state.slot() { return Err(BeaconChainError::BlockRewardSlotError); } @@ -67,7 +67,7 @@ impl BeaconChain { } else { *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards as i64 }; - SyncCommitteeAttestationReward { + SyncCommitteeReward { validator_index: *i as u64, reward } diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 9c93692b99a..093f2e1f010 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes, BeaconChainError}; use eth2::types::ValidatorId; -use eth2::lighthouse::{SyncCommitteeAttestationRewards, SyncCommitteeAttestationReward}; +use eth2::lighthouse::{SyncCommitteeRewards, SyncCommitteeReward}; use slog::{debug, Logger}; use state_processing::BlockReplayer; use types::{BeaconState, SignedBlindedBeaconBlock}; @@ -13,7 +13,7 @@ pub fn compute_sync_committee_rewards( block_id: BlockId, validators: Vec, log: Logger -) -> Result { +) -> Result { let (block, _) = block_id.blinded_block(&chain)?; @@ -49,12 +49,12 @@ pub fn compute_sync_committee_rewards( } }) }) - .collect::>() + .collect::>() ) }; - Ok(SyncCommitteeAttestationRewards{ + Ok(SyncCommitteeRewards{ execution_optimistic: None, finalized: None, data diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index d7350646580..00b664446d3 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -1029,7 +1029,7 @@ impl BeaconNodeHttpClient { /// `POST beacon/rewards/sync_committee` pub async fn post_beacon_rewards_sync_committee( &self, - rewards: &[Option>], + rewards: &[Option>], ) -> Result<(), Error> { let mut path = self.eth_path(V1)?; diff --git a/common/eth2/src/lighthouse.rs b/common/eth2/src/lighthouse.rs index db29fa89e38..50f345a38f8 100644 --- a/common/eth2/src/lighthouse.rs +++ b/common/eth2/src/lighthouse.rs @@ -3,7 +3,7 @@ mod attestation_performance; mod block_packing_efficiency; mod block_rewards; -mod sync_committee_attestation_rewards; +mod sync_committee_rewards; use crate::{ ok_or_error, @@ -27,7 +27,7 @@ pub use block_packing_efficiency::{ BlockPackingEfficiency, BlockPackingEfficiencyQuery, ProposerInfo, UniqueAttestation, }; pub use block_rewards::{AttestationRewards, BlockReward, BlockRewardMeta, BlockRewardsQuery}; -pub use sync_committee_attestation_rewards::{SyncCommitteeAttestationRewards, SyncCommitteeAttestationReward}; +pub use sync_committee_rewards::{SyncCommitteeRewards, SyncCommitteeReward}; pub use lighthouse_network::{types::SyncState, PeerInfo}; // Define "legacy" implementations of `Option` which use four bytes for encoding the union diff --git a/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs b/common/eth2/src/lighthouse/sync_committee_rewards.rs similarity index 75% rename from common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs rename to common/eth2/src/lighthouse/sync_committee_rewards.rs index 3dd4b4cdf1c..d360938adf8 100644 --- a/common/eth2/src/lighthouse/sync_committee_attestation_rewards.rs +++ b/common/eth2/src/lighthouse/sync_committee_rewards.rs @@ -4,17 +4,17 @@ use serde::{Deserialize, Serialize}; // All rewards in GWei #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] -pub struct SyncCommitteeAttestationRewards { +pub struct SyncCommitteeRewards { pub execution_optimistic: Option, pub finalized: Option, - pub data: Option> + pub data: Option> } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] -pub struct SyncCommitteeAttestationReward { +pub struct SyncCommitteeReward { pub validator_index: u64, // sync committee reward in gwei for the validator diff --git a/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs b/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs index fb86a1bf2a3..306e86714c6 100644 --- a/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs +++ b/consensus/state_processing/src/per_block_processing/altair/sync_committee.rs @@ -69,7 +69,6 @@ pub fn compute_sync_aggregate_rewards( state: &BeaconState, 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)?; From 0843f23231023119ea391b76d8c51b5a9cfe63a3 Mon Sep 17 00:00:00 2001 From: navie Date: Tue, 17 Jan 2023 22:13:39 +0800 Subject: [PATCH 33/38] Polish code according to PR comments --- .../src/sync_committee_rewards.rs | 72 +++++++++++-------- beacon_node/beacon_chain/src/test_utils.rs | 15 ++-- beacon_node/beacon_chain/tests/rewards.rs | 3 +- beacon_node/http_api/src/lib.rs | 15 +++- .../http_api/src/sync_committee_rewards.rs | 20 +++--- common/eth2/src/lighthouse.rs | 2 +- .../src/lighthouse/sync_committee_rewards.rs | 11 +-- .../types/src/sync_committee_contribution.rs | 1 - 8 files changed, 73 insertions(+), 66 deletions(-) diff --git a/beacon_node/beacon_chain/src/sync_committee_rewards.rs b/beacon_node/beacon_chain/src/sync_committee_rewards.rs index a0ed0a6526a..fb5b1f70c68 100644 --- a/beacon_node/beacon_chain/src/sync_committee_rewards.rs +++ b/beacon_node/beacon_chain/src/sync_committee_rewards.rs @@ -1,9 +1,12 @@ use crate::{BeaconChain, BeaconChainError, BeaconChainTypes}; use eth2::lighthouse::SyncCommitteeReward; +use safe_arith::SafeArith; use state_processing::per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards; +use store::RelativeEpoch; use types::{BeaconBlockRef, BeaconState, ExecPayload}; use std::collections::HashMap; +use slog::error; impl BeaconChain { pub fn compute_sync_committee_rewards>( @@ -14,9 +17,11 @@ impl BeaconChain { if block.slot() != state.slot() { return Err(BeaconChainError::BlockRewardSlotError); } - + let spec = &self.spec; + state.build_committee_cache(RelativeEpoch::Current, spec)?; + let sync_aggregate = block .body() .sync_aggregate()?; @@ -29,7 +34,13 @@ impl BeaconChain { .get_sync_committee_indices(&sync_committee)?; let (participant_reward_value, proposer_reward_per_bit) = compute_sync_aggregate_rewards(&state, spec) - .map_err(|_| BeaconChainError::SyncCommitteeRewardsSyncError)?; + .map_err(|e| { + error!( + self.log, "Error calculating sync aggregate rewards"; + "error" => ?e + ); + BeaconChainError::SyncCommitteeRewardsSyncError + })?; let mut balances = sync_committee_indices .iter() @@ -42,38 +53,41 @@ impl BeaconChain { // Apply rewards to participant balances. Keep track of proposer rewards for (validator_index, participant_bit) in sync_committee_indices.iter().zip(sync_aggregate.sync_committee_bits.iter()) { - let participant_balance = balances.get(validator_index); + let participant_balance = balances + .entry(*validator_index) + .or_insert(state.balances()[*validator_index]); if participant_bit { - if let Some(balance_value) = participant_balance { - balances.insert(*validator_index, balance_value + participant_reward_value); - } - *balances.get_mut(&proposer_index).unwrap() += proposer_reward_per_bit; - total_proposer_rewards += proposer_reward_per_bit; + participant_balance.safe_add_assign(participant_reward_value)?; + + balances + .entry(proposer_index) + .or_insert(state.balances()[proposer_index]) + .safe_add_assign(proposer_reward_per_bit)?; + + total_proposer_rewards.safe_add_assign(proposer_reward_per_bit)?; } else { - if let Some(balance_value) = participant_balance { - balances.insert(*validator_index, balance_value.saturating_sub(participant_reward_value)); - } + *participant_balance = participant_balance.saturating_sub(participant_reward_value); } } - if sync_committee.pubkeys.is_empty() { - Ok(Vec::new()) - } else { - Ok( - balances.iter().map(|(i, new_balance)| { - let reward = if *i != proposer_index { - *new_balance as i64 - state.balances()[*i] as i64 - } else { - *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards as i64 - }; - SyncCommitteeReward { - validator_index: *i as u64, - reward - } - }) - .collect() - ) - } + Ok( + sync_committee_indices.iter().map(|i| { + let new_balance = *balances + .entry(*i) + .or_insert(state.balances()[*i]) as i64; + + let reward = if *i != proposer_index { + new_balance - state.balances()[*i] as i64 + } else { + new_balance - state.balances()[*i] as i64 - total_proposer_rewards as i64 + }; + SyncCommitteeReward { + validator_index: *i as u64, + reward + } + }) + .collect() + ) } } diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 2693c96aecb..093c3979a91 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -49,7 +49,6 @@ use store::{config::StoreConfig, HotColdDB, ItemStore, LevelDB, MemoryStore}; use task_executor::{test_utils::TestRuntime, ShutdownReason}; use tree_hash::TreeHash; use types::sync_selection_proof::SyncSelectionProof; -use types::sync_committee_contribution::Error as ContributionError; pub use types::test_utils::generate_deterministic_keypairs; use types::{typenum::U4294967296, *}; @@ -1889,16 +1888,14 @@ where let mut verified_contributions = Vec::with_capacity(sync_contributions.len()); for (_, contribution_and_proof) in sync_contributions { - if let Some(signed_contribution_and_proof) = contribution_and_proof { - let verified_contribution = self - .chain - .verify_sync_contribution_for_gossip(signed_contribution_and_proof)?; + let signed_contribution_and_proof = contribution_and_proof.unwrap(); + + let verified_contribution = self + .chain + .verify_sync_contribution_for_gossip(signed_contribution_and_proof)?; - verified_contributions.push(verified_contribution); + verified_contributions.push(verified_contribution); - } else { - return Err(SyncCommitteeError::ContributionError(ContributionError::VerificationFail)); - } } for verified_contribution in verified_contributions { diff --git a/beacon_node/beacon_chain/tests/rewards.rs b/beacon_node/beacon_chain/tests/rewards.rs index 6827b343031..56ce7fc5b2a 100644 --- a/beacon_node/beacon_chain/tests/rewards.rs +++ b/beacon_node/beacon_chain/tests/rewards.rs @@ -33,8 +33,7 @@ fn get_harness() -> BeaconChainHarness> { #[tokio::test] async fn test_sync_committee_rewards() { - let num_block_produced = MinimalEthSpec::slots_per_epoch() * 5 + 2; // Avoid latest block at - // boundary + let num_block_produced = MinimalEthSpec::slots_per_epoch(); let harness = get_harness::(); let latest_block_root = harness diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index e557294b284..af7bfb6b4b0 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1721,10 +1721,21 @@ pub fn serve( block_id: BlockId, validators: Vec, log: Logger| { - blocking_json_task(move || sync_committee_rewards::compute_sync_committee_rewards( - chain, block_id, validators, log)) + blocking_json_task(move || { + let (rewards, execution_optimistic) = sync_committee_rewards::compute_sync_committee_rewards( + chain, + block_id, + validators, + log)?; + + Ok(rewards) + .map(api_types::GenericResponse::from) + .map(|resp| resp.add_execution_optimistic(execution_optimistic)) + + }) }); + /* * config */ diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index 093f2e1f010..d78fcd8fcc7 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,22 +1,22 @@ use std::sync::Arc; use beacon_chain::{BeaconChain, BeaconChainTypes, BeaconChainError}; use eth2::types::ValidatorId; -use eth2::lighthouse::{SyncCommitteeRewards, SyncCommitteeReward}; +use eth2::lighthouse::SyncCommitteeReward; use slog::{debug, Logger}; use state_processing::BlockReplayer; use types::{BeaconState, SignedBlindedBeaconBlock}; use warp_utils::reject::beacon_chain_error; -use crate::BlockId; +use crate::{BlockId, ExecutionOptimistic}; pub fn compute_sync_committee_rewards( chain: Arc>, block_id: BlockId, validators: Vec, log: Logger -) -> Result { +) -> Result<(Option>, ExecutionOptimistic), warp::Rejection> { - let (block, _) = block_id.blinded_block(&chain)?; + let (block, execution_optimistic) = block_id.blinded_block(&chain)?; let mut state = get_state_before_applying_block(chain.clone(), block.clone()) .map_err(beacon_chain_error)?; @@ -54,11 +54,7 @@ pub fn compute_sync_committee_rewards( }; - Ok(SyncCommitteeRewards{ - execution_optimistic: None, - finalized: None, - data - }) + Ok((data, execution_optimistic)) } @@ -70,19 +66,19 @@ fn get_state_before_applying_block( let parent_block: SignedBlindedBeaconBlock = chain .get_blinded_block(&block.parent_root())? - .ok_or_else(|| BeaconChainError::SyncCommitteeRewardsSyncError)?; + .ok_or_else(|| BeaconChainError::SyncCommitteeRewardsSyncError)?; //TODO let parent_state = chain .get_state(&parent_block.state_root(), Some(parent_block.slot()))? - .ok_or_else(|| BeaconChainError::SyncCommitteeRewardsSyncError)?; + .ok_or_else(|| BeaconChainError::SyncCommitteeRewardsSyncError)?; //TODO let replayer = BlockReplayer::new(parent_state, &chain.spec) .no_signature_verification() .state_root_iter([Ok((parent_block.state_root(), parent_block.slot()))].into_iter()) .minimal_block_root_verification() .apply_blocks(vec![], Some(block.slot())) - .map_err(|_: BeaconChainError| BeaconChainError::SyncCommitteeRewardsSyncError)?; + .map_err(|_: BeaconChainError| BeaconChainError::SyncCommitteeRewardsSyncError)?; //TODO Ok(replayer.into_state()) } diff --git a/common/eth2/src/lighthouse.rs b/common/eth2/src/lighthouse.rs index 50f345a38f8..7bc68854943 100644 --- a/common/eth2/src/lighthouse.rs +++ b/common/eth2/src/lighthouse.rs @@ -27,7 +27,7 @@ pub use block_packing_efficiency::{ BlockPackingEfficiency, BlockPackingEfficiencyQuery, ProposerInfo, UniqueAttestation, }; pub use block_rewards::{AttestationRewards, BlockReward, BlockRewardMeta, BlockRewardsQuery}; -pub use sync_committee_rewards::{SyncCommitteeRewards, SyncCommitteeReward}; +pub use sync_committee_rewards::SyncCommitteeReward; pub use lighthouse_network::{types::SyncState, PeerInfo}; // Define "legacy" implementations of `Option` which use four bytes for encoding the union diff --git a/common/eth2/src/lighthouse/sync_committee_rewards.rs b/common/eth2/src/lighthouse/sync_committee_rewards.rs index d360938adf8..b3200dafda2 100644 --- a/common/eth2/src/lighthouse/sync_committee_rewards.rs +++ b/common/eth2/src/lighthouse/sync_committee_rewards.rs @@ -3,19 +3,10 @@ use serde::{Deserialize, Serialize}; // Details about the rewards paid to sync committee members for attesting headers // All rewards in GWei -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] -pub struct SyncCommitteeRewards { - - pub execution_optimistic: Option, - - pub finalized: Option, - - pub data: Option> -} - #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct SyncCommitteeReward { + #[serde(with = "eth2_serde_utils::quoted_u64")] pub validator_index: u64, // sync committee reward in gwei for the validator pub reward: i64, diff --git a/consensus/types/src/sync_committee_contribution.rs b/consensus/types/src/sync_committee_contribution.rs index ada0345b803..c79ceb92fbb 100644 --- a/consensus/types/src/sync_committee_contribution.rs +++ b/consensus/types/src/sync_committee_contribution.rs @@ -12,7 +12,6 @@ pub enum Error { SszTypesError(ssz_types::Error), AlreadySigned(usize), SubnetCountIsZero(ArithError), - VerificationFail, } /// An aggregation of `SyncCommitteeMessage`s, used in creating a `SignedContributionAndProof`. From 1f894aa4c22cd5237c06c909664aaaf771508d43 Mon Sep 17 00:00:00 2001 From: navie Date: Wed, 18 Jan 2023 00:26:53 +0800 Subject: [PATCH 34/38] To be more specific with http status code it returns --- .../http_api/src/sync_committee_rewards.rs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index d78fcd8fcc7..aba635c7e80 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -5,7 +5,7 @@ use eth2::lighthouse::SyncCommitteeReward; use slog::{debug, Logger}; use state_processing::BlockReplayer; use types::{BeaconState, SignedBlindedBeaconBlock}; -use warp_utils::reject::beacon_chain_error; +use warp_utils::reject::{beacon_chain_error, custom_not_found}; use crate::{BlockId, ExecutionOptimistic}; pub fn compute_sync_committee_rewards( @@ -18,8 +18,7 @@ pub fn compute_sync_committee_rewards( let (block, execution_optimistic) = block_id.blinded_block(&chain)?; - let mut state = get_state_before_applying_block(chain.clone(), block.clone()) - .map_err(beacon_chain_error)?; + let mut state = get_state_before_applying_block(chain.clone(), block.clone())?; let reward_payload = chain .compute_sync_committee_rewards(block.message(), &mut state) @@ -62,23 +61,32 @@ pub fn compute_sync_committee_rewards( fn get_state_before_applying_block( chain: Arc>, block: SignedBlindedBeaconBlock -) -> Result, BeaconChainError> { +) -> Result, warp::reject::Rejection> { let parent_block: SignedBlindedBeaconBlock = chain - .get_blinded_block(&block.parent_root())? - .ok_or_else(|| BeaconChainError::SyncCommitteeRewardsSyncError)?; //TODO - + .get_blinded_block(&block.parent_root()) + .and_then(|maybe_block| { + maybe_block.ok_or(BeaconChainError::MissingBeaconBlock(block.parent_root())) + }) + .map_err(|e| { + custom_not_found(format!("Parent block is not available! {:?}", e)) + })?; let parent_state = chain - .get_state(&parent_block.state_root(), Some(parent_block.slot()))? - .ok_or_else(|| BeaconChainError::SyncCommitteeRewardsSyncError)?; //TODO + .get_state(&parent_block.state_root(), Some(parent_block.slot())) + .and_then(|maybe_state| { + maybe_state.ok_or(BeaconChainError::MissingBeaconState(parent_block.state_root())) + }) + .map_err(|e| { + custom_not_found(format!("Parent state is not available! {:?}", e)) + })?; let replayer = BlockReplayer::new(parent_state, &chain.spec) .no_signature_verification() .state_root_iter([Ok((parent_block.state_root(), parent_block.slot()))].into_iter()) .minimal_block_root_verification() .apply_blocks(vec![], Some(block.slot())) - .map_err(|_: BeaconChainError| BeaconChainError::SyncCommitteeRewardsSyncError)?; //TODO + .map_err(beacon_chain_error)?; Ok(replayer.into_state()) } From fa4fe11d388a79d14495e96524f8c14ee0185357 Mon Sep 17 00:00:00 2001 From: navie Date: Wed, 18 Jan 2023 00:52:27 +0800 Subject: [PATCH 35/38] Format some of the code --- beacon_node/beacon_chain/src/lib.rs | 2 +- .../src/sync_committee_rewards.rs | 40 +++++----- beacon_node/beacon_chain/src/test_utils.rs | 9 +-- beacon_node/beacon_chain/tests/main.rs | 2 +- beacon_node/beacon_chain/tests/rewards.rs | 66 +++++++++------- beacon_node/http_api/src/lib.rs | 24 +++--- .../http_api/src/sync_committee_rewards.rs | 76 ++++++++----------- common/eth2/src/lighthouse.rs | 2 +- .../src/lighthouse/sync_committee_rewards.rs | 2 - 9 files changed, 103 insertions(+), 120 deletions(-) diff --git a/beacon_node/beacon_chain/src/lib.rs b/beacon_node/beacon_chain/src/lib.rs index d3b1e53b7ed..ae3e98f9131 100644 --- a/beacon_node/beacon_chain/src/lib.rs +++ b/beacon_node/beacon_chain/src/lib.rs @@ -6,7 +6,6 @@ mod beacon_fork_choice_store; pub mod beacon_proposer_cache; mod beacon_snapshot; pub mod block_reward; -pub mod sync_committee_rewards; mod block_times_cache; mod block_verification; pub mod builder; @@ -41,6 +40,7 @@ pub mod schema_change; mod shuffling_cache; mod snapshot_cache; pub mod state_advance_timer; +pub mod sync_committee_rewards; pub mod sync_committee_verification; pub mod test_utils; mod timeout_rw_lock; diff --git a/beacon_node/beacon_chain/src/sync_committee_rewards.rs b/beacon_node/beacon_chain/src/sync_committee_rewards.rs index fb5b1f70c68..6b5f749d2ef 100644 --- a/beacon_node/beacon_chain/src/sync_committee_rewards.rs +++ b/beacon_node/beacon_chain/src/sync_committee_rewards.rs @@ -2,11 +2,11 @@ use crate::{BeaconChain, BeaconChainError, BeaconChainTypes}; use eth2::lighthouse::SyncCommitteeReward; use safe_arith::SafeArith; +use slog::error; use state_processing::per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards; +use std::collections::HashMap; use store::RelativeEpoch; use types::{BeaconBlockRef, BeaconState, ExecPayload}; -use std::collections::HashMap; -use slog::error; impl BeaconChain { pub fn compute_sync_committee_rewards>( @@ -17,24 +17,19 @@ impl BeaconChain { if block.slot() != state.slot() { return Err(BeaconChainError::BlockRewardSlotError); } - + let spec = &self.spec; state.build_committee_cache(RelativeEpoch::Current, spec)?; - let sync_aggregate = block - .body() - .sync_aggregate()?; + let sync_aggregate = block.body().sync_aggregate()?; - let sync_committee = state - .current_sync_committee()? - .clone(); + let sync_committee = state.current_sync_committee()?.clone(); - let sync_committee_indices = state - .get_sync_committee_indices(&sync_committee)?; + let sync_committee_indices = state.get_sync_committee_indices(&sync_committee)?; - let (participant_reward_value, proposer_reward_per_bit) = compute_sync_aggregate_rewards(&state, spec) - .map_err(|e| { + let (participant_reward_value, proposer_reward_per_bit) = + compute_sync_aggregate_rewards(&state, spec).map_err(|e| { error!( self.log, "Error calculating sync aggregate rewards"; "error" => ?e @@ -52,7 +47,10 @@ impl BeaconChain { balances.insert(proposer_index, state.balances()[proposer_index]); // Apply rewards to participant balances. Keep track of proposer rewards - for (validator_index, participant_bit) in sync_committee_indices.iter().zip(sync_aggregate.sync_committee_bits.iter()) { + for (validator_index, participant_bit) in sync_committee_indices + .iter() + .zip(sync_aggregate.sync_committee_bits.iter()) + { let participant_balance = balances .entry(*validator_index) .or_insert(state.balances()[*validator_index]); @@ -71,11 +69,10 @@ impl BeaconChain { } } - Ok( - sync_committee_indices.iter().map(|i| { - let new_balance = *balances - .entry(*i) - .or_insert(state.balances()[*i]) as i64; + Ok(sync_committee_indices + .iter() + .map(|i| { + let new_balance = *balances.entry(*i).or_insert(state.balances()[*i]) as i64; let reward = if *i != proposer_index { new_balance - state.balances()[*i] as i64 @@ -84,10 +81,9 @@ impl BeaconChain { }; SyncCommitteeReward { validator_index: *i as u64, - reward + reward, } }) - .collect() - ) + .collect()) } } diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 156f2efa9be..749487dc5aa 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -1984,9 +1984,8 @@ where pub fn process_sync_contributions( &self, - sync_contributions: HarnessSyncContributions + sync_contributions: HarnessSyncContributions, ) -> Result<(), SyncCommitteeError> { - let mut verified_contributions = Vec::with_capacity(sync_contributions.len()); for (_, contribution_and_proof) in sync_contributions { @@ -1997,19 +1996,15 @@ where .verify_sync_contribution_for_gossip(signed_contribution_and_proof)?; verified_contributions.push(verified_contribution); - } for verified_contribution in verified_contributions { - self - .chain + self.chain .add_contribution_to_block_inclusion_pool(verified_contribution)?; } Ok(()) - } - } // Junk `Debug` impl to satistfy certain trait bounds during testing. diff --git a/beacon_node/beacon_chain/tests/main.rs b/beacon_node/beacon_chain/tests/main.rs index b9845f5ca18..eceb4f2e85a 100644 --- a/beacon_node/beacon_chain/tests/main.rs +++ b/beacon_node/beacon_chain/tests/main.rs @@ -4,7 +4,7 @@ mod block_verification; mod merge; mod op_verification; mod payload_invalidation; +mod rewards; mod store_tests; mod sync_committee_verification; mod tests; -mod rewards; diff --git a/beacon_node/beacon_chain/tests/rewards.rs b/beacon_node/beacon_chain/tests/rewards.rs index 56ce7fc5b2a..e8c7430f484 100644 --- a/beacon_node/beacon_chain/tests/rewards.rs +++ b/beacon_node/beacon_chain/tests/rewards.rs @@ -2,12 +2,14 @@ use std::collections::HashMap; +use beacon_chain::test_utils::{ + generate_deterministic_keypairs, BeaconChainHarness, EphemeralHarnessType, +}; +use beacon_chain::{ + test_utils::{AttestationStrategy, BlockStrategy, RelativeSyncCommittee}, + types::{Epoch, EthSpec, Keypair, MinimalEthSpec}, +}; use lazy_static::lazy_static; -use beacon_chain::{types::{ - Epoch, EthSpec, Keypair, - MinimalEthSpec -}, test_utils::{BlockStrategy, AttestationStrategy, RelativeSyncCommittee}}; -use beacon_chain::test_utils::{EphemeralHarnessType, BeaconChainHarness, generate_deterministic_keypairs}; pub const VALIDATOR_COUNT: usize = 64; @@ -16,8 +18,8 @@ lazy_static! { } fn get_harness() -> BeaconChainHarness> { - let mut spec = E::default_spec(); - + let mut spec = E::default_spec(); + spec.altair_fork_epoch = Some(Epoch::new(0)); // We use altair for all tests let harness = BeaconChainHarness::builder(E::default()) @@ -33,21 +35,24 @@ fn get_harness() -> BeaconChainHarness> { #[tokio::test] async fn test_sync_committee_rewards() { - let num_block_produced = MinimalEthSpec::slots_per_epoch(); + let num_block_produced = MinimalEthSpec::slots_per_epoch(); let harness = get_harness::(); let latest_block_root = harness - .extend_chain(num_block_produced as usize, BlockStrategy::OnCanonicalHead, AttestationStrategy::AllValidators) + .extend_chain( + num_block_produced as usize, + BlockStrategy::OnCanonicalHead, + AttestationStrategy::AllValidators, + ) .await; // Create and add sync committee message to op_pool - let sync_contributions = harness - .make_sync_contributions( - &harness.get_current_state(), - latest_block_root, - harness.get_current_slot(), - RelativeSyncCommittee::Current - ); + let sync_contributions = harness.make_sync_contributions( + &harness.get_current_state(), + latest_block_root, + harness.get_current_slot(), + RelativeSyncCommittee::Current, + ); harness .process_sync_contributions(sync_contributions) @@ -55,7 +60,7 @@ async fn test_sync_committee_rewards() { // Add block let chain = &harness.chain; - let (head_state, head_state_root) = harness.get_current_state_and_root(); + let (head_state, head_state_root) = harness.get_current_state_and_root(); let target_slot = harness.get_current_slot() + 1; let (block_root, mut state) = harness @@ -72,7 +77,7 @@ async fn test_sync_committee_rewards() { .get_state(&parent_block.state_root(), Some(parent_block.slot())) .unwrap() .unwrap(); - + let reward_payload = chain .compute_sync_committee_rewards(block.message(), &mut state) .unwrap(); @@ -82,12 +87,18 @@ async fn test_sync_committee_rewards() { .map(|reward| (reward.validator_index, reward.reward)) .collect::>(); - let proposer_index = state.get_beacon_proposer_index(target_slot, &MinimalEthSpec::default_spec()).unwrap(); + let proposer_index = state + .get_beacon_proposer_index(target_slot, &MinimalEthSpec::default_spec()) + .unwrap(); let mut mismatches = vec![]; for validator in state.validators() { - let validator_index = state.clone().get_validator_index(&validator.pubkey).unwrap().unwrap(); + let validator_index = state + .clone() + .get_validator_index(&validator.pubkey) + .unwrap() + .unwrap(); let pre_state_balance = parent_state.balances()[validator_index]; let post_state_balance = state.balances()[validator_index]; let sync_committee_reward = rewards.get(&(validator_index as u64)).unwrap_or_else(|| &0); @@ -95,17 +106,16 @@ async fn test_sync_committee_rewards() { if validator_index == proposer_index { continue; // Ignore proposer } - + if pre_state_balance as i64 + *sync_committee_reward != post_state_balance as i64 { mismatches.push(validator_index.to_string()); } } - - assert_eq!(mismatches.len(), - 0, - "Expect 0 mismatches, but these validators have mismatches on balance: {} ", - mismatches.join(",") - ); - + assert_eq!( + mismatches.len(), + 0, + "Expect 0 mismatches, but these validators have mismatches on balance: {} ", + mismatches.join(",") + ); } diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index bbf5c6a3cc4..1399bb99a4f 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1722,20 +1722,18 @@ pub fn serve( block_id: BlockId, validators: Vec, log: Logger| { - blocking_json_task(move || { - let (rewards, execution_optimistic) = sync_committee_rewards::compute_sync_committee_rewards( - chain, - block_id, - validators, - log)?; - - Ok(rewards) - .map(api_types::GenericResponse::from) - .map(|resp| resp.add_execution_optimistic(execution_optimistic)) - - }) - }); + blocking_json_task(move || { + let (rewards, execution_optimistic) = + sync_committee_rewards::compute_sync_committee_rewards( + chain, block_id, validators, log, + )?; + Ok(rewards) + .map(api_types::GenericResponse::from) + .map(|resp| resp.add_execution_optimistic(execution_optimistic)) + }) + }, + ); /* * config diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index aba635c7e80..cf2a9583fb2 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -1,21 +1,19 @@ -use std::sync::Arc; -use beacon_chain::{BeaconChain, BeaconChainTypes, BeaconChainError}; -use eth2::types::ValidatorId; +use crate::{BlockId, ExecutionOptimistic}; +use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes}; use eth2::lighthouse::SyncCommitteeReward; +use eth2::types::ValidatorId; use slog::{debug, Logger}; use state_processing::BlockReplayer; +use std::sync::Arc; use types::{BeaconState, SignedBlindedBeaconBlock}; use warp_utils::reject::{beacon_chain_error, custom_not_found}; -use crate::{BlockId, ExecutionOptimistic}; pub fn compute_sync_committee_rewards( chain: Arc>, block_id: BlockId, validators: Vec, - log: Logger + log: Logger, ) -> Result<(Option>, ExecutionOptimistic), warp::Rejection> { - - let (block, execution_optimistic) = block_id.blinded_block(&chain)?; let mut state = get_state_before_applying_block(chain.clone(), block.clone())?; @@ -25,61 +23,49 @@ pub fn compute_sync_committee_rewards( .map_err(beacon_chain_error)?; let data = if reward_payload.is_empty() { - debug!(log, "compute_sync_committee_rewards returned empty"); - None - } else if validators.is_empty() { - Some(reward_payload) - } else { - Some( - reward_payload - .into_iter() - .filter(|reward| { - validators - .iter() - .any(|validator| match validator { - ValidatorId::Index(i) => { - reward.validator_index == *i - } - ValidatorId::PublicKey(pubkey) => { - match state.get_validator_index(pubkey) { - Ok(Some(i)) => { reward.validator_index == i as u64 } - _ => { false } - } - } - }) + debug!(log, "compute_sync_committee_rewards returned empty"); + None + } else if validators.is_empty() { + Some(reward_payload) + } else { + Some( + reward_payload + .into_iter() + .filter(|reward| { + validators.iter().any(|validator| match validator { + ValidatorId::Index(i) => reward.validator_index == *i, + ValidatorId::PublicKey(pubkey) => match state.get_validator_index(pubkey) { + Ok(Some(i)) => reward.validator_index == i as u64, + _ => false, + }, }) - .collect::>() - ) - }; - + }) + .collect::>(), + ) + }; Ok((data, execution_optimistic)) - - } -fn get_state_before_applying_block( +fn get_state_before_applying_block( chain: Arc>, - block: SignedBlindedBeaconBlock + block: SignedBlindedBeaconBlock, ) -> Result, warp::reject::Rejection> { - let parent_block: SignedBlindedBeaconBlock = chain .get_blinded_block(&block.parent_root()) .and_then(|maybe_block| { maybe_block.ok_or(BeaconChainError::MissingBeaconBlock(block.parent_root())) }) - .map_err(|e| { - custom_not_found(format!("Parent block is not available! {:?}", e)) - })?; + .map_err(|e| custom_not_found(format!("Parent block is not available! {:?}", e)))?; let parent_state = chain .get_state(&parent_block.state_root(), Some(parent_block.slot())) .and_then(|maybe_state| { - maybe_state.ok_or(BeaconChainError::MissingBeaconState(parent_block.state_root())) + maybe_state.ok_or(BeaconChainError::MissingBeaconState( + parent_block.state_root(), + )) }) - .map_err(|e| { - custom_not_found(format!("Parent state is not available! {:?}", e)) - })?; + .map_err(|e| custom_not_found(format!("Parent state is not available! {:?}", e)))?; let replayer = BlockReplayer::new(parent_state, &chain.spec) .no_signature_verification() diff --git a/common/eth2/src/lighthouse.rs b/common/eth2/src/lighthouse.rs index 7bc68854943..068abd693a2 100644 --- a/common/eth2/src/lighthouse.rs +++ b/common/eth2/src/lighthouse.rs @@ -27,8 +27,8 @@ pub use block_packing_efficiency::{ BlockPackingEfficiency, BlockPackingEfficiencyQuery, ProposerInfo, UniqueAttestation, }; pub use block_rewards::{AttestationRewards, BlockReward, BlockRewardMeta, BlockRewardsQuery}; -pub use sync_committee_rewards::SyncCommitteeReward; pub use lighthouse_network::{types::SyncState, PeerInfo}; +pub use sync_committee_rewards::SyncCommitteeReward; // Define "legacy" implementations of `Option` which use four bytes for encoding the union // selector. diff --git a/common/eth2/src/lighthouse/sync_committee_rewards.rs b/common/eth2/src/lighthouse/sync_committee_rewards.rs index b3200dafda2..cdd6850650c 100644 --- a/common/eth2/src/lighthouse/sync_committee_rewards.rs +++ b/common/eth2/src/lighthouse/sync_committee_rewards.rs @@ -5,10 +5,8 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct SyncCommitteeReward { - #[serde(with = "eth2_serde_utils::quoted_u64")] pub validator_index: u64, // sync committee reward in gwei for the validator pub reward: i64, - } From 7a150e651cb9282dbfa38c1fa31d69b666c47d05 Mon Sep 17 00:00:00 2001 From: navie Date: Fri, 20 Jan 2023 15:29:58 +0800 Subject: [PATCH 36/38] Fix lint error --- .../beacon_chain/src/beacon_block_reward.rs | 55 +++++++++++++++++++ .../src/sync_committee_rewards.rs | 9 +-- beacon_node/beacon_chain/tests/rewards.rs | 2 +- .../http_api/src/sync_committee_rewards.rs | 7 +-- 4 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 beacon_node/beacon_chain/src/beacon_block_reward.rs diff --git a/beacon_node/beacon_chain/src/beacon_block_reward.rs b/beacon_node/beacon_chain/src/beacon_block_reward.rs new file mode 100644 index 00000000000..675923e394d --- /dev/null +++ b/beacon_node/beacon_chain/src/beacon_block_reward.rs @@ -0,0 +1,55 @@ +use crate::{BeaconChain, BeaconChainError, BeaconChainTypes}; +use eth2::lighthouse::{AttestationRewards, BlockReward, BlockRewardMeta}; +use operation_pool::{AttMaxCover, MaxCover, RewardCache, SplitAttestation}; +use state_processing::{ + common::get_attesting_indices_from_state, + per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards, +}; +use types::{BeaconBlockRef, BeaconState, EthSpec, ExecPayload, Hash256}; + +impl BeaconChain { + pub fn compute_beacon_block_reward>( + &self, + block: BeaconBlockRef<'_, T::EthSpec, Payload>, + state: &BeaconState, + ) -> Result { + + + + + } + + fn compute_sync_aggregate_reward> ( + &self, + block: BeaconBlockRef<'_, T::EthSpec, Payload>, + state: &BeaconState, + ) -> Result { + + if let Ok(sync_aggregate) = block.body().sync_aggregate() { + let (_, proposer_reward_per_bit) = compute_sync_aggregate_rewards(state, &self.spec) + .map_err(|_| BeaconChainError::BlockRewardSyncError)?; + Ok(sync_aggregate.sync_committee_bits.num_set_bits() as u64 * proposer_reward_per_bit) + + } else { + Ok(0) + } + } + + fn compute_proposer_slashing_reward> ( + &self, + block: BeaconBlockRef<'_, T::EthSpec, Payload>, + state: &BeaconState, + ) -> Result { + + //TODO: need to take care using safe_add and safe_div + block + .body() + .proposer_slashings() + .iter() + .map(|proposer_slashing| { + state.get_validator(proposer_slashing.proposer_index).effective_balance / WHISTLEBLOWER_REWARD_QUOTIENT + }) + .sum() + + } +} diff --git a/beacon_node/beacon_chain/src/sync_committee_rewards.rs b/beacon_node/beacon_chain/src/sync_committee_rewards.rs index 6b5f749d2ef..3534f1dfc2b 100644 --- a/beacon_node/beacon_chain/src/sync_committee_rewards.rs +++ b/beacon_node/beacon_chain/src/sync_committee_rewards.rs @@ -29,7 +29,7 @@ impl BeaconChain { let sync_committee_indices = state.get_sync_committee_indices(&sync_committee)?; let (participant_reward_value, proposer_reward_per_bit) = - compute_sync_aggregate_rewards(&state, spec).map_err(|e| { + compute_sync_aggregate_rewards(state, spec).map_err(|e| { error!( self.log, "Error calculating sync aggregate rewards"; "error" => ?e @@ -53,14 +53,14 @@ impl BeaconChain { { let participant_balance = balances .entry(*validator_index) - .or_insert(state.balances()[*validator_index]); + .or_insert_with(|| state.balances()[*validator_index]); if participant_bit { participant_balance.safe_add_assign(participant_reward_value)?; balances .entry(proposer_index) - .or_insert(state.balances()[proposer_index]) + .or_insert_with(|| state.balances()[proposer_index]) .safe_add_assign(proposer_reward_per_bit)?; total_proposer_rewards.safe_add_assign(proposer_reward_per_bit)?; @@ -72,7 +72,8 @@ impl BeaconChain { Ok(sync_committee_indices .iter() .map(|i| { - let new_balance = *balances.entry(*i).or_insert(state.balances()[*i]) as i64; + let new_balance = + *balances.entry(*i).or_insert_with(|| state.balances()[*i]) as i64; let reward = if *i != proposer_index { new_balance - state.balances()[*i] as i64 diff --git a/beacon_node/beacon_chain/tests/rewards.rs b/beacon_node/beacon_chain/tests/rewards.rs index e8c7430f484..b61bea12429 100644 --- a/beacon_node/beacon_chain/tests/rewards.rs +++ b/beacon_node/beacon_chain/tests/rewards.rs @@ -101,7 +101,7 @@ async fn test_sync_committee_rewards() { .unwrap(); let pre_state_balance = parent_state.balances()[validator_index]; let post_state_balance = state.balances()[validator_index]; - let sync_committee_reward = rewards.get(&(validator_index as u64)).unwrap_or_else(|| &0); + let sync_committee_reward = rewards.get(&(validator_index as u64)).unwrap_or(&0); if validator_index == proposer_index { continue; // Ignore proposer diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index cf2a9583fb2..af0557773c3 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -54,16 +54,15 @@ fn get_state_before_applying_block( let parent_block: SignedBlindedBeaconBlock = chain .get_blinded_block(&block.parent_root()) .and_then(|maybe_block| { - maybe_block.ok_or(BeaconChainError::MissingBeaconBlock(block.parent_root())) + maybe_block.ok_or_else(|| BeaconChainError::MissingBeaconBlock(block.parent_root())) }) .map_err(|e| custom_not_found(format!("Parent block is not available! {:?}", e)))?; let parent_state = chain .get_state(&parent_block.state_root(), Some(parent_block.slot())) .and_then(|maybe_state| { - maybe_state.ok_or(BeaconChainError::MissingBeaconState( - parent_block.state_root(), - )) + maybe_state + .ok_or_else(|| BeaconChainError::MissingBeaconState(parent_block.state_root())) }) .map_err(|e| custom_not_found(format!("Parent state is not available! {:?}", e)))?; From 32bce39a63b7c087e612bfabf3c94c297dc74999 Mon Sep 17 00:00:00 2001 From: navie Date: Mon, 23 Jan 2023 22:20:59 +0800 Subject: [PATCH 37/38] Addressed comments --- .../beacon_chain/src/beacon_block_reward.rs | 55 ------------------- .../src/sync_committee_rewards.rs | 25 ++++----- .../http_api/src/sync_committee_rewards.rs | 4 +- 3 files changed, 13 insertions(+), 71 deletions(-) delete mode 100644 beacon_node/beacon_chain/src/beacon_block_reward.rs diff --git a/beacon_node/beacon_chain/src/beacon_block_reward.rs b/beacon_node/beacon_chain/src/beacon_block_reward.rs deleted file mode 100644 index 675923e394d..00000000000 --- a/beacon_node/beacon_chain/src/beacon_block_reward.rs +++ /dev/null @@ -1,55 +0,0 @@ -use crate::{BeaconChain, BeaconChainError, BeaconChainTypes}; -use eth2::lighthouse::{AttestationRewards, BlockReward, BlockRewardMeta}; -use operation_pool::{AttMaxCover, MaxCover, RewardCache, SplitAttestation}; -use state_processing::{ - common::get_attesting_indices_from_state, - per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards, -}; -use types::{BeaconBlockRef, BeaconState, EthSpec, ExecPayload, Hash256}; - -impl BeaconChain { - pub fn compute_beacon_block_reward>( - &self, - block: BeaconBlockRef<'_, T::EthSpec, Payload>, - state: &BeaconState, - ) -> Result { - - - - - } - - fn compute_sync_aggregate_reward> ( - &self, - block: BeaconBlockRef<'_, T::EthSpec, Payload>, - state: &BeaconState, - ) -> Result { - - if let Ok(sync_aggregate) = block.body().sync_aggregate() { - let (_, proposer_reward_per_bit) = compute_sync_aggregate_rewards(state, &self.spec) - .map_err(|_| BeaconChainError::BlockRewardSyncError)?; - Ok(sync_aggregate.sync_committee_bits.num_set_bits() as u64 * proposer_reward_per_bit) - - } else { - Ok(0) - } - } - - fn compute_proposer_slashing_reward> ( - &self, - block: BeaconBlockRef<'_, T::EthSpec, Payload>, - state: &BeaconState, - ) -> Result { - - //TODO: need to take care using safe_add and safe_div - block - .body() - .proposer_slashings() - .iter() - .map(|proposer_slashing| { - state.get_validator(proposer_slashing.proposer_index).effective_balance / WHISTLEBLOWER_REWARD_QUOTIENT - }) - .sum() - - } -} diff --git a/beacon_node/beacon_chain/src/sync_committee_rewards.rs b/beacon_node/beacon_chain/src/sync_committee_rewards.rs index 3534f1dfc2b..b87736bd607 100644 --- a/beacon_node/beacon_chain/src/sync_committee_rewards.rs +++ b/beacon_node/beacon_chain/src/sync_committee_rewards.rs @@ -37,14 +37,10 @@ impl BeaconChain { BeaconChainError::SyncCommitteeRewardsSyncError })?; - let mut balances = sync_committee_indices - .iter() - .map(|i| (*i, state.balances()[*i])) - .collect::>(); + let mut balances = HashMap::::new(); let mut total_proposer_rewards = 0; let proposer_index = state.get_beacon_proposer_index(block.slot(), spec)?; - balances.insert(proposer_index, state.balances()[proposer_index]); // Apply rewards to participant balances. Keep track of proposer rewards for (validator_index, participant_bit) in sync_committee_indices @@ -69,21 +65,22 @@ impl BeaconChain { } } - Ok(sync_committee_indices + Ok(balances .iter() - .map(|i| { - let new_balance = - *balances.entry(*i).or_insert_with(|| state.balances()[*i]) as i64; - + .filter_map(|(i, new_balance)| { let reward = if *i != proposer_index { - new_balance - state.balances()[*i] as i64 + *new_balance as i64 - state.balances()[*i] as i64 + } else if sync_committee_indices.contains(&i) { + *new_balance as i64 + - state.balances()[*i] as i64 + - total_proposer_rewards as i64 } else { - new_balance - state.balances()[*i] as i64 - total_proposer_rewards as i64 + return None; }; - SyncCommitteeReward { + Some(SyncCommitteeReward { validator_index: *i as u64, reward, - } + }) }) .collect()) } diff --git a/beacon_node/http_api/src/sync_committee_rewards.rs b/beacon_node/http_api/src/sync_committee_rewards.rs index af0557773c3..ae369115d5c 100644 --- a/beacon_node/http_api/src/sync_committee_rewards.rs +++ b/beacon_node/http_api/src/sync_committee_rewards.rs @@ -16,7 +16,7 @@ pub fn compute_sync_committee_rewards( ) -> Result<(Option>, ExecutionOptimistic), warp::Rejection> { let (block, execution_optimistic) = block_id.blinded_block(&chain)?; - let mut state = get_state_before_applying_block(chain.clone(), block.clone())?; + let mut state = get_state_before_applying_block(chain.clone(), &block)?; let reward_payload = chain .compute_sync_committee_rewards(block.message(), &mut state) @@ -49,7 +49,7 @@ pub fn compute_sync_committee_rewards( fn get_state_before_applying_block( chain: Arc>, - block: SignedBlindedBeaconBlock, + block: &SignedBlindedBeaconBlock, ) -> Result, warp::reject::Rejection> { let parent_block: SignedBlindedBeaconBlock = chain .get_blinded_block(&block.parent_root()) From 1d746c0f58d464f56c7ce94d740a8ecffbb720db Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Tue, 24 Jan 2023 12:39:54 +1100 Subject: [PATCH 38/38] Fix Clippy --- beacon_node/beacon_chain/src/sync_committee_rewards.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/beacon_chain/src/sync_committee_rewards.rs b/beacon_node/beacon_chain/src/sync_committee_rewards.rs index b87736bd607..561fed1a86a 100644 --- a/beacon_node/beacon_chain/src/sync_committee_rewards.rs +++ b/beacon_node/beacon_chain/src/sync_committee_rewards.rs @@ -70,7 +70,7 @@ impl BeaconChain { .filter_map(|(i, new_balance)| { let reward = if *i != proposer_index { *new_balance as i64 - state.balances()[*i] as i64 - } else if sync_committee_indices.contains(&i) { + } else if sync_committee_indices.contains(i) { *new_balance as i64 - state.balances()[*i] as i64 - total_proposer_rewards as i64