sc_subspace_block_relay/consensus/
types.rsuse crate::protocol::compact_block::{
CompactBlockHandshake, CompactBlockInitialRequest, CompactBlockInitialResponse,
};
use crate::types::RelayError;
use crate::utils::{RelayCounter, RelayCounterVec};
use derive_more::From;
use parity_scale_codec::{Decode, Encode};
use sc_network_common::sync::message::{BlockAttributes, BlockData, BlockRequest};
use sp_runtime::generic::BlockId;
use sp_runtime::traits::{Block as BlockT, NumberFor};
use sp_runtime::Justifications;
use substrate_prometheus_endpoint::{PrometheusError, Registry};
pub(crate) type BlockHash<Block> = <Block as BlockT>::Hash;
pub(crate) type BlockHeader<Block> = <Block as BlockT>::Header;
pub(crate) type Extrinsic<Block> = <Block as BlockT>::Extrinsic;
const STATUS_LABEL: &str = "status";
const STATUS_SUCCESS: &str = "success";
const DOWNLOAD_LABEL: &str = "client_download";
const DOWNLOAD_BLOCKS: &str = "blocks";
const DOWNLOAD_BYTES: &str = "bytes";
#[derive(From, Encode, Decode)]
pub(crate) enum ConsensusRequest<Block: BlockT, TxHash> {
#[codec(index = 0)]
BlockDownloadV0(InitialRequest<Block>),
#[codec(index = 1)]
ProtocolMessageV0(ProtocolMessage<Block, TxHash>),
#[codec(index = 2)]
FullBlockDownloadV0(FullDownloadRequest<Block>),
}
#[derive(Encode, Decode)]
pub(crate) struct InitialRequest<Block: BlockT> {
pub(crate) from_block: BlockId<Block>,
pub(crate) block_attributes: BlockAttributes,
pub(crate) protocol_request: ProtocolInitialRequest,
}
#[derive(Encode, Decode)]
pub(crate) struct InitialResponse<Block: BlockT, TxHash> {
pub(crate) block_hash: BlockHash<Block>,
pub(crate) partial_block: PartialBlock<Block>,
pub(crate) protocol_response: Option<ProtocolInitialResponse<Block, TxHash>>,
}
#[derive(From, Encode, Decode)]
pub(crate) enum ProtocolInitialRequest {
#[codec(index = 0)]
CompactBlock(CompactBlockInitialRequest),
}
#[derive(From, Encode, Decode)]
pub(crate) enum ProtocolInitialResponse<Block: BlockT, TxHash> {
#[codec(index = 0)]
CompactBlock(CompactBlockInitialResponse<BlockHash<Block>, TxHash, Extrinsic<Block>>),
}
#[derive(From, Encode, Decode)]
pub(crate) enum ProtocolMessage<Block: BlockT, TxHash> {
#[codec(index = 0)]
CompactBlock(CompactBlockHandshake<BlockHash<Block>, TxHash>),
}
impl<Block: BlockT, TxHash> From<CompactBlockHandshake<BlockHash<Block>, TxHash>>
for ConsensusRequest<Block, TxHash>
{
fn from(
inner: CompactBlockHandshake<BlockHash<Block>, TxHash>,
) -> ConsensusRequest<Block, TxHash> {
ConsensusRequest::ProtocolMessageV0(ProtocolMessage::CompactBlock(inner))
}
}
#[derive(Encode, Decode)]
pub(crate) struct FullDownloadRequest<Block: BlockT>(pub(crate) BlockRequest<Block>);
#[derive(Encode, Decode)]
pub(crate) struct FullDownloadResponse<Block: BlockT>(pub(crate) Vec<BlockData<Block>>);
#[derive(Encode, Decode)]
pub(crate) struct PartialBlock<Block: BlockT> {
pub(crate) parent_hash: BlockHash<Block>,
pub(crate) block_number: NumberFor<Block>,
pub(crate) block_header_hash: BlockHash<Block>,
pub(crate) header: Option<BlockHeader<Block>>,
pub(crate) indexed_body: Option<Vec<Vec<u8>>>,
pub(crate) justifications: Option<Justifications>,
}
impl<Block: BlockT> PartialBlock<Block> {
pub(crate) fn block_data(self, body: Option<Vec<Extrinsic<Block>>>) -> BlockData<Block> {
BlockData::<Block> {
hash: self.block_header_hash,
header: self.header,
body,
indexed_body: self.indexed_body,
receipt: None,
message_queue: None,
justification: None,
justifications: self.justifications,
}
}
}
pub(crate) struct ConsensusClientMetrics {
pub(crate) requests: RelayCounterVec,
pub(crate) downloads: RelayCounterVec,
pub(crate) tx_pool_miss: RelayCounter,
}
impl ConsensusClientMetrics {
pub(crate) fn new(registry: Option<&Registry>) -> Result<Self, PrometheusError> {
Ok(Self {
requests: RelayCounterVec::new(
"relay_client_requests",
"Relay client request metrics(by completion status)",
&[STATUS_LABEL],
registry,
)?,
downloads: RelayCounterVec::new(
"relay_client_downloads",
"Relay client download metrics",
&[DOWNLOAD_LABEL],
registry,
)?,
tx_pool_miss: RelayCounter::new(
"relay_client_tx_pool_miss",
"Number of extrinsics not found in the tx pool",
registry,
)?,
})
}
pub(crate) fn on_download<Block: BlockT>(&self, blocks: &[BlockData<Block>]) {
self.requests.inc(STATUS_LABEL, STATUS_SUCCESS);
if let Ok(blocks) = u64::try_from(blocks.len()) {
self.downloads
.inc_by(DOWNLOAD_LABEL, DOWNLOAD_BLOCKS, blocks);
}
if let Ok(bytes) = u64::try_from(blocks.encoded_size()) {
self.downloads.inc_by(DOWNLOAD_LABEL, DOWNLOAD_BYTES, bytes);
}
}
pub(crate) fn on_download_fail(&self, err: &RelayError) {
self.requests.inc(STATUS_LABEL, err.as_ref());
}
}
pub(crate) struct ConsensusServerMetrics {
pub(crate) requests: RelayCounterVec,
}
impl ConsensusServerMetrics {
pub(crate) fn new(registry: Option<&Registry>) -> Result<Self, PrometheusError> {
Ok(Self {
requests: RelayCounterVec::new(
"relay_server_status",
"Relay server request metrics(by status)",
&[STATUS_LABEL],
registry,
)?,
})
}
pub(crate) fn on_request(&self) {
self.requests.inc(STATUS_LABEL, STATUS_SUCCESS);
}
pub(crate) fn on_failed_request(&self, err: &RelayError) {
self.requests.inc(STATUS_LABEL, err.as_ref());
}
}