mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 00:31:07 +00:00
Set StateBackend::Transaction to PrefixedMemoryDB (#14612)
* Yep * Try to get it working everywhere * Make `from_raw_storage` start with an empty db * More fixes! * Make everything compile * Fix `child_storage_root` * Fix after merge * Cleanups * Update primitives/state-machine/src/overlayed_changes/mod.rs Co-authored-by: Davide Galassi <davxy@datawok.net> * Review comments * Fix issues * Silence warning * FMT * Clippy --------- Co-authored-by: Davide Galassi <davxy@datawok.net>
This commit is contained in:
@@ -175,8 +175,8 @@ where
|
||||
{
|
||||
async fn verify(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<B, ()>,
|
||||
) -> Result<BlockImportParams<B, ()>, String> {
|
||||
mut block: BlockImportParams<B>,
|
||||
) -> Result<BlockImportParams<B>, String> {
|
||||
// Skip checks that include execution, if being told so or when importing only state.
|
||||
//
|
||||
// This is done for example when gap syncing and it is expected that the block after the gap
|
||||
@@ -348,7 +348,7 @@ pub fn import_queue<P, Block, I, C, S, CIDP>(
|
||||
telemetry,
|
||||
compatibility_mode,
|
||||
}: ImportQueueParams<Block, I, C, S, CIDP>,
|
||||
) -> Result<DefaultImportQueue<Block, C>, sp_consensus::Error>
|
||||
) -> Result<DefaultImportQueue<Block>, sp_consensus::Error>
|
||||
where
|
||||
Block: BlockT,
|
||||
C::Api: BlockBuilderApi<Block> + AuraApi<Block, AuthorityId<P>> + ApiExt<Block>,
|
||||
@@ -360,10 +360,7 @@ where
|
||||
+ AuxStore
|
||||
+ UsageProvider<Block>
|
||||
+ HeaderBackend<Block>,
|
||||
I: BlockImport<Block, Error = ConsensusError, Transaction = sp_api::TransactionFor<C, Block>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
I: BlockImport<Block, Error = ConsensusError> + Send + Sync + 'static,
|
||||
P: Pair + 'static,
|
||||
P::Public: Codec + Debug,
|
||||
P::Signature: Codec,
|
||||
|
||||
@@ -178,9 +178,9 @@ where
|
||||
C: ProvideRuntimeApi<B> + BlockOf + AuxStore + HeaderBackend<B> + Send + Sync,
|
||||
C::Api: AuraApi<B, AuthorityId<P>>,
|
||||
SC: SelectChain<B>,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
I: BlockImport<B> + Send + Sync + 'static,
|
||||
PF: Environment<B, Error = Error> + Send + Sync + 'static,
|
||||
PF::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
PF::Proposer: Proposer<B, Error = Error>,
|
||||
SO: SyncOracle + Send + Sync + Clone,
|
||||
L: sc_consensus::JustificationSyncLink<B>,
|
||||
CIDP: CreateInherentDataProviders<B, ()> + Send + 'static,
|
||||
@@ -279,11 +279,11 @@ where
|
||||
C: ProvideRuntimeApi<B> + BlockOf + AuxStore + HeaderBackend<B> + Send + Sync,
|
||||
C::Api: AuraApi<B, AuthorityId<P>>,
|
||||
PF: Environment<B, Error = Error> + Send + Sync + 'static,
|
||||
PF::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
PF::Proposer: Proposer<B, Error = Error>,
|
||||
P: Pair,
|
||||
P::Public: AppPublic + Member,
|
||||
P::Signature: TryFrom<Vec<u8>> + Member + Codec,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
I: BlockImport<B> + Send + Sync + 'static,
|
||||
Error: std::error::Error + Send + From<ConsensusError> + 'static,
|
||||
SO: SyncOracle + Send + Sync + Clone,
|
||||
L: sc_consensus::JustificationSyncLink<B>,
|
||||
@@ -330,8 +330,8 @@ where
|
||||
C: ProvideRuntimeApi<B> + BlockOf + HeaderBackend<B> + Sync,
|
||||
C::Api: AuraApi<B, AuthorityId<P>>,
|
||||
E: Environment<B, Error = Error> + Send + Sync,
|
||||
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
E::Proposer: Proposer<B, Error = Error>,
|
||||
I: BlockImport<B> + Send + Sync + 'static,
|
||||
P: Pair,
|
||||
P::Public: AppPublic + Member,
|
||||
P::Signature: TryFrom<Vec<u8>> + Member + Codec,
|
||||
@@ -388,13 +388,10 @@ where
|
||||
header: B::Header,
|
||||
header_hash: &B::Hash,
|
||||
body: Vec<B::Extrinsic>,
|
||||
storage_changes: StorageChanges<<Self::BlockImport as BlockImport<B>>::Transaction, B>,
|
||||
storage_changes: StorageChanges<B>,
|
||||
public: Self::Claim,
|
||||
_authorities: Self::AuxData,
|
||||
) -> Result<
|
||||
sc_consensus::BlockImportParams<B, <Self::BlockImport as BlockImport<B>>::Transaction>,
|
||||
ConsensusError,
|
||||
> {
|
||||
) -> Result<sc_consensus::BlockImportParams<B>, ConsensusError> {
|
||||
let signature_digest_item =
|
||||
crate::standalone::seal::<_, P>(header_hash, &public, &self.keystore)?;
|
||||
|
||||
@@ -596,9 +593,7 @@ mod tests {
|
||||
|
||||
impl Proposer<TestBlock> for DummyProposer {
|
||||
type Error = Error;
|
||||
type Transaction =
|
||||
sc_client_api::TransactionFor<substrate_test_runtime_client::Backend, TestBlock>;
|
||||
type Proposal = future::Ready<Result<Proposal<TestBlock, Self::Transaction, ()>, Error>>;
|
||||
type Proposal = future::Ready<Result<Proposal<TestBlock, ()>, Error>>;
|
||||
type ProofRecording = DisableProofRecording;
|
||||
type Proof = ();
|
||||
|
||||
|
||||
@@ -492,11 +492,8 @@ where
|
||||
C::Api: BabeApi<B>,
|
||||
SC: SelectChain<B> + 'static,
|
||||
E: Environment<B, Error = Error> + Send + Sync + 'static,
|
||||
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
I: BlockImport<B, Error = ConsensusError, Transaction = sp_api::TransactionFor<C, B>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
E::Proposer: Proposer<B, Error = Error>,
|
||||
I: BlockImport<B, Error = ConsensusError> + Send + Sync + 'static,
|
||||
SO: SyncOracle + Send + Sync + Clone + 'static,
|
||||
L: sc_consensus::JustificationSyncLink<B> + 'static,
|
||||
CIDP: CreateInherentDataProviders<B, ()> + Send + Sync + 'static,
|
||||
@@ -727,8 +724,8 @@ where
|
||||
C: ProvideRuntimeApi<B> + HeaderBackend<B> + HeaderMetadata<B, Error = ClientError>,
|
||||
C::Api: BabeApi<B>,
|
||||
E: Environment<B, Error = Error> + Sync,
|
||||
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
E::Proposer: Proposer<B, Error = Error>,
|
||||
I: BlockImport<B> + Send + Sync + 'static,
|
||||
SO: SyncOracle + Send + Clone + Sync,
|
||||
L: sc_consensus::JustificationSyncLink<B>,
|
||||
BS: BackoffAuthoringBlocksStrategy<NumberFor<B>> + Sync,
|
||||
@@ -822,13 +819,10 @@ where
|
||||
header: B::Header,
|
||||
header_hash: &B::Hash,
|
||||
body: Vec<B::Extrinsic>,
|
||||
storage_changes: StorageChanges<<Self::BlockImport as BlockImport<B>>::Transaction, B>,
|
||||
storage_changes: StorageChanges<B>,
|
||||
(_, public): Self::Claim,
|
||||
epoch_descriptor: Self::AuxData,
|
||||
) -> Result<
|
||||
BlockImportParams<B, <Self::BlockImport as BlockImport<B>>::Transaction>,
|
||||
ConsensusError,
|
||||
> {
|
||||
) -> Result<BlockImportParams<B>, ConsensusError> {
|
||||
let signature = self
|
||||
.keystore
|
||||
.sr25519_sign(<AuthorityId as AppCrypto>::ID, public.as_ref(), header_hash.as_ref())
|
||||
@@ -1137,8 +1131,8 @@ where
|
||||
{
|
||||
async fn verify(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<Block, ()>,
|
||||
) -> Result<BlockImportParams<Block, ()>, String> {
|
||||
mut block: BlockImportParams<Block>,
|
||||
) -> Result<BlockImportParams<Block>, String> {
|
||||
trace!(
|
||||
target: LOG_TARGET,
|
||||
"Verifying origin: {:?} header: {:?} justification(s): {:?} body: {:?}",
|
||||
@@ -1336,7 +1330,7 @@ impl<Block: BlockT, Client, I> BabeBlockImport<Block, Client, I> {
|
||||
impl<Block, Client, Inner> BabeBlockImport<Block, Client, Inner>
|
||||
where
|
||||
Block: BlockT,
|
||||
Inner: BlockImport<Block, Transaction = sp_api::TransactionFor<Client, Block>> + Send + Sync,
|
||||
Inner: BlockImport<Block> + Send + Sync,
|
||||
Inner::Error: Into<ConsensusError>,
|
||||
Client: HeaderBackend<Block>
|
||||
+ HeaderMetadata<Block, Error = sp_blockchain::Error>
|
||||
@@ -1351,7 +1345,7 @@ where
|
||||
// end up in an inconsistent state and have to resync.
|
||||
async fn import_state(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<Block, sp_api::TransactionFor<Client, Block>>,
|
||||
mut block: BlockImportParams<Block>,
|
||||
) -> Result<ImportResult, ConsensusError> {
|
||||
let hash = block.post_hash();
|
||||
let parent_hash = *block.header.parent_hash();
|
||||
@@ -1400,7 +1394,7 @@ where
|
||||
impl<Block, Client, Inner> BlockImport<Block> for BabeBlockImport<Block, Client, Inner>
|
||||
where
|
||||
Block: BlockT,
|
||||
Inner: BlockImport<Block, Transaction = sp_api::TransactionFor<Client, Block>> + Send + Sync,
|
||||
Inner: BlockImport<Block> + Send + Sync,
|
||||
Inner::Error: Into<ConsensusError>,
|
||||
Client: HeaderBackend<Block>
|
||||
+ HeaderMetadata<Block, Error = sp_blockchain::Error>
|
||||
@@ -1411,11 +1405,10 @@ where
|
||||
Client::Api: BabeApi<Block> + ApiExt<Block>,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = sp_api::TransactionFor<Client, Block>;
|
||||
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<Block, Self::Transaction>,
|
||||
mut block: BlockImportParams<Block>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
let hash = block.post_hash();
|
||||
let number = *block.header.number();
|
||||
@@ -1827,15 +1820,9 @@ pub fn import_queue<Block: BlockT, Client, SelectChain, BI, CIDP, Spawn>(
|
||||
telemetry,
|
||||
offchain_tx_pool_factory,
|
||||
}: ImportQueueParams<'_, Block, BI, Client, CIDP, SelectChain, Spawn>,
|
||||
) -> ClientResult<(DefaultImportQueue<Block, Client>, BabeWorkerHandle<Block>)>
|
||||
) -> ClientResult<(DefaultImportQueue<Block>, BabeWorkerHandle<Block>)>
|
||||
where
|
||||
BI: BlockImport<
|
||||
Block,
|
||||
Error = ConsensusError,
|
||||
Transaction = sp_api::TransactionFor<Client, Block>,
|
||||
> + Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
BI: BlockImport<Block, Error = ConsensusError> + Send + Sync + 'static,
|
||||
Client: ProvideRuntimeApi<Block>
|
||||
+ HeaderBackend<Block>
|
||||
+ HeaderMetadata<Block, Error = sp_blockchain::Error>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
use super::*;
|
||||
use authorship::claim_slot;
|
||||
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
|
||||
use sc_client_api::{backend::TransactionFor, BlockchainEvents, Finalizer};
|
||||
use sc_client_api::{BlockchainEvents, Finalizer};
|
||||
use sc_consensus::{BoxBlockImport, BoxJustificationImport};
|
||||
use sc_consensus_epochs::{EpochIdentifier, EpochIdentifierPosition};
|
||||
use sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging;
|
||||
@@ -97,16 +97,7 @@ impl DummyProposer {
|
||||
fn propose_with(
|
||||
&mut self,
|
||||
pre_digests: Digest,
|
||||
) -> future::Ready<
|
||||
Result<
|
||||
Proposal<
|
||||
TestBlock,
|
||||
sc_client_api::TransactionFor<substrate_test_runtime_client::Backend, TestBlock>,
|
||||
(),
|
||||
>,
|
||||
Error,
|
||||
>,
|
||||
> {
|
||||
) -> future::Ready<Result<Proposal<TestBlock, ()>, Error>> {
|
||||
let block_builder =
|
||||
self.factory.client.new_block_at(self.parent_hash, pre_digests, false).unwrap();
|
||||
|
||||
@@ -124,9 +115,7 @@ impl DummyProposer {
|
||||
|
||||
impl Proposer<TestBlock> for DummyProposer {
|
||||
type Error = Error;
|
||||
type Transaction =
|
||||
sc_client_api::TransactionFor<substrate_test_runtime_client::Backend, TestBlock>;
|
||||
type Proposal = future::Ready<Result<Proposal<TestBlock, Self::Transaction, ()>, Error>>;
|
||||
type Proposal = future::Ready<Result<Proposal<TestBlock, ()>, Error>>;
|
||||
type ProofRecording = DisableProofRecording;
|
||||
type Proof = ();
|
||||
|
||||
@@ -151,15 +140,13 @@ pub struct PanickingBlockImport<B>(B);
|
||||
#[async_trait::async_trait]
|
||||
impl<B: BlockImport<TestBlock>> BlockImport<TestBlock> for PanickingBlockImport<B>
|
||||
where
|
||||
B::Transaction: Send,
|
||||
B: Send,
|
||||
{
|
||||
type Error = B::Error;
|
||||
type Transaction = B::Transaction;
|
||||
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<TestBlock, Self::Transaction>,
|
||||
block: BlockImportParams<TestBlock>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
Ok(self.0.import_block(block).await.expect("importing block failed"))
|
||||
}
|
||||
@@ -207,8 +194,8 @@ impl Verifier<TestBlock> for TestVerifier {
|
||||
/// presented to the User in the logs.
|
||||
async fn verify(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<TestBlock, ()>,
|
||||
) -> Result<BlockImportParams<TestBlock, ()>, String> {
|
||||
mut block: BlockImportParams<TestBlock>,
|
||||
) -> Result<BlockImportParams<TestBlock>, String> {
|
||||
// apply post-sealing mutations (i.e. stripping seal, if desired).
|
||||
(self.mutator)(&mut block.header, Stage::PostSeal);
|
||||
self.inner.verify(block).await
|
||||
@@ -217,14 +204,7 @@ impl Verifier<TestBlock> for TestVerifier {
|
||||
|
||||
pub struct PeerData {
|
||||
link: BabeLink<TestBlock>,
|
||||
block_import: Mutex<
|
||||
Option<
|
||||
BoxBlockImport<
|
||||
TestBlock,
|
||||
TransactionFor<substrate_test_runtime_client::Backend, TestBlock>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
block_import: Mutex<Option<BoxBlockImport<TestBlock>>>,
|
||||
}
|
||||
|
||||
impl TestNetFactory for BabeTestNet {
|
||||
@@ -249,7 +229,7 @@ impl TestNetFactory for BabeTestNet {
|
||||
let block_import = PanickingBlockImport(block_import);
|
||||
|
||||
let data_block_import =
|
||||
Mutex::new(Some(Box::new(block_import.clone()) as BoxBlockImport<_, _>));
|
||||
Mutex::new(Some(Box::new(block_import.clone()) as BoxBlockImport<_>));
|
||||
(
|
||||
BlockImportAdapter::new(block_import),
|
||||
None,
|
||||
@@ -630,11 +610,11 @@ fn claim_vrf_check() {
|
||||
}
|
||||
|
||||
// Propose and import a new BABE block on top of the given parent.
|
||||
async fn propose_and_import_block<Transaction: Send + 'static>(
|
||||
async fn propose_and_import_block(
|
||||
parent: &TestHeader,
|
||||
slot: Option<Slot>,
|
||||
proposer_factory: &mut DummyFactory,
|
||||
block_import: &mut BoxBlockImport<TestBlock, Transaction>,
|
||||
block_import: &mut BoxBlockImport<TestBlock>,
|
||||
) -> Hash {
|
||||
let mut proposer = proposer_factory.init(parent).await.unwrap();
|
||||
|
||||
@@ -701,10 +681,10 @@ async fn propose_and_import_block<Transaction: Send + 'static>(
|
||||
// Propose and import n valid BABE blocks that are built on top of the given parent.
|
||||
// The proposer takes care of producing epoch change digests according to the epoch
|
||||
// duration (which is set to 6 slots in the test runtime).
|
||||
async fn propose_and_import_blocks<Transaction: Send + 'static>(
|
||||
async fn propose_and_import_blocks(
|
||||
client: &PeersFullClient,
|
||||
proposer_factory: &mut DummyFactory,
|
||||
block_import: &mut BoxBlockImport<TestBlock, Transaction>,
|
||||
block_import: &mut BoxBlockImport<TestBlock>,
|
||||
parent_hash: Hash,
|
||||
n: usize,
|
||||
) -> Vec<Hash> {
|
||||
|
||||
@@ -20,7 +20,7 @@ use std::sync::Arc;
|
||||
|
||||
use log::debug;
|
||||
|
||||
use sp_api::{ProvideRuntimeApi, TransactionFor};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_consensus::Error as ConsensusError;
|
||||
use sp_consensus_beefy::{ecdsa_crypto::AuthorityId, BeefyApi, BEEFY_ENGINE_ID};
|
||||
use sp_runtime::{
|
||||
@@ -118,21 +118,15 @@ impl<Block, BE, Runtime, I> BlockImport<Block> for BeefyBlockImport<Block, BE, R
|
||||
where
|
||||
Block: BlockT,
|
||||
BE: Backend<Block>,
|
||||
I: BlockImport<
|
||||
Block,
|
||||
Error = ConsensusError,
|
||||
Transaction = sp_api::TransactionFor<Runtime, Block>,
|
||||
> + Send
|
||||
+ Sync,
|
||||
I: BlockImport<Block, Error = ConsensusError> + Send + Sync,
|
||||
Runtime: ProvideRuntimeApi<Block> + Send + Sync,
|
||||
Runtime::Api: BeefyApi<Block, AuthorityId>,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = TransactionFor<Runtime, Block>;
|
||||
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<Block, Self::Transaction>,
|
||||
mut block: BlockImportParams<Block>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
let hash = block.post_hash();
|
||||
let number = *block.header.number();
|
||||
|
||||
@@ -139,9 +139,7 @@ pub fn beefy_block_import_and_links<B, BE, RuntimeApi, I>(
|
||||
where
|
||||
B: Block,
|
||||
BE: Backend<B>,
|
||||
I: BlockImport<B, Error = ConsensusError, Transaction = sp_api::TransactionFor<RuntimeApi, B>>
|
||||
+ Send
|
||||
+ Sync,
|
||||
I: BlockImport<B, Error = ConsensusError> + Send + Sync,
|
||||
RuntimeApi: ProvideRuntimeApi<B> + Send + Sync,
|
||||
RuntimeApi::Api: BeefyApi<B, AuthorityId>,
|
||||
{
|
||||
|
||||
@@ -83,7 +83,7 @@ type BeefyBlockImport = crate::BeefyBlockImport<
|
||||
Block,
|
||||
substrate_test_runtime_client::Backend,
|
||||
TestApi,
|
||||
BlockImportAdapter<PeersClient, sp_api::TransactionFor<TestApi, Block>>,
|
||||
BlockImportAdapter<PeersClient>,
|
||||
>;
|
||||
|
||||
pub(crate) type BeefyValidatorSet = ValidatorSet<AuthorityId>;
|
||||
|
||||
@@ -119,9 +119,9 @@ pub struct BlockCheckParams<Block: BlockT> {
|
||||
}
|
||||
|
||||
/// Precomputed storage.
|
||||
pub enum StorageChanges<Block: BlockT, Transaction> {
|
||||
pub enum StorageChanges<Block: BlockT> {
|
||||
/// Changes coming from block execution.
|
||||
Changes(sp_state_machine::StorageChanges<Transaction, HashingFor<Block>>),
|
||||
Changes(sp_state_machine::StorageChanges<HashingFor<Block>>),
|
||||
/// Whole new state.
|
||||
Import(ImportedState<Block>),
|
||||
}
|
||||
@@ -142,9 +142,9 @@ impl<B: BlockT> std::fmt::Debug for ImportedState<B> {
|
||||
}
|
||||
|
||||
/// Defines how a new state is computed for a given imported block.
|
||||
pub enum StateAction<Block: BlockT, Transaction> {
|
||||
pub enum StateAction<Block: BlockT> {
|
||||
/// Apply precomputed changes coming from block execution or state sync.
|
||||
ApplyChanges(StorageChanges<Block, Transaction>),
|
||||
ApplyChanges(StorageChanges<Block>),
|
||||
/// Execute block body (required) and compute state.
|
||||
Execute,
|
||||
/// Execute block body if parent state is available and compute state.
|
||||
@@ -153,7 +153,7 @@ pub enum StateAction<Block: BlockT, Transaction> {
|
||||
Skip,
|
||||
}
|
||||
|
||||
impl<Block: BlockT, Transaction> StateAction<Block, Transaction> {
|
||||
impl<Block: BlockT> StateAction<Block> {
|
||||
/// Check if execution checks that require runtime calls should be skipped.
|
||||
pub fn skip_execution_checks(&self) -> bool {
|
||||
match self {
|
||||
@@ -167,7 +167,7 @@ impl<Block: BlockT, Transaction> StateAction<Block, Transaction> {
|
||||
|
||||
/// Data required to import a Block.
|
||||
#[non_exhaustive]
|
||||
pub struct BlockImportParams<Block: BlockT, Transaction> {
|
||||
pub struct BlockImportParams<Block: BlockT> {
|
||||
/// Origin of the Block
|
||||
pub origin: BlockOrigin,
|
||||
/// The header, without consensus post-digests applied. This should be in the same
|
||||
@@ -192,7 +192,7 @@ pub struct BlockImportParams<Block: BlockT, Transaction> {
|
||||
/// Indexed transaction body of the block.
|
||||
pub indexed_body: Option<Vec<Vec<u8>>>,
|
||||
/// Specify how the new state is computed.
|
||||
pub state_action: StateAction<Block, Transaction>,
|
||||
pub state_action: StateAction<Block>,
|
||||
/// Is this block finalized already?
|
||||
/// `true` implies instant finality.
|
||||
pub finalized: bool,
|
||||
@@ -218,7 +218,7 @@ pub struct BlockImportParams<Block: BlockT, Transaction> {
|
||||
pub post_hash: Option<Block::Hash>,
|
||||
}
|
||||
|
||||
impl<Block: BlockT, Transaction> BlockImportParams<Block, Transaction> {
|
||||
impl<Block: BlockT> BlockImportParams<Block> {
|
||||
/// Create a new block import params.
|
||||
pub fn new(origin: BlockOrigin, header: Block::Header) -> Self {
|
||||
Self {
|
||||
@@ -261,39 +261,6 @@ impl<Block: BlockT, Transaction> BlockImportParams<Block, Transaction> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Auxiliary function for "converting" the transaction type.
|
||||
///
|
||||
/// Actually this just sets `StorageChanges::Changes` to `None` and makes rustc think that
|
||||
/// `Self` now uses a different transaction type.
|
||||
pub fn clear_storage_changes_and_mutate<Transaction2>(
|
||||
self,
|
||||
) -> BlockImportParams<Block, Transaction2> {
|
||||
// Preserve imported state.
|
||||
let state_action = match self.state_action {
|
||||
StateAction::ApplyChanges(StorageChanges::Import(state)) =>
|
||||
StateAction::ApplyChanges(StorageChanges::Import(state)),
|
||||
StateAction::ApplyChanges(StorageChanges::Changes(_)) => StateAction::Skip,
|
||||
StateAction::Execute => StateAction::Execute,
|
||||
StateAction::ExecuteIfPossible => StateAction::ExecuteIfPossible,
|
||||
StateAction::Skip => StateAction::Skip,
|
||||
};
|
||||
BlockImportParams {
|
||||
origin: self.origin,
|
||||
header: self.header,
|
||||
justifications: self.justifications,
|
||||
post_digests: self.post_digests,
|
||||
body: self.body,
|
||||
indexed_body: self.indexed_body,
|
||||
state_action,
|
||||
finalized: self.finalized,
|
||||
auxiliary: self.auxiliary,
|
||||
intermediates: self.intermediates,
|
||||
fork_choice: self.fork_choice,
|
||||
import_existing: self.import_existing,
|
||||
post_hash: self.post_hash,
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert intermediate by given key.
|
||||
pub fn insert_intermediate<T: 'static + Send>(&mut self, key: &'static [u8], value: T) {
|
||||
self.intermediates.insert(Cow::from(key), Box::new(value));
|
||||
@@ -338,8 +305,6 @@ impl<Block: BlockT, Transaction> BlockImportParams<Block, Transaction> {
|
||||
pub trait BlockImport<B: BlockT> {
|
||||
/// The error type.
|
||||
type Error: std::error::Error + Send + 'static;
|
||||
/// The transaction type used by the backend.
|
||||
type Transaction: Send + 'static;
|
||||
|
||||
/// Check block preconditions.
|
||||
async fn check_block(
|
||||
@@ -350,17 +315,13 @@ pub trait BlockImport<B: BlockT> {
|
||||
/// Import a block.
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<B, Self::Transaction>,
|
||||
block: BlockImportParams<B>,
|
||||
) -> Result<ImportResult, Self::Error>;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<B: BlockT, Transaction> BlockImport<B> for crate::import_queue::BoxBlockImport<B, Transaction>
|
||||
where
|
||||
Transaction: Send + 'static,
|
||||
{
|
||||
impl<B: BlockT> BlockImport<B> for crate::import_queue::BoxBlockImport<B> {
|
||||
type Error = sp_consensus::error::Error;
|
||||
type Transaction = Transaction;
|
||||
|
||||
/// Check block preconditions.
|
||||
async fn check_block(
|
||||
@@ -373,21 +334,19 @@ where
|
||||
/// Import a block.
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<B, Transaction>,
|
||||
block: BlockImportParams<B>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
(**self).import_block(block).await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<B: BlockT, T, E: std::error::Error + Send + 'static, Transaction> BlockImport<B> for Arc<T>
|
||||
impl<B: BlockT, T, E: std::error::Error + Send + 'static> BlockImport<B> for Arc<T>
|
||||
where
|
||||
for<'r> &'r T: BlockImport<B, Error = E, Transaction = Transaction>,
|
||||
for<'r> &'r T: BlockImport<B, Error = E>,
|
||||
T: Send + Sync,
|
||||
Transaction: Send + 'static,
|
||||
{
|
||||
type Error = E;
|
||||
type Transaction = Transaction;
|
||||
|
||||
async fn check_block(
|
||||
&mut self,
|
||||
@@ -398,7 +357,7 @@ where
|
||||
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<B, Transaction>,
|
||||
block: BlockImportParams<B>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
(&**self).import_block(block).await
|
||||
}
|
||||
|
||||
@@ -50,16 +50,14 @@ const LOG_TARGET: &str = "sync::import-queue";
|
||||
/// A commonly-used Import Queue type.
|
||||
///
|
||||
/// This defines the transaction type of the `BasicQueue` to be the transaction type for a client.
|
||||
pub type DefaultImportQueue<Block, Client> =
|
||||
BasicQueue<Block, sp_api::TransactionFor<Client, Block>>;
|
||||
pub type DefaultImportQueue<Block> = BasicQueue<Block>;
|
||||
|
||||
mod basic_queue;
|
||||
pub mod buffered_link;
|
||||
pub mod mock;
|
||||
|
||||
/// Shared block import struct used by the queue.
|
||||
pub type BoxBlockImport<B, Transaction> =
|
||||
Box<dyn BlockImport<B, Error = ConsensusError, Transaction = Transaction> + Send + Sync>;
|
||||
pub type BoxBlockImport<B> = Box<dyn BlockImport<B, Error = ConsensusError> + Send + Sync>;
|
||||
|
||||
/// Shared justification import struct used by the queue.
|
||||
pub type BoxJustificationImport<B> =
|
||||
@@ -98,10 +96,8 @@ pub struct IncomingBlock<B: BlockT> {
|
||||
pub trait Verifier<B: BlockT>: Send {
|
||||
/// Verify the given block data and return the `BlockImportParams` to
|
||||
/// continue the block import process.
|
||||
async fn verify(
|
||||
&mut self,
|
||||
block: BlockImportParams<B, ()>,
|
||||
) -> Result<BlockImportParams<B, ()>, String>;
|
||||
async fn verify(&mut self, block: BlockImportParams<B>)
|
||||
-> Result<BlockImportParams<B>, String>;
|
||||
}
|
||||
|
||||
/// Blocks import queue API.
|
||||
@@ -221,8 +217,8 @@ pub enum BlockImportError {
|
||||
type BlockImportResult<B> = Result<BlockImportStatus<NumberFor<B>>, BlockImportError>;
|
||||
|
||||
/// Single block import function.
|
||||
pub async fn import_single_block<B: BlockT, V: Verifier<B>, Transaction: Send + 'static>(
|
||||
import_handle: &mut impl BlockImport<B, Transaction = Transaction, Error = ConsensusError>,
|
||||
pub async fn import_single_block<B: BlockT, V: Verifier<B>>(
|
||||
import_handle: &mut impl BlockImport<B, Error = ConsensusError>,
|
||||
block_origin: BlockOrigin,
|
||||
block: IncomingBlock<B>,
|
||||
verifier: &mut V,
|
||||
@@ -231,12 +227,8 @@ pub async fn import_single_block<B: BlockT, V: Verifier<B>, Transaction: Send +
|
||||
}
|
||||
|
||||
/// Single block import function with metering.
|
||||
pub(crate) async fn import_single_block_metered<
|
||||
B: BlockT,
|
||||
V: Verifier<B>,
|
||||
Transaction: Send + 'static,
|
||||
>(
|
||||
import_handle: &mut impl BlockImport<B, Transaction = Transaction, Error = ConsensusError>,
|
||||
pub(crate) async fn import_single_block_metered<B: BlockT, V: Verifier<B>>(
|
||||
import_handle: &mut impl BlockImport<B, Error = ConsensusError>,
|
||||
block_origin: BlockOrigin,
|
||||
block: IncomingBlock<B>,
|
||||
verifier: &mut V,
|
||||
@@ -350,7 +342,6 @@ pub(crate) async fn import_single_block_metered<
|
||||
metrics.report_verification(true, started.elapsed());
|
||||
}
|
||||
|
||||
let import_block = import_block.clear_storage_changes_and_mutate();
|
||||
let imported = import_handle.import_block(import_block).await;
|
||||
if let Some(metrics) = metrics.as_ref() {
|
||||
metrics.report_verification_and_import(started.elapsed());
|
||||
|
||||
@@ -28,7 +28,7 @@ use sp_runtime::{
|
||||
traits::{Block as BlockT, Header as HeaderT, NumberFor},
|
||||
Justification, Justifications,
|
||||
};
|
||||
use std::{marker::PhantomData, pin::Pin, time::Duration};
|
||||
use std::{pin::Pin, time::Duration};
|
||||
|
||||
use crate::{
|
||||
import_queue::{
|
||||
@@ -42,15 +42,14 @@ use crate::{
|
||||
|
||||
/// Interface to a basic block import queue that is importing blocks sequentially in a separate
|
||||
/// task, with plugable verification.
|
||||
pub struct BasicQueue<B: BlockT, Transaction> {
|
||||
pub struct BasicQueue<B: BlockT> {
|
||||
/// Handle for sending justification and block import messages to the background task.
|
||||
handle: BasicQueueHandle<B>,
|
||||
/// Results coming from the worker task.
|
||||
result_port: BufferedLinkReceiver<B>,
|
||||
_phantom: PhantomData<Transaction>,
|
||||
}
|
||||
|
||||
impl<B: BlockT, Transaction> Drop for BasicQueue<B, Transaction> {
|
||||
impl<B: BlockT> Drop for BasicQueue<B> {
|
||||
fn drop(&mut self) {
|
||||
// Flush the queue and close the receiver to terminate the future.
|
||||
self.handle.close();
|
||||
@@ -58,13 +57,13 @@ impl<B: BlockT, Transaction> Drop for BasicQueue<B, Transaction> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT, Transaction: Send + 'static> BasicQueue<B, Transaction> {
|
||||
impl<B: BlockT> BasicQueue<B> {
|
||||
/// Instantiate a new basic queue, with given verifier.
|
||||
///
|
||||
/// This creates a background task, and calls `on_start` on the justification importer.
|
||||
pub fn new<V: 'static + Verifier<B>>(
|
||||
verifier: V,
|
||||
block_import: BoxBlockImport<B, Transaction>,
|
||||
block_import: BoxBlockImport<B>,
|
||||
justification_import: Option<BoxJustificationImport<B>>,
|
||||
spawner: &impl sp_core::traits::SpawnEssentialNamed,
|
||||
prometheus_registry: Option<&Registry>,
|
||||
@@ -96,7 +95,6 @@ impl<B: BlockT, Transaction: Send + 'static> BasicQueue<B, Transaction> {
|
||||
Self {
|
||||
handle: BasicQueueHandle::new(justification_sender, block_import_sender),
|
||||
result_port,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,7 +163,7 @@ impl<B: BlockT> ImportQueueService<B> for BasicQueueHandle<B> {
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<B: BlockT, Transaction: Send> ImportQueue<B> for BasicQueue<B, Transaction> {
|
||||
impl<B: BlockT> ImportQueue<B> for BasicQueue<B> {
|
||||
/// Get handle to [`ImportQueueService`].
|
||||
fn service(&self) -> Box<dyn ImportQueueService<B>> {
|
||||
Box::new(self.handle.clone())
|
||||
@@ -220,8 +218,8 @@ mod worker_messages {
|
||||
/// to give other futures the possibility to be run.
|
||||
///
|
||||
/// Returns when `block_import` ended.
|
||||
async fn block_import_process<B: BlockT, Transaction: Send + 'static>(
|
||||
mut block_import: BoxBlockImport<B, Transaction>,
|
||||
async fn block_import_process<B: BlockT>(
|
||||
mut block_import: BoxBlockImport<B>,
|
||||
mut verifier: impl Verifier<B>,
|
||||
mut result_sender: BufferedLinkSender<B>,
|
||||
mut block_import_receiver: TracingUnboundedReceiver<worker_messages::ImportBlocks<B>>,
|
||||
@@ -262,10 +260,10 @@ struct BlockImportWorker<B: BlockT> {
|
||||
}
|
||||
|
||||
impl<B: BlockT> BlockImportWorker<B> {
|
||||
fn new<V: 'static + Verifier<B>, Transaction: Send + 'static>(
|
||||
fn new<V: 'static + Verifier<B>>(
|
||||
result_sender: BufferedLinkSender<B>,
|
||||
verifier: V,
|
||||
block_import: BoxBlockImport<B, Transaction>,
|
||||
block_import: BoxBlockImport<B>,
|
||||
justification_import: Option<BoxJustificationImport<B>>,
|
||||
metrics: Option<Metrics>,
|
||||
) -> (
|
||||
@@ -391,8 +389,8 @@ struct ImportManyBlocksResult<B: BlockT> {
|
||||
///
|
||||
/// This will yield after each imported block once, to ensure that other futures can
|
||||
/// be called as well.
|
||||
async fn import_many_blocks<B: BlockT, V: Verifier<B>, Transaction: Send + 'static>(
|
||||
import_handle: &mut BoxBlockImport<B, Transaction>,
|
||||
async fn import_many_blocks<B: BlockT, V: Verifier<B>>(
|
||||
import_handle: &mut BoxBlockImport<B>,
|
||||
blocks_origin: BlockOrigin,
|
||||
blocks: Vec<IncomingBlock<B>>,
|
||||
verifier: &mut V,
|
||||
@@ -507,14 +505,14 @@ mod tests {
|
||||
import_queue::Verifier,
|
||||
};
|
||||
use futures::{executor::block_on, Future};
|
||||
use sp_test_primitives::{Block, BlockNumber, Extrinsic, Hash, Header};
|
||||
use sp_test_primitives::{Block, BlockNumber, Hash, Header};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Verifier<Block> for () {
|
||||
async fn verify(
|
||||
&mut self,
|
||||
block: BlockImportParams<Block, ()>,
|
||||
) -> Result<BlockImportParams<Block, ()>, String> {
|
||||
block: BlockImportParams<Block>,
|
||||
) -> Result<BlockImportParams<Block>, String> {
|
||||
Ok(BlockImportParams::new(block.origin, block.header))
|
||||
}
|
||||
}
|
||||
@@ -522,7 +520,6 @@ mod tests {
|
||||
#[async_trait::async_trait]
|
||||
impl BlockImport<Block> for () {
|
||||
type Error = sp_consensus::Error;
|
||||
type Transaction = Extrinsic;
|
||||
|
||||
async fn check_block(
|
||||
&mut self,
|
||||
@@ -533,7 +530,7 @@ mod tests {
|
||||
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
_block: BlockImportParams<Block, Self::Transaction>,
|
||||
_block: BlockImportParams<Block>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
Ok(ImportResult::imported(true))
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ use sc_consensus::{
|
||||
};
|
||||
use sc_telemetry::TelemetryHandle;
|
||||
use sc_utils::mpsc::TracingUnboundedSender;
|
||||
use sp_api::{Core, RuntimeApiInfo, TransactionFor};
|
||||
use sp_api::{Core, RuntimeApiInfo};
|
||||
use sp_blockchain::BlockStatus;
|
||||
use sp_consensus::{BlockOrigin, Error as ConsensusError, SelectChain};
|
||||
use sp_consensus_grandpa::{ConsensusLog, GrandpaApi, ScheduledChange, SetId, GRANDPA_ENGINE_ID};
|
||||
@@ -234,9 +234,7 @@ where
|
||||
BE: Backend<Block>,
|
||||
Client: ClientForGrandpa<Block, BE>,
|
||||
Client::Api: GrandpaApi<Block>,
|
||||
for<'a> &'a Client:
|
||||
BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<Client, Block>>,
|
||||
TransactionFor<Client, Block>: 'static,
|
||||
for<'a> &'a Client: BlockImport<Block, Error = ConsensusError>,
|
||||
{
|
||||
// check for a new authority set change.
|
||||
fn check_new_change(
|
||||
@@ -273,7 +271,7 @@ where
|
||||
|
||||
fn make_authorities_changes(
|
||||
&self,
|
||||
block: &mut BlockImportParams<Block, TransactionFor<Client, Block>>,
|
||||
block: &mut BlockImportParams<Block>,
|
||||
hash: Block::Hash,
|
||||
initial_sync: bool,
|
||||
) -> Result<PendingSetChanges<Block>, ConsensusError> {
|
||||
@@ -461,7 +459,7 @@ where
|
||||
/// Import whole new state and reset authority set.
|
||||
async fn import_state(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<Block, TransactionFor<Client, Block>>,
|
||||
mut block: BlockImportParams<Block>,
|
||||
) -> Result<ImportResult, ConsensusError> {
|
||||
let hash = block.post_hash();
|
||||
let number = *block.header.number();
|
||||
@@ -516,17 +514,14 @@ where
|
||||
BE: Backend<Block>,
|
||||
Client: ClientForGrandpa<Block, BE>,
|
||||
Client::Api: GrandpaApi<Block>,
|
||||
for<'a> &'a Client:
|
||||
BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<Client, Block>>,
|
||||
TransactionFor<Client, Block>: 'static,
|
||||
for<'a> &'a Client: BlockImport<Block, Error = ConsensusError>,
|
||||
SC: Send,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = TransactionFor<Client, Block>;
|
||||
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<Block, Self::Transaction>,
|
||||
mut block: BlockImportParams<Block>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
let hash = block.post_hash();
|
||||
let number = *block.header.number();
|
||||
|
||||
@@ -65,7 +65,6 @@ use sc_client_api::{
|
||||
backend::{AuxStore, Backend},
|
||||
utils::is_descendent_of,
|
||||
BlockchainEvents, CallExecutor, ExecutorProvider, Finalizer, LockImportRun, StorageProvider,
|
||||
TransactionFor,
|
||||
};
|
||||
use sc_consensus::BlockImport;
|
||||
use sc_network::types::ProtocolName;
|
||||
@@ -309,7 +308,7 @@ pub trait ClientForGrandpa<Block, BE>:
|
||||
+ BlockchainEvents<Block>
|
||||
+ ProvideRuntimeApi<Block>
|
||||
+ ExecutorProvider<Block>
|
||||
+ BlockImport<Block, Transaction = TransactionFor<BE, Block>, Error = sp_consensus::Error>
|
||||
+ BlockImport<Block, Error = sp_consensus::Error>
|
||||
+ StorageProvider<Block, BE>
|
||||
where
|
||||
BE: Backend<Block>,
|
||||
@@ -329,7 +328,7 @@ where
|
||||
+ BlockchainEvents<Block>
|
||||
+ ProvideRuntimeApi<Block>
|
||||
+ ExecutorProvider<Block>
|
||||
+ BlockImport<Block, Transaction = TransactionFor<BE, Block>, Error = sp_consensus::Error>
|
||||
+ BlockImport<Block, Error = sp_consensus::Error>
|
||||
+ StorageProvider<Block, BE>,
|
||||
{
|
||||
}
|
||||
|
||||
@@ -30,9 +30,6 @@ pub mod timestamp;
|
||||
/// Consensus data provider, manual seal uses this trait object for authoring blocks valid
|
||||
/// for any runtime.
|
||||
pub trait ConsensusDataProvider<B: BlockT>: Send + Sync {
|
||||
/// Block import transaction type
|
||||
type Transaction;
|
||||
|
||||
/// The proof type.
|
||||
type Proof;
|
||||
|
||||
@@ -43,7 +40,7 @@ pub trait ConsensusDataProvider<B: BlockT>: Send + Sync {
|
||||
fn append_block_import(
|
||||
&self,
|
||||
parent: &B::Header,
|
||||
params: &mut BlockImportParams<B, Self::Transaction>,
|
||||
params: &mut BlockImportParams<B>,
|
||||
inherents: &InherentData,
|
||||
proof: Self::Proof,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
use crate::{ConsensusDataProvider, Error};
|
||||
use sc_client_api::{AuxStore, UsageProvider};
|
||||
use sc_consensus::BlockImportParams;
|
||||
use sp_api::{ProvideRuntimeApi, TransactionFor};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_blockchain::{HeaderBackend, HeaderMetadata};
|
||||
use sp_consensus_aura::{
|
||||
digests::CompatibleDigestItem,
|
||||
@@ -69,7 +69,6 @@ where
|
||||
C::Api: AuraApi<B, AuthorityId>,
|
||||
P: Send + Sync,
|
||||
{
|
||||
type Transaction = TransactionFor<C, B>;
|
||||
type Proof = P;
|
||||
|
||||
fn create_digest(
|
||||
@@ -92,7 +91,7 @@ where
|
||||
fn append_block_import(
|
||||
&self,
|
||||
_parent: &B::Header,
|
||||
_params: &mut BlockImportParams<B, Self::Transaction>,
|
||||
_params: &mut BlockImportParams<B>,
|
||||
_inherents: &InherentData,
|
||||
_proof: Self::Proof,
|
||||
) -> Result<(), Error> {
|
||||
|
||||
@@ -33,7 +33,7 @@ use sp_keystore::KeystorePtr;
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
use sc_consensus::{BlockImportParams, ForkChoiceStrategy, Verifier};
|
||||
use sp_api::{ProvideRuntimeApi, TransactionFor};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_blockchain::{HeaderBackend, HeaderMetadata};
|
||||
use sp_consensus_babe::{
|
||||
digests::{NextEpochDescriptor, PreDigest, SecondaryPlainPreDigest},
|
||||
@@ -97,8 +97,8 @@ where
|
||||
{
|
||||
async fn verify(
|
||||
&mut self,
|
||||
mut import_params: BlockImportParams<B, ()>,
|
||||
) -> Result<BlockImportParams<B, ()>, String> {
|
||||
mut import_params: BlockImportParams<B>,
|
||||
) -> Result<BlockImportParams<B>, String> {
|
||||
import_params.finalized = false;
|
||||
import_params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
|
||||
|
||||
@@ -197,7 +197,6 @@ where
|
||||
C::Api: BabeApi<B>,
|
||||
P: Send + Sync,
|
||||
{
|
||||
type Transaction = TransactionFor<C, B>;
|
||||
type Proof = P;
|
||||
|
||||
fn create_digest(&self, parent: &B::Header, inherents: &InherentData) -> Result<Digest, Error> {
|
||||
@@ -264,7 +263,7 @@ where
|
||||
fn append_block_import(
|
||||
&self,
|
||||
parent: &B::Header,
|
||||
params: &mut BlockImportParams<B, Self::Transaction>,
|
||||
params: &mut BlockImportParams<B>,
|
||||
inherents: &InherentData,
|
||||
_proof: Self::Proof,
|
||||
) -> Result<(), Error> {
|
||||
|
||||
@@ -52,7 +52,7 @@ pub use self::{
|
||||
seal_block::{seal_block, SealBlockParams, MAX_PROPOSAL_DURATION},
|
||||
};
|
||||
use sc_transaction_pool_api::TransactionPool;
|
||||
use sp_api::{ProvideRuntimeApi, TransactionFor};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
|
||||
const LOG_TARGET: &str = "manual-seal";
|
||||
|
||||
@@ -66,8 +66,8 @@ struct ManualSealVerifier;
|
||||
impl<B: BlockT> Verifier<B> for ManualSealVerifier {
|
||||
async fn verify(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<B, ()>,
|
||||
) -> Result<BlockImportParams<B, ()>, String> {
|
||||
mut block: BlockImportParams<B>,
|
||||
) -> Result<BlockImportParams<B>, String> {
|
||||
block.finalized = false;
|
||||
block.fork_choice = Some(ForkChoiceStrategy::LongestChain);
|
||||
Ok(block)
|
||||
@@ -75,14 +75,13 @@ impl<B: BlockT> Verifier<B> for ManualSealVerifier {
|
||||
}
|
||||
|
||||
/// Instantiate the import queue for the manual seal consensus engine.
|
||||
pub fn import_queue<Block, Transaction>(
|
||||
block_import: BoxBlockImport<Block, Transaction>,
|
||||
pub fn import_queue<Block>(
|
||||
block_import: BoxBlockImport<Block>,
|
||||
spawner: &impl sp_core::traits::SpawnEssentialNamed,
|
||||
registry: Option<&Registry>,
|
||||
) -> BasicQueue<Block, Transaction>
|
||||
) -> BasicQueue<Block>
|
||||
where
|
||||
Block: BlockT,
|
||||
Transaction: Send + Sync + 'static,
|
||||
{
|
||||
BasicQueue::new(ManualSealVerifier, block_import, None, spawner, registry)
|
||||
}
|
||||
@@ -109,8 +108,7 @@ pub struct ManualSealParams<B: BlockT, BI, E, C: ProvideRuntimeApi<B>, TP, SC, C
|
||||
pub select_chain: SC,
|
||||
|
||||
/// Digest provider for inclusion in blocks.
|
||||
pub consensus_data_provider:
|
||||
Option<Box<dyn ConsensusDataProvider<B, Proof = P, Transaction = TransactionFor<C, B>>>>,
|
||||
pub consensus_data_provider: Option<Box<dyn ConsensusDataProvider<B, Proof = P>>>,
|
||||
|
||||
/// Something that can create the inherent data providers.
|
||||
pub create_inherent_data_providers: CIDP,
|
||||
@@ -134,8 +132,7 @@ pub struct InstantSealParams<B: BlockT, BI, E, C: ProvideRuntimeApi<B>, TP, SC,
|
||||
pub select_chain: SC,
|
||||
|
||||
/// Digest provider for inclusion in blocks.
|
||||
pub consensus_data_provider:
|
||||
Option<Box<dyn ConsensusDataProvider<B, Proof = P, Transaction = TransactionFor<C, B>>>>,
|
||||
pub consensus_data_provider: Option<Box<dyn ConsensusDataProvider<B, Proof = P>>>,
|
||||
|
||||
/// Something that can create the inherent data providers.
|
||||
pub create_inherent_data_providers: CIDP,
|
||||
@@ -167,17 +164,13 @@ pub async fn run_manual_seal<B, BI, CB, E, C, TP, SC, CS, CIDP, P>(
|
||||
}: ManualSealParams<B, BI, E, C, TP, SC, CS, CIDP, P>,
|
||||
) where
|
||||
B: BlockT + 'static,
|
||||
BI: BlockImport<B, Error = sp_consensus::Error, Transaction = sp_api::TransactionFor<C, B>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
BI: BlockImport<B, Error = sp_consensus::Error> + Send + Sync + 'static,
|
||||
C: HeaderBackend<B> + Finalizer<B, CB> + ProvideRuntimeApi<B> + 'static,
|
||||
CB: ClientBackend<B> + 'static,
|
||||
E: Environment<B> + 'static,
|
||||
E::Proposer: Proposer<B, Proof = P, Transaction = TransactionFor<C, B>>,
|
||||
E::Proposer: Proposer<B, Proof = P>,
|
||||
CS: Stream<Item = EngineCommand<<B as BlockT>::Hash>> + Unpin + 'static,
|
||||
SC: SelectChain<B> + 'static,
|
||||
TransactionFor<C, B>: 'static,
|
||||
TP: TransactionPool<Block = B>,
|
||||
CIDP: CreateInherentDataProviders<B, ()>,
|
||||
P: Send + Sync + 'static,
|
||||
@@ -230,16 +223,12 @@ pub async fn run_instant_seal<B, BI, CB, E, C, TP, SC, CIDP, P>(
|
||||
}: InstantSealParams<B, BI, E, C, TP, SC, CIDP, P>,
|
||||
) where
|
||||
B: BlockT + 'static,
|
||||
BI: BlockImport<B, Error = sp_consensus::Error, Transaction = sp_api::TransactionFor<C, B>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
BI: BlockImport<B, Error = sp_consensus::Error> + Send + Sync + 'static,
|
||||
C: HeaderBackend<B> + Finalizer<B, CB> + ProvideRuntimeApi<B> + 'static,
|
||||
CB: ClientBackend<B> + 'static,
|
||||
E: Environment<B> + 'static,
|
||||
E::Proposer: Proposer<B, Proof = P, Transaction = TransactionFor<C, B>>,
|
||||
E::Proposer: Proposer<B, Proof = P>,
|
||||
SC: SelectChain<B> + 'static,
|
||||
TransactionFor<C, B>: 'static,
|
||||
TP: TransactionPool<Block = B>,
|
||||
CIDP: CreateInherentDataProviders<B, ()>,
|
||||
P: Send + Sync + 'static,
|
||||
@@ -284,16 +273,12 @@ pub async fn run_instant_seal_and_finalize<B, BI, CB, E, C, TP, SC, CIDP, P>(
|
||||
}: InstantSealParams<B, BI, E, C, TP, SC, CIDP, P>,
|
||||
) where
|
||||
B: BlockT + 'static,
|
||||
BI: BlockImport<B, Error = sp_consensus::Error, Transaction = sp_api::TransactionFor<C, B>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
BI: BlockImport<B, Error = sp_consensus::Error> + Send + Sync + 'static,
|
||||
C: HeaderBackend<B> + Finalizer<B, CB> + ProvideRuntimeApi<B> + 'static,
|
||||
CB: ClientBackend<B> + 'static,
|
||||
E: Environment<B> + 'static,
|
||||
E::Proposer: Proposer<B, Proof = P, Transaction = TransactionFor<C, B>>,
|
||||
E::Proposer: Proposer<B, Proof = P>,
|
||||
SC: SelectChain<B> + 'static,
|
||||
TransactionFor<C, B>: 'static,
|
||||
TP: TransactionPool<Block = B>,
|
||||
CIDP: CreateInherentDataProviders<B, ()>,
|
||||
P: Send + Sync + 'static,
|
||||
@@ -386,7 +371,6 @@ mod tests {
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi<B> + Send + Sync,
|
||||
{
|
||||
type Transaction = TransactionFor<C, B>;
|
||||
type Proof = ();
|
||||
|
||||
fn create_digest(
|
||||
@@ -400,7 +384,7 @@ mod tests {
|
||||
fn append_block_import(
|
||||
&self,
|
||||
_parent: &B::Header,
|
||||
params: &mut BlockImportParams<B, Self::Transaction>,
|
||||
params: &mut BlockImportParams<B>,
|
||||
_inherents: &InherentData,
|
||||
_proof: Self::Proof,
|
||||
) -> Result<(), Error> {
|
||||
|
||||
@@ -22,7 +22,7 @@ use crate::{rpc, ConsensusDataProvider, CreatedBlock, Error};
|
||||
use futures::prelude::*;
|
||||
use sc_consensus::{BlockImport, BlockImportParams, ForkChoiceStrategy, ImportResult, StateAction};
|
||||
use sc_transaction_pool_api::TransactionPool;
|
||||
use sp_api::{ProvideRuntimeApi, TransactionFor};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_consensus::{self, BlockOrigin, Environment, Proposer, SelectChain};
|
||||
use sp_inherents::{CreateInherentDataProviders, InherentDataProvider};
|
||||
@@ -52,8 +52,7 @@ pub struct SealBlockParams<'a, B: BlockT, BI, SC, C: ProvideRuntimeApi<B>, E, TP
|
||||
/// SelectChain object
|
||||
pub select_chain: &'a SC,
|
||||
/// Digest provider for inclusion in blocks.
|
||||
pub consensus_data_provider:
|
||||
Option<&'a dyn ConsensusDataProvider<B, Proof = P, Transaction = TransactionFor<C, B>>>,
|
||||
pub consensus_data_provider: Option<&'a dyn ConsensusDataProvider<B, Proof = P>>,
|
||||
/// block import object
|
||||
pub block_import: &'a mut BI,
|
||||
/// Something that can create the inherent data providers.
|
||||
@@ -77,16 +76,12 @@ pub async fn seal_block<B, BI, SC, C, E, TP, CIDP, P>(
|
||||
}: SealBlockParams<'_, B, BI, SC, C, E, TP, CIDP, P>,
|
||||
) where
|
||||
B: BlockT,
|
||||
BI: BlockImport<B, Error = sp_consensus::Error, Transaction = sp_api::TransactionFor<C, B>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
BI: BlockImport<B, Error = sp_consensus::Error> + Send + Sync + 'static,
|
||||
C: HeaderBackend<B> + ProvideRuntimeApi<B>,
|
||||
E: Environment<B>,
|
||||
E::Proposer: Proposer<B, Proof = P, Transaction = TransactionFor<C, B>>,
|
||||
E::Proposer: Proposer<B, Proof = P>,
|
||||
TP: TransactionPool<Block = B>,
|
||||
SC: SelectChain<B>,
|
||||
TransactionFor<C, B>: 'static,
|
||||
CIDP: CreateInherentDataProviders<B, ()>,
|
||||
P: Send + Sync + 'static,
|
||||
{
|
||||
|
||||
@@ -237,7 +237,7 @@ impl<B: BlockT, I: Clone, C, S: Clone, Algorithm: Clone, CIDP> Clone
|
||||
impl<B, I, C, S, Algorithm, CIDP> PowBlockImport<B, I, C, S, Algorithm, CIDP>
|
||||
where
|
||||
B: BlockT,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync,
|
||||
I: BlockImport<B> + Send + Sync,
|
||||
I::Error: Into<ConsensusError>,
|
||||
C: ProvideRuntimeApi<B> + Send + Sync + HeaderBackend<B> + AuxStore + BlockOf,
|
||||
C::Api: BlockBuilderApi<B>,
|
||||
@@ -301,7 +301,7 @@ where
|
||||
impl<B, I, C, S, Algorithm, CIDP> BlockImport<B> for PowBlockImport<B, I, C, S, Algorithm, CIDP>
|
||||
where
|
||||
B: BlockT,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync,
|
||||
I: BlockImport<B> + Send + Sync,
|
||||
I::Error: Into<ConsensusError>,
|
||||
S: SelectChain<B>,
|
||||
C: ProvideRuntimeApi<B> + Send + Sync + HeaderBackend<B> + AuxStore + BlockOf,
|
||||
@@ -311,7 +311,6 @@ where
|
||||
CIDP: CreateInherentDataProviders<B, ()> + Send + Sync,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = sp_api::TransactionFor<C, B>;
|
||||
|
||||
async fn check_block(
|
||||
&mut self,
|
||||
@@ -322,7 +321,7 @@ where
|
||||
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<B, Self::Transaction>,
|
||||
mut block: BlockImportParams<B>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
let best_header = self
|
||||
.select_chain
|
||||
@@ -444,8 +443,8 @@ where
|
||||
{
|
||||
async fn verify(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<B, ()>,
|
||||
) -> Result<BlockImportParams<B, ()>, String> {
|
||||
mut block: BlockImportParams<B>,
|
||||
) -> Result<BlockImportParams<B>, String> {
|
||||
let hash = block.header.hash();
|
||||
let (checked_header, seal) = self.check_header(block.header)?;
|
||||
|
||||
@@ -460,19 +459,18 @@ where
|
||||
}
|
||||
|
||||
/// The PoW import queue type.
|
||||
pub type PowImportQueue<B, Transaction> = BasicQueue<B, Transaction>;
|
||||
pub type PowImportQueue<B> = BasicQueue<B>;
|
||||
|
||||
/// Import queue for PoW engine.
|
||||
pub fn import_queue<B, Transaction, Algorithm>(
|
||||
block_import: BoxBlockImport<B, Transaction>,
|
||||
pub fn import_queue<B, Algorithm>(
|
||||
block_import: BoxBlockImport<B>,
|
||||
justification_import: Option<BoxJustificationImport<B>>,
|
||||
algorithm: Algorithm,
|
||||
spawner: &impl sp_core::traits::SpawnEssentialNamed,
|
||||
registry: Option<&Registry>,
|
||||
) -> Result<PowImportQueue<B, Transaction>, sp_consensus::Error>
|
||||
) -> Result<PowImportQueue<B>, sp_consensus::Error>
|
||||
where
|
||||
B: BlockT,
|
||||
Transaction: Send + Sync + 'static,
|
||||
Algorithm: PowAlgorithm<B> + Clone + Send + Sync + 'static,
|
||||
Algorithm::Difficulty: Send,
|
||||
{
|
||||
@@ -491,7 +489,7 @@ where
|
||||
/// `pre_runtime` is a parameter that allows a custom additional pre-runtime digest to be inserted
|
||||
/// for blocks being built. This can encode authorship information, or just be a graffiti.
|
||||
pub fn start_mining_worker<Block, C, S, Algorithm, E, SO, L, CIDP>(
|
||||
block_import: BoxBlockImport<Block, sp_api::TransactionFor<C, Block>>,
|
||||
block_import: BoxBlockImport<Block>,
|
||||
client: Arc<C>,
|
||||
select_chain: S,
|
||||
algorithm: Algorithm,
|
||||
@@ -503,18 +501,18 @@ pub fn start_mining_worker<Block, C, S, Algorithm, E, SO, L, CIDP>(
|
||||
timeout: Duration,
|
||||
build_time: Duration,
|
||||
) -> (
|
||||
MiningHandle<Block, Algorithm, C, L, <E::Proposer as Proposer<Block>>::Proof>,
|
||||
MiningHandle<Block, Algorithm, L, <E::Proposer as Proposer<Block>>::Proof>,
|
||||
impl Future<Output = ()>,
|
||||
)
|
||||
where
|
||||
Block: BlockT,
|
||||
C: ProvideRuntimeApi<Block> + BlockchainEvents<Block> + 'static,
|
||||
C: BlockchainEvents<Block> + 'static,
|
||||
S: SelectChain<Block> + 'static,
|
||||
Algorithm: PowAlgorithm<Block> + Clone,
|
||||
Algorithm::Difficulty: Send + 'static,
|
||||
E: Environment<Block> + Send + Sync + 'static,
|
||||
E::Error: std::fmt::Debug,
|
||||
E::Proposer: Proposer<Block, Transaction = sp_api::TransactionFor<C, Block>>,
|
||||
E::Proposer: Proposer<Block>,
|
||||
SO: SyncOracle + Clone + Send + Sync + 'static,
|
||||
L: sc_consensus::JustificationSyncLink<Block>,
|
||||
CIDP: CreateInherentDataProviders<Block, ()>,
|
||||
@@ -632,7 +630,7 @@ where
|
||||
},
|
||||
};
|
||||
|
||||
let build = MiningBuild::<Block, Algorithm, C, _> {
|
||||
let build = MiningBuild::<Block, Algorithm, _> {
|
||||
metadata: MiningMetadata {
|
||||
best_hash,
|
||||
pre_hash: proposal.block.header().hash(),
|
||||
|
||||
@@ -56,16 +56,11 @@ pub struct MiningMetadata<H, D> {
|
||||
}
|
||||
|
||||
/// A build of mining, containing the metadata and the block proposal.
|
||||
pub struct MiningBuild<
|
||||
Block: BlockT,
|
||||
Algorithm: PowAlgorithm<Block>,
|
||||
C: sp_api::ProvideRuntimeApi<Block>,
|
||||
Proof,
|
||||
> {
|
||||
pub struct MiningBuild<Block: BlockT, Algorithm: PowAlgorithm<Block>, Proof> {
|
||||
/// Mining metadata.
|
||||
pub metadata: MiningMetadata<Block::Hash, Algorithm::Difficulty>,
|
||||
/// Mining proposal.
|
||||
pub proposal: Proposal<Block, sp_api::TransactionFor<C, Block>, Proof>,
|
||||
pub proposal: Proposal<Block, Proof>,
|
||||
}
|
||||
|
||||
/// Version of the mining worker.
|
||||
@@ -76,25 +71,22 @@ pub struct Version(usize);
|
||||
pub struct MiningHandle<
|
||||
Block: BlockT,
|
||||
Algorithm: PowAlgorithm<Block>,
|
||||
C: sp_api::ProvideRuntimeApi<Block>,
|
||||
L: sc_consensus::JustificationSyncLink<Block>,
|
||||
Proof,
|
||||
> {
|
||||
version: Arc<AtomicUsize>,
|
||||
algorithm: Arc<Algorithm>,
|
||||
justification_sync_link: Arc<L>,
|
||||
build: Arc<Mutex<Option<MiningBuild<Block, Algorithm, C, Proof>>>>,
|
||||
block_import: Arc<Mutex<BoxBlockImport<Block, sp_api::TransactionFor<C, Block>>>>,
|
||||
build: Arc<Mutex<Option<MiningBuild<Block, Algorithm, Proof>>>>,
|
||||
block_import: Arc<Mutex<BoxBlockImport<Block>>>,
|
||||
}
|
||||
|
||||
impl<Block, Algorithm, C, L, Proof> MiningHandle<Block, Algorithm, C, L, Proof>
|
||||
impl<Block, Algorithm, L, Proof> MiningHandle<Block, Algorithm, L, Proof>
|
||||
where
|
||||
Block: BlockT,
|
||||
C: sp_api::ProvideRuntimeApi<Block>,
|
||||
Algorithm: PowAlgorithm<Block>,
|
||||
Algorithm::Difficulty: 'static + Send,
|
||||
L: sc_consensus::JustificationSyncLink<Block>,
|
||||
sp_api::TransactionFor<C, Block>: Send + 'static,
|
||||
{
|
||||
fn increment_version(&self) {
|
||||
self.version.fetch_add(1, Ordering::SeqCst);
|
||||
@@ -102,7 +94,7 @@ where
|
||||
|
||||
pub(crate) fn new(
|
||||
algorithm: Algorithm,
|
||||
block_import: BoxBlockImport<Block, sp_api::TransactionFor<C, Block>>,
|
||||
block_import: BoxBlockImport<Block>,
|
||||
justification_sync_link: L,
|
||||
) -> Self {
|
||||
Self {
|
||||
@@ -120,7 +112,7 @@ where
|
||||
self.increment_version();
|
||||
}
|
||||
|
||||
pub(crate) fn on_build(&self, value: MiningBuild<Block, Algorithm, C, Proof>) {
|
||||
pub(crate) fn on_build(&self, value: MiningBuild<Block, Algorithm, Proof>) {
|
||||
let mut build = self.build.lock();
|
||||
*build = Some(value);
|
||||
self.increment_version();
|
||||
@@ -224,11 +216,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block, Algorithm, C, L, Proof> Clone for MiningHandle<Block, Algorithm, C, L, Proof>
|
||||
impl<Block, Algorithm, L, Proof> Clone for MiningHandle<Block, Algorithm, L, Proof>
|
||||
where
|
||||
Block: BlockT,
|
||||
Algorithm: PowAlgorithm<Block>,
|
||||
C: sp_api::ProvideRuntimeApi<Block>,
|
||||
L: sc_consensus::JustificationSyncLink<Block>,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
|
||||
@@ -53,8 +53,7 @@ const LOG_TARGET: &str = "slots";
|
||||
/// The changes that need to applied to the storage to create the state for a block.
|
||||
///
|
||||
/// See [`sp_state_machine::StorageChanges`] for more information.
|
||||
pub type StorageChanges<Transaction, Block> =
|
||||
sp_state_machine::StorageChanges<Transaction, HashingFor<Block>>;
|
||||
pub type StorageChanges<Block> = sp_state_machine::StorageChanges<HashingFor<Block>>;
|
||||
|
||||
/// The result of [`SlotWorker::on_slot`].
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -84,9 +83,7 @@ pub trait SlotWorker<B: BlockT, Proof> {
|
||||
#[async_trait::async_trait]
|
||||
pub trait SimpleSlotWorker<B: BlockT> {
|
||||
/// A handle to a `BlockImport`.
|
||||
type BlockImport: BlockImport<B, Transaction = <Self::Proposer as Proposer<B>>::Transaction>
|
||||
+ Send
|
||||
+ 'static;
|
||||
type BlockImport: BlockImport<B> + Send + 'static;
|
||||
|
||||
/// A handle to a `SyncOracle`.
|
||||
type SyncOracle: SyncOracle;
|
||||
@@ -148,13 +145,10 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
header: B::Header,
|
||||
header_hash: &B::Hash,
|
||||
body: Vec<B::Extrinsic>,
|
||||
storage_changes: StorageChanges<<Self::BlockImport as BlockImport<B>>::Transaction, B>,
|
||||
storage_changes: StorageChanges<B>,
|
||||
public: Self::Claim,
|
||||
aux_data: Self::AuxData,
|
||||
) -> Result<
|
||||
sc_consensus::BlockImportParams<B, <Self::BlockImport as BlockImport<B>>::Transaction>,
|
||||
sp_consensus::Error,
|
||||
>;
|
||||
) -> Result<sc_consensus::BlockImportParams<B>, sp_consensus::Error>;
|
||||
|
||||
/// Whether to force authoring if offline.
|
||||
fn force_authoring(&self) -> bool;
|
||||
@@ -191,13 +185,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
claim: &Self::Claim,
|
||||
slot_info: SlotInfo<B>,
|
||||
end_proposing_at: Instant,
|
||||
) -> Option<
|
||||
Proposal<
|
||||
B,
|
||||
<Self::Proposer as Proposer<B>>::Transaction,
|
||||
<Self::Proposer as Proposer<B>>::Proof,
|
||||
>,
|
||||
> {
|
||||
) -> Option<Proposal<B, <Self::Proposer as Proposer<B>>::Proof>> {
|
||||
let slot = slot_info.slot;
|
||||
let telemetry = self.telemetry();
|
||||
let log_target = self.logging_target();
|
||||
|
||||
Reference in New Issue
Block a user