Skip to content

[BREAKING CHANGE] Add multisig_v2 to devchain #4872

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

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
18 changes: 16 additions & 2 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ ckb-spawn = { path = "util/spawn", version = "=0.203.0-pre" }
ckb-stop-handler = { path = "util/stop-handler", version = "=0.203.0-pre" }
ckb-store = { path = "store", version = "=0.203.0-pre" }
ckb-sync = { path = "sync", version = "=0.203.0-pre" }
ckb-system-scripts = "=0.5.4"
ckb-system-scripts-v0_5_4 = { package="ckb-system-scripts", version="=0.5.4" }
ckb-system-scripts-v0_6_0 = { package="ckb-system-scripts", version="=0.6.0" }
ckb-systemtime = { path = "util/systemtime", version = "=0.203.0-pre" }
ckb-test-chain-utils = { path = "util/test-chain-utils", version = "=0.203.0-pre" }
ckb-test = { path = "test", version = "=0.203.0-pre" }
Expand Down
2 changes: 1 addition & 1 deletion benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ckb-hash.workspace = true
ckb-test-chain-utils.workspace = true
ckb-dao-utils.workspace = true
ckb-dao.workspace = true
ckb-system-scripts.workspace = true
ckb-system-scripts-v0_5_4.workspace = true
ckb-crypto.workspace = true
ckb-jsonrpc-types.workspace = true
ckb-verification.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion benches/benches/benchmarks/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ckb_dao::DaoCalculator;
use ckb_dao_utils::genesis_dao_data;
use ckb_shared::{Shared, SharedBuilder, Snapshot};
use ckb_store::ChainStore;
use ckb_system_scripts::BUNDLED_CELL;
use ckb_system_scripts_v0_5_4::BUNDLED_CELL;
use ckb_test_chain_utils::always_success_cell;
use ckb_types::{
H160, H256, U256,
Expand Down
6 changes: 4 additions & 2 deletions resource/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ phf = "0.8.0" # ckb-resource's build script need this, and cargo shear think ckb
includedir.workspace = true
serde = { workspace = true, features = ["derive"] }
ckb-types.workspace = true
ckb-system-scripts.workspace = true
ckb-system-scripts-v0_5_4.workspace = true
ckb-system-scripts-v0_6_0.workspace = true

[build-dependencies]
includedir_codegen.workspace = true
walkdir.workspace = true
ckb-types.workspace = true
ckb-system-scripts.workspace = true
ckb-system-scripts-v0_5_4.workspace = true
ckb-system-scripts-v0_6_0.workspace = true

[dev-dependencies]
tempfile.workspace = true
Expand Down
29 changes: 24 additions & 5 deletions resource/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ use std::io::{BufWriter, Write};
use std::path::Path;
use walkdir::WalkDir;

use ckb_system_scripts::{
CODE_HASH_DAO, CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL,
CODE_HASH_SECP256K1_BLAKE160_SIGHASH_ALL, CODE_HASH_SECP256K1_DATA,
use ckb_system_scripts_v0_5_4::{
CODE_HASH_DAO, CODE_HASH_SECP256K1_BLAKE160_SIGHASH_ALL, CODE_HASH_SECP256K1_DATA,
};

use ckb_system_scripts_v0_5_4::CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL as CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL_LEGACY;
use ckb_system_scripts_v0_6_0::CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL as CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL_V2;

fn main() {
let mut bundled = includedir_codegen::start("BUNDLED");

Expand Down Expand Up @@ -58,9 +60,26 @@ fn main() {

writeln!(
&mut out_file,
"/// Data hash of the cell containing secp256k1 blake160 multisig all lock script.\n\
"/// Data hash of the cell containing secp256k1 blake160 multisig(legacy) all lock script. Deprecated.\n\
#[deprecated]
pub const CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL: H256 = {:?};",
H256(CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL)
H256(CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL_LEGACY)
)
.expect("write to code_hashes.rs");

writeln!(
&mut out_file,
"/// Data hash of the cell containing secp256k1 blake160 multisig(legacy) all lock script.\n\
pub const CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL_LEGACY: H256 = {:?};",
H256(CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL_LEGACY)
)
.expect("write to code_hashes.rs");

writeln!(
&mut out_file,
"/// Data hash of the cell containing secp256k1 blake160 multisig(v1) all lock script.\n\
pub const CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL_V2: H256 = {:?};",
H256(CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL_V2)
)
.expect("write to code_hashes.rs");

Expand Down
16 changes: 14 additions & 2 deletions resource/specs/dev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ file = { bundled = "specs/cells/secp256k1_data" }
create_type_id = false
capacity = 1_048_617_0000_0000
[[genesis.system_cells]]
file = { bundled = "specs/cells/secp256k1_blake160_multisig_all" }
file = { version = "v0.5.4", bundled = "specs/cells/secp256k1_blake160_multisig_all" }
create_type_id = true
capacity = 100_000_0000_0000

[[genesis.system_cells]]
file = { version = "v0.6.0", bundled = "specs/cells/secp256k1_blake160_multisig_all" }
create_type_id = true
capacity = 100_000_0000_0000

Expand All @@ -53,7 +58,14 @@ files = [
name = "secp256k1_blake160_multisig_all"
files = [
{ bundled = "specs/cells/secp256k1_data" },
{ bundled = "specs/cells/secp256k1_blake160_multisig_all" },
{ version = "v0.5.4", bundled = "specs/cells/secp256k1_blake160_multisig_all" },
]

[[genesis.dep_groups]]
name = "secp256k1_blake160_multisig_all_v2"
files = [
{ bundled = "specs/cells/secp256k1_data" },
{ version = "v0.6.0", bundled = "specs/cells/secp256k1_blake160_multisig_all" },
Copy link
Collaborator Author

@eval-exec eval-exec May 23, 2025

Choose a reason for hiding this comment

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

I need to add a new field: ckb-system-scripts's version to DepGroup.
ckb-system-scripts v0.5.4's specs/cells/secp256k1_blake160_multisig_all is legacy multisig.
ckb-system-scripts v0.6.0's specs/cells/secp256k1_blake160_multisig_all is v2 multisig.

If version field is missing, default to [email protected]

@driftluo @zhangsoledad @quake @doitian

]

# For first 11 block
Expand Down
84 changes: 75 additions & 9 deletions resource/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ use std::fs;
use std::io::{self, BufReader, Cursor, Read};
use std::path::{Path, PathBuf};

use ckb_system_scripts::BUNDLED_CELL;
use ckb_system_scripts_v0_5_4::BUNDLED_CELL;
/// get multisig_legacy from v_0_5_4
use ckb_system_scripts_v0_5_4::BUNDLED_CELL as BUNDLED_CELL_v0_5_4;
/// get multisg_v1 from v0_6_0
use ckb_system_scripts_v0_6_0::BUNDLED_CELL as BUNDLED_CELL_v0_6_0;

mod bundled {
#![allow(missing_docs, clippy::unreadable_literal)]
Expand All @@ -56,13 +60,40 @@ pub const SPEC_DEV_FILE_NAME: &str = "specs/dev.toml";
/// The file name of the generated RocksDB options file.
pub const DB_OPTIONS_FILE_NAME: &str = "default.db-options";

/// Represents versions of bundled system scripts.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum BundledSystemScriptVersion {
/// The bundled resource version is 0.5.4, used before `CKB v0.201.0`
#[serde(rename = "v0.5.4")]
V0_5_4,
/// The bundled resource version is 0.6.0, contains multisig v2
#[serde(rename = "v0.6.0")]
V0_6_0,
}

impl std::fmt::Display for BundledSystemScriptVersion {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
BundledSystemScriptVersion::V0_5_4 => write!(f, "v0.5.4"),
BundledSystemScriptVersion::V0_6_0 => write!(f, "v0.6.0"),
}
}
}

fn default_bundled_version() -> BundledSystemScriptVersion {
BundledSystemScriptVersion::V0_5_4
}

/// Represents a resource, which is either bundled in the CKB binary or resident in the local file
/// system.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Resource {
/// A resource that bundled in the CKB binary.
Bundled {
/// The version of the bundled resource. default is v0.5.4
#[serde(default = "default_bundled_version")]
version: BundledSystemScriptVersion,
/// The identifier of the bundled resource.
bundled: String,
},
Expand All @@ -81,7 +112,9 @@ pub enum Resource {
impl fmt::Display for Resource {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Resource::Bundled { bundled } => write!(f, "Bundled({bundled})"),
Resource::Bundled { bundled, version } => {
write!(f, "Bundled(bundled: {bundled}, version:{version}))")
}
Resource::FileSystem { file } => write!(f, "FileSystem({})", file.display()),
Resource::Raw { raw } => write!(f, "Raw({})", raw),
}
Expand All @@ -90,8 +123,18 @@ impl fmt::Display for Resource {

impl Resource {
/// Creates a reference to the bundled resource.
/// This function, will use ckb_system_scripts v0.5.4 crate
pub fn bundled(bundled: String) -> Resource {
Resource::Bundled { bundled }
Resource::Bundled {
version: BundledSystemScriptVersion::V0_5_4,
bundled,
}
}

/// Creates a reference to the bundled resource.
/// use specific version of ckb_system_scripts crate
pub fn bundled_with_version(version: BundledSystemScriptVersion, bundled: String) -> Resource {
Resource::Bundled { version, bundled }
}

/// Creates a reference to the resource resident in the file system.
Expand Down Expand Up @@ -163,9 +206,15 @@ impl Resource {
/// The file system resource exists only when the file exists.
pub fn exists(&self) -> bool {
match self {
Resource::Bundled { bundled } => {
SourceFiles::new(&BUNDLED_CELL, &BUNDLED).is_available(bundled)
Resource::Bundled { bundled, version } => match version {
BundledSystemScriptVersion::V0_5_4 => {
SourceFiles::new(&BUNDLED_CELL_v0_5_4, &BUNDLED)
}
BundledSystemScriptVersion::V0_6_0 => {
SourceFiles::new(&BUNDLED_CELL_v0_6_0, &BUNDLED)
}
}
.is_available(bundled),
Resource::FileSystem { file } => file.exists(),
Resource::Raw { .. } => true,
}
Expand Down Expand Up @@ -195,7 +244,15 @@ impl Resource {
/// Gets resource content.
pub fn get(&self) -> Result<Cow<'static, [u8]>> {
match self {
Resource::Bundled { bundled } => SourceFiles::new(&BUNDLED_CELL, &BUNDLED).get(bundled),
Resource::Bundled { bundled, version } => match version {
BundledSystemScriptVersion::V0_5_4 => {
SourceFiles::new(&BUNDLED_CELL_v0_5_4, &BUNDLED)
}
BundledSystemScriptVersion::V0_6_0 => {
SourceFiles::new(&BUNDLED_CELL_v0_6_0, &BUNDLED)
}
}
.get(bundled),
Resource::FileSystem { file } => Ok(Cow::Owned(fs::read(file)?)),
Resource::Raw { raw } => Ok(Cow::Owned(raw.to_owned().into_bytes())),
}
Expand All @@ -204,9 +261,15 @@ impl Resource {
/// Gets resource content via an input stream.
pub fn read(&self) -> Result<Box<dyn Read>> {
match self {
Resource::Bundled { bundled } => {
SourceFiles::new(&BUNDLED_CELL, &BUNDLED).read(bundled)
Resource::Bundled { bundled, version } => match version {
BundledSystemScriptVersion::V0_5_4 => {
SourceFiles::new(&BUNDLED_CELL_v0_5_4, &BUNDLED)
}
BundledSystemScriptVersion::V0_6_0 => {
SourceFiles::new(&BUNDLED_CELL_v0_6_0, &BUNDLED)
}
}
.read(bundled),
Resource::FileSystem { file } => Ok(Box::new(BufReader::new(fs::File::open(file)?))),
Resource::Raw { raw } => Ok(Box::new(Cursor::new(raw.to_owned().into_bytes()))),
}
Expand All @@ -222,7 +285,10 @@ impl Resource {
/// See [Template](struct.Template.html).
pub fn export<P: AsRef<Path>>(&self, context: &TemplateContext<'_>, root_dir: P) -> Result<()> {
let key = match self {
Resource::Bundled { bundled } => bundled,
Resource::Bundled {
bundled,
version: _,
} => bundled,
_ => return Ok(()),
};
let target = join_bundled_key(root_dir.as_ref().to_path_buf(), key);
Expand Down
2 changes: 2 additions & 0 deletions rpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1657,6 +1657,8 @@ The response looks like below when `verbosity` is 0.

Return various consensus parameters.

Notes: The `secp256k1_blake160_multisig_all_type_hash` the hash created on genesis block, CKB may upgrade the multisig script: https://github.com/nervosnetwork/ckb-system-scripts

###### Returns

If any hardfork feature has `epoch=null`, it means the feature will never be activated.
Expand Down
2 changes: 2 additions & 0 deletions rpc/src/module/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,8 @@ pub trait ChainRpc {

/// Return various consensus parameters.
///
/// Notes: The `secp256k1_blake160_multisig_all_type_hash` the hash created on genesis block, CKB may upgrade the multisig script: https://github.com/nervosnetwork/ckb-system-scripts
///
/// ## Returns
///
/// If any hardfork feature has `epoch=null`, it means the feature will never be activated.
Expand Down
34 changes: 31 additions & 3 deletions rpc/src/module/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use ckb_jsonrpc_types::{
use ckb_logger::error;
use ckb_shared::shared::Shared;
use ckb_types::core::TransactionView;
use ckb_types::{H256, core, packed, prelude::*};
use ckb_types::{H256, core, h256, packed, prelude::*};
use ckb_verification::{Since, SinceMetric};
use jsonrpc_core::Result;
use jsonrpc_utils::rpc;
Expand Down Expand Up @@ -771,7 +771,8 @@ impl<'a> WellKnownScriptsOnlyValidator<'a> {
output: &packed::CellOutput,
) -> std::result::Result<(), DefaultOutputsValidatorError> {
self.validate_secp256k1_blake160_sighash_all(output)
.or_else(|_| self.validate_secp256k1_blake160_multisig_all(output))
.or_else(|_| self.validate_secp256k1_blake160_multisig_all_legacy(output))
.or_else(|_| self.validate_secp256k1_blake160_multisig_all_v2(output))
.or_else(|_| self.validate_well_known_lock_scripts(output))
}

Expand Down Expand Up @@ -804,7 +805,7 @@ impl<'a> WellKnownScriptsOnlyValidator<'a> {
}
}

fn validate_secp256k1_blake160_multisig_all(
fn validate_secp256k1_blake160_multisig_all_legacy(
&self,
output: &packed::CellOutput,
) -> std::result::Result<(), DefaultOutputsValidatorError> {
Expand Down Expand Up @@ -834,6 +835,33 @@ impl<'a> WellKnownScriptsOnlyValidator<'a> {
}
}

fn validate_secp256k1_blake160_multisig_all_v2(
&self,
output: &packed::CellOutput,
) -> std::result::Result<(), DefaultOutputsValidatorError> {
let script = output.lock();
if !script.is_hash_type_data1() {
Err(DefaultOutputsValidatorError::HashType)
} else if script.code_hash()
!= h256!("0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29").pack()
{
Err(DefaultOutputsValidatorError::CodeHash)
} else if script.args().len() != BLAKE160_LEN {
if script.args().len() == BLAKE160_LEN + SINCE_LEN {
if extract_since_from_secp256k1_blake160_multisig_all_args(&script).flags_is_valid()
{
Ok(())
} else {
Err(DefaultOutputsValidatorError::ArgsSince)
}
} else {
Err(DefaultOutputsValidatorError::ArgsLen)
}
} else {
Ok(())
}
}

fn validate_well_known_lock_scripts(
&self,
output: &packed::CellOutput,
Expand Down
Loading
Loading