mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 19:11:04 +00:00
enable disputes (#3478)
* initial integration and migration code * fix tests * fix counting test * assume the current version on missing file * use SelectRelayChain * remove duplicate metric * Update node/service/src/lib.rs Co-authored-by: Robert Habermeier <rphmeier@gmail.com> * remove ApprovalCheckingVotingRule * address my concern * never mode for StagnantCheckInterval * REVERTME: some logs * w00t * it's ugly but it works * Revert "REVERTME: some logs" This reverts commit e210505a2e83e31c381394924500b69277bb042e. * it's handle, not handler * fix a few typos Co-authored-by: Robert Habermeier <rphmeier@gmail.com>
This commit is contained in:
@@ -23,179 +23,7 @@ use sp_runtime::generic::BlockId;
|
||||
use sp_runtime::traits::Header as _;
|
||||
|
||||
#[cfg(feature = "full-node")]
|
||||
use {
|
||||
polkadot_primitives::v1::{Hash, Block as PolkadotBlock, Header as PolkadotHeader},
|
||||
polkadot_subsystem::messages::ApprovalVotingMessage,
|
||||
prometheus_endpoint::{self, Registry},
|
||||
polkadot_overseer::Handle,
|
||||
futures::channel::oneshot,
|
||||
};
|
||||
|
||||
/// A custom GRANDPA voting rule that acts as a diagnostic for the approval
|
||||
/// voting subsystem's desired votes.
|
||||
///
|
||||
/// The practical effect of this voting rule is to implement a fixed delay of
|
||||
/// blocks and to issue a prometheus metric on the lag behind the head that
|
||||
/// approval checking would indicate.
|
||||
#[cfg(feature = "full-node")]
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ApprovalCheckingVotingRule {
|
||||
checking_lag: Option<prometheus_endpoint::Gauge<prometheus_endpoint::U64>>,
|
||||
overseer: Handle,
|
||||
}
|
||||
|
||||
#[cfg(feature = "full-node")]
|
||||
impl ApprovalCheckingVotingRule {
|
||||
/// Create a new approval checking diagnostic voting rule.
|
||||
pub fn new(overseer: Handle, registry: Option<&Registry>)
|
||||
-> Result<Self, prometheus_endpoint::PrometheusError>
|
||||
{
|
||||
Ok(ApprovalCheckingVotingRule {
|
||||
checking_lag: if let Some(registry) = registry {
|
||||
Some(prometheus_endpoint::register(
|
||||
prometheus_endpoint::Gauge::with_opts(
|
||||
prometheus_endpoint::Opts::new(
|
||||
"parachain_approval_checking_finality_lag",
|
||||
"How far behind the head of the chain the Approval Checking protocol wants to vote",
|
||||
)
|
||||
)?,
|
||||
registry,
|
||||
)?)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
overseer,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "full-node")]
|
||||
#[derive(Debug, PartialEq)]
|
||||
/// Vote explicitly on the given hash.
|
||||
enum ParachainVotingRuleTarget<H, N> {
|
||||
Explicit((H, N)),
|
||||
/// Vote on the current target.
|
||||
Current,
|
||||
/// Vote on the base target - the minimal possible vote.
|
||||
Base,
|
||||
}
|
||||
|
||||
#[cfg(feature = "full-node")]
|
||||
fn approval_checking_vote_to_grandpa_vote<H, N: PartialOrd>(
|
||||
approval_checking_vote: Option<(H, N)>,
|
||||
current_number: N,
|
||||
) -> ParachainVotingRuleTarget<H, N> {
|
||||
match approval_checking_vote {
|
||||
Some((hash, number)) => if number > current_number {
|
||||
// respect other voting rule.
|
||||
ParachainVotingRuleTarget::Current
|
||||
} else {
|
||||
ParachainVotingRuleTarget::Explicit((hash, number))
|
||||
},
|
||||
// If approval-voting chooses 'None', that means we should vote on the base (last round estimate).
|
||||
None => ParachainVotingRuleTarget::Base,
|
||||
}
|
||||
}
|
||||
|
||||
/// The maximum amount of unfinalized blocks we are willing to allow due to approval checking lag.
|
||||
/// This is a safety net that should be removed at some point in the future.
|
||||
#[cfg(feature = "full-node")]
|
||||
const MAX_APPROVAL_CHECKING_FINALITY_LAG: polkadot_primitives::v1::BlockNumber = 50;
|
||||
|
||||
#[cfg(feature = "full-node")]
|
||||
impl<B> grandpa::VotingRule<PolkadotBlock, B> for ApprovalCheckingVotingRule
|
||||
where B: sp_blockchain::HeaderBackend<PolkadotBlock> + 'static
|
||||
{
|
||||
fn restrict_vote(
|
||||
&self,
|
||||
backend: Arc<B>,
|
||||
base: &PolkadotHeader,
|
||||
best_target: &PolkadotHeader,
|
||||
current_target: &PolkadotHeader,
|
||||
) -> grandpa::VotingRuleResult<PolkadotBlock> {
|
||||
// Query approval checking and issue metrics.
|
||||
let mut overseer = self.overseer.clone();
|
||||
let checking_lag = self.checking_lag.clone();
|
||||
|
||||
let best_hash = best_target.hash();
|
||||
let best_number = best_target.number.clone();
|
||||
let best_header = best_target.clone();
|
||||
|
||||
let current_hash = current_target.hash();
|
||||
let current_number = current_target.number.clone();
|
||||
|
||||
let base_hash = base.hash();
|
||||
let base_number = base.number;
|
||||
|
||||
Box::pin(async move {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let approval_checking_subsystem_vote = {
|
||||
overseer.send_msg(
|
||||
ApprovalVotingMessage::ApprovedAncestor(
|
||||
best_hash,
|
||||
base_number,
|
||||
tx,
|
||||
),
|
||||
std::any::type_name::<Self>(),
|
||||
).await;
|
||||
|
||||
rx.await.ok().and_then(|v| v)
|
||||
};
|
||||
|
||||
let approval_checking_subsystem_lag = approval_checking_subsystem_vote.map_or(
|
||||
best_number - base_number,
|
||||
|(_h, n)| best_number - n,
|
||||
);
|
||||
|
||||
if let Some(ref checking_lag) = checking_lag {
|
||||
checking_lag.set(approval_checking_subsystem_lag as _);
|
||||
}
|
||||
|
||||
let min_vote = {
|
||||
let diff = best_number.saturating_sub(base_number);
|
||||
if diff >= MAX_APPROVAL_CHECKING_FINALITY_LAG {
|
||||
// Catch up to the best, with some extra lag.
|
||||
let target_number = best_number - MAX_APPROVAL_CHECKING_FINALITY_LAG;
|
||||
if target_number >= current_number {
|
||||
Some((current_hash, current_number))
|
||||
} else {
|
||||
walk_backwards_to_target_block(&*backend, target_number, &best_header).ok()
|
||||
}
|
||||
} else {
|
||||
Some((base_hash, base_number))
|
||||
}
|
||||
};
|
||||
|
||||
let vote = match approval_checking_vote_to_grandpa_vote(
|
||||
approval_checking_subsystem_vote,
|
||||
current_number,
|
||||
) {
|
||||
ParachainVotingRuleTarget::Explicit(vote) => {
|
||||
if min_vote.as_ref().map_or(false, |min| min.1 > vote.1) {
|
||||
min_vote
|
||||
} else {
|
||||
Some(vote)
|
||||
}
|
||||
}
|
||||
ParachainVotingRuleTarget::Current => Some((current_hash, current_number)),
|
||||
ParachainVotingRuleTarget::Base => min_vote.or(Some((base_hash, base_number))),
|
||||
};
|
||||
|
||||
tracing::trace!(
|
||||
target: "parachain::approval-voting",
|
||||
?vote,
|
||||
?approval_checking_subsystem_vote,
|
||||
approval_checking_subsystem_lag,
|
||||
current_number,
|
||||
best_number,
|
||||
base_number,
|
||||
"GRANDPA: voting based on approved ancestor.",
|
||||
);
|
||||
|
||||
vote
|
||||
})
|
||||
}
|
||||
}
|
||||
use polkadot_primitives::v1::Hash;
|
||||
|
||||
/// Returns the block hash of the block at the given `target_number` by walking
|
||||
/// backwards from the given `current_header`.
|
||||
@@ -433,7 +261,6 @@ mod tests {
|
||||
use sp_runtime::{generic::BlockId, traits::Header};
|
||||
use consensus_common::BlockOrigin;
|
||||
use std::sync::Arc;
|
||||
use super::{approval_checking_vote_to_grandpa_vote, ParachainVotingRuleTarget};
|
||||
|
||||
#[test]
|
||||
fn grandpa_pause_voting_rule_works() {
|
||||
@@ -545,27 +372,4 @@ mod tests {
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn approval_checking_to_grandpa_rules() {
|
||||
assert_eq!(
|
||||
approval_checking_vote_to_grandpa_vote::<(), _>(None, 5),
|
||||
ParachainVotingRuleTarget::Base,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
approval_checking_vote_to_grandpa_vote(Some(("2", 2)), 3),
|
||||
ParachainVotingRuleTarget::Explicit(("2", 2)),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
approval_checking_vote_to_grandpa_vote(Some(("2", 2)), 2),
|
||||
ParachainVotingRuleTarget::Explicit(("2", 2)),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
approval_checking_vote_to_grandpa_vote(Some(("2", 2)), 1),
|
||||
ParachainVotingRuleTarget::Current,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,11 @@ use {
|
||||
polkadot_node_core_av_store::Error as AvailabilityError,
|
||||
polkadot_node_core_approval_voting::Config as ApprovalVotingConfig,
|
||||
polkadot_node_core_candidate_validation::Config as CandidateValidationConfig,
|
||||
polkadot_node_core_chain_selection::{
|
||||
self as chain_selection_subsystem,
|
||||
Config as ChainSelectionConfig,
|
||||
},
|
||||
polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig,
|
||||
polkadot_overseer::BlockInfo,
|
||||
sp_trie::PrefixedMemoryDB,
|
||||
sc_client_api::ExecutorProvider,
|
||||
@@ -56,7 +61,7 @@ pub use {
|
||||
sp_authority_discovery::AuthorityDiscoveryApi,
|
||||
sc_client_api::AuxStore,
|
||||
polkadot_primitives::v1::ParachainHost,
|
||||
polkadot_overseer::{Overseer, Handle},
|
||||
polkadot_overseer::{Overseer, Handle, OverseerHandle},
|
||||
};
|
||||
pub use sp_core::traits::SpawnNamed;
|
||||
|
||||
@@ -214,7 +219,7 @@ fn jaeger_launch_collector_with_agent(spawner: impl SpawnNamed, config: &Configu
|
||||
}
|
||||
|
||||
#[cfg(feature = "full-node")]
|
||||
type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
|
||||
type FullSelectChain = relay_chain_selection::SelectRelayChain<FullBackend>;
|
||||
#[cfg(feature = "full-node")]
|
||||
type FullGrandpaBlockImport<RuntimeApi, Executor> = grandpa::GrandpaBlockImport<
|
||||
FullBackend, Block, FullClient<RuntimeApi, Executor>, FullSelectChain
|
||||
@@ -298,7 +303,11 @@ fn new_partial<RuntimeApi, Executor>(
|
||||
|
||||
jaeger_launch_collector_with_agent(task_manager.spawn_handle(), &*config, jaeger_agent)?;
|
||||
|
||||
let select_chain = sc_consensus::LongestChain::new(backend.clone());
|
||||
let select_chain = relay_chain_selection::SelectRelayChain::new(
|
||||
backend.clone(),
|
||||
Handle::new_disconnected(),
|
||||
polkadot_node_subsystem_util::metrics::Metrics::register(config.prometheus_registry())?,
|
||||
);
|
||||
|
||||
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
|
||||
config.transaction_pool.clone(),
|
||||
@@ -427,7 +436,7 @@ fn new_partial<RuntimeApi, Executor>(
|
||||
pub struct NewFull<C> {
|
||||
pub task_manager: TaskManager,
|
||||
pub client: C,
|
||||
pub overseer_handler: Option<Handle>,
|
||||
pub overseer_handle: Option<Handle>,
|
||||
pub network: Arc<sc_network::NetworkService<Block, <Block as BlockT>::Hash>>,
|
||||
pub rpc_handlers: RpcHandlers,
|
||||
pub backend: Arc<FullBackend>,
|
||||
@@ -440,7 +449,7 @@ impl<C> NewFull<C> {
|
||||
NewFull {
|
||||
client: func(self.client),
|
||||
task_manager: self.task_manager,
|
||||
overseer_handler: self.overseer_handler,
|
||||
overseer_handle: self.overseer_handle,
|
||||
network: self.network,
|
||||
rpc_handlers: self.rpc_handlers,
|
||||
backend: self.backend,
|
||||
@@ -480,7 +489,7 @@ impl IsCollator {
|
||||
/// Returns the active leaves the overseer should start with.
|
||||
#[cfg(feature = "full-node")]
|
||||
async fn active_leaves<RuntimeApi, Executor>(
|
||||
select_chain: &sc_consensus::LongestChain<FullBackend, Block>,
|
||||
select_chain: &impl SelectChain<Block>,
|
||||
client: &FullClient<RuntimeApi, Executor>,
|
||||
) -> Result<Vec<BlockInfo>, Error>
|
||||
where
|
||||
@@ -573,7 +582,7 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
backend,
|
||||
mut task_manager,
|
||||
keystore_container,
|
||||
select_chain,
|
||||
mut select_chain,
|
||||
import_queue,
|
||||
transaction_pool,
|
||||
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry)
|
||||
@@ -655,6 +664,15 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
},
|
||||
};
|
||||
|
||||
let chain_selection_config = ChainSelectionConfig {
|
||||
col_data: crate::parachains_db::REAL_COLUMNS.col_chain_selection_data,
|
||||
stagnant_check_interval: chain_selection_subsystem::StagnantCheckInterval::never(),
|
||||
};
|
||||
|
||||
let dispute_coordinator_config = DisputeCoordinatorConfig {
|
||||
col_data: crate::parachains_db::REAL_COLUMNS.col_dispute_coordinator_data,
|
||||
};
|
||||
|
||||
let chain_spec = config.chain_spec.cloned_box();
|
||||
let rpc_handlers = service::spawn_tasks(service::SpawnTasksParams {
|
||||
config,
|
||||
@@ -714,8 +732,6 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
None
|
||||
};
|
||||
|
||||
// we'd say let overseer_handler = authority_discovery_service.map(|authority_discovery_service|, ...),
|
||||
// but in that case we couldn't use ? to propagate errors
|
||||
let local_keystore = keystore_container.local_keystore();
|
||||
if local_keystore.is_none() {
|
||||
tracing::info!("Cannot run as validator without local keystore.");
|
||||
@@ -724,8 +740,8 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
let maybe_params = local_keystore
|
||||
.and_then(move |k| authority_discovery_service.map(|a| (a, k)));
|
||||
|
||||
let overseer_handler = if let Some((authority_discovery_service, keystore)) = maybe_params {
|
||||
let (overseer, overseer_handler) = overseer_gen.generate::<
|
||||
let overseer_handle = if let Some((authority_discovery_service, keystore)) = maybe_params {
|
||||
let (overseer, overseer_handle) = overseer_gen.generate::<
|
||||
service::SpawnTaskHandle,
|
||||
FullClient<RuntimeApi, Executor>,
|
||||
>(
|
||||
@@ -734,23 +750,26 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
keystore,
|
||||
runtime_client: overseer_client.clone(),
|
||||
parachains_db,
|
||||
availability_config,
|
||||
approval_voting_config,
|
||||
network_service: network.clone(),
|
||||
authority_discovery_service,
|
||||
request_multiplexer,
|
||||
registry: prometheus_registry.as_ref(),
|
||||
spawner,
|
||||
is_collator,
|
||||
approval_voting_config,
|
||||
availability_config,
|
||||
candidate_validation_config,
|
||||
chain_selection_config,
|
||||
dispute_coordinator_config,
|
||||
}
|
||||
)?;
|
||||
let overseer_handler_clone = overseer_handler.clone();
|
||||
let handle = Handle::Connected(overseer_handle.clone());
|
||||
let handle_clone = handle.clone();
|
||||
|
||||
task_manager.spawn_essential_handle().spawn_blocking("overseer", Box::pin(async move {
|
||||
use futures::{pin_mut, select, FutureExt};
|
||||
|
||||
let forward = polkadot_overseer::forward_events(overseer_client, overseer_handler_clone);
|
||||
let forward = polkadot_overseer::forward_events(overseer_client, handle_clone);
|
||||
|
||||
let forward = forward.fuse();
|
||||
let overseer_fut = overseer.run().fuse();
|
||||
@@ -764,8 +783,19 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
complete => (),
|
||||
}
|
||||
}));
|
||||
// we should remove this check before we deploy parachains on polkadot
|
||||
// TODO: https://github.com/paritytech/polkadot/issues/3326
|
||||
let should_connect_overseer = chain_spec.is_kusama()
|
||||
|| chain_spec.is_westend()
|
||||
|| chain_spec.is_rococo()
|
||||
|| chain_spec.is_wococo();
|
||||
|
||||
Some(overseer_handler)
|
||||
if should_connect_overseer {
|
||||
select_chain.connect_to_overseer(overseer_handle.clone());
|
||||
} else {
|
||||
tracing::info!("Overseer is running in the disconnected state");
|
||||
}
|
||||
Some(handle)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -783,7 +813,7 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
);
|
||||
|
||||
let client_clone = client.clone();
|
||||
let overseer_handler = overseer_handler.as_ref().ok_or(Error::AuthoritiesRequireRealOverseer)?.clone();
|
||||
let overseer_handle = overseer_handle.as_ref().ok_or(Error::AuthoritiesRequireRealOverseer)?.clone();
|
||||
let slot_duration = babe_link.config().slot_duration();
|
||||
let babe_config = babe::BabeParams {
|
||||
keystore: keystore_container.sync_keystore(),
|
||||
@@ -795,11 +825,11 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
justification_sync_link: network.clone(),
|
||||
create_inherent_data_providers: move |parent, ()| {
|
||||
let client_clone = client_clone.clone();
|
||||
let overseer_handler = overseer_handler.clone();
|
||||
let overseer_handle = overseer_handle.clone();
|
||||
async move {
|
||||
let parachain = polkadot_node_core_parachains_inherent::ParachainsInherentDataProvider::create(
|
||||
&*client_clone,
|
||||
overseer_handler,
|
||||
overseer_handle,
|
||||
parent,
|
||||
).await.map_err(|e| Box::new(e))?;
|
||||
|
||||
@@ -889,24 +919,6 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
// after the given pause block is finalized and restarting after the
|
||||
// given delay.
|
||||
let builder = grandpa::VotingRulesBuilder::default();
|
||||
// we should enable approval checking voting rule before we deploy parachains on polkadot
|
||||
let enable_approval_checking_voting_rule = chain_spec.is_kusama()
|
||||
|| chain_spec.is_westend()
|
||||
|| chain_spec.is_rococo()
|
||||
|| chain_spec.is_wococo();
|
||||
|
||||
let builder = if let Some(ref overseer) = overseer_handler {
|
||||
if enable_approval_checking_voting_rule {
|
||||
builder.add(grandpa_support::ApprovalCheckingVotingRule::new(
|
||||
overseer.clone(),
|
||||
prometheus_registry.as_ref(),
|
||||
)?)
|
||||
} else {
|
||||
builder
|
||||
}
|
||||
} else {
|
||||
builder
|
||||
};
|
||||
|
||||
let voting_rule = match grandpa_pause {
|
||||
Some((block, delay)) => {
|
||||
@@ -946,7 +958,7 @@ pub fn new_full<RuntimeApi, Executor, OverseerGenerator>(
|
||||
Ok(NewFull {
|
||||
task_manager,
|
||||
client,
|
||||
overseer_handler,
|
||||
overseer_handle,
|
||||
network,
|
||||
rpc_handlers,
|
||||
backend,
|
||||
|
||||
@@ -28,7 +28,9 @@ use polkadot_network_bridge::RequestMultiplexer;
|
||||
use polkadot_node_core_av_store::Config as AvailabilityConfig;
|
||||
use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig;
|
||||
use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig;
|
||||
use polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, Handle};
|
||||
use polkadot_node_core_chain_selection::Config as ChainSelectionConfig;
|
||||
use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig;
|
||||
use polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, OverseerHandle};
|
||||
use polkadot_primitives::v1::ParachainHost;
|
||||
use sc_authority_discovery::Service as AuthorityDiscoveryService;
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
@@ -54,6 +56,10 @@ pub use polkadot_availability_recovery::AvailabilityRecoverySubsystem;
|
||||
pub use polkadot_approval_distribution::ApprovalDistribution as ApprovalDistributionSubsystem;
|
||||
pub use polkadot_node_core_approval_voting::ApprovalVotingSubsystem;
|
||||
pub use polkadot_gossip_support::GossipSupport as GossipSupportSubsystem;
|
||||
pub use polkadot_node_core_dispute_coordinator::DisputeCoordinatorSubsystem;
|
||||
pub use polkadot_node_core_dispute_participation::DisputeParticipationSubsystem;
|
||||
pub use polkadot_dispute_distribution::DisputeDistributionSubsystem;
|
||||
pub use polkadot_node_core_chain_selection::ChainSelectionSubsystem;
|
||||
|
||||
/// Arguments passed for overseer construction.
|
||||
pub struct OverseerGenArgs<'a, Spawner, RuntimeClient> where
|
||||
@@ -69,10 +75,6 @@ pub struct OverseerGenArgs<'a, Spawner, RuntimeClient> where
|
||||
pub runtime_client: Arc<RuntimeClient>,
|
||||
/// The underlying key value store for the parachains.
|
||||
pub parachains_db: Arc<dyn kvdb::KeyValueDB>,
|
||||
/// Configuration for the availability store subsystem.
|
||||
pub availability_config: AvailabilityConfig,
|
||||
/// Configuration for the approval voting subsystem.
|
||||
pub approval_voting_config: ApprovalVotingConfig,
|
||||
/// Underlying network service implementation.
|
||||
pub network_service: Arc<sc_network::NetworkService<Block, Hash>>,
|
||||
/// Underlying authority discovery service.
|
||||
@@ -85,8 +87,16 @@ pub struct OverseerGenArgs<'a, Spawner, RuntimeClient> where
|
||||
pub spawner: Spawner,
|
||||
/// Determines the behavior of the collator.
|
||||
pub is_collator: IsCollator,
|
||||
/// Configuration for the approval voting subsystem.
|
||||
pub approval_voting_config: ApprovalVotingConfig,
|
||||
/// Configuration for the availability store subsystem.
|
||||
pub availability_config: AvailabilityConfig,
|
||||
/// Configuration for the candidate validation subsystem.
|
||||
pub candidate_validation_config: CandidateValidationConfig,
|
||||
/// Configuration for the chain selection subsystem.
|
||||
pub chain_selection_config: ChainSelectionConfig,
|
||||
/// Configuration for the dispute coordinator subsystem.
|
||||
pub dispute_coordinator_config: DisputeCoordinatorConfig,
|
||||
}
|
||||
|
||||
/// Create a default, unaltered set of subsystems.
|
||||
@@ -99,15 +109,17 @@ pub fn create_default_subsystems<'a, Spawner, RuntimeClient>
|
||||
keystore,
|
||||
runtime_client,
|
||||
parachains_db,
|
||||
availability_config,
|
||||
approval_voting_config,
|
||||
network_service,
|
||||
authority_discovery_service,
|
||||
request_multiplexer,
|
||||
registry,
|
||||
spawner,
|
||||
is_collator,
|
||||
approval_voting_config,
|
||||
availability_config,
|
||||
candidate_validation_config,
|
||||
chain_selection_config,
|
||||
dispute_coordinator_config,
|
||||
..
|
||||
} : OverseerGenArgs<'a, Spawner, RuntimeClient>
|
||||
) -> Result<
|
||||
@@ -129,6 +141,10 @@ pub fn create_default_subsystems<'a, Spawner, RuntimeClient>
|
||||
ApprovalDistributionSubsystem,
|
||||
ApprovalVotingSubsystem,
|
||||
GossipSupportSubsystem,
|
||||
DisputeCoordinatorSubsystem,
|
||||
DisputeParticipationSubsystem,
|
||||
DisputeDistributionSubsystem<AuthorityDiscoveryService>,
|
||||
ChainSelectionSubsystem,
|
||||
>,
|
||||
Error
|
||||
>
|
||||
@@ -218,7 +234,7 @@ where
|
||||
),
|
||||
approval_voting: ApprovalVotingSubsystem::with_config(
|
||||
approval_voting_config,
|
||||
parachains_db,
|
||||
parachains_db.clone(),
|
||||
keystore.clone(),
|
||||
Box::new(network_service.clone()),
|
||||
Metrics::register(registry)?,
|
||||
@@ -226,6 +242,21 @@ where
|
||||
gossip_support: GossipSupportSubsystem::new(
|
||||
keystore.clone(),
|
||||
),
|
||||
dispute_coordinator: DisputeCoordinatorSubsystem::new(
|
||||
parachains_db.clone(),
|
||||
dispute_coordinator_config,
|
||||
keystore.clone(),
|
||||
),
|
||||
dispute_participation: DisputeParticipationSubsystem::new(),
|
||||
dispute_distribution: DisputeDistributionSubsystem::new(
|
||||
keystore.clone(),
|
||||
authority_discovery_service.clone(),
|
||||
Metrics::register(registry)?,
|
||||
),
|
||||
chain_selection: ChainSelectionSubsystem::new(
|
||||
chain_selection_config,
|
||||
parachains_db,
|
||||
),
|
||||
};
|
||||
Ok(all_subsystems)
|
||||
}
|
||||
@@ -237,7 +268,7 @@ where
|
||||
/// would do.
|
||||
pub trait OverseerGen {
|
||||
/// Overwrite the full generation of the overseer, including the subsystems.
|
||||
fn generate<'a, Spawner, RuntimeClient>(&self, args: OverseerGenArgs<'a, Spawner, RuntimeClient>) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, Handle), Error>
|
||||
fn generate<'a, Spawner, RuntimeClient>(&self, args: OverseerGenArgs<'a, Spawner, RuntimeClient>) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, OverseerHandle), Error>
|
||||
where
|
||||
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
|
||||
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
|
||||
@@ -256,7 +287,7 @@ pub struct RealOverseerGen;
|
||||
impl OverseerGen for RealOverseerGen {
|
||||
fn generate<'a, Spawner, RuntimeClient>(&self,
|
||||
args : OverseerGenArgs<'a, Spawner, RuntimeClient>
|
||||
) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, Handle), Error>
|
||||
) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, OverseerHandle), Error>
|
||||
where
|
||||
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
|
||||
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
|
||||
|
||||
@@ -22,16 +22,21 @@ use {
|
||||
kvdb::KeyValueDB,
|
||||
};
|
||||
|
||||
#[cfg(feature = "full-node")]
|
||||
mod upgrade;
|
||||
|
||||
#[cfg(any(test,feature = "full-node"))]
|
||||
mod columns {
|
||||
pub const NUM_COLUMNS: u32 = 3;
|
||||
|
||||
pub(crate) mod columns {
|
||||
pub mod v0 {
|
||||
pub const NUM_COLUMNS: u32 = 3;
|
||||
}
|
||||
pub const NUM_COLUMNS: u32 = 5;
|
||||
|
||||
pub const COL_AVAILABILITY_DATA: u32 = 0;
|
||||
pub const COL_AVAILABILITY_META: u32 = 1;
|
||||
pub const COL_APPROVAL_DATA: u32 = 2;
|
||||
pub const COL_CHAIN_SELECTION_DATA: u32 = 3;
|
||||
pub const COL_DISPUTE_COORDINATOR_DATA: u32 = 4;
|
||||
}
|
||||
|
||||
/// Columns used by different subsystems.
|
||||
@@ -44,6 +49,10 @@ pub struct ColumnsConfig {
|
||||
pub col_availability_meta: u32,
|
||||
/// The column used by approval voting for data.
|
||||
pub col_approval_data: u32,
|
||||
/// The column used by chain selection for data.
|
||||
pub col_chain_selection_data: u32,
|
||||
/// The column used by dispute coordinator for data.
|
||||
pub col_dispute_coordinator_data: u32,
|
||||
}
|
||||
|
||||
/// The real columns used by the parachains DB.
|
||||
@@ -52,6 +61,8 @@ pub const REAL_COLUMNS: ColumnsConfig = ColumnsConfig {
|
||||
col_availability_data: columns::COL_AVAILABILITY_DATA,
|
||||
col_availability_meta: columns::COL_AVAILABILITY_META,
|
||||
col_approval_data: columns::COL_APPROVAL_DATA,
|
||||
col_chain_selection_data: columns::COL_CHAIN_SELECTION_DATA,
|
||||
col_dispute_coordinator_data: columns::COL_DISPUTE_COORDINATOR_DATA,
|
||||
};
|
||||
|
||||
/// The cache size for each column, in megabytes.
|
||||
@@ -76,7 +87,7 @@ impl Default for CacheSizes {
|
||||
}
|
||||
|
||||
#[cfg(feature = "full-node")]
|
||||
fn other_io_error(err: String) -> io::Error {
|
||||
pub(crate) fn other_io_error(err: String) -> io::Error {
|
||||
io::Error::new(io::ErrorKind::Other, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ type Version = u32;
|
||||
const VERSION_FILE_NAME: &'static str = "parachain_db_version";
|
||||
|
||||
/// Current db version.
|
||||
const CURRENT_VERSION: Version = 0;
|
||||
const CURRENT_VERSION: Version = 1;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
@@ -56,6 +56,7 @@ pub fn try_upgrade_db(db_path: &Path) -> Result<(), Error> {
|
||||
let is_empty = db_path.read_dir().map_or(true, |mut d| d.next().is_none());
|
||||
if !is_empty {
|
||||
match current_version(db_path)? {
|
||||
0 => migrate_from_version_0_to_1(db_path)?,
|
||||
CURRENT_VERSION => (),
|
||||
v => return Err(Error::FutureVersion {
|
||||
current: CURRENT_VERSION,
|
||||
@@ -68,10 +69,10 @@ pub fn try_upgrade_db(db_path: &Path) -> Result<(), Error> {
|
||||
}
|
||||
|
||||
/// Reads current database version from the file at given path.
|
||||
/// If the file does not exist, assumes version 0.
|
||||
/// If the file does not exist, assumes the current version.
|
||||
fn current_version(path: &Path) -> Result<Version, Error> {
|
||||
match fs::read_to_string(version_file_path(path)) {
|
||||
Err(ref err) if err.kind() == io::ErrorKind::NotFound => Ok(0),
|
||||
Err(ref err) if err.kind() == io::ErrorKind::NotFound => Ok(CURRENT_VERSION),
|
||||
Err(err) => Err(err.into()),
|
||||
Ok(content) => u32::from_str(&content).map_err(|_| Error::CorruptedVersionFile),
|
||||
}
|
||||
@@ -90,3 +91,20 @@ fn version_file_path(path: &Path) -> PathBuf {
|
||||
file_path.push(VERSION_FILE_NAME);
|
||||
file_path
|
||||
}
|
||||
|
||||
|
||||
/// Migration from version 0 to version 1:
|
||||
/// * the number of columns has changed from 3 to 5;
|
||||
fn migrate_from_version_0_to_1(path: &Path) -> Result<(), Error> {
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
|
||||
let db_path = path.to_str()
|
||||
.ok_or_else(|| super::other_io_error("Invalid database path".into()))?;
|
||||
let db_cfg = DatabaseConfig::with_columns(super::columns::v0::NUM_COLUMNS);
|
||||
let db = Database::open(&db_cfg, db_path)?;
|
||||
|
||||
db.add_column()?;
|
||||
db.add_column()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ use {
|
||||
},
|
||||
polkadot_subsystem::messages::{ApprovalVotingMessage, ChainSelectionMessage},
|
||||
polkadot_node_subsystem_util::metrics::{self, prometheus},
|
||||
polkadot_overseer::Handle,
|
||||
polkadot_overseer::{Handle, OverseerHandle},
|
||||
futures::channel::oneshot,
|
||||
consensus_common::{Error as ConsensusError, SelectChain},
|
||||
sp_blockchain::HeaderBackend,
|
||||
@@ -125,7 +125,6 @@ impl<B> SelectRelayChain<B>
|
||||
{
|
||||
/// Create a new [`SelectRelayChain`] wrapping the given chain backend
|
||||
/// and a handle to the overseer.
|
||||
#[allow(unused)]
|
||||
pub fn new(backend: Arc<B>, overseer: Handle, metrics: Metrics) -> Self {
|
||||
SelectRelayChain {
|
||||
fallback: sc_consensus::LongestChain::new(backend.clone()),
|
||||
@@ -167,14 +166,13 @@ impl<B> SelectRelayChain<B>
|
||||
}
|
||||
|
||||
impl<B> SelectRelayChain<B> {
|
||||
/// Given an overseer handler, this connects the [`SelectRelayChain`]'s
|
||||
/// internal handler to the same overseer.
|
||||
#[allow(unused)]
|
||||
pub fn connect_overseer_handler(
|
||||
/// Given an overseer handle, connects the [`SelectRelayChain`]'s
|
||||
/// internal handle and its clones to the same overseer.
|
||||
pub fn connect_to_overseer(
|
||||
&mut self,
|
||||
other_handler: &Handle,
|
||||
handle: OverseerHandle,
|
||||
) {
|
||||
other_handler.connect_other(&mut self.overseer);
|
||||
self.overseer.connect_to_overseer(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user