Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 5feadf4

Browse files
committed
move min backing votes const to runtime
also cache it per-session in the backing subsystem Signed-off-by: alindima <[email protected]>
1 parent aba8bee commit 5feadf4

File tree

20 files changed

+226
-66
lines changed

20 files changed

+226
-66
lines changed

node/core/backing/src/lib.rs

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ use futures::{
8080

8181
use error::{Error, FatalResult};
8282
use polkadot_node_primitives::{
83-
minimum_votes, AvailableData, InvalidCandidate, PoV, SignedFullStatementWithPVD,
84-
StatementWithPVD, ValidationResult,
83+
AvailableData, InvalidCandidate, PoV, SignedFullStatementWithPVD, StatementWithPVD,
84+
ValidationResult,
8585
};
8686
use polkadot_node_subsystem::{
8787
messages::{
@@ -96,8 +96,7 @@ use polkadot_node_subsystem::{
9696
use polkadot_node_subsystem_util::{
9797
self as util,
9898
backing_implicit_view::{FetchError as ImplicitViewFetchError, View as ImplicitView},
99-
request_from_runtime, request_session_index_for_child, request_validator_groups,
100-
request_validators,
99+
request_from_runtime, request_validator_groups, request_validators,
101100
runtime::{prospective_parachains_mode, ProspectiveParachainsMode},
102101
Validator,
103102
};
@@ -116,6 +115,7 @@ use statement_table::{
116115
},
117116
Config as TableConfig, Context as TableContextTrait, Table,
118117
};
118+
use util::runtime::RuntimeInfo;
119119

120120
mod error;
121121

@@ -219,6 +219,8 @@ struct PerRelayParentState {
219219
awaiting_validation: HashSet<CandidateHash>,
220220
/// Data needed for retrying in case of `ValidatedCandidateCommand::AttestNoPoV`.
221221
fallbacks: HashMap<CandidateHash, AttestingData>,
222+
/// The minimum backing votes threshold.
223+
minimum_backing_votes: u32,
222224
}
223225

224226
struct PerCandidateState {
@@ -275,6 +277,8 @@ struct State {
275277
background_validation_tx: mpsc::Sender<(Hash, ValidatedCandidateCommand)>,
276278
/// The handle to the keystore used for signing.
277279
keystore: KeystorePtr,
280+
/// The minimum backing votes threshold.
281+
runtime_info: RuntimeInfo,
278282
}
279283

280284
impl State {
@@ -289,6 +293,7 @@ impl State {
289293
per_candidate: HashMap::new(),
290294
background_validation_tx,
291295
keystore,
296+
runtime_info: RuntimeInfo::new(None),
292297
}
293298
}
294299
}
@@ -400,8 +405,8 @@ impl TableContextTrait for TableContext {
400405
self.groups.get(group).map_or(false, |g| g.iter().any(|a| a == authority))
401406
}
402407

403-
fn requisite_votes(&self, group: &ParaId) -> usize {
404-
self.groups.get(group).map_or(usize::MAX, |g| minimum_votes(g.len()))
408+
fn get_group_size(&self, group: &ParaId) -> Option<usize> {
409+
self.groups.get(group).map(|g| g.len())
405410
}
406411
}
407412

@@ -943,7 +948,14 @@ async fn handle_active_leaves_update<Context>(
943948

944949
// construct a `PerRelayParent` from the runtime API
945950
// and insert it.
946-
let per = construct_per_relay_parent_state(ctx, maybe_new, &state.keystore, mode).await?;
951+
let per = construct_per_relay_parent_state(
952+
ctx,
953+
maybe_new,
954+
&state.keystore,
955+
&mut state.runtime_info,
956+
mode,
957+
)
958+
.await?;
947959

948960
if let Some(per) = per {
949961
state.per_relay_parent.insert(maybe_new, per);
@@ -959,6 +971,7 @@ async fn construct_per_relay_parent_state<Context>(
959971
ctx: &mut Context,
960972
relay_parent: Hash,
961973
keystore: &KeystorePtr,
974+
runtime_info: &mut RuntimeInfo,
962975
mode: ProspectiveParachainsMode,
963976
) -> Result<Option<PerRelayParentState>, Error> {
964977
macro_rules! try_runtime_api {
@@ -983,10 +996,14 @@ async fn construct_per_relay_parent_state<Context>(
983996

984997
let parent = relay_parent;
985998

986-
let (validators, groups, session_index, cores) = futures::try_join!(
999+
let session_index =
1000+
try_runtime_api!(runtime_info.get_session_index_for_child(ctx.sender(), parent).await);
1001+
let minimum_backing_votes =
1002+
runtime_info.get_min_backing_votes(ctx.sender(), session_index, parent).await;
1003+
1004+
let (validators, groups, cores) = futures::try_join!(
9871005
request_validators(parent, ctx.sender()).await,
9881006
request_validator_groups(parent, ctx.sender()).await,
989-
request_session_index_for_child(parent, ctx.sender()).await,
9901007
request_from_runtime(parent, ctx.sender(), |tx| {
9911008
RuntimeApiRequest::AvailabilityCores(tx)
9921009
},)
@@ -996,8 +1013,8 @@ async fn construct_per_relay_parent_state<Context>(
9961013

9971014
let validators: Vec<_> = try_runtime_api!(validators);
9981015
let (validator_groups, group_rotation_info) = try_runtime_api!(groups);
999-
let session_index = try_runtime_api!(session_index);
10001016
let cores = try_runtime_api!(cores);
1017+
let minimum_backing_votes = try_runtime_api!(minimum_backing_votes);
10011018

10021019
let signing_context = SigningContext { parent_hash: parent, session_index };
10031020
let validator =
@@ -1061,6 +1078,7 @@ async fn construct_per_relay_parent_state<Context>(
10611078
issued_statements: HashSet::new(),
10621079
awaiting_validation: HashSet::new(),
10631080
fallbacks: HashMap::new(),
1081+
minimum_backing_votes,
10641082
}))
10651083
}
10661084

@@ -1563,10 +1581,13 @@ async fn post_import_statement_actions<Context>(
15631581
rp_state: &mut PerRelayParentState,
15641582
summary: Option<&TableSummary>,
15651583
) -> Result<(), Error> {
1566-
if let Some(attested) = summary
1567-
.as_ref()
1568-
.and_then(|s| rp_state.table.attested_candidate(&s.candidate, &rp_state.table_context))
1569-
{
1584+
if let Some(attested) = summary.as_ref().and_then(|s| {
1585+
rp_state.table.attested_candidate(
1586+
&s.candidate,
1587+
&rp_state.table_context,
1588+
rp_state.minimum_backing_votes,
1589+
)
1590+
}) {
15701591
let candidate_hash = attested.candidate.hash();
15711592

15721593
// `HashSet::insert` returns true if the thing wasn't in there already.
@@ -2009,7 +2030,11 @@ fn handle_get_backed_candidates_message(
20092030
};
20102031
rp_state
20112032
.table
2012-
.attested_candidate(&candidate_hash, &rp_state.table_context)
2033+
.attested_candidate(
2034+
&candidate_hash,
2035+
&rp_state.table_context,
2036+
rp_state.minimum_backing_votes,
2037+
)
20132038
.and_then(|attested| table_attested_to_backed(attested, &rp_state.table_context))
20142039
})
20152040
.collect();

node/core/backing/src/tests/mod.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct TestState {
8080
head_data: HashMap<ParaId, HeadData>,
8181
signing_context: SigningContext,
8282
relay_parent: Hash,
83+
minimum_backing_votes: u32,
8384
}
8485

8586
impl TestState {
@@ -150,6 +151,7 @@ impl Default for TestState {
150151
validation_data,
151152
signing_context,
152153
relay_parent,
154+
minimum_backing_votes: 2,
153155
}
154156
}
155157
}
@@ -250,33 +252,50 @@ async fn test_startup(virtual_overseer: &mut VirtualOverseer, test_state: &TestS
250252
}
251253
);
252254

253-
// Check that subsystem job issues a request for a validator set.
255+
// Check that subsystem job issues a request for the session index for child.
254256
assert_matches!(
255257
virtual_overseer.recv().await,
256258
AllMessages::RuntimeApi(
257-
RuntimeApiMessage::Request(parent, RuntimeApiRequest::Validators(tx))
259+
RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx))
258260
) if parent == test_state.relay_parent => {
259-
tx.send(Ok(test_state.validator_public.clone())).unwrap();
261+
tx.send(Ok(test_state.signing_context.session_index)).unwrap();
260262
}
261263
);
262264

263-
// Check that subsystem job issues a request for the validator groups.
265+
// Check if subsystem job issues a request for the minimum backing votes.
266+
// This may or may not happen, depending if the minimum backing votes is already cached in the
267+
// RuntimeInfo.
268+
let next_message = {
269+
let msg = virtual_overseer.recv().await;
270+
match msg {
271+
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
272+
parent,
273+
RuntimeApiRequest::MinimumBackingVotes(tx),
274+
)) if parent == test_state.relay_parent => {
275+
tx.send(Ok(test_state.minimum_backing_votes)).unwrap();
276+
virtual_overseer.recv().await
277+
},
278+
_ => msg,
279+
}
280+
};
281+
282+
// Check that subsystem job issues a request for a validator set.
264283
assert_matches!(
265-
virtual_overseer.recv().await,
284+
next_message,
266285
AllMessages::RuntimeApi(
267-
RuntimeApiMessage::Request(parent, RuntimeApiRequest::ValidatorGroups(tx))
286+
RuntimeApiMessage::Request(parent, RuntimeApiRequest::Validators(tx))
268287
) if parent == test_state.relay_parent => {
269-
tx.send(Ok(test_state.validator_groups.clone())).unwrap();
288+
tx.send(Ok(test_state.validator_public.clone())).unwrap();
270289
}
271290
);
272291

273-
// Check that subsystem job issues a request for the session index for child.
292+
// Check that subsystem job issues a request for the validator groups.
274293
assert_matches!(
275294
virtual_overseer.recv().await,
276295
AllMessages::RuntimeApi(
277-
RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx))
296+
RuntimeApiMessage::Request(parent, RuntimeApiRequest::ValidatorGroups(tx))
278297
) if parent == test_state.relay_parent => {
279-
tx.send(Ok(test_state.signing_context.session_index)).unwrap();
298+
tx.send(Ok(test_state.validator_groups.clone())).unwrap();
280299
}
281300
);
282301

node/core/backing/src/tests/prospective_parachains.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,41 @@ async fn activate_leaf(
138138
}
139139

140140
for (hash, number) in ancestry_iter.take(requested_len) {
141-
// Check that subsystem job issues a request for a validator set.
142141
let msg = match next_overseer_message.take() {
143142
Some(msg) => msg,
144143
None => virtual_overseer.recv().await,
145144
};
145+
146+
// Check that subsystem job issues a request for the session index for child.
146147
assert_matches!(
147148
msg,
149+
AllMessages::RuntimeApi(
150+
RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx))
151+
) if parent == hash => {
152+
tx.send(Ok(test_state.signing_context.session_index)).unwrap();
153+
}
154+
);
155+
156+
// Check if subsystem job issues a request for the minimum backing votes.
157+
// This may or may not happen, depending if the minimum backing votes is already cached in
158+
// the `RuntimeInfo`.
159+
let next_message = {
160+
let msg = virtual_overseer.recv().await;
161+
match msg {
162+
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
163+
parent,
164+
RuntimeApiRequest::MinimumBackingVotes(tx),
165+
)) if parent == hash => {
166+
tx.send(Ok(test_state.minimum_backing_votes)).unwrap();
167+
virtual_overseer.recv().await
168+
},
169+
_ => msg,
170+
}
171+
};
172+
173+
// Check that subsystem job issues a request for a validator set.
174+
assert_matches!(
175+
next_message,
148176
AllMessages::RuntimeApi(
149177
RuntimeApiMessage::Request(parent, RuntimeApiRequest::Validators(tx))
150178
) if parent == hash => {
@@ -164,16 +192,6 @@ async fn activate_leaf(
164192
}
165193
);
166194

167-
// Check that subsystem job issues a request for the session index for child.
168-
assert_matches!(
169-
virtual_overseer.recv().await,
170-
AllMessages::RuntimeApi(
171-
RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx))
172-
) if parent == hash => {
173-
tx.send(Ok(test_state.signing_context.session_index)).unwrap();
174-
}
175-
);
176-
177195
// Check that subsystem job issues a request for the availability cores.
178196
assert_matches!(
179197
virtual_overseer.recv().await,

node/core/runtime-api/src/cache.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const DEFAULT_CACHE_CAP: NonZeroUsize = match NonZeroUsize::new(128) {
4040
pub(crate) struct RequestResultCache {
4141
authorities: LruCache<Hash, Vec<AuthorityDiscoveryId>>,
4242
validators: LruCache<Hash, Vec<ValidatorId>>,
43+
minimum_backing_votes: LruCache<Hash, u32>,
4344
validator_groups: LruCache<Hash, (Vec<Vec<ValidatorIndex>>, GroupRotationInfo)>,
4445
availability_cores: LruCache<Hash, Vec<CoreState>>,
4546
persisted_validation_data:
@@ -78,6 +79,7 @@ impl Default for RequestResultCache {
7879
Self {
7980
authorities: LruCache::new(DEFAULT_CACHE_CAP),
8081
validators: LruCache::new(DEFAULT_CACHE_CAP),
82+
minimum_backing_votes: LruCache::new(DEFAULT_CACHE_CAP),
8183
validator_groups: LruCache::new(DEFAULT_CACHE_CAP),
8284
availability_cores: LruCache::new(DEFAULT_CACHE_CAP),
8385
persisted_validation_data: LruCache::new(DEFAULT_CACHE_CAP),
@@ -131,6 +133,18 @@ impl RequestResultCache {
131133
self.validators.put(relay_parent, validators);
132134
}
133135

136+
pub(crate) fn minimum_backing_votes(&mut self, relay_parent: &Hash) -> Option<u32> {
137+
self.minimum_backing_votes.get(relay_parent).copied()
138+
}
139+
140+
pub(crate) fn cache_minimum_backing_votes(
141+
&mut self,
142+
relay_parent: Hash,
143+
minimum_backing_votes: u32,
144+
) {
145+
self.minimum_backing_votes.put(relay_parent, minimum_backing_votes);
146+
}
147+
134148
pub(crate) fn validator_groups(
135149
&mut self,
136150
relay_parent: &Hash,
@@ -472,6 +486,7 @@ pub(crate) enum RequestResult {
472486
// The structure of each variant is (relay_parent, [params,]*, result)
473487
Authorities(Hash, Vec<AuthorityDiscoveryId>),
474488
Validators(Hash, Vec<ValidatorId>),
489+
MinimumBackingVotes(Hash, u32),
475490
ValidatorGroups(Hash, (Vec<Vec<ValidatorIndex>>, GroupRotationInfo)),
476491
AvailabilityCores(Hash, Vec<CoreState>),
477492
PersistedValidationData(Hash, ParaId, OccupiedCoreAssumption, Option<PersistedValidationData>),

node/core/runtime-api/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ where
101101
self.requests_cache.cache_authorities(relay_parent, authorities),
102102
Validators(relay_parent, validators) =>
103103
self.requests_cache.cache_validators(relay_parent, validators),
104+
MinimumBackingVotes(relay_parent, minimum_backing_votes) => self
105+
.requests_cache
106+
.cache_minimum_backing_votes(relay_parent, minimum_backing_votes),
104107
ValidatorGroups(relay_parent, groups) =>
105108
self.requests_cache.cache_validator_groups(relay_parent, groups),
106109
AvailabilityCores(relay_parent, cores) =>
@@ -301,6 +304,8 @@ where
301304
Request::StagingAsyncBackingParams(sender) =>
302305
query!(staging_async_backing_params(), sender)
303306
.map(|sender| Request::StagingAsyncBackingParams(sender)),
307+
Request::MinimumBackingVotes(sender) => query!(minimum_backing_votes(), sender)
308+
.map(|sender| Request::MinimumBackingVotes(sender)),
304309
}
305310
}
306311

@@ -450,6 +455,9 @@ where
450455

451456
Request::Authorities(sender) => query!(Authorities, authorities(), ver = 1, sender),
452457
Request::Validators(sender) => query!(Validators, validators(), ver = 1, sender),
458+
Request::MinimumBackingVotes(sender) =>
459+
query!(MinimumBackingVotes, minimum_backing_votes(), ver = 1, sender),
460+
453461
Request::ValidatorGroups(sender) => {
454462
query!(ValidatorGroups, validator_groups(), ver = 1, sender)
455463
},

node/service/src/fake_runtime_api.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ sp_api::impl_runtime_apis! {
121121
unimplemented!()
122122
}
123123

124+
fn minimum_backing_votes() -> u32 {
125+
unimplemented!()
126+
}
127+
124128
fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
125129
unimplemented!()
126130
}

node/subsystem-types/src/messages.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,8 @@ pub enum RuntimeApiRequest {
606606
Authorities(RuntimeApiSender<Vec<AuthorityDiscoveryId>>),
607607
/// Get the current validator set.
608608
Validators(RuntimeApiSender<Vec<ValidatorId>>),
609+
/// Get the minimum required backing votes.
610+
MinimumBackingVotes(RuntimeApiSender<u32>),
609611
/// Get the validator groups and group rotation info.
610612
ValidatorGroups(RuntimeApiSender<(Vec<Vec<ValidatorIndex>>, GroupRotationInfo)>),
611613
/// Get information on all availability cores.

0 commit comments

Comments
 (0)