diff --git a/node/core/backing/src/lib.rs b/node/core/backing/src/lib.rs index 9af0d6046b96..fee4d0df2567 100644 --- a/node/core/backing/src/lib.rs +++ b/node/core/backing/src/lib.rs @@ -115,7 +115,7 @@ use statement_table::{ }, Config as TableConfig, Context as TableContextTrait, Table, }; -use util::runtime::RuntimeInfo; +use util::{request_runtime_api_version, runtime::RuntimeInfo}; mod error; @@ -127,6 +127,9 @@ mod tests; const LOG_TARGET: &str = "parachain::candidate-backing"; +/// Used prior to runtime API version 6. +const LEGACY_MIN_BACKING_VOTES: u32 = 2; + /// PoV data to validate. enum PoVData { /// Already available (from candidate selection). @@ -998,9 +1001,19 @@ async fn construct_per_relay_parent_state( let session_index = try_runtime_api!(runtime_info.get_session_index_for_child(ctx.sender(), parent).await); + let runtime_api_version = try_runtime_api!(request_runtime_api_version(parent, ctx.sender()) + .await + .await + .map_err(Error::RuntimeApiUnavailable)?); + let minimum_backing_votes = - runtime_info.get_min_backing_votes(ctx.sender(), session_index, parent).await; - // TODO: if this does not exist, fall back to the hardcoded 2 value. + if runtime_api_version >= RuntimeApiRequest::MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT { + try_runtime_api!( + runtime_info.get_min_backing_votes(ctx.sender(), session_index, parent).await + ) + } else { + LEGACY_MIN_BACKING_VOTES + }; let (validators, groups, cores) = futures::try_join!( request_validators(parent, ctx.sender()).await, @@ -1015,7 +1028,6 @@ async fn construct_per_relay_parent_state( let validators: Vec<_> = try_runtime_api!(validators); let (validator_groups, group_rotation_info) = try_runtime_api!(groups); let cores = try_runtime_api!(cores); - let minimum_backing_votes = try_runtime_api!(minimum_backing_votes); let signing_context = SigningContext { parent_hash: parent, session_index }; let validator = diff --git a/node/core/backing/src/tests/mod.rs b/node/core/backing/src/tests/mod.rs index 5bb8326d409c..e23eb51983d5 100644 --- a/node/core/backing/src/tests/mod.rs +++ b/node/core/backing/src/tests/mod.rs @@ -262,6 +262,16 @@ async fn test_startup(virtual_overseer: &mut VirtualOverseer, test_state: &TestS } ); + // Check that subsystem job issues a request for the runtime API version. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::Version(tx)) + ) if parent == test_state.relay_parent => { + tx.send(Ok(RuntimeApiRequest::MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT)).unwrap(); + } + ); + // Check if subsystem job issues a request for the minimum backing votes. // This may or may not happen, depending if the minimum backing votes is already cached in the // RuntimeInfo. diff --git a/node/core/backing/src/tests/prospective_parachains.rs b/node/core/backing/src/tests/prospective_parachains.rs index 93a8e94b98de..a08c4b1fb070 100644 --- a/node/core/backing/src/tests/prospective_parachains.rs +++ b/node/core/backing/src/tests/prospective_parachains.rs @@ -153,6 +153,16 @@ async fn activate_leaf( } ); + // Check that subsystem job issues a request for the runtime API version. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::Version(tx)) + ) if parent == hash => { + tx.send(Ok(RuntimeApiRequest::MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT)).unwrap(); + } + ); + // Check if subsystem job issues a request for the minimum backing votes. // This may or may not happen, depending if the minimum backing votes is already cached in // the `RuntimeInfo`. diff --git a/node/core/runtime-api/src/lib.rs b/node/core/runtime-api/src/lib.rs index 37e63ff673cd..c33e057d4362 100644 --- a/node/core/runtime-api/src/lib.rs +++ b/node/core/runtime-api/src/lib.rs @@ -455,9 +455,6 @@ where Request::Authorities(sender) => query!(Authorities, authorities(), ver = 1, sender), Request::Validators(sender) => query!(Validators, validators(), ver = 1, sender), - Request::MinimumBackingVotes(sender) => - query!(MinimumBackingVotes, minimum_backing_votes(), ver = 1, sender), - Request::ValidatorGroups(sender) => { query!(ValidatorGroups, validator_groups(), ver = 1, sender) }, @@ -559,6 +556,12 @@ where ver = Request::SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT, sender ), + Request::MinimumBackingVotes(sender) => query!( + MinimumBackingVotes, + minimum_backing_votes(), + ver = Request::MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT, + sender + ), Request::StagingParaBackingState(para, sender) => { query!( diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 392781783319..f44179096ab4 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -659,6 +659,8 @@ pub fn maybe_compress_pov(pov: PoV) -> PoV { /// How many votes we need to consider a candidate backed. /// /// WARNING: This has to be kept in sync with the runtime check in the inclusion module. +/// The min threshold has been added to the HostConfiguration and after the runtime API for querying +/// it, `minimum_backing_votes`, is moved from vstaging to production, we can remove this. pub fn minimum_votes(n_validators: usize) -> usize { std::cmp::min(2, n_validators) } diff --git a/node/service/src/fake_runtime_api.rs b/node/service/src/fake_runtime_api.rs index f8eec2143352..d9553afa024b 100644 --- a/node/service/src/fake_runtime_api.rs +++ b/node/service/src/fake_runtime_api.rs @@ -121,10 +121,6 @@ sp_api::impl_runtime_apis! { unimplemented!() } - fn minimum_backing_votes() -> u32 { - unimplemented!() - } - fn validator_groups() -> (Vec>, GroupRotationInfo) { unimplemented!() } diff --git a/node/subsystem-types/src/messages.rs b/node/subsystem-types/src/messages.rs index aafec7c8bbee..13759a12d395 100644 --- a/node/subsystem-types/src/messages.rs +++ b/node/subsystem-types/src/messages.rs @@ -721,6 +721,9 @@ impl RuntimeApiRequest { /// `SubmitReportDisputeLost` pub const SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT: u32 = 5; + /// `MinimumBackingVotes` + pub const MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT: u32 = 6; + /// Minimum version for backing state, required for async backing. /// /// 99 for now, should be adjusted to VSTAGING/actual runtime version once released. diff --git a/primitives/src/runtime_api.rs b/primitives/src/runtime_api.rs index d7eadc43ed69..86aca6c9bc6f 100644 --- a/primitives/src/runtime_api.rs +++ b/primitives/src/runtime_api.rs @@ -240,8 +240,11 @@ sp_api::decl_runtime_apis! { key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, ) -> Option<()>; + /***** Staging *****/ + /// Get the minimum number of backing votes for a parachain candidate. - /// TODO: bump api version here? + /// This is a staging method! Do not use on production runtimes! + #[api_version(6)] fn minimum_backing_votes() -> u32; /***** Asynchronous backing *****/ diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 9555eb176d07..448f018384d8 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -1894,10 +1894,6 @@ sp_api::impl_runtime_apis! { parachains_runtime_api_impl::validators::() } - fn minimum_backing_votes() -> u32 { - parachains_runtime_api_impl::minimum_backing_votes::() - } - fn validator_groups() -> (Vec>, GroupRotationInfo) { parachains_runtime_api_impl::validator_groups::() } diff --git a/runtime/parachains/src/runtime_api_impl/v5.rs b/runtime/parachains/src/runtime_api_impl/v5.rs index 1f88833e2749..cd1579689733 100644 --- a/runtime/parachains/src/runtime_api_impl/v5.rs +++ b/runtime/parachains/src/runtime_api_impl/v5.rs @@ -38,12 +38,6 @@ pub fn validators() -> Vec { >::active_validator_keys() } -/// Implementation of the `minimum_backing_votes` function of the runtime API. -pub fn minimum_backing_votes() -> u32 { - let config = >::config(); - config.minimum_backing_votes -} - /// Implementation for the `validator_groups` function of the runtime API. pub fn validator_groups( ) -> (Vec>, GroupRotationInfo>) { diff --git a/runtime/parachains/src/runtime_api_impl/vstaging.rs b/runtime/parachains/src/runtime_api_impl/vstaging.rs index 5406428377d0..7446e769d845 100644 --- a/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -118,3 +118,9 @@ pub fn backing_state( pub fn async_backing_params() -> AsyncBackingParams { >::config().async_backing_params } + +/// Implementation of the `minimum_backing_votes` function of the runtime API. +pub fn minimum_backing_votes() -> u32 { + let config = >::config(); + config.minimum_backing_votes +} diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index 5b9d374ae3b7..ea7639ee3a48 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -1697,10 +1697,6 @@ sp_api::impl_runtime_apis! { parachains_runtime_api_impl::validators::() } - fn minimum_backing_votes() -> u32 { - parachains_runtime_api_impl::minimum_backing_votes::() - } - fn validator_groups() -> (Vec>, GroupRotationInfo) { parachains_runtime_api_impl::validator_groups::() } diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index ec45fb1a289e..f02936d16b07 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -46,7 +46,9 @@ use runtime_parachains::{ inclusion::{AggregateMessageOrigin, UmpQueueId}, initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras, paras_inherent as parachains_paras_inherent, - runtime_api_impl::v5 as parachains_runtime_api_impl, + runtime_api_impl::{ + v5 as parachains_runtime_api_impl, vstaging as parachains_staging_runtime_api_impl, + }, scheduler as parachains_scheduler, session_info as parachains_session_info, shared as parachains_shared, }; @@ -1715,15 +1717,12 @@ sp_api::impl_runtime_apis! { } } + #[api_version(6)] impl primitives::runtime_api::ParachainHost for Runtime { fn validators() -> Vec { parachains_runtime_api_impl::validators::() } - fn minimum_backing_votes() -> u32 { - parachains_runtime_api_impl::minimum_backing_votes::() - } - fn validator_groups() -> (Vec>, GroupRotationInfo) { parachains_runtime_api_impl::validator_groups::() } @@ -1849,6 +1848,10 @@ sp_api::impl_runtime_apis! { key_ownership_proof, ) } + + fn minimum_backing_votes() -> u32 { + parachains_staging_runtime_api_impl::minimum_backing_votes::() + } } #[api_version(3)] diff --git a/runtime/test-runtime/src/lib.rs b/runtime/test-runtime/src/lib.rs index 154ee6001f63..b2397299430d 100644 --- a/runtime/test-runtime/src/lib.rs +++ b/runtime/test-runtime/src/lib.rs @@ -826,10 +826,6 @@ sp_api::impl_runtime_apis! { runtime_impl::validators::() } - fn minimum_backing_votes() -> u32 { - runtime_impl::minimum_backing_votes::() - } - fn validator_groups() -> (Vec>, GroupRotationInfo) { runtime_impl::validator_groups::() } diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index 66c5a9d08044..232045ab9f78 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -1567,10 +1567,6 @@ sp_api::impl_runtime_apis! { parachains_runtime_api_impl::validators::() } - fn minimum_backing_votes() -> u32 { - parachains_runtime_api_impl::minimum_backing_votes::() - } - fn validator_groups() -> (Vec>, GroupRotationInfo) { parachains_runtime_api_impl::validator_groups::() }