gossip: move authorities request to runtime api subsystem (#2798)

This commit is contained in:
Andronik Ordian
2021-04-01 23:51:01 +02:00
committed by GitHub
parent 05a5047e40
commit 98082c5326
9 changed files with 87 additions and 47 deletions
@@ -19,6 +19,7 @@ use polkadot_primitives::v1::{
CoreState, GroupRotationInfo, InboundDownwardMessage, InboundHrmpMessage, Hash,
PersistedValidationData, Id as ParaId, OccupiedCoreAssumption,
SessionIndex, SessionInfo, ValidationCode, ValidatorId, ValidatorIndex,
AuthorityDiscoveryId,
};
use sp_consensus_babe::Epoch;
use parity_util_mem::{MallocSizeOf, MallocSizeOfExt};
@@ -28,6 +29,7 @@ use memory_lru::{MemoryLruCache, ResidentSize};
use std::collections::btree_map::BTreeMap;
const AUTHORITIES_CACHE_SIZE: usize = 128 * 1024;
const VALIDATORS_CACHE_SIZE: usize = 64 * 1024;
const VALIDATOR_GROUPS_CACHE_SIZE: usize = 64 * 1024;
const AVAILABILITY_CORES_CACHE_SIZE: usize = 64 * 1024;
@@ -59,7 +61,18 @@ impl<T> ResidentSize for DoesNotAllocate<T> {
}
}
// this is an ugly workaround for `AuthorityDiscoveryId`
// not implementing `MallocSizeOf`
struct VecOfDoesNotAllocate<T>(Vec<T>);
impl<T> ResidentSize for VecOfDoesNotAllocate<T> {
fn resident_size(&self) -> usize {
std::mem::size_of::<T>() * self.0.capacity()
}
}
pub(crate) struct RequestResultCache {
authorities: MemoryLruCache<Hash, VecOfDoesNotAllocate<AuthorityDiscoveryId>>,
validators: MemoryLruCache<Hash, ResidentSizeOf<Vec<ValidatorId>>>,
validator_groups: MemoryLruCache<Hash, ResidentSizeOf<(Vec<Vec<ValidatorIndex>>, GroupRotationInfo)>>,
availability_cores: MemoryLruCache<Hash, ResidentSizeOf<Vec<CoreState>>>,
@@ -79,6 +92,7 @@ pub(crate) struct RequestResultCache {
impl Default for RequestResultCache {
fn default() -> Self {
Self {
authorities: MemoryLruCache::new(AUTHORITIES_CACHE_SIZE),
validators: MemoryLruCache::new(VALIDATORS_CACHE_SIZE),
validator_groups: MemoryLruCache::new(VALIDATOR_GROUPS_CACHE_SIZE),
availability_cores: MemoryLruCache::new(AVAILABILITY_CORES_CACHE_SIZE),
@@ -98,6 +112,14 @@ impl Default for RequestResultCache {
}
impl RequestResultCache {
pub(crate) fn authorities(&mut self, relay_parent: &Hash) -> Option<&Vec<AuthorityDiscoveryId>> {
self.authorities.get(relay_parent).map(|v| &v.0)
}
pub(crate) fn cache_authorities(&mut self, relay_parent: Hash, authorities: Vec<AuthorityDiscoveryId>) {
self.authorities.insert(relay_parent, VecOfDoesNotAllocate(authorities));
}
pub(crate) fn validators(&mut self, relay_parent: &Hash) -> Option<&Vec<ValidatorId>> {
self.validators.get(relay_parent).map(|v| &v.0)
}
@@ -212,6 +234,7 @@ impl RequestResultCache {
}
pub(crate) enum RequestResult {
Authorities(Hash, Vec<AuthorityDiscoveryId>),
Validators(Hash, Vec<ValidatorId>),
ValidatorGroups(Hash, (Vec<Vec<ValidatorIndex>>, GroupRotationInfo)),
AvailabilityCores(Hash, Vec<CoreState>),
+42 -5
View File
@@ -34,6 +34,7 @@ use polkadot_node_subsystem_util::metrics::{self, prometheus};
use polkadot_primitives::v1::{Block, BlockId, Hash, ParachainHost};
use sp_api::ProvideRuntimeApi;
use sp_authority_discovery::AuthorityDiscoveryApi;
use sp_core::traits::SpawnNamed;
use sp_consensus_babe::BabeApi;
@@ -83,7 +84,7 @@ impl<Client> RuntimeApiSubsystem<Client> {
impl<Client, Context> Subsystem<Context> for RuntimeApiSubsystem<Client> where
Client: ProvideRuntimeApi<Block> + Send + 'static + Sync,
Client::Api: ParachainHost<Block> + BabeApi<Block>,
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Context: SubsystemContext<Message = RuntimeApiMessage>
{
fn start(self, ctx: Context) -> SpawnedSubsystem {
@@ -96,12 +97,14 @@ impl<Client, Context> Subsystem<Context> for RuntimeApiSubsystem<Client> where
impl<Client> RuntimeApiSubsystem<Client> where
Client: ProvideRuntimeApi<Block> + Send + 'static + Sync,
Client::Api: ParachainHost<Block> + BabeApi<Block>,
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
{
fn store_cache(&mut self, result: RequestResult) {
use RequestResult::*;
match result {
Authorities(relay_parent, authorities) =>
self.requests_cache.cache_authorities(relay_parent, authorities),
Validators(relay_parent, validators) =>
self.requests_cache.cache_validators(relay_parent, validators),
ValidatorGroups(relay_parent, groups) =>
@@ -160,6 +163,8 @@ impl<Client> RuntimeApiSubsystem<Client> where
}
match request {
Request::Authorities(sender) => query!(authorities(), sender)
.map(|sender| Request::Authorities(sender)),
Request::Validators(sender) => query!(validators(), sender)
.map(|sender| Request::Validators(sender)),
Request::ValidatorGroups(sender) => query!(validator_groups(), sender)
@@ -263,7 +268,7 @@ async fn run<Client>(
mut subsystem: RuntimeApiSubsystem<Client>,
) -> SubsystemResult<()> where
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static,
Client::Api: ParachainHost<Block> + BabeApi<Block>,
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
{
loop {
select! {
@@ -291,7 +296,7 @@ fn make_runtime_api_request<Client>(
) -> Option<RequestResult>
where
Client: ProvideRuntimeApi<Block>,
Client::Api: ParachainHost<Block> + BabeApi<Block>,
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
{
let _timer = metrics.time_make_runtime_api_request();
@@ -327,6 +332,7 @@ where
}
match request {
Request::Authorities(sender) => query!(Authorities, authorities(), sender),
Request::Validators(sender) => query!(Validators, validators(), sender),
Request::ValidatorGroups(sender) => query!(ValidatorGroups, validator_groups(), sender),
Request::AvailabilityCores(sender) => query!(AvailabilityCores, availability_cores(), sender),
@@ -416,7 +422,7 @@ mod tests {
ValidatorId, ValidatorIndex, GroupRotationInfo, CoreState, PersistedValidationData,
Id as ParaId, OccupiedCoreAssumption, SessionIndex, ValidationCode,
CommittedCandidateReceipt, CandidateEvent, InboundDownwardMessage,
BlockNumber, InboundHrmpMessage, SessionInfo,
BlockNumber, InboundHrmpMessage, SessionInfo, AuthorityDiscoveryId,
};
use polkadot_node_subsystem_test_helpers as test_helpers;
use sp_core::testing::TaskExecutor;
@@ -428,6 +434,7 @@ mod tests {
#[derive(Default, Clone)]
struct MockRuntimeApi {
authorities: Vec<AuthorityDiscoveryId>,
validators: Vec<ValidatorId>,
validator_groups: Vec<Vec<ValidatorIndex>>,
availability_cores: Vec<CoreState>,
@@ -582,6 +589,36 @@ mod tests {
None
}
}
impl AuthorityDiscoveryApi<Block> for MockRuntimeApi {
fn authorities(&self) -> Vec<AuthorityDiscoveryId> {
self.authorities.clone()
}
}
}
#[test]
fn requests_authorities() {
let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new());
let runtime_api = Arc::new(MockRuntimeApi::default());
let relay_parent = [1; 32].into();
let spawner = sp_core::testing::TaskExecutor::new();
let subsystem = RuntimeApiSubsystem::new(runtime_api.clone(), Metrics(None), spawner);
let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap());
let test_task = async move {
let (tx, rx) = oneshot::channel();
ctx_handle.send(FromOverseer::Communication {
msg: RuntimeApiMessage::Request(relay_parent, Request::Authorities(tx))
}).await;
assert_eq!(rx.await.unwrap().unwrap(), runtime_api.authorities);
ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
};
futures::executor::block_on(future::join(subsystem_task, test_task));
}
#[test]