Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support btc chain type signet #39

Merged
merged 3 commits into from
Jun 12, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 2 additions & 25 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ckb-hash = "0.115.0-rc2"
[dependencies.ckb-bitcoin-spv-verifier]
version = "0.1.0"
git = "https://github.com/ckb-cell/ckb-bitcoin-spv"
rev = "a6fce4b"
rev = "bfc71d7"

[features]
default = ["default-tls"]
Expand Down
33 changes: 19 additions & 14 deletions src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{collections::HashMap, path::PathBuf};

use bitcoin::blockdata::constants::DIFFCHANGE_INTERVAL;
use ckb_bitcoin_spv_verifier::{
constants::FLAG_DISABLE_DIFFICULTY_CHECK,
constants::{FLAG_CHAIN_TYPE_MAINNET, FLAG_CHAIN_TYPE_SIGNET, FLAG_CHAIN_TYPE_TESTNET},
types::{core::Hash as BitcoinHash, packed, prelude::Pack as VPack},
};
use ckb_jsonrpc_types::TransactionView;
Expand All @@ -31,7 +31,7 @@ use ckb_types::{
prelude::*,
H256,
};
use clap::{Args as ClapArgs, Parser};
use clap::{Args as ClapArgs, Parser, ValueEnum};
use secp256k1::SecretKey;

use crate::{
Expand Down Expand Up @@ -78,14 +78,9 @@ pub struct Args {
#[clap(flatten)]
pub(crate) spv_owner: super::SpvOwner,

/// Disable the on-chain difficulty check.
///
/// ### Warning
///
/// For testing purpose only.
/// Do NOT enable this flag in production environment.
/// Bitcoin chain type.
#[arg(long)]
pub(crate) disable_difficulty_check: bool,
pub(crate) bitcoin_chain_type: BitcoinChainType,

/// Perform all steps without sending.
#[arg(long, hide = true)]
Expand All @@ -104,14 +99,22 @@ pub struct CodeHash {
pub(crate) spv_contract_type_hash: Option<H256>,
}

#[derive(Clone, PartialEq, ValueEnum)]
pub enum BitcoinChainType {
Mainnet,
Testnet,
Signet,
}

impl Args {
// TODO Split this method into several smaller methods.
pub fn execute(&self) -> Result<()> {
log::info!("Try to initialize a Bitcoin SPV instance on CKB");

if self.disable_difficulty_check && self.ckb.network == NetworkType::Mainnet {
let msg = "For safety, the option `self.disable_difficulty_check` \
are not allowed on the mainnet";
if self.bitcoin_chain_type != BitcoinChainType::Mainnet
&& self.ckb.network == NetworkType::Mainnet
{
let msg = "The Bitcoin chain type is not mainnet, but the CKB network is mainnet";
return Err(Error::other(msg));
}

Expand Down Expand Up @@ -182,8 +185,10 @@ impl Args {
let type_id_array = calculate_type_id(input0.cell_input(), cells_count);
let type_id = BitcoinHash::from_bytes_ref(&type_id_array);
let mut flags = 0u8;
if self.disable_difficulty_check {
flags |= FLAG_DISABLE_DIFFICULTY_CHECK;
match self.bitcoin_chain_type {
BitcoinChainType::Mainnet => flags |= FLAG_CHAIN_TYPE_MAINNET,
BitcoinChainType::Testnet => flags |= FLAG_CHAIN_TYPE_TESTNET,
BitcoinChainType::Signet => flags |= FLAG_CHAIN_TYPE_SIGNET,
}
let args = packed::SpvTypeArgs::new_builder()
.type_id(type_id.pack())
Expand Down
8 changes: 6 additions & 2 deletions src/cli/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ impl Args {
let (spv_client, spv_update) = storage.generate_spv_client_and_spv_update(
spv_tip_height,
self.spv_headers_update_limit,
input.info.get_flags()?,
)?;

let tx_hash =
Expand All @@ -193,8 +194,11 @@ impl Args {

let spv_tip_height = input.curr.client.headers_mmr_root.max_height;

let (spv_client, spv_update) = storage
.generate_spv_client_and_spv_update(spv_tip_height, NonZeroU32::MAX)?;
let (spv_client, spv_update) = storage.generate_spv_client_and_spv_update(
spv_tip_height,
NonZeroU32::MAX,
input.info.get_flags()?,
)?;

let tx_hash =
self.reorg_spv_cells(&spv_service, input, spv_client, spv_update)?;
Expand Down
18 changes: 18 additions & 0 deletions src/components/ckb_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,24 @@ impl SpvInfoCell {
0
}
}

pub(crate) fn get_flags(&self) -> Result<u8> {
let script_args = self
.cell
.output
.type_()
.to_opt()
.ok_or_else(|| Error::other("the SPV info cell has no type script"))?
.args();
let script_args_slice = script_args.as_reader().raw_data();
let args = packed::SpvTypeArgsReader::from_slice(script_args_slice).map_err(|err| {
let msg =
format!("failed to parse the type script args for the SPV info cell since {err}");
Error::other(msg)
})?;
let flags: u8 = args.flags().into();
Ok(flags)
}
}

pub trait CkbRpcClientExtension {
Expand Down
3 changes: 2 additions & 1 deletion src/components/storage/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ pub(crate) trait BitcoinSpvStorage: InternalBitcoinSpvStorage {
&self,
prev_height: u32,
limit: NonZeroU32,
flags: u8,
) -> Result<(SpvClient, packed::SpvUpdate)> {
let mut tip_height = self.get_tip_bitcoin_height()?;
if tip_height > prev_height.saturating_add(limit.into()) {
Expand Down Expand Up @@ -200,7 +201,7 @@ pub(crate) trait BitcoinSpvStorage: InternalBitcoinSpvStorage {
tip_header.time
);
let next_target =
calculate_next_target(curr_target, start_header.time, tip_header.time);
calculate_next_target(curr_target, start_header.time, tip_header.time, flags);
log::trace!("calculated new target {next_target:#x}");
let next_bits = next_target.to_compact_lossy();
let next_target: Target = next_bits.into();
Expand Down