mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 21:37:56 +00:00
past-session validator discovery APIs (#2009)
* guide: fix formatting for SessionInfo module * primitives: SessionInfo type * punt on approval keys * ah, revert the type alias * session info runtime module skeleton * update the guide * runtime/configuration: sync with the guide * runtime/configuration: setters for newly added fields * runtime/configuration: set codec indexes * runtime/configuration: update test * primitives: fix SessionInfo definition * runtime/session_info: initial impl * runtime/session_info: use initializer for session handling (wip) * runtime/session_info: mock authority discovery trait * guide: update the initializer's order * runtime/session_info: tests skeleton * runtime/session_info: store n_delay_tranches in Configuration * runtime/session_info: punt on approval keys * runtime/session_info: add some basic tests * Update primitives/src/v1.rs * small fixes * remove codec index annotation on structs * fix off-by-one error * validator_discovery: accept a session index * runtime: replace validator_discovery api with session_info * Update runtime/parachains/src/session_info.rs Co-authored-by: Sergei Shulepov <sergei@parity.io> * runtime/session_info: add a comment about missing entries * runtime/session_info: define the keys * util: expose connect_to_past_session_validators * util: allow session_info requests for jobs * runtime-api: add mock test for session_info * collator-protocol: add session_index to test state * util: fix error message for runtime error * fix compilation * fix tests after merge with master Co-authored-by: Sergei Shulepov <sergei@parity.io>
This commit is contained in:
@@ -37,6 +37,7 @@ use polkadot_primitives::v1::{
|
||||
CandidateEvent, CommittedCandidateReceipt, CoreState, EncodeAs, PersistedValidationData,
|
||||
GroupRotationInfo, Hash, Id as ParaId, ValidationData, OccupiedCoreAssumption,
|
||||
SessionIndex, Signed, SigningContext, ValidationCode, ValidatorId, ValidatorIndex,
|
||||
SessionInfo,
|
||||
};
|
||||
use sp_core::{
|
||||
traits::SpawnNamed,
|
||||
@@ -193,6 +194,7 @@ specialize_requests! {
|
||||
fn request_validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option<ValidationCode>; ValidationCode;
|
||||
fn request_candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt>; CandidatePendingAvailability;
|
||||
fn request_candidate_events() -> Vec<CandidateEvent>; CandidateEvents;
|
||||
fn request_session_info(index: SessionIndex) -> Option<SessionInfo>; SessionInfo;
|
||||
}
|
||||
|
||||
/// Request some data from the `RuntimeApi` via a SubsystemContext.
|
||||
@@ -274,6 +276,7 @@ specialize_requests_ctx! {
|
||||
fn request_validation_code_ctx(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option<ValidationCode>; ValidationCode;
|
||||
fn request_candidate_pending_availability_ctx(para_id: ParaId) -> Option<CommittedCandidateReceipt>; CandidatePendingAvailability;
|
||||
fn request_candidate_events_ctx() -> Vec<CandidateEvent>; CandidateEvents;
|
||||
fn request_session_info_ctx(index: SessionIndex) -> Option<SessionInfo>; SessionInfo;
|
||||
}
|
||||
|
||||
/// From the given set of validators, find the first key we can sign with, if any.
|
||||
|
||||
@@ -20,34 +20,20 @@ use std::collections::HashMap;
|
||||
use std::pin::Pin;
|
||||
|
||||
use futures::{
|
||||
channel::{mpsc, oneshot},
|
||||
channel::mpsc,
|
||||
task::{Poll, self},
|
||||
stream,
|
||||
};
|
||||
use streamunordered::{StreamUnordered, StreamYield};
|
||||
use thiserror::Error;
|
||||
|
||||
use polkadot_node_subsystem::{
|
||||
errors::RuntimeApiError, SubsystemError,
|
||||
messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest, NetworkBridgeMessage},
|
||||
errors::RuntimeApiError,
|
||||
messages::{AllMessages, NetworkBridgeMessage},
|
||||
SubsystemContext,
|
||||
};
|
||||
use polkadot_primitives::v1::{Hash, ValidatorId, AuthorityDiscoveryId};
|
||||
use polkadot_primitives::v1::{Hash, ValidatorId, AuthorityDiscoveryId, SessionIndex};
|
||||
use sc_network::PeerId;
|
||||
|
||||
/// Error when making a request to connect to validators.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
/// Attempted to send or receive on a oneshot channel which had been canceled
|
||||
#[error(transparent)]
|
||||
Oneshot(#[from] oneshot::Canceled),
|
||||
/// A subsystem error.
|
||||
#[error(transparent)]
|
||||
Subsystem(#[from] SubsystemError),
|
||||
/// An error in the Runtime API.
|
||||
#[error(transparent)]
|
||||
RuntimeApi(#[from] RuntimeApiError),
|
||||
}
|
||||
use crate::Error;
|
||||
|
||||
/// Utility function to make it easier to connect to validators.
|
||||
pub async fn connect_to_validators<Context: SubsystemContext>(
|
||||
@@ -55,17 +41,42 @@ pub async fn connect_to_validators<Context: SubsystemContext>(
|
||||
relay_parent: Hash,
|
||||
validators: Vec<ValidatorId>,
|
||||
) -> Result<ConnectionRequest, Error> {
|
||||
// ValidatorId -> AuthorityDiscoveryId
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let current_index = crate::request_session_index_for_child_ctx(relay_parent, ctx).await?.await??;
|
||||
connect_to_past_session_validators(ctx, relay_parent, validators, current_index).await
|
||||
}
|
||||
|
||||
ctx.send_message(AllMessages::RuntimeApi(
|
||||
RuntimeApiMessage::Request(
|
||||
relay_parent,
|
||||
RuntimeApiRequest::ValidatorDiscovery(validators.clone(), tx),
|
||||
)
|
||||
)).await;
|
||||
/// Utility function to make it easier to connect to validators in the past sessions.
|
||||
pub async fn connect_to_past_session_validators<Context: SubsystemContext>(
|
||||
ctx: &mut Context,
|
||||
relay_parent: Hash,
|
||||
validators: Vec<ValidatorId>,
|
||||
session_index: SessionIndex,
|
||||
) -> Result<ConnectionRequest, Error> {
|
||||
let session_info = crate::request_session_info_ctx(
|
||||
relay_parent,
|
||||
session_index,
|
||||
ctx,
|
||||
).await?.await??;
|
||||
|
||||
let (session_validators, discovery_keys) = match session_info {
|
||||
Some(info) => (info.validators, info.discovery_keys),
|
||||
None => return Err(RuntimeApiError::from(
|
||||
format!("No SessionInfo found for the index {}", session_index)
|
||||
).into()),
|
||||
};
|
||||
|
||||
let id_to_index = session_validators.iter()
|
||||
.zip(0usize..)
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
// We assume the same ordering in authorities as in validators so we can do an index search
|
||||
let maybe_authorities: Vec<_> = validators.iter()
|
||||
.map(|id| {
|
||||
let validator_index = id_to_index.get(&id);
|
||||
validator_index.and_then(|i| discovery_keys.get(*i).cloned())
|
||||
})
|
||||
.collect();
|
||||
|
||||
let maybe_authorities = rx.await??;
|
||||
let authorities: Vec<_> = maybe_authorities.iter()
|
||||
.cloned()
|
||||
.filter_map(|id| id)
|
||||
|
||||
Reference in New Issue
Block a user