mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-22 16:05:41 +00:00
Add feature flag to enable v2 assignments (#2444)
Scaffold everything, so that we can enable v2 assignments via a node feature bit, once all nodes have upgraded to the new protocol. Implements: https://github.com/paritytech/polkadot-sdk/issues/628 --------- Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
This commit is contained in:
committed by
GitHub
parent
6cedb0c78d
commit
84c932cd8a
@@ -261,6 +261,7 @@ pub(crate) trait AssignmentCriteria {
|
|||||||
relay_vrf_story: RelayVRFStory,
|
relay_vrf_story: RelayVRFStory,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
leaving_cores: Vec<(CandidateHash, CoreIndex, GroupIndex)>,
|
leaving_cores: Vec<(CandidateHash, CoreIndex, GroupIndex)>,
|
||||||
|
enable_v2_assignments: bool,
|
||||||
) -> HashMap<CoreIndex, OurAssignment>;
|
) -> HashMap<CoreIndex, OurAssignment>;
|
||||||
|
|
||||||
fn check_assignment_cert(
|
fn check_assignment_cert(
|
||||||
@@ -284,8 +285,9 @@ impl AssignmentCriteria for RealAssignmentCriteria {
|
|||||||
relay_vrf_story: RelayVRFStory,
|
relay_vrf_story: RelayVRFStory,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
leaving_cores: Vec<(CandidateHash, CoreIndex, GroupIndex)>,
|
leaving_cores: Vec<(CandidateHash, CoreIndex, GroupIndex)>,
|
||||||
|
enable_v2_assignments: bool,
|
||||||
) -> HashMap<CoreIndex, OurAssignment> {
|
) -> HashMap<CoreIndex, OurAssignment> {
|
||||||
compute_assignments(keystore, relay_vrf_story, config, leaving_cores, false)
|
compute_assignments(keystore, relay_vrf_story, config, leaving_cores, enable_v2_assignments)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_assignment_cert(
|
fn check_assignment_cert(
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ use polkadot_node_subsystem::{
|
|||||||
};
|
};
|
||||||
use polkadot_node_subsystem_util::{determine_new_blocks, runtime::RuntimeInfo};
|
use polkadot_node_subsystem_util::{determine_new_blocks, runtime::RuntimeInfo};
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt, ConsensusLog, CoreIndex,
|
vstaging::node_features, BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt,
|
||||||
GroupIndex, Hash, Header, SessionIndex,
|
ConsensusLog, CoreIndex, GroupIndex, Hash, Header, SessionIndex,
|
||||||
};
|
};
|
||||||
use sc_keystore::LocalKeystore;
|
use sc_keystore::LocalKeystore;
|
||||||
use sp_consensus_slots::Slot;
|
use sp_consensus_slots::Slot;
|
||||||
@@ -60,7 +60,7 @@ use super::approval_db::v2;
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::{Backend, OverlayedBackend},
|
backend::{Backend, OverlayedBackend},
|
||||||
criteria::{AssignmentCriteria, OurAssignment},
|
criteria::{AssignmentCriteria, OurAssignment},
|
||||||
get_session_info,
|
get_extended_session_info, get_session_info,
|
||||||
persisted_entries::CandidateEntry,
|
persisted_entries::CandidateEntry,
|
||||||
time::{slot_number_to_tick, Tick},
|
time::{slot_number_to_tick, Tick},
|
||||||
};
|
};
|
||||||
@@ -214,10 +214,21 @@ async fn imported_block_info<Context>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let extended_session_info =
|
||||||
|
get_extended_session_info(env.runtime_info, ctx.sender(), block_hash, session_index).await;
|
||||||
|
let enable_v2_assignments = extended_session_info.map_or(false, |extended_session_info| {
|
||||||
|
*extended_session_info
|
||||||
|
.node_features
|
||||||
|
.get(node_features::FeatureIndex::EnableAssignmentsV2 as usize)
|
||||||
|
.as_deref()
|
||||||
|
.unwrap_or(&false)
|
||||||
|
});
|
||||||
|
|
||||||
let session_info = get_session_info(env.runtime_info, ctx.sender(), block_hash, session_index)
|
let session_info = get_session_info(env.runtime_info, ctx.sender(), block_hash, session_index)
|
||||||
.await
|
.await
|
||||||
.ok_or(ImportedBlockInfoError::SessionInfoUnavailable)?;
|
.ok_or(ImportedBlockInfoError::SessionInfoUnavailable)?;
|
||||||
|
|
||||||
|
gum::debug!(target: LOG_TARGET, ?enable_v2_assignments, "V2 assignments");
|
||||||
let (assignments, slot, relay_vrf_story) = {
|
let (assignments, slot, relay_vrf_story) = {
|
||||||
let unsafe_vrf = approval_types::v1::babe_unsafe_vrf_info(&block_header);
|
let unsafe_vrf = approval_types::v1::babe_unsafe_vrf_info(&block_header);
|
||||||
|
|
||||||
@@ -239,6 +250,7 @@ async fn imported_block_info<Context>(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(c_hash, _, core, group)| (*c_hash, *core, *group))
|
.map(|(c_hash, _, core, group)| (*c_hash, *core, *group))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
enable_v2_assignments,
|
||||||
);
|
);
|
||||||
|
|
||||||
(assignments, slot, relay_vrf)
|
(assignments, slot, relay_vrf)
|
||||||
@@ -603,6 +615,7 @@ pub(crate) mod tests {
|
|||||||
use polkadot_node_subsystem_test_helpers::make_subsystem_context;
|
use polkadot_node_subsystem_test_helpers::make_subsystem_context;
|
||||||
use polkadot_node_subsystem_util::database::Database;
|
use polkadot_node_subsystem_util::database::Database;
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
|
vstaging::{node_features::FeatureIndex, NodeFeatures},
|
||||||
ExecutorParams, Id as ParaId, IndexedVec, SessionInfo, ValidatorId, ValidatorIndex,
|
ExecutorParams, Id as ParaId, IndexedVec, SessionInfo, ValidatorId, ValidatorIndex,
|
||||||
};
|
};
|
||||||
pub(crate) use sp_consensus_babe::{
|
pub(crate) use sp_consensus_babe::{
|
||||||
@@ -639,7 +652,7 @@ pub(crate) mod tests {
|
|||||||
keystore: Arc::new(LocalKeystore::in_memory()),
|
keystore: Arc::new(LocalKeystore::in_memory()),
|
||||||
slot_duration_millis: 6_000,
|
slot_duration_millis: 6_000,
|
||||||
clock: Box::new(MockClock::default()),
|
clock: Box::new(MockClock::default()),
|
||||||
assignment_criteria: Box::new(MockAssignmentCriteria),
|
assignment_criteria: Box::new(MockAssignmentCriteria::default()),
|
||||||
spans: HashMap::new(),
|
spans: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -654,7 +667,10 @@ pub(crate) mod tests {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MockAssignmentCriteria;
|
#[derive(Default)]
|
||||||
|
struct MockAssignmentCriteria {
|
||||||
|
enable_v2: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl AssignmentCriteria for MockAssignmentCriteria {
|
impl AssignmentCriteria for MockAssignmentCriteria {
|
||||||
fn compute_assignments(
|
fn compute_assignments(
|
||||||
@@ -667,7 +683,9 @@ pub(crate) mod tests {
|
|||||||
polkadot_primitives::CoreIndex,
|
polkadot_primitives::CoreIndex,
|
||||||
polkadot_primitives::GroupIndex,
|
polkadot_primitives::GroupIndex,
|
||||||
)>,
|
)>,
|
||||||
|
enable_assignments_v2: bool,
|
||||||
) -> HashMap<polkadot_primitives::CoreIndex, criteria::OurAssignment> {
|
) -> HashMap<polkadot_primitives::CoreIndex, criteria::OurAssignment> {
|
||||||
|
assert_eq!(enable_assignments_v2, self.enable_v2);
|
||||||
HashMap::new()
|
HashMap::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,154 +729,164 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn imported_block_info_is_good() {
|
fn imported_block_info_is_good() {
|
||||||
let pool = TaskExecutor::new();
|
for enable_v2 in [false, true] {
|
||||||
let (mut ctx, mut handle) =
|
let pool = TaskExecutor::new();
|
||||||
make_subsystem_context::<ApprovalVotingMessage, _>(pool.clone());
|
let (mut ctx, mut handle) =
|
||||||
|
make_subsystem_context::<ApprovalVotingMessage, _>(pool.clone());
|
||||||
|
|
||||||
let session = 5;
|
let session = 5;
|
||||||
let session_info = dummy_session_info(session);
|
let session_info = dummy_session_info(session);
|
||||||
|
|
||||||
let slot = Slot::from(10);
|
let slot = Slot::from(10);
|
||||||
|
let header = Header {
|
||||||
|
digest: {
|
||||||
|
let mut d = Digest::default();
|
||||||
|
let vrf_signature = garbage_vrf_signature();
|
||||||
|
d.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF(
|
||||||
|
SecondaryVRFPreDigest { authority_index: 0, slot, vrf_signature },
|
||||||
|
)));
|
||||||
|
|
||||||
let header = Header {
|
d
|
||||||
digest: {
|
},
|
||||||
let mut d = Digest::default();
|
extrinsics_root: Default::default(),
|
||||||
let vrf_signature = garbage_vrf_signature();
|
number: 5,
|
||||||
d.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF(
|
state_root: Default::default(),
|
||||||
SecondaryVRFPreDigest { authority_index: 0, slot, vrf_signature },
|
parent_hash: Default::default(),
|
||||||
)));
|
};
|
||||||
|
|
||||||
d
|
let hash = header.hash();
|
||||||
},
|
let make_candidate = |para_id| {
|
||||||
extrinsics_root: Default::default(),
|
let mut r = dummy_candidate_receipt(dummy_hash());
|
||||||
number: 5,
|
r.descriptor.para_id = para_id;
|
||||||
state_root: Default::default(),
|
r.descriptor.relay_parent = hash;
|
||||||
parent_hash: Default::default(),
|
r
|
||||||
};
|
};
|
||||||
|
let candidates = vec![
|
||||||
|
(make_candidate(1.into()), CoreIndex(0), GroupIndex(2)),
|
||||||
|
(make_candidate(2.into()), CoreIndex(1), GroupIndex(3)),
|
||||||
|
];
|
||||||
|
|
||||||
let hash = header.hash();
|
let inclusion_events = candidates
|
||||||
let make_candidate = |para_id| {
|
|
||||||
let mut r = dummy_candidate_receipt(dummy_hash());
|
|
||||||
r.descriptor.para_id = para_id;
|
|
||||||
r.descriptor.relay_parent = hash;
|
|
||||||
r
|
|
||||||
};
|
|
||||||
let candidates = vec![
|
|
||||||
(make_candidate(1.into()), CoreIndex(0), GroupIndex(2)),
|
|
||||||
(make_candidate(2.into()), CoreIndex(1), GroupIndex(3)),
|
|
||||||
];
|
|
||||||
|
|
||||||
let inclusion_events = candidates
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let test_fut = {
|
|
||||||
let included_candidates = candidates
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(r, c, g)| (r.hash(), r.clone(), *c, *g))
|
.cloned()
|
||||||
|
.map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig {
|
let test_fut = {
|
||||||
keystore: None,
|
let included_candidates = candidates
|
||||||
session_cache_lru_size: DISPUTE_WINDOW.get(),
|
.iter()
|
||||||
|
.map(|(r, c, g)| (r.hash(), r.clone(), *c, *g))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig {
|
||||||
|
keystore: None,
|
||||||
|
session_cache_lru_size: DISPUTE_WINDOW.get(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let header = header.clone();
|
||||||
|
Box::pin(async move {
|
||||||
|
let env = ImportedBlockInfoEnv {
|
||||||
|
runtime_info: &mut runtime_info,
|
||||||
|
assignment_criteria: &MockAssignmentCriteria { enable_v2 },
|
||||||
|
keystore: &LocalKeystore::in_memory(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let info =
|
||||||
|
imported_block_info(&mut ctx, env, hash, &header, &Some(4)).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(info.included_candidates, included_candidates);
|
||||||
|
assert_eq!(info.session_index, session);
|
||||||
|
assert!(info.assignments.is_empty());
|
||||||
|
assert_eq!(info.n_validators, 0);
|
||||||
|
assert_eq!(info.slot, slot);
|
||||||
|
assert!(info.force_approve.is_none());
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let aux_fut = Box::pin(async move {
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||||
|
h,
|
||||||
|
RuntimeApiRequest::CandidateEvents(c_tx),
|
||||||
|
)) => {
|
||||||
|
assert_eq!(h, hash);
|
||||||
|
let _ = c_tx.send(Ok(inclusion_events));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||||
|
h,
|
||||||
|
RuntimeApiRequest::SessionIndexForChild(c_tx),
|
||||||
|
)) => {
|
||||||
|
assert_eq!(h, header.parent_hash);
|
||||||
|
let _ = c_tx.send(Ok(session));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||||
|
h,
|
||||||
|
RuntimeApiRequest::CurrentBabeEpoch(c_tx),
|
||||||
|
)) => {
|
||||||
|
assert_eq!(h, hash);
|
||||||
|
let _ = c_tx.send(Ok(BabeEpoch {
|
||||||
|
epoch_index: session as _,
|
||||||
|
start_slot: Slot::from(0),
|
||||||
|
duration: 200,
|
||||||
|
authorities: vec![(Sr25519Keyring::Alice.public().into(), 1)],
|
||||||
|
randomness: [0u8; 32],
|
||||||
|
config: BabeEpochConfiguration {
|
||||||
|
c: (1, 4),
|
||||||
|
allowed_slots: AllowedSlots::PrimarySlots,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(
|
||||||
|
req_block_hash,
|
||||||
|
RuntimeApiRequest::SessionInfo(idx, si_tx),
|
||||||
|
)
|
||||||
|
) => {
|
||||||
|
assert_eq!(session, idx);
|
||||||
|
assert_eq!(req_block_hash, hash);
|
||||||
|
si_tx.send(Ok(Some(session_info.clone()))).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(
|
||||||
|
req_block_hash,
|
||||||
|
RuntimeApiRequest::SessionExecutorParams(idx, si_tx),
|
||||||
|
)
|
||||||
|
) => {
|
||||||
|
assert_eq!(session, idx);
|
||||||
|
assert_eq!(req_block_hash, hash);
|
||||||
|
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::repeat(enable_v2, FeatureIndex::EnableAssignmentsV2 as usize + 1))).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let header = header.clone();
|
futures::executor::block_on(futures::future::join(test_fut, aux_fut));
|
||||||
Box::pin(async move {
|
}
|
||||||
let env = ImportedBlockInfoEnv {
|
|
||||||
runtime_info: &mut runtime_info,
|
|
||||||
assignment_criteria: &MockAssignmentCriteria,
|
|
||||||
keystore: &LocalKeystore::in_memory(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let info =
|
|
||||||
imported_block_info(&mut ctx, env, hash, &header, &Some(4)).await.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(info.included_candidates, included_candidates);
|
|
||||||
assert_eq!(info.session_index, session);
|
|
||||||
assert!(info.assignments.is_empty());
|
|
||||||
assert_eq!(info.n_validators, 0);
|
|
||||||
assert_eq!(info.slot, slot);
|
|
||||||
assert!(info.force_approve.is_none());
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let aux_fut = Box::pin(async move {
|
|
||||||
assert_matches!(
|
|
||||||
handle.recv().await,
|
|
||||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
|
||||||
h,
|
|
||||||
RuntimeApiRequest::CandidateEvents(c_tx),
|
|
||||||
)) => {
|
|
||||||
assert_eq!(h, hash);
|
|
||||||
let _ = c_tx.send(Ok(inclusion_events));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_matches!(
|
|
||||||
handle.recv().await,
|
|
||||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
|
||||||
h,
|
|
||||||
RuntimeApiRequest::SessionIndexForChild(c_tx),
|
|
||||||
)) => {
|
|
||||||
assert_eq!(h, header.parent_hash);
|
|
||||||
let _ = c_tx.send(Ok(session));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_matches!(
|
|
||||||
handle.recv().await,
|
|
||||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
|
||||||
h,
|
|
||||||
RuntimeApiRequest::CurrentBabeEpoch(c_tx),
|
|
||||||
)) => {
|
|
||||||
assert_eq!(h, hash);
|
|
||||||
let _ = c_tx.send(Ok(BabeEpoch {
|
|
||||||
epoch_index: session as _,
|
|
||||||
start_slot: Slot::from(0),
|
|
||||||
duration: 200,
|
|
||||||
authorities: vec![(Sr25519Keyring::Alice.public().into(), 1)],
|
|
||||||
randomness: [0u8; 32],
|
|
||||||
config: BabeEpochConfiguration {
|
|
||||||
c: (1, 4),
|
|
||||||
allowed_slots: AllowedSlots::PrimarySlots,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_matches!(
|
|
||||||
handle.recv().await,
|
|
||||||
AllMessages::RuntimeApi(
|
|
||||||
RuntimeApiMessage::Request(
|
|
||||||
req_block_hash,
|
|
||||||
RuntimeApiRequest::SessionInfo(idx, si_tx),
|
|
||||||
)
|
|
||||||
) => {
|
|
||||||
assert_eq!(session, idx);
|
|
||||||
assert_eq!(req_block_hash, hash);
|
|
||||||
si_tx.send(Ok(Some(session_info.clone()))).unwrap();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_matches!(
|
|
||||||
handle.recv().await,
|
|
||||||
AllMessages::RuntimeApi(
|
|
||||||
RuntimeApiMessage::Request(
|
|
||||||
req_block_hash,
|
|
||||||
RuntimeApiRequest::SessionExecutorParams(idx, si_tx),
|
|
||||||
)
|
|
||||||
) => {
|
|
||||||
assert_eq!(session, idx);
|
|
||||||
assert_eq!(req_block_hash, hash);
|
|
||||||
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
futures::executor::block_on(futures::future::join(test_fut, aux_fut));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -906,7 +934,7 @@ pub(crate) mod tests {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let env = ImportedBlockInfoEnv {
|
let env = ImportedBlockInfoEnv {
|
||||||
runtime_info: &mut runtime_info,
|
runtime_info: &mut runtime_info,
|
||||||
assignment_criteria: &MockAssignmentCriteria,
|
assignment_criteria: &MockAssignmentCriteria::default(),
|
||||||
keystore: &LocalKeystore::in_memory(),
|
keystore: &LocalKeystore::in_memory(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -987,6 +1015,15 @@ pub(crate) mod tests {
|
|||||||
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
futures::executor::block_on(futures::future::join(test_fut, aux_fut));
|
futures::executor::block_on(futures::future::join(test_fut, aux_fut));
|
||||||
@@ -1036,7 +1073,7 @@ pub(crate) mod tests {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let env = ImportedBlockInfoEnv {
|
let env = ImportedBlockInfoEnv {
|
||||||
runtime_info: &mut runtime_info,
|
runtime_info: &mut runtime_info,
|
||||||
assignment_criteria: &MockAssignmentCriteria,
|
assignment_criteria: &MockAssignmentCriteria::default(),
|
||||||
keystore: &LocalKeystore::in_memory(),
|
keystore: &LocalKeystore::in_memory(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1134,7 +1171,7 @@ pub(crate) mod tests {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let env = ImportedBlockInfoEnv {
|
let env = ImportedBlockInfoEnv {
|
||||||
runtime_info: &mut runtime_info,
|
runtime_info: &mut runtime_info,
|
||||||
assignment_criteria: &MockAssignmentCriteria,
|
assignment_criteria: &MockAssignmentCriteria::default(),
|
||||||
keystore: &LocalKeystore::in_memory(),
|
keystore: &LocalKeystore::in_memory(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1221,6 +1258,15 @@ pub(crate) mod tests {
|
|||||||
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
futures::executor::block_on(futures::future::join(test_fut, aux_fut));
|
futures::executor::block_on(futures::future::join(test_fut, aux_fut));
|
||||||
@@ -1438,6 +1484,15 @@ pub(crate) mod tests {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
handle.recv().await,
|
handle.recv().await,
|
||||||
AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks(
|
AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks(
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ use polkadot_node_subsystem_test_helpers as test_helpers;
|
|||||||
use polkadot_node_subsystem_util::TimeoutExt;
|
use polkadot_node_subsystem_util::TimeoutExt;
|
||||||
use polkadot_overseer::HeadSupportsParachains;
|
use polkadot_overseer::HeadSupportsParachains;
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
CandidateCommitments, CandidateEvent, CoreIndex, GroupIndex, Header, Id as ParaId, IndexedVec,
|
vstaging::NodeFeatures, CandidateCommitments, CandidateEvent, CoreIndex, GroupIndex, Header,
|
||||||
ValidationCode, ValidatorSignature,
|
Id as ParaId, IndexedVec, ValidationCode, ValidatorSignature,
|
||||||
};
|
};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@@ -243,6 +243,7 @@ where
|
|||||||
polkadot_primitives::CoreIndex,
|
polkadot_primitives::CoreIndex,
|
||||||
polkadot_primitives::GroupIndex,
|
polkadot_primitives::GroupIndex,
|
||||||
)>,
|
)>,
|
||||||
|
_enable_assignments_v2: bool,
|
||||||
) -> HashMap<polkadot_primitives::CoreIndex, criteria::OurAssignment> {
|
) -> HashMap<polkadot_primitives::CoreIndex, criteria::OurAssignment> {
|
||||||
self.0()
|
self.0()
|
||||||
}
|
}
|
||||||
@@ -1003,6 +1004,15 @@ async fn import_block(
|
|||||||
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
overseer_recv(overseer).await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
|
|||||||
@@ -61,10 +61,11 @@ use polkadot_node_subsystem_test_helpers::{
|
|||||||
make_buffered_subsystem_context, mock::new_leaf, TestSubsystemContextHandle,
|
make_buffered_subsystem_context, mock::new_leaf, TestSubsystemContextHandle,
|
||||||
};
|
};
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
ApprovalVote, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash,
|
vstaging::NodeFeatures, ApprovalVote, BlockNumber, CandidateCommitments, CandidateEvent,
|
||||||
CandidateReceipt, CoreIndex, DisputeStatement, ExecutorParams, GroupIndex, Hash, HeadData,
|
CandidateHash, CandidateReceipt, CoreIndex, DisputeStatement, ExecutorParams, GroupIndex, Hash,
|
||||||
Header, IndexedVec, MultiDisputeStatementSet, ScrapedOnChainVotes, SessionIndex, SessionInfo,
|
HeadData, Header, IndexedVec, MultiDisputeStatementSet, ScrapedOnChainVotes, SessionIndex,
|
||||||
SigningContext, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature,
|
SessionInfo, SigningContext, ValidDisputeStatementKind, ValidatorId, ValidatorIndex,
|
||||||
|
ValidatorSignature,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -352,6 +353,15 @@ impl TestState {
|
|||||||
let _ = tx.send(Ok(Some(ExecutorParams::default())));
|
let _ = tx.send(Ok(Some(ExecutorParams::default())));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
overseer_recv(virtual_overseer).await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3492,6 +3502,14 @@ fn session_info_is_requested_only_once() {
|
|||||||
let _ = tx.send(Ok(Some(ExecutorParams::default())));
|
let _ = tx.send(Ok(Some(ExecutorParams::default())));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
assert_matches!(
|
||||||
|
virtual_overseer.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
test_state
|
test_state
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@@ -3552,6 +3570,15 @@ fn session_info_big_jump_works() {
|
|||||||
let _ = tx.send(Ok(Some(ExecutorParams::default())));
|
let _ = tx.send(Ok(Some(ExecutorParams::default())));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
virtual_overseer.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
test_state
|
test_state
|
||||||
})
|
})
|
||||||
@@ -3612,6 +3639,14 @@ fn session_info_small_jump_works() {
|
|||||||
let _ = tx.send(Ok(Some(ExecutorParams::default())));
|
let _ = tx.send(Ok(Some(ExecutorParams::default())));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
assert_matches!(
|
||||||
|
virtual_overseer.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
test_state
|
test_state
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -146,7 +146,9 @@ mod tests {
|
|||||||
AllMessages, AvailabilityDistributionMessage, RuntimeApiMessage, RuntimeApiRequest,
|
AllMessages, AvailabilityDistributionMessage, RuntimeApiMessage, RuntimeApiRequest,
|
||||||
};
|
};
|
||||||
use polkadot_node_subsystem_test_helpers as test_helpers;
|
use polkadot_node_subsystem_test_helpers as test_helpers;
|
||||||
use polkadot_primitives::{CandidateHash, ExecutorParams, Hash, ValidatorIndex};
|
use polkadot_primitives::{
|
||||||
|
vstaging::NodeFeatures, CandidateHash, ExecutorParams, Hash, ValidatorIndex,
|
||||||
|
};
|
||||||
use test_helpers::mock::make_ferdie_keystore;
|
use test_helpers::mock::make_ferdie_keystore;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -214,6 +216,12 @@ mod tests {
|
|||||||
)) => {
|
)) => {
|
||||||
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
||||||
},
|
},
|
||||||
|
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||||
|
_,
|
||||||
|
RuntimeApiRequest::NodeFeatures(_, si_tx),
|
||||||
|
)) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
},
|
||||||
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests(
|
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests(
|
||||||
mut reqs,
|
mut reqs,
|
||||||
_,
|
_,
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ use polkadot_node_primitives::{BlockData, ErasureChunk, PoV};
|
|||||||
use polkadot_node_subsystem_test_helpers::mock::new_leaf;
|
use polkadot_node_subsystem_test_helpers::mock::new_leaf;
|
||||||
use polkadot_node_subsystem_util::runtime::RuntimeInfo;
|
use polkadot_node_subsystem_util::runtime::RuntimeInfo;
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
BlockNumber, CoreState, ExecutorParams, GroupIndex, Hash, Id as ParaId, ScheduledCore,
|
vstaging::NodeFeatures, BlockNumber, CoreState, ExecutorParams, GroupIndex, Hash, Id as ParaId,
|
||||||
SessionIndex, SessionInfo,
|
ScheduledCore, SessionIndex, SessionInfo,
|
||||||
};
|
};
|
||||||
use sp_core::traits::SpawnNamed;
|
use sp_core::traits::SpawnNamed;
|
||||||
|
|
||||||
@@ -125,6 +125,10 @@ fn spawn_virtual_overseer(
|
|||||||
tx.send(Ok(Some(ExecutorParams::default())))
|
tx.send(Ok(Some(ExecutorParams::default())))
|
||||||
.expect("Receiver should be alive.");
|
.expect("Receiver should be alive.");
|
||||||
},
|
},
|
||||||
|
RuntimeApiRequest::NodeFeatures(_, tx) => {
|
||||||
|
tx.send(Ok(NodeFeatures::EMPTY))
|
||||||
|
.expect("Receiver should be alive.");
|
||||||
|
},
|
||||||
RuntimeApiRequest::AvailabilityCores(tx) => {
|
RuntimeApiRequest::AvailabilityCores(tx) => {
|
||||||
let para_id = ParaId::from(1_u32);
|
let para_id = ParaId::from(1_u32);
|
||||||
let maybe_block_position =
|
let maybe_block_position =
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ use polkadot_node_subsystem::{
|
|||||||
};
|
};
|
||||||
use polkadot_node_subsystem_test_helpers as test_helpers;
|
use polkadot_node_subsystem_test_helpers as test_helpers;
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
CandidateHash, CoreState, ExecutorParams, GroupIndex, Hash, Id as ParaId, ScheduledCore,
|
vstaging::NodeFeatures, CandidateHash, CoreState, ExecutorParams, GroupIndex, Hash,
|
||||||
SessionInfo, ValidatorIndex,
|
Id as ParaId, ScheduledCore, SessionInfo, ValidatorIndex,
|
||||||
};
|
};
|
||||||
use test_helpers::mock::{make_ferdie_keystore, new_leaf};
|
use test_helpers::mock::{make_ferdie_keystore, new_leaf};
|
||||||
|
|
||||||
@@ -264,6 +264,9 @@ impl TestState {
|
|||||||
tx.send(Ok(Some(ExecutorParams::default())))
|
tx.send(Ok(Some(ExecutorParams::default())))
|
||||||
.expect("Receiver should be alive.");
|
.expect("Receiver should be alive.");
|
||||||
},
|
},
|
||||||
|
RuntimeApiRequest::NodeFeatures(_, si_tx) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).expect("Receiver should be alive.");
|
||||||
|
},
|
||||||
RuntimeApiRequest::AvailabilityCores(tx) => {
|
RuntimeApiRequest::AvailabilityCores(tx) => {
|
||||||
gum::trace!(target: LOG_TARGET, cores= ?self.cores[&hash], hash = ?hash, "Sending out cores for hash");
|
gum::trace!(target: LOG_TARGET, cores= ?self.cores[&hash], hash = ?hash, "Sending out cores for hash");
|
||||||
tx.send(Ok(self.cores[&hash].clone()))
|
tx.send(Ok(self.cores[&hash].clone()))
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ use polkadot_node_subsystem::{
|
|||||||
use polkadot_node_subsystem_test_helpers as test_helpers;
|
use polkadot_node_subsystem_test_helpers as test_helpers;
|
||||||
use polkadot_node_subsystem_util::{reputation::add_reputation, TimeoutExt};
|
use polkadot_node_subsystem_util::{reputation::add_reputation, TimeoutExt};
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
AuthorityDiscoveryId, CollatorPair, ExecutorParams, GroupIndex, GroupRotationInfo, IndexedVec,
|
vstaging::NodeFeatures, AuthorityDiscoveryId, CollatorPair, ExecutorParams, GroupIndex,
|
||||||
ScheduledCore, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex,
|
GroupRotationInfo, IndexedVec, ScheduledCore, SessionIndex, SessionInfo, ValidatorId,
|
||||||
|
ValidatorIndex,
|
||||||
};
|
};
|
||||||
use polkadot_primitives_test_helpers::TestCandidateBuilder;
|
use polkadot_primitives_test_helpers::TestCandidateBuilder;
|
||||||
use test_helpers::mock::new_leaf;
|
use test_helpers::mock::new_leaf;
|
||||||
@@ -406,7 +407,12 @@ async fn distribute_collation_with_receipt(
|
|||||||
|
|
||||||
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
|
||||||
},
|
},
|
||||||
|
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||||
|
_,
|
||||||
|
RuntimeApiRequest::NodeFeatures(_, si_tx),
|
||||||
|
)) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
},
|
||||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||||
_relay_parent,
|
_relay_parent,
|
||||||
RuntimeApiRequest::ValidatorGroups(tx),
|
RuntimeApiRequest::ValidatorGroups(tx),
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ use polkadot_node_subsystem_test_helpers::{
|
|||||||
subsystem_test_harness, TestSubsystemContextHandle,
|
subsystem_test_harness, TestSubsystemContextHandle,
|
||||||
};
|
};
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
AuthorityDiscoveryId, CandidateHash, CandidateReceipt, ExecutorParams, Hash, SessionIndex,
|
vstaging::NodeFeatures, AuthorityDiscoveryId, CandidateHash, CandidateReceipt, ExecutorParams,
|
||||||
SessionInfo,
|
Hash, SessionIndex, SessionInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::mock::{
|
use self::mock::{
|
||||||
@@ -646,6 +646,16 @@ async fn nested_network_dispute_request<'a, F, O>(
|
|||||||
},
|
},
|
||||||
unexpected => panic!("Unexpected message {:?}", unexpected),
|
unexpected => panic!("Unexpected message {:?}", unexpected),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match handle.recv().await {
|
||||||
|
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||||
|
_,
|
||||||
|
RuntimeApiRequest::NodeFeatures(_, si_tx),
|
||||||
|
)) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
},
|
||||||
|
unexpected => panic!("Unexpected message {:?}", unexpected),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import should get initiated:
|
// Import should get initiated:
|
||||||
@@ -773,6 +783,14 @@ async fn activate_leaf(
|
|||||||
tx.send(Ok(Some(ExecutorParams::default()))).expect("Receiver should stay alive.");
|
tx.send(Ok(Some(ExecutorParams::default()))).expect("Receiver should stay alive.");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ use polkadot_node_subsystem::{
|
|||||||
};
|
};
|
||||||
use polkadot_node_subsystem_test_helpers::mock::{make_ferdie_keystore, new_leaf};
|
use polkadot_node_subsystem_test_helpers::mock::{make_ferdie_keystore, new_leaf};
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
ExecutorParams, GroupIndex, Hash, HeadData, Id as ParaId, IndexedVec, SessionInfo,
|
vstaging::NodeFeatures, ExecutorParams, GroupIndex, Hash, HeadData, Id as ParaId, IndexedVec,
|
||||||
ValidationCode,
|
SessionInfo, ValidationCode,
|
||||||
};
|
};
|
||||||
use polkadot_primitives_test_helpers::{
|
use polkadot_primitives_test_helpers::{
|
||||||
dummy_committed_candidate_receipt, dummy_hash, AlwaysZeroRng,
|
dummy_committed_candidate_receipt, dummy_hash, AlwaysZeroRng,
|
||||||
@@ -834,6 +834,15 @@ fn receiving_from_one_sends_to_another_and_to_candidate_backing() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// notify of peers and view
|
// notify of peers and view
|
||||||
handle
|
handle
|
||||||
.send(FromOrchestra::Communication {
|
.send(FromOrchestra::Communication {
|
||||||
@@ -1074,6 +1083,15 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// notify of peers and view
|
// notify of peers and view
|
||||||
handle
|
handle
|
||||||
.send(FromOrchestra::Communication {
|
.send(FromOrchestra::Communication {
|
||||||
@@ -1604,6 +1622,15 @@ fn delay_reputation_changes() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// notify of peers and view
|
// notify of peers and view
|
||||||
handle
|
handle
|
||||||
.send(FromOrchestra::Communication {
|
.send(FromOrchestra::Communication {
|
||||||
@@ -2084,6 +2111,15 @@ fn share_prioritizes_backing_group() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// notify of dummy peers and view
|
// notify of dummy peers and view
|
||||||
for (peer, pair) in dummy_peers.clone().into_iter().zip(dummy_pairs) {
|
for (peer, pair) in dummy_peers.clone().into_iter().zip(dummy_pairs) {
|
||||||
handle
|
handle
|
||||||
@@ -2406,6 +2442,15 @@ fn peer_cant_flood_with_large_statements() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// notify of peers and view
|
// notify of peers and view
|
||||||
handle
|
handle
|
||||||
.send(FromOrchestra::Communication {
|
.send(FromOrchestra::Communication {
|
||||||
@@ -2631,6 +2676,14 @@ fn handle_multiple_seconded_statements() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
handle.recv().await,
|
||||||
|
AllMessages::RuntimeApi(
|
||||||
|
RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), )
|
||||||
|
) => {
|
||||||
|
si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap();
|
||||||
|
}
|
||||||
|
);
|
||||||
// notify of peers and view
|
// notify of peers and view
|
||||||
for peer in all_peers.iter() {
|
for peer in all_peers.iter() {
|
||||||
handle
|
handle
|
||||||
|
|||||||
@@ -30,10 +30,12 @@ use polkadot_node_subsystem::{
|
|||||||
};
|
};
|
||||||
use polkadot_node_subsystem_types::UnpinHandle;
|
use polkadot_node_subsystem_types::UnpinHandle;
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
slashing, vstaging::NodeFeatures, AsyncBackingParams, CandidateEvent, CandidateHash, CoreState,
|
slashing,
|
||||||
EncodeAs, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, IndexedVec, OccupiedCore,
|
vstaging::{node_features::FeatureIndex, NodeFeatures},
|
||||||
ScrapedOnChainVotes, SessionIndex, SessionInfo, Signed, SigningContext, UncheckedSigned,
|
AsyncBackingParams, CandidateEvent, CandidateHash, CoreState, EncodeAs, ExecutorParams,
|
||||||
ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, LEGACY_MIN_BACKING_VOTES,
|
GroupIndex, GroupRotationInfo, Hash, IndexedVec, OccupiedCore, ScrapedOnChainVotes,
|
||||||
|
SessionIndex, SessionInfo, Signed, SigningContext, UncheckedSigned, ValidationCode,
|
||||||
|
ValidationCodeHash, ValidatorId, ValidatorIndex, LEGACY_MIN_BACKING_VOTES,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -92,6 +94,8 @@ pub struct ExtendedSessionInfo {
|
|||||||
pub validator_info: ValidatorInfo,
|
pub validator_info: ValidatorInfo,
|
||||||
/// Session executor parameters
|
/// Session executor parameters
|
||||||
pub executor_params: ExecutorParams,
|
pub executor_params: ExecutorParams,
|
||||||
|
/// Node features
|
||||||
|
pub node_features: NodeFeatures,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about ourselves, in case we are an `Authority`.
|
/// Information about ourselves, in case we are an `Authority`.
|
||||||
@@ -202,7 +206,20 @@ impl RuntimeInfo {
|
|||||||
|
|
||||||
let validator_info = self.get_validator_info(&session_info)?;
|
let validator_info = self.get_validator_info(&session_info)?;
|
||||||
|
|
||||||
let full_info = ExtendedSessionInfo { session_info, validator_info, executor_params };
|
let node_features = request_node_features(parent, session_index, sender)
|
||||||
|
.await?
|
||||||
|
.unwrap_or(NodeFeatures::EMPTY);
|
||||||
|
let last_set_index = node_features.iter_ones().last().unwrap_or_default();
|
||||||
|
if last_set_index >= FeatureIndex::FirstUnassigned as usize {
|
||||||
|
gum::warn!(target: LOG_TARGET, "Runtime requires feature bit {} that node doesn't support, please upgrade node version", last_set_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
let full_info = ExtendedSessionInfo {
|
||||||
|
session_info,
|
||||||
|
validator_info,
|
||||||
|
executor_params,
|
||||||
|
node_features,
|
||||||
|
};
|
||||||
|
|
||||||
self.session_info_cache.insert(session_index, full_info);
|
self.session_info_cache.insert(session_index, full_info);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,3 +22,19 @@ use bitvec::vec::BitVec;
|
|||||||
|
|
||||||
/// Bit indices in the `HostConfiguration.node_features` that correspond to different node features.
|
/// Bit indices in the `HostConfiguration.node_features` that correspond to different node features.
|
||||||
pub type NodeFeatures = BitVec<u8, bitvec::order::Lsb0>;
|
pub type NodeFeatures = BitVec<u8, bitvec::order::Lsb0>;
|
||||||
|
|
||||||
|
/// Module containing feature-specific bit indices into the `NodeFeatures` bitvec.
|
||||||
|
pub mod node_features {
|
||||||
|
/// A feature index used to indentify a bit into the node_features array stored
|
||||||
|
/// in the HostConfiguration.
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum FeatureIndex {
|
||||||
|
/// Tells if tranch0 assignments could be sent in a single certificate.
|
||||||
|
/// Reserved for: `<https://github.com/paritytech/polkadot-sdk/issues/628>`
|
||||||
|
EnableAssignmentsV2 = 0,
|
||||||
|
/// First unassigned feature bit.
|
||||||
|
/// Every time a new feature flag is assigned it should take this value.
|
||||||
|
/// and this should be incremented.
|
||||||
|
FirstUnassigned = 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user