Skip to content

Commit 4a627eb

Browse files
committed
ckb-export: Support export to stdout, then can pipe using zstd tar, etc.
Signed-off-by: Eval EXEC <[email protected]>
1 parent d2e4841 commit 4a627eb

File tree

8 files changed

+62
-32
lines changed

8 files changed

+62
-32
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ckb-bin/src/cli.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,9 @@ fn export() -> Command {
386386
.short('t')
387387
.long(ARG_TARGET)
388388
.value_name("path")
389-
.value_parser(clap::builder::PathBufValueParser::new())
389+
.value_parser(clap::value_parser!(String))
390390
.required(true)
391-
.help("Specify the export target path"),
391+
.help("Specify the export target path (use '-' for stdout)"),
392392
)
393393
.arg(
394394
Arg::new(ARG_FROM)

ckb-bin/src/setup.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#[cfg(not(target_os = "windows"))]
22
use ckb_app_config::DaemonArgs;
33
use ckb_app_config::{
4-
AppConfig, CustomizeSpec, ExitCode, ExportArgs, ImportArgs, InitArgs, MigrateArgs, MinerArgs,
5-
PeerIDArgs, ReplayArgs, ResetDataArgs, RunArgs, StatsArgs, generate_random_key,
6-
read_secret_key, write_secret_to_file,
4+
AppConfig, CustomizeSpec, ExitCode, ExportArgs, ExportTarget, ImportArgs, InitArgs,
5+
MigrateArgs, MinerArgs, PeerIDArgs, ReplayArgs, ResetDataArgs, RunArgs, StatsArgs,
6+
generate_random_key, read_secret_key, write_secret_to_file,
77
};
88
use ckb_chain_spec::{ChainSpec, consensus::Consensus};
99
use ckb_jsonrpc_types::{Either, ScriptHashType};
@@ -245,13 +245,27 @@ H256::from_str(&target[2..]).expect("default assume_valid_target for testnet mus
245245
pub fn export(self, matches: &ArgMatches) -> Result<ExportArgs, ExitCode> {
246246
let consensus = self.consensus()?;
247247
let config = self.config.into_ckb()?;
248-
let target = matches
249-
.get_one::<PathBuf>(cli::ARG_TARGET)
250-
.ok_or_else(|| {
251-
eprintln!("Args Error: {:?} no found", cli::ARG_TARGET);
252-
ExitCode::Cli
253-
})?
254-
.clone();
248+
let target = {
249+
let target = matches
250+
.get_one::<String>(cli::ARG_TARGET)
251+
.ok_or_else(|| {
252+
eprintln!("Args Error: {:?} no found", cli::ARG_TARGET);
253+
ExitCode::Cli
254+
})?
255+
.clone();
256+
if target.eq("-") {
257+
ExportTarget::Stdout
258+
} else {
259+
let target_path = PathBuf::from_str(&target).map_err(|err| {
260+
eprintln!(
261+
"Args Error: failed to convert {} to PathBuf: {}",
262+
target, err
263+
);
264+
ExitCode::Cli
265+
})?;
266+
ExportTarget::Path(target_path)
267+
}
268+
};
255269

256270
fn parse_either(arg: String) -> Either<u64, String> {
257271
match arg.parse::<u64>() {
@@ -269,6 +283,7 @@ H256::from_str(&target[2..]).expect("default assume_valid_target for testnet mus
269283
.get_one::<String>(cli::ARG_TO)
270284
.cloned()
271285
.map(parse_either);
286+
272287
Ok(ExportArgs {
273288
from,
274289
to,

ckb-bin/src/subcommand/export.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ pub fn export(args: ExportArgs, async_handle: Handle) -> Result<(), ExitCode> {
3131
let from = args.from.map(parse_from_to_arg).transpose()?;
3232

3333
let to = args.to.map(parse_from_to_arg).transpose()?;
34-
3534
Export::new(shared, args.target, from, to)
3635
.execute()
3736
.map_err(|err| {

util/app-config/src/args.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,19 @@ use ckb_verification_traits::Switch;
88
use std::path::PathBuf;
99
use std::sync::Arc;
1010

11+
pub enum ExportTarget {
12+
Path(PathBuf),
13+
Stdout,
14+
}
15+
1116
/// Parsed command line arguments for `ckb export`.
1217
pub struct ExportArgs {
1318
/// Parsed `ckb.toml`.
1419
pub config: Box<CKBAppConfig>,
1520
/// Loaded consensus.
1621
pub consensus: Consensus,
1722
/// The target directory to save the exported file.
18-
pub target: PathBuf,
23+
pub target: ExportTarget,
1924
/// The range start block number or block hash.
2025
pub from: Option<Either<u64, String>>,
2126
/// The range end block number or block hash.

util/app-config/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ pub use app_config::{
1515
AppConfig, CKBAppConfig, ChainConfig, LogConfig, MetricsConfig, MinerAppConfig,
1616
};
1717
pub use args::{
18-
CustomizeSpec, DaemonArgs, ExportArgs, ImportArgs, InitArgs, MigrateArgs, MinerArgs,
19-
PeerIDArgs, ReplayArgs, ResetDataArgs, RunArgs, StatsArgs,
18+
CustomizeSpec, DaemonArgs, ExportArgs, ExportTarget, ImportArgs, InitArgs, MigrateArgs,
19+
MinerArgs, PeerIDArgs, ReplayArgs, ResetDataArgs, RunArgs, StatsArgs,
2020
};
2121

2222
pub use configs::*;

util/instrument/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ indicatif = { workspace = true, optional = true }
2222
rayon.workspace = true
2323
rayon-progress-bar.workspace = true
2424
itertools.workspace = true
25+
ckb-app-config.workspace = true
2526

2627

2728
[features]

util/instrument/src/export.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use ckb_app_config::ExportTarget;
12
use ckb_jsonrpc_types::BlockView as JsonBlock;
23
use ckb_jsonrpc_types::Either;
34
use ckb_shared::Snapshot;
@@ -13,13 +14,12 @@ use std::error::Error;
1314
use std::fs;
1415
use std::io;
1516
use std::io::Write;
16-
use std::path::PathBuf;
1717
use std::sync::Arc;
1818

1919
/// Export block from database to specify file.
2020
pub struct Export {
2121
/// export target path
22-
pub target: PathBuf,
22+
pub target: ExportTarget,
2323
/// CKB shared data.
2424
pub shared: Shared,
2525
/// the snapshot of the shared data
@@ -35,7 +35,7 @@ impl Export {
3535
/// Creates the export job.
3636
pub fn new(
3737
shared: Shared,
38-
target: PathBuf,
38+
target: ExportTarget,
3939
from: Option<Either<BlockNumber, H256>>,
4040
to: Option<Either<BlockNumber, H256>>,
4141
) -> Self {
@@ -52,17 +52,18 @@ impl Export {
5252
/// export file name
5353
fn file_name(&self, from_number: u64, to_number: u64) -> Result<String, Box<dyn Error>> {
5454
Ok(format!(
55-
"{}-{}-{}.{}",
55+
"{}-{}-{}.jsonl",
5656
self.shared.consensus().id,
5757
from_number,
58-
to_number,
59-
"jsonl"
58+
to_number
6059
))
6160
}
6261

6362
/// Executes the export job.
6463
pub fn execute(self) -> Result<(), Box<dyn Error>> {
65-
fs::create_dir_all(&self.target)?;
64+
if let ExportTarget::Path(ref path) = self.target {
65+
fs::create_dir_all(path)?;
66+
}
6667
self.write_to_json()
6768
}
6869

@@ -89,16 +90,24 @@ impl Export {
8990
return Err(format!("Invalid range: from {} to {}", from_number, to_number).into());
9091
}
9192

92-
let file_name = self.file_name(from_number, to_number)?;
93-
let file_path = self.target.join(file_name);
94-
println!("Writing to {}", file_path.display());
95-
let f = fs::OpenOptions::new()
96-
.create_new(true)
97-
.read(true)
98-
.write(true)
99-
.open(file_path)?;
93+
let mut writer: Box<dyn Write> = {
94+
match self.target {
95+
ExportTarget::Path(ref path_buf) => {
96+
let file_name = self.file_name(from_number, to_number)?;
97+
let file_path = path_buf.join(file_name);
98+
println!("Writing to {}", file_path.display());
99+
let f = fs::OpenOptions::new()
100+
.create_new(true)
101+
.read(true)
102+
.write(true)
103+
.open(file_path)?;
104+
105+
Box::new(io::BufWriter::new(f))
106+
}
107+
ExportTarget::Stdout => Box::new(std::io::stdout()),
108+
}
109+
};
100110

101-
let mut writer = io::BufWriter::new(f);
102111
let snapshot = self.shared.snapshot();
103112

104113
#[cfg(feature = "progress_bar")]

0 commit comments

Comments
 (0)