diff --git a/client/beefy/src/lib.rs b/client/beefy/src/lib.rs index 9b2bf383df8ef..4dceccafa290a 100644 --- a/client/beefy/src/lib.rs +++ b/client/beefy/src/lib.rs @@ -27,7 +27,7 @@ use sc_network_gossip::{GossipEngine, Network as GossipNetwork}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_keystore::SyncCryptoStorePtr; -use sp_runtime::traits::Block; +use sp_runtime::traits::{Block, NumberFor}; use beefy_primitives::BeefyApi; @@ -111,7 +111,7 @@ where B: Block, BE: Backend, C: Client, - C::Api: BeefyApi, + C::Api: BeefyApi>, N: GossipNetwork + Clone + Send + 'static, { /// BEEFY client @@ -142,7 +142,7 @@ where B: Block, BE: Backend, C: Client, - C::Api: BeefyApi, + C::Api: BeefyApi>, N: GossipNetwork + Clone + Send + 'static, { let BeefyParams { diff --git a/client/beefy/src/worker.rs b/client/beefy/src/worker.rs index 0c7d8d4ffdc9c..1e38ae0fcff50 100644 --- a/client/beefy/src/worker.rs +++ b/client/beefy/src/worker.rs @@ -100,7 +100,7 @@ where B: Block + Codec, BE: Backend, C: Client, - C::Api: BeefyApi, + C::Api: BeefyApi>, { /// Return a new BEEFY worker instance. /// @@ -146,7 +146,7 @@ where B: Block, BE: Backend, C: Client, - C::Api: BeefyApi, + C::Api: BeefyApi>, { /// Return `true`, if we should vote on block `number` fn should_vote_on(&self, number: NumberFor) -> bool { @@ -247,14 +247,19 @@ where debug!(target: "beefy", "🥩 New Rounds for id: {:?}", id); - self.best_beefy_block = Some(*notification.header.number()); + let at = BlockId::hash(notification.header.hash()); + let session_boundary = self.client.runtime_api().get_session_boundary(&at).ok(); + self.best_beefy_block = session_boundary.clone(); self.beefy_best_block_sender .notify(|| Ok::<_, ()>(notification.hash.clone())) .expect("forwards closure result; the closure always returns Ok; qed."); - // this metric is kind of 'fake'. Best BEEFY block should only be updated once we - // have a signed commitment for the block. Remove once the above TODO is done. - metric_set!(self, beefy_best_block, *notification.header.number()); + // this metric is kind of 'fake'. Best BEEFY block should only be updated once + // we have a signed commitment for the block. Remove once the above TODO is + // done. + if let Some(session_boundary) = session_boundary { + metric_set!(self, beefy_best_block, session_boundary); + } } } diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 4cf793a9b4739..81509301a8e7c 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -494,6 +494,7 @@ pub mod pallet { Validators::::put(initial_validators_0); >::put(queued_keys); + SessionStart::::put(T::BlockNumber::default()); T::SessionManager::start_session(0); } @@ -509,6 +510,11 @@ pub mod pallet { #[pallet::getter(fn current_index)] pub type CurrentIndex = StorageValue<_, SessionIndex, ValueQuery>; + /// Block number at which the current session began + #[pallet::storage] + #[pallet::getter(fn session_start)] + pub type SessionStart = StorageValue<_, T::BlockNumber, ValueQuery>; + /// True if the underlying economic identities or weighting behind the validators /// has changed in the queued validator set. #[pallet::storage] @@ -573,6 +579,7 @@ pub mod pallet { fn on_initialize(n: T::BlockNumber) -> Weight { if T::ShouldEndSession::should_end_session(n) { Self::rotate_session(); + SessionStart::::put(n); T::BlockWeights::get().max_block } else { // NOTE: the non-database part of the weight for `should_end_session(n)` is @@ -899,6 +906,11 @@ impl Pallet { fn clear_key_owner(id: KeyTypeId, key_data: &[u8]) { >::remove((id, key_data)); } + + /// Returns the block number at which the session began + pub fn get_session_boundary() -> T::BlockNumber { + Pallet::::session_start() + } } impl ValidatorRegistration for Pallet { diff --git a/primitives/beefy/src/lib.rs b/primitives/beefy/src/lib.rs index 8dbdd66f3559b..7ce07b75997e8 100644 --- a/primitives/beefy/src/lib.rs +++ b/primitives/beefy/src/lib.rs @@ -156,10 +156,12 @@ pub struct VoteMessage { sp_api::decl_runtime_apis! { /// API necessary for BEEFY voters. - pub trait BeefyApi + pub trait BeefyApi { /// Return the current active BEEFY validator set fn validator_set() -> Option>; + /// Returns the block number at which the current session began + fn get_session_boundary() -> BlockNumber; } }