Skip to content

Commit

Permalink
Merge pull request #10 from ckb-cell/feature/watch-only
Browse files Browse the repository at this point in the history
feat: add subcommand to provide JSON-RPC APIs without updating any CKB cells
  • Loading branch information
yangby-cryptape authored Apr 2, 2024
2 parents 88311d5 + dec3ea0 commit ceab665
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub struct Args {

/// Disable the on-chain difficulty check.
///
/// Warning
/// ### Warning
///
/// For testing purpose only.
/// Do NOT enable this flag in production environment.
Expand Down
15 changes: 13 additions & 2 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod deploy;
mod init;
mod serve;
mod sync;
mod watch;

#[derive(Parser)]
#[command(author, version, about)]
Expand All @@ -33,9 +34,17 @@ pub enum Commands {
Deploy(deploy::Args),
/// Initialize a new Bitcoin SPV instance on CKB, and initialize local storage.
Init(init::Args),
/// Run a service to update a Bitcoin SPV instance base on local storage.
/// Run a service to update a Bitcoin SPV instance base on local storage,
/// and provide JSON-RPC APIs.
///
/// If you don't want to update the Bitcoin SPV instance, try the subcommand `watch`.
Serve(serve::Args),
/// Sync data to rebuild local storage base on an existed Bitcoin SPV instance.
/// Run a read-only service to provide JSON-RPC APIs,
/// without updating for the Bitcoin SPV instance.
///
/// If you want to update the Bitcoin SPV instance, try the subcommand `serve`.
Watch(watch::Args),
/// Sync data to rebuild local storage base on an existed on-chain Bitcoin SPV instance.
Sync(sync::Args),
}

Expand Down Expand Up @@ -121,6 +130,7 @@ impl Cli {
Commands::Deploy(args) => args.execute()?,
Commands::Init(args) => args.execute()?,
Commands::Serve(args) => args.execute()?,
Commands::Watch(args) => args.execute()?,
Commands::Sync(args) => args.execute()?,
}
log::info!("Bitcoin SPV on CKB service is stopped.");
Expand All @@ -132,6 +142,7 @@ impl Cli {
Commands::Deploy(ref args) => args.common.configure_logger(),
Commands::Init(ref args) => args.common.configure_logger(),
Commands::Serve(ref args) => args.common.configure_logger(),
Commands::Watch(ref args) => args.common.configure_logger(),
Commands::Sync(ref args) => args.common.configure_logger(),
}
}
Expand Down
80 changes: 80 additions & 0 deletions src/cli/watch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//! The `watch` sub-command.
use std::{net::SocketAddr, path::PathBuf, thread, time};

use clap::Parser;

use crate::{
components::{ApiServiceConfig, SpvService, Storage},
prelude::*,
result::{Error, Result},
};

#[derive(Parser)]
pub struct Args {
#[clap(flatten)]
pub(crate) common: super::CommonArgs,

/// The directory, which stores all cached data.
#[arg(long)]
pub(crate) data_dir: PathBuf,

#[clap(flatten)]
pub(crate) ckb: super::CkbRoArgs,

#[clap(flatten)]
pub(crate) bitcoin: super::BitcoinArgs,

/// The JSON-RPC server's listen address.
#[arg(long)]
pub(crate) listen_address: SocketAddr,

/// A interval in seconds.
///
/// - When no better bitcoin blocks, waiting for several seconds.
/// - After a CKB transaction is sent, waiting for several seconds.
#[arg(long, default_value = "30")]
pub(crate) interval: u64,

/// The batch size that how many Bitcoin headers will be downloaded at once.
#[arg(long, default_value = "30")]
pub(crate) bitcoin_headers_download_batch_size: u32,
}

impl Args {
pub fn execute(&self) -> Result<()> {
log::info!("Starting the Bitcoin SPV service (readonly)");

let storage = Storage::new(&self.data_dir)?;
if !storage.is_initialized()? {
let msg = format!(
"user-provided data directory \"{}\" is empty, please initialize it",
self.data_dir.display()
);
return Err(Error::other(msg));
}
let ckb_cli = self.ckb.client();
let btc_cli = self.bitcoin.client();

let spv_service = SpvService {
ckb_cli: ckb_cli.clone(),
btc_cli: btc_cli.clone(),
storage: storage.clone(),
};

let _api_service = ApiServiceConfig::new(self.listen_address).start(spv_service.clone());

loop {
if !spv_service.sync_storage(self.bitcoin_headers_download_batch_size)? {
continue;
}
self.take_a_break();
}

// TODO Handle Ctrl-C and clean resources before exit.
}

fn take_a_break(&self) {
thread::sleep(time::Duration::from_secs(self.interval));
}
}

0 comments on commit ceab665

Please sign in to comment.