mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 17:41:08 +00:00
block_import: switch to Box<dyn Any> for intermediates representation (#4809)
* block_import: switch to Box<dyn Any> for intermediates representation * Use Cow and return Error instead of Option * Remove unused error * Distinguish NoIntermediate/InvalidIntermediate
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
//! clients.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::any::Any;
|
||||
use std::borrow::Cow;
|
||||
use std::thread;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
@@ -63,8 +65,6 @@ pub enum Error<B: BlockT> {
|
||||
InvalidSeal,
|
||||
#[display(fmt = "PoW validation error: invalid difficulty")]
|
||||
InvalidDifficulty,
|
||||
#[display(fmt = "PoW block import expects an intermediate, but not found one")]
|
||||
NoIntermediate,
|
||||
#[display(fmt = "Rejecting block too far in future")]
|
||||
TooFarInFuture,
|
||||
#[display(fmt = "Fetching best header failed using select chain: {:?}", _0)]
|
||||
@@ -257,6 +257,7 @@ impl<B, I, C, S, Algorithm> BlockImport<B> for PowBlockImport<B, I, C, S, Algori
|
||||
C: ProvideRuntimeApi<B> + Send + Sync + HeaderBackend<B> + AuxStore + ProvideCache<B> + BlockOf,
|
||||
C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>,
|
||||
Algorithm: PowAlgorithm<B>,
|
||||
Algorithm::Difficulty: 'static,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = sp_api::TransactionFor<C, B>;
|
||||
@@ -312,10 +313,9 @@ impl<B, I, C, S, Algorithm> BlockImport<B> for PowBlockImport<B, I, C, S, Algori
|
||||
_ => return Err(Error::<B>::HeaderUnsealed(block.header.hash()).into()),
|
||||
};
|
||||
|
||||
let intermediate = PowIntermediate::<B, Algorithm::Difficulty>::decode(
|
||||
&mut &block.intermediates.remove(INTERMEDIATE_KEY)
|
||||
.ok_or(Error::<B>::NoIntermediate)?[..]
|
||||
).map_err(|_| Error::<B>::NoIntermediate)?;
|
||||
let intermediate = block.take_intermediate::<PowIntermediate::<B, Algorithm::Difficulty>>(
|
||||
INTERMEDIATE_KEY
|
||||
)?;
|
||||
|
||||
let difficulty = match intermediate.difficulty {
|
||||
Some(difficulty) => difficulty,
|
||||
@@ -392,6 +392,7 @@ impl<B: BlockT, Algorithm> PowVerifier<B, Algorithm> {
|
||||
|
||||
impl<B: BlockT, Algorithm> Verifier<B> for PowVerifier<B, Algorithm> where
|
||||
Algorithm: PowAlgorithm<B> + Send + Sync,
|
||||
Algorithm::Difficulty: 'static,
|
||||
{
|
||||
fn verify(
|
||||
&mut self,
|
||||
@@ -418,7 +419,7 @@ impl<B: BlockT, Algorithm> Verifier<B> for PowVerifier<B, Algorithm> where
|
||||
justification,
|
||||
intermediates: {
|
||||
let mut ret = HashMap::new();
|
||||
ret.insert(INTERMEDIATE_KEY.to_vec(), intermediate.encode());
|
||||
ret.insert(Cow::from(INTERMEDIATE_KEY), Box::new(intermediate) as Box<dyn Any>);
|
||||
ret
|
||||
},
|
||||
auxiliary: vec![],
|
||||
@@ -553,6 +554,7 @@ fn mine_loop<B: BlockT, C, Algorithm, E, SO, S, CAW>(
|
||||
) -> Result<(), Error<B>> where
|
||||
C: HeaderBackend<B> + AuxStore + ProvideRuntimeApi<B>,
|
||||
Algorithm: PowAlgorithm<B>,
|
||||
Algorithm::Difficulty: 'static,
|
||||
E: Environment<B>,
|
||||
E::Proposer: Proposer<B, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
E::Error: std::fmt::Debug,
|
||||
@@ -659,7 +661,7 @@ fn mine_loop<B: BlockT, C, Algorithm, E, SO, S, CAW>(
|
||||
storage_changes: Some(proposal.storage_changes),
|
||||
intermediates: {
|
||||
let mut ret = HashMap::new();
|
||||
ret.insert(INTERMEDIATE_KEY.to_vec(), intermediate.encode());
|
||||
ret.insert(Cow::from(INTERMEDIATE_KEY), Box::new(intermediate) as Box<dyn Any>);
|
||||
ret
|
||||
},
|
||||
finalized: false,
|
||||
|
||||
@@ -22,7 +22,9 @@ use serde::{Serialize, Deserialize};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::any::Any;
|
||||
|
||||
use crate::Error;
|
||||
use crate::import_queue::{Verifier, CacheKeyId};
|
||||
|
||||
/// Block import result.
|
||||
@@ -144,7 +146,7 @@ pub struct BlockImportParams<Block: BlockT, Transaction> {
|
||||
/// Intermediate values that are interpreted by block importers. Each block importer,
|
||||
/// upon handling a value, removes it from the intermediate list. The final block importer
|
||||
/// rejects block import if there are still intermediate values that remain unhandled.
|
||||
pub intermediates: HashMap<Vec<u8>, Vec<u8>>,
|
||||
pub intermediates: HashMap<Cow<'static, [u8]>, Box<dyn Any>>,
|
||||
/// Auxiliary consensus data produced by the block.
|
||||
/// Contains a list of key-value pairs. If values are `None`, the keys
|
||||
/// will be deleted.
|
||||
@@ -223,6 +225,36 @@ impl<Block: BlockT, Transaction> BlockImportParams<Block, Transaction> {
|
||||
import_existing: self.import_existing,
|
||||
}
|
||||
}
|
||||
|
||||
/// Take interemdiate by given key, and remove it from the processing list.
|
||||
pub fn take_intermediate<T: 'static>(&mut self, key: &[u8]) -> Result<Box<T>, Error> {
|
||||
if self.intermediates.contains_key(key) {
|
||||
self.intermediates.remove(key)
|
||||
.ok_or(Error::NoIntermediate)
|
||||
.and_then(|value| {
|
||||
value.downcast::<T>()
|
||||
.map_err(|_| Error::InvalidIntermediate)
|
||||
})
|
||||
} else {
|
||||
Err(Error::NoIntermediate)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to a given intermediate.
|
||||
pub fn intermediate<T: 'static>(&self, key: &[u8]) -> Result<&T, Error> {
|
||||
self.intermediates.get(key)
|
||||
.ok_or(Error::NoIntermediate)?
|
||||
.downcast_ref::<T>()
|
||||
.ok_or(Error::InvalidIntermediate)
|
||||
}
|
||||
|
||||
/// Get a mutable reference to a given intermediate.
|
||||
pub fn intermediate_mut<T: 'static>(&mut self, key: &[u8]) -> Result<&mut T, Error> {
|
||||
self.intermediates.get_mut(key)
|
||||
.ok_or(Error::NoIntermediate)?
|
||||
.downcast_mut::<T>()
|
||||
.ok_or(Error::InvalidIntermediate)
|
||||
}
|
||||
}
|
||||
|
||||
/// Block import trait.
|
||||
|
||||
@@ -31,6 +31,12 @@ pub enum Error {
|
||||
/// I/O terminated unexpectedly
|
||||
#[display(fmt="I/O terminated unexpectedly.")]
|
||||
IoTerminated,
|
||||
/// Intermediate missing.
|
||||
#[display(fmt="Missing intermediate.")]
|
||||
NoIntermediate,
|
||||
/// Intermediate is of wrong type.
|
||||
#[display(fmt="Invalid intermediate.")]
|
||||
InvalidIntermediate,
|
||||
/// Unable to schedule wakeup.
|
||||
#[display(fmt="Timer error: {}", _0)]
|
||||
FaultyTimer(std::io::Error),
|
||||
|
||||
Reference in New Issue
Block a user