Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

[client cli] generic blocknumber #4376

Merged
merged 6 commits into from
Dec 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 12 additions & 7 deletions client/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use network::{
use primitives::H256;

use std::{
io::{Write, Read, Seek, Cursor, stdin, stdout, ErrorKind}, iter, fs::{self, File},
io::{Write, Read, Seek, Cursor, stdin, stdout, ErrorKind}, iter, fmt::Debug, fs::{self, File},
net::{Ipv4Addr, SocketAddr}, path::{Path, PathBuf}, str::FromStr, pin::Pin, task::Poll
};

Expand All @@ -64,7 +64,7 @@ use lazy_static::lazy_static;
use futures::{Future, compat::Future01CompatExt, executor::block_on};
use sc_telemetry::TelemetryEndpoints;
use sp_runtime::generic::BlockId;
use sp_runtime::traits::Block as BlockT;
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};

/// default sub directory to store network config
const DEFAULT_NETWORK_CONFIG_PATH : &'static str = "network";
Expand Down Expand Up @@ -373,6 +373,8 @@ impl<'a> ParseAndPrepareExport<'a> {
where S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
F: FnOnce(Configuration<C, G, E>) -> Result<B, error::Error>,
B: ServiceBuilderCommand,
<<<<B as ServiceBuilderCommand>::Block as BlockT>::Header as HeaderT>
::Number as FromStr>::Err: Debug,
C: Default,
G: RuntimeGenesis,
E: ChainSpecExtension,
Expand All @@ -383,8 +385,9 @@ impl<'a> ParseAndPrepareExport<'a> {
if let DatabaseConfig::Path { ref path, .. } = &config.database {
info!("DB path: {}", path.display());
}
let from = self.params.from.unwrap_or(1);
let to = self.params.to;
let from = self.params.from.and_then(|f| f.parse().ok()).unwrap_or(1);
let to = self.params.to.and_then(|t| t.parse().ok());

let json = self.params.json;

let file: Box<dyn Write> = match self.params.output {
Expand All @@ -402,7 +405,7 @@ impl<'a> ParseAndPrepareExport<'a> {
});

let mut export_fut = builder(config)?
.export_blocks(file, from.into(), to.map(Into::into), json)
.export_blocks(file, from.into(), to, json)
.compat();
let fut = futures::future::poll_fn(|cx| {
if exit_recv.try_recv().is_ok() {
Expand Down Expand Up @@ -596,15 +599,17 @@ impl<'a> ParseAndPrepareRevert<'a> {
S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
F: FnOnce(Configuration<C, G, E>) -> Result<B, error::Error>,
B: ServiceBuilderCommand,
<<<<B as ServiceBuilderCommand>::Block as BlockT>::Header as HeaderT>
::Number as FromStr>::Err: Debug,
C: Default,
G: RuntimeGenesis,
E: ChainSpecExtension,
{
let config = create_config_with_db_path(
spec_factory, &self.params.shared_params, self.version
)?;
let blocks = self.params.num;
builder(config)?.revert_chain(blocks.into())?;
let blocks = self.params.num.parse()?;
builder(config)?.revert_chain(blocks)?;
Ok(())
}
}
Expand Down
43 changes: 39 additions & 4 deletions client/cli/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

use crate::traits::{AugmentClap, GetLogFilter};

use std::path::PathBuf;
use std::{str::FromStr, path::PathBuf};
use structopt::{StructOpt, clap::{arg_enum, App, AppSettings, SubCommand, Arg}};

pub use crate::execution_strategy::ExecutionStrategy;
Expand Down Expand Up @@ -734,6 +734,41 @@ pub struct BuildSpecCmd {

impl_get_log_filter!(BuildSpecCmd);

/// Wrapper type of `String` which holds an arbitary sized unsigned integer formatted as decimal.
#[derive(Debug, Clone)]
pub struct BlockNumber(String);

impl FromStr for BlockNumber {
type Err = String;

fn from_str(block_number: &str) -> Result<Self, Self::Err> {
if block_number.chars().any(|d| !d.is_digit(10)) {
Err(format!(
"Invalid block number: {}, expected decimal formatted unsigned integer",
block_number
))
} else {
Ok(Self(block_number.to_owned()))
}
}
}

impl BlockNumber {
/// Wrapper on top of `std::str::parse<N>` but with `Error` as a `String`
///
/// See `https://doc.rust-lang.org/std/primitive.str.html#method.parse` for more elaborate
/// documentation.
pub fn parse<N>(&self) -> Result<N, String>
Copy link
Member Author

@niklasad1 niklasad1 Dec 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nothing prevents parsing BlockNumber to a signed integer thus it relies on each type's FromStr` implementation.

If the value is bigger than 2^(n-1) it will be an Overflow for the types in core::num at least, where n is the number of bits of the integer.

where
N: FromStr,
N::Err: std::fmt::Debug,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just for printing the error which can be useful

{
self.0
.parse()
.map_err(|e| format!("BlockNumber: {} parsing failed because of {:?}", self.0, e))
}
}

/// The `export-blocks` command used to export blocks.
#[derive(Debug, StructOpt, Clone)]
pub struct ExportBlocksCmd {
Expand All @@ -745,13 +780,13 @@ pub struct ExportBlocksCmd {
///
/// Default is 1.
#[structopt(long = "from", value_name = "BLOCK")]
pub from: Option<u32>,
pub from: Option<BlockNumber>,

/// Specify last block number.
///
/// Default is best block.
#[structopt(long = "to", value_name = "BLOCK")]
pub to: Option<u32>,
pub to: Option<BlockNumber>,

/// Use JSON output rather than binary.
#[structopt(long = "json")]
Expand Down Expand Up @@ -817,7 +852,7 @@ impl_get_log_filter!(CheckBlockCmd);
pub struct RevertCmd {
/// Number of blocks to revert.
#[structopt(default_value = "256")]
pub num: u32,
pub num: BlockNumber,

#[allow(missing_docs)]
#[structopt(flatten)]
Expand Down
2 changes: 1 addition & 1 deletion frame/system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ pub trait Trait: 'static + Eq + Clone {
/// The block number type used by the runtime.
type BlockNumber:
Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleArithmetic
+ Default + Bounded + Copy + sp_std::hash::Hash;
+ Default + Bounded + Copy + sp_std::hash::Hash + sp_std::str::FromStr;

/// The output of the `Hashing` function.
type Hash:
Expand Down
2 changes: 1 addition & 1 deletion primitives/runtime/src/generic/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl<Number, Hash> codec::EncodeLike for Header<Number, Hash> where

impl<Number, Hash> traits::Header for Header<Number, Hash> where
Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + MaybeDisplay +
SimpleArithmetic + Codec + Copy + Into<U256> + TryFrom<U256>,
SimpleArithmetic + Codec + Copy + Into<U256> + TryFrom<U256> + sp_std::str::FromStr,
Hash: HashT,
Hash::Output: Default + sp_std::hash::Hash + Copy + Member +
MaybeSerialize + Debug + MaybeDisplay + SimpleBitOps + Codec,
Expand Down
2 changes: 1 addition & 1 deletion primitives/runtime/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ pub trait IsMember<MemberId> {
pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'static {
/// Header number.
type Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash
+ Copy + MaybeDisplay + SimpleArithmetic + Codec;
+ Copy + MaybeDisplay + SimpleArithmetic + Codec + sp_std::str::FromStr;
/// Header hash type
type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash
+ Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>;
Expand Down