feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// This file is part of Pezcumulus.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// Pezcumulus is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Pezcumulus is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Pezcumulus. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Pezcumulus Collator implementation for Bizinikiwi.
|
||||
|
||||
use pezkuwi_node_primitives::CollationGenerationConfig;
|
||||
use pezkuwi_node_subsystem::messages::{CollationGenerationMessage, CollatorProtocolMessage};
|
||||
use pezkuwi_overseer::Handle as OverseerHandle;
|
||||
use pezkuwi_primitives::{CollatorPair, Id as ParaId};
|
||||
pub mod service;
|
||||
|
||||
/// Relay-chain-driven collators are those whose block production is driven purely
|
||||
/// by new relay chain blocks and the most recently included teyrchain blocks
|
||||
/// within them.
|
||||
///
|
||||
/// This method of driving collators is not suited to anything but the most simple teyrchain
|
||||
/// consensus mechanisms, and this module may soon be deprecated.
|
||||
pub mod relay_chain_driven {
|
||||
use futures::{
|
||||
channel::{mpsc, oneshot},
|
||||
prelude::*,
|
||||
};
|
||||
use pezkuwi_node_primitives::{CollationGenerationConfig, CollationResult};
|
||||
use pezkuwi_node_subsystem::messages::{CollationGenerationMessage, CollatorProtocolMessage};
|
||||
use pezkuwi_overseer::Handle as OverseerHandle;
|
||||
use pezkuwi_primitives::{CollatorPair, Id as ParaId};
|
||||
|
||||
use cumulus_primitives_core::{relay_chain::Hash as PHash, PersistedValidationData};
|
||||
|
||||
/// A request to author a collation, based on the advancement of the relay chain.
|
||||
///
|
||||
/// See the module docs for more info on relay-chain-driven collators.
|
||||
pub struct CollationRequest {
|
||||
relay_parent: PHash,
|
||||
pvd: PersistedValidationData,
|
||||
sender: oneshot::Sender<Option<CollationResult>>,
|
||||
}
|
||||
|
||||
impl CollationRequest {
|
||||
/// Get the relay parent of the collation request.
|
||||
pub fn relay_parent(&self) -> &PHash {
|
||||
&self.relay_parent
|
||||
}
|
||||
|
||||
/// Get the [`PersistedValidationData`] for the request.
|
||||
pub fn persisted_validation_data(&self) -> &PersistedValidationData {
|
||||
&self.pvd
|
||||
}
|
||||
|
||||
/// Complete the request with a collation, if any.
|
||||
pub fn complete(self, collation: Option<CollationResult>) {
|
||||
let _ = self.sender.send(collation);
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the collator with Pezkuwi's collation-generation
|
||||
/// subsystem, returning a stream of collation requests to handle.
|
||||
pub async fn init(
|
||||
key: CollatorPair,
|
||||
para_id: ParaId,
|
||||
overseer_handle: OverseerHandle,
|
||||
) -> mpsc::Receiver<CollationRequest> {
|
||||
let mut overseer_handle = overseer_handle;
|
||||
|
||||
let (stream_tx, stream_rx) = mpsc::channel(0);
|
||||
let config = CollationGenerationConfig {
|
||||
key,
|
||||
para_id,
|
||||
collator: Some(Box::new(move |relay_parent, validation_data| {
|
||||
// Cloning the channel on each usage effectively makes the channel
|
||||
// unbounded. The channel is actually bounded by the block production
|
||||
// and consensus systems of Pezkuwi, which limits the amount of possible
|
||||
// blocks.
|
||||
let mut stream_tx = stream_tx.clone();
|
||||
let validation_data = validation_data.clone();
|
||||
Box::pin(async move {
|
||||
let (this_tx, this_rx) = oneshot::channel();
|
||||
let request =
|
||||
CollationRequest { relay_parent, pvd: validation_data, sender: this_tx };
|
||||
|
||||
if stream_tx.send(request).await.is_err() {
|
||||
return None;
|
||||
}
|
||||
|
||||
this_rx.await.ok().flatten()
|
||||
})
|
||||
})),
|
||||
};
|
||||
|
||||
overseer_handle
|
||||
.send_msg(CollationGenerationMessage::Initialize(config), "StartCollator")
|
||||
.await;
|
||||
|
||||
overseer_handle
|
||||
.send_msg(CollatorProtocolMessage::CollateOn(para_id), "StartCollator")
|
||||
.await;
|
||||
|
||||
stream_rx
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the collation-related subsystems on the relay-chain side.
|
||||
///
|
||||
/// This must be done prior to collation, and does not set up any callback for collation.
|
||||
/// For callback-driven collators, use the [`relay_chain_driven`] module.
|
||||
pub async fn initialize_collator_subsystems(
|
||||
overseer_handle: &mut OverseerHandle,
|
||||
key: CollatorPair,
|
||||
para_id: ParaId,
|
||||
reinitialize: bool,
|
||||
) {
|
||||
let config = CollationGenerationConfig { key, para_id, collator: None };
|
||||
|
||||
if reinitialize {
|
||||
overseer_handle
|
||||
.send_msg(CollationGenerationMessage::Reinitialize(config), "StartCollator")
|
||||
.await;
|
||||
} else {
|
||||
overseer_handle
|
||||
.send_msg(CollationGenerationMessage::Initialize(config), "StartCollator")
|
||||
.await;
|
||||
}
|
||||
|
||||
overseer_handle
|
||||
.send_msg(CollatorProtocolMessage::CollateOn(para_id), "StartCollator")
|
||||
.await;
|
||||
}
|
||||
@@ -0,0 +1,361 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// This file is part of Pezcumulus.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// Pezcumulus is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Pezcumulus is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Pezcumulus. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! The Pezcumulus [`CollatorService`] is a utility struct for performing common
|
||||
//! operations used in teyrchain consensus/authoring.
|
||||
|
||||
use cumulus_client_network::WaitToAnnounce;
|
||||
use cumulus_primitives_core::{CollationInfo, CollectCollationInfo, TeyrchainBlockData};
|
||||
|
||||
use pezsc_client_api::BlockBackend;
|
||||
use pezsp_api::{ApiExt, ProvideRuntimeApi};
|
||||
use pezsp_consensus::BlockStatus;
|
||||
use pezsp_core::traits::SpawnNamed;
|
||||
use pezsp_runtime::traits::{Block as BlockT, HashingFor, Header as HeaderT, Zero};
|
||||
|
||||
use cumulus_client_consensus_common::TeyrchainCandidate;
|
||||
use pezkuwi_node_primitives::{
|
||||
BlockData, Collation, CollationSecondedSignal, MaybeCompressedPoV, PoV,
|
||||
};
|
||||
|
||||
use codec::Encode;
|
||||
use futures::channel::oneshot;
|
||||
use parking_lot::Mutex;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// The logging target.
|
||||
const LOG_TARGET: &str = "pezcumulus-collator";
|
||||
|
||||
/// Utility functions generally applicable to writing collators for Pezcumulus.
|
||||
pub trait ServiceInterface<Block: BlockT> {
|
||||
/// Checks the status of the given block hash in the Teyrchain.
|
||||
///
|
||||
/// Returns `true` if the block could be found and is good to be build on.
|
||||
fn check_block_status(&self, hash: Block::Hash, header: &Block::Header) -> bool;
|
||||
|
||||
/// Build a full [`Collation`] from a given [`TeyrchainCandidate`]. This requires
|
||||
/// that the underlying block has been fully imported into the underlying client,
|
||||
/// as implementations will fetch underlying runtime API data.
|
||||
///
|
||||
/// This also returns the unencoded teyrchain block data, in case that is desired.
|
||||
fn build_collation(
|
||||
&self,
|
||||
parent_header: &Block::Header,
|
||||
block_hash: Block::Hash,
|
||||
candidate: TeyrchainCandidate<Block>,
|
||||
) -> Option<(Collation, TeyrchainBlockData<Block>)>;
|
||||
|
||||
/// Inform networking systems that the block should be announced after a signal has
|
||||
/// been received to indicate the block has been seconded by a relay-chain validator.
|
||||
///
|
||||
/// This sets up the barrier and returns the sending side of a channel, for the signal
|
||||
/// to be passed through.
|
||||
fn announce_with_barrier(
|
||||
&self,
|
||||
block_hash: Block::Hash,
|
||||
) -> oneshot::Sender<CollationSecondedSignal>;
|
||||
|
||||
/// Directly announce a block on the network.
|
||||
fn announce_block(&self, block_hash: Block::Hash, data: Option<Vec<u8>>);
|
||||
}
|
||||
|
||||
/// The [`CollatorService`] provides common utilities for teyrchain consensus and authoring.
|
||||
///
|
||||
/// This includes logic for checking the block status of arbitrary teyrchain headers
|
||||
/// gathered from the relay chain state, creating full [`Collation`]s to be shared with validators,
|
||||
/// and distributing new teyrchain blocks along the network.
|
||||
pub struct CollatorService<Block: BlockT, BS, RA> {
|
||||
block_status: Arc<BS>,
|
||||
wait_to_announce: Arc<Mutex<WaitToAnnounce<Block>>>,
|
||||
announce_block: Arc<dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync>,
|
||||
runtime_api: Arc<RA>,
|
||||
}
|
||||
|
||||
impl<Block: BlockT, BS, RA> Clone for CollatorService<Block, BS, RA> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
block_status: self.block_status.clone(),
|
||||
wait_to_announce: self.wait_to_announce.clone(),
|
||||
announce_block: self.announce_block.clone(),
|
||||
runtime_api: self.runtime_api.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block, BS, RA> CollatorService<Block, BS, RA>
|
||||
where
|
||||
Block: BlockT,
|
||||
BS: BlockBackend<Block>,
|
||||
RA: ProvideRuntimeApi<Block>,
|
||||
RA::Api: CollectCollationInfo<Block>,
|
||||
{
|
||||
/// Create a new instance.
|
||||
pub fn new(
|
||||
block_status: Arc<BS>,
|
||||
spawner: Arc<dyn SpawnNamed + Send + Sync>,
|
||||
announce_block: Arc<dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync>,
|
||||
runtime_api: Arc<RA>,
|
||||
) -> Self {
|
||||
let wait_to_announce =
|
||||
Arc::new(Mutex::new(WaitToAnnounce::new(spawner, announce_block.clone())));
|
||||
|
||||
Self { block_status, wait_to_announce, announce_block, runtime_api }
|
||||
}
|
||||
|
||||
/// Checks the status of the given block hash in the Teyrchain.
|
||||
///
|
||||
/// Returns `true` if the block could be found and is good to be build on.
|
||||
pub fn check_block_status(&self, hash: Block::Hash, header: &Block::Header) -> bool {
|
||||
match self.block_status.block_status(hash) {
|
||||
Ok(BlockStatus::Queued) => {
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
block_hash = ?hash,
|
||||
"Skipping candidate production, because block is still queued for import.",
|
||||
);
|
||||
false
|
||||
},
|
||||
Ok(BlockStatus::InChainWithState) => true,
|
||||
Ok(BlockStatus::InChainPruned) => {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
"Skipping candidate production, because block `{:?}` is already pruned!",
|
||||
hash,
|
||||
);
|
||||
false
|
||||
},
|
||||
Ok(BlockStatus::KnownBad) => {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
block_hash = ?hash,
|
||||
"Block is tagged as known bad and is included in the relay chain! Skipping candidate production!",
|
||||
);
|
||||
false
|
||||
},
|
||||
Ok(BlockStatus::Unknown) => {
|
||||
if header.number().is_zero() {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
block_hash = ?hash,
|
||||
"Could not find the header of the genesis block in the database!",
|
||||
);
|
||||
} else {
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
block_hash = ?hash,
|
||||
"Skipping candidate production, because block is unknown.",
|
||||
);
|
||||
}
|
||||
false
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
block_hash = ?hash,
|
||||
error = ?e,
|
||||
"Failed to get block status.",
|
||||
);
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch the collation info from the runtime.
|
||||
///
|
||||
/// Returns `Ok(Some((CollationInfo, ApiVersion)))` on success, `Err(_)` on error or `Ok(None)`
|
||||
/// if the runtime api isn't implemented by the runtime. `ApiVersion` being the version of the
|
||||
/// [`CollectCollationInfo`] runtime api.
|
||||
pub fn fetch_collation_info(
|
||||
&self,
|
||||
block_hash: Block::Hash,
|
||||
header: &Block::Header,
|
||||
) -> Result<Option<(CollationInfo, u32)>, pezsp_api::ApiError> {
|
||||
let runtime_api = self.runtime_api.runtime_api();
|
||||
|
||||
let api_version =
|
||||
match runtime_api.api_version::<dyn CollectCollationInfo<Block>>(block_hash)? {
|
||||
Some(version) => version,
|
||||
None => {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
"Could not fetch `CollectCollationInfo` runtime api version."
|
||||
);
|
||||
return Ok(None);
|
||||
},
|
||||
};
|
||||
|
||||
let collation_info = if api_version < 2 {
|
||||
#[allow(deprecated)]
|
||||
runtime_api
|
||||
.collect_collation_info_before_version_2(block_hash)?
|
||||
.into_latest(header.encode().into())
|
||||
} else {
|
||||
runtime_api.collect_collation_info(block_hash, header)?
|
||||
};
|
||||
|
||||
Ok(Some((collation_info, api_version)))
|
||||
}
|
||||
|
||||
/// Build a full [`Collation`] from a given [`TeyrchainCandidate`]. This requires
|
||||
/// that the underlying block has been fully imported into the underlying client,
|
||||
/// as it fetches underlying runtime API data.
|
||||
///
|
||||
/// This also returns the unencoded teyrchain block data, in case that is desired.
|
||||
pub fn build_collation(
|
||||
&self,
|
||||
parent_header: &Block::Header,
|
||||
block_hash: Block::Hash,
|
||||
candidate: TeyrchainCandidate<Block>,
|
||||
) -> Option<(Collation, TeyrchainBlockData<Block>)> {
|
||||
let block = candidate.block;
|
||||
|
||||
let compact_proof = match candidate
|
||||
.proof
|
||||
.into_compact_proof::<HashingFor<Block>>(*parent_header.state_root())
|
||||
{
|
||||
Ok(proof) => proof,
|
||||
Err(e) => {
|
||||
tracing::error!(target: "pezcumulus-collator", "Failed to compact proof: {:?}", e);
|
||||
return None;
|
||||
},
|
||||
};
|
||||
|
||||
// Create the teyrchain block data for the validators.
|
||||
let (collation_info, _api_version) = self
|
||||
.fetch_collation_info(block_hash, block.header())
|
||||
.map_err(|e| {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
error = ?e,
|
||||
"Failed to collect collation info.",
|
||||
)
|
||||
})
|
||||
.ok()
|
||||
.flatten()?;
|
||||
|
||||
// Workaround for: https://github.com/pezkuwichain/pezkuwi-sdk/issues/98
|
||||
//
|
||||
// We are always using the `api_version` of the parent block. The `api_version` can only
|
||||
// change with a runtime upgrade and this is when we want to observe the old `api_version`.
|
||||
// Because this old `api_version` is the one used to validate this block. Otherwise we
|
||||
// already assume the `api_version` is higher than what the relay chain will use and this
|
||||
// will lead to validation errors.
|
||||
let api_version = self
|
||||
.runtime_api
|
||||
.runtime_api()
|
||||
.api_version::<dyn CollectCollationInfo<Block>>(parent_header.hash())
|
||||
.ok()
|
||||
.flatten()?;
|
||||
|
||||
let block_data = TeyrchainBlockData::<Block>::new(vec![block], compact_proof);
|
||||
|
||||
let pov = pezkuwi_node_primitives::maybe_compress_pov(PoV {
|
||||
block_data: BlockData(if api_version >= 3 {
|
||||
block_data.encode()
|
||||
} else {
|
||||
let block_data = block_data.as_v0();
|
||||
|
||||
if block_data.is_none() {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
"Trying to submit a collation with multiple blocks is not supported by the current runtime."
|
||||
);
|
||||
}
|
||||
|
||||
block_data?.encode()
|
||||
}),
|
||||
});
|
||||
|
||||
let upward_messages = collation_info
|
||||
.upward_messages
|
||||
.try_into()
|
||||
.map_err(|e| {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
error = ?e,
|
||||
"Number of upward messages should not be greater than `MAX_UPWARD_MESSAGE_NUM`",
|
||||
)
|
||||
})
|
||||
.ok()?;
|
||||
let horizontal_messages = collation_info
|
||||
.horizontal_messages
|
||||
.try_into()
|
||||
.map_err(|e| {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
error = ?e,
|
||||
"Number of horizontal messages should not be greater than `MAX_HORIZONTAL_MESSAGE_NUM`",
|
||||
)
|
||||
})
|
||||
.ok()?;
|
||||
|
||||
let collation = Collation {
|
||||
upward_messages,
|
||||
new_validation_code: collation_info.new_validation_code,
|
||||
processed_downward_messages: collation_info.processed_downward_messages,
|
||||
horizontal_messages,
|
||||
hrmp_watermark: collation_info.hrmp_watermark,
|
||||
head_data: collation_info.head_data,
|
||||
proof_of_validity: MaybeCompressedPoV::Compressed(pov),
|
||||
};
|
||||
|
||||
Some((collation, block_data))
|
||||
}
|
||||
|
||||
/// Inform the networking systems that the block should be announced after an appropriate
|
||||
/// signal has been received. This returns the sending half of the signal.
|
||||
pub fn announce_with_barrier(
|
||||
&self,
|
||||
block_hash: Block::Hash,
|
||||
) -> oneshot::Sender<CollationSecondedSignal> {
|
||||
let (result_sender, signed_stmt_recv) = oneshot::channel();
|
||||
self.wait_to_announce.lock().wait_to_announce(block_hash, signed_stmt_recv);
|
||||
result_sender
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block, BS, RA> ServiceInterface<Block> for CollatorService<Block, BS, RA>
|
||||
where
|
||||
Block: BlockT,
|
||||
BS: BlockBackend<Block>,
|
||||
RA: ProvideRuntimeApi<Block>,
|
||||
RA::Api: CollectCollationInfo<Block>,
|
||||
{
|
||||
fn check_block_status(&self, hash: Block::Hash, header: &Block::Header) -> bool {
|
||||
CollatorService::check_block_status(self, hash, header)
|
||||
}
|
||||
|
||||
fn build_collation(
|
||||
&self,
|
||||
parent_header: &Block::Header,
|
||||
block_hash: Block::Hash,
|
||||
candidate: TeyrchainCandidate<Block>,
|
||||
) -> Option<(Collation, TeyrchainBlockData<Block>)> {
|
||||
CollatorService::build_collation(self, parent_header, block_hash, candidate)
|
||||
}
|
||||
|
||||
fn announce_with_barrier(
|
||||
&self,
|
||||
block_hash: Block::Hash,
|
||||
) -> oneshot::Sender<CollationSecondedSignal> {
|
||||
CollatorService::announce_with_barrier(self, block_hash)
|
||||
}
|
||||
|
||||
fn announce_block(&self, block_hash: Block::Hash, data: Option<Vec<u8>>) {
|
||||
(self.announce_block)(block_hash, data)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user