Skip to content

Commit

Permalink
fix: fix vm version select
Browse files Browse the repository at this point in the history
  • Loading branch information
driftluo committed Nov 2, 2023
1 parent d0a434a commit 1c45ea4
Show file tree
Hide file tree
Showing 21 changed files with 272 additions and 164 deletions.
3 changes: 2 additions & 1 deletion ckb-bin/src/subcommand/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ pub fn export(args: ExportArgs, async_handle: Handle) -> Result<(), ExitCode> {
&args.config.db,
None,
async_handle,
args.consensus,
)?;
let (shared, _) = builder.consensus(args.consensus).build()?;
let (shared, _) = builder.build()?;
Export::new(shared, args.target).execute().map_err(|err| {
eprintln!("Export error: {err:?}");
ExitCode::Failure
Expand Down
3 changes: 2 additions & 1 deletion ckb-bin/src/subcommand/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ pub fn import(args: ImportArgs, async_handle: Handle) -> Result<(), ExitCode> {
&args.config.db,
None,
async_handle,
args.consensus,
)?;
let (shared, mut pack) = builder.consensus(args.consensus).build()?;
let (shared, mut pack) = builder.build()?;

let chain_service = ChainService::new(shared, pack.take_proposal_table());
let chain_controller = chain_service.start::<&str>(Some("ImportChainService"));
Expand Down
2 changes: 1 addition & 1 deletion ckb-bin/src/subcommand/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::cmp::Ordering;
use crate::helper::prompt;

pub fn migrate(args: MigrateArgs) -> Result<(), ExitCode> {
let migrate = Migrate::new(&args.config.db.path);
let migrate = Migrate::new(&args.config.db.path, args.consensus.hardfork_switch);

{
let read_only_db = migrate.open_read_only_db().map_err(|e| {
Expand Down
8 changes: 3 additions & 5 deletions ckb-bin/src/subcommand/replay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ pub fn replay(args: ReplayArgs, async_handle: Handle) -> Result<(), ExitCode> {
&args.config.db,
None,
async_handle.clone(),
args.consensus.clone(),
)?;
let (shared, _) = shared_builder
.consensus(args.consensus.clone())
.tx_pool_config(args.config.tx_pool.clone())
.build()?;

Expand All @@ -45,11 +45,9 @@ pub fn replay(args: ReplayArgs, async_handle: Handle) -> Result<(), ExitCode> {
&tmp_db_config,
None,
async_handle,
args.consensus,
)?;
let (tmp_shared, mut pack) = shared_builder
.consensus(args.consensus)
.tx_pool_config(args.config.tx_pool)
.build()?;
let (tmp_shared, mut pack) = shared_builder.tx_pool_config(args.config.tx_pool).build()?;
let chain = ChainService::new(tmp_shared, pack.take_proposal_table());

if let Some((from, to)) = args.profile {
Expand Down
3 changes: 2 additions & 1 deletion ckb-bin/src/subcommand/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ impl Statics {
&args.config.db,
None,
async_handle,
args.consensus,
)?;
let (shared, _) = shared_builder.consensus(args.consensus).build()?;
let (shared, _) = shared_builder.build()?;

let tip_number = shared.snapshot().tip_number();

Expand Down
12 changes: 6 additions & 6 deletions rpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1659,12 +1659,12 @@ Response
"genesis_hash": "0x7978ec7ce5b507cfb52e149e36b1a23f6062ed150503c85bbf825da3599095ed",
"hardfork_features": [
{ "rfc": "0028", "epoch_number": "0x1526" },
{ "rfc": "0029", "epoch_number": "0x0" },
{ "rfc": "0030", "epoch_number": "0x0" },
{ "rfc": "0031", "epoch_number": "0x0" },
{ "rfc": "0032", "epoch_number": "0x0" },
{ "rfc": "0036", "epoch_number": "0x0" },
{ "rfc": "0038", "epoch_number": "0x0" },
{ "rfc": "0029", "epoch_number": "0x1526" },
{ "rfc": "0030", "epoch_number": "0x1526" },
{ "rfc": "0031", "epoch_number": "0x1526" },
{ "rfc": "0032", "epoch_number": "0x1526" },
{ "rfc": "0036", "epoch_number": "0x1526" },
{ "rfc": "0038", "epoch_number": "0x1526" },
{ "rfc": "0048", "epoch_number": null },
{ "rfc": "0049", "epoch_number": null }
],
Expand Down
12 changes: 6 additions & 6 deletions rpc/src/module/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1341,12 +1341,12 @@ pub trait ChainRpc {
/// "genesis_hash": "0x7978ec7ce5b507cfb52e149e36b1a23f6062ed150503c85bbf825da3599095ed",
/// "hardfork_features": [
/// { "rfc": "0028", "epoch_number": "0x1526" },
/// { "rfc": "0029", "epoch_number": "0x0" },
/// { "rfc": "0030", "epoch_number": "0x0" },
/// { "rfc": "0031", "epoch_number": "0x0" },
/// { "rfc": "0032", "epoch_number": "0x0" },
/// { "rfc": "0036", "epoch_number": "0x0" },
/// { "rfc": "0038", "epoch_number": "0x0" },
/// { "rfc": "0029", "epoch_number": "0x1526" },
/// { "rfc": "0030", "epoch_number": "0x1526" },
/// { "rfc": "0031", "epoch_number": "0x1526" },
/// { "rfc": "0032", "epoch_number": "0x1526" },
/// { "rfc": "0036", "epoch_number": "0x1526" },
/// { "rfc": "0038", "epoch_number": "0x1526" },
/// { "rfc": "0048", "epoch_number": null },
/// { "rfc": "0049", "epoch_number": null }
/// ],
Expand Down
17 changes: 16 additions & 1 deletion script/src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,18 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
}
}

fn is_vm_version_1_and_syscalls_2_enabled(&self) -> bool {
// If the proposal window is allowed to prejudge on the vm version,
// it will cause proposal tx to start a new vm in the blocks before hardfork,
// destroying the assumption that the transaction execution only uses the old vm
// before hardfork, leading to unexpected network splits.
let epoch_number = self.tx_env.epoch_number_without_proposal_window();
let hardfork_switch = self.consensus.hardfork_switch();
hardfork_switch
.ckb2021
.is_vm_version_1_and_syscalls_2_enabled(epoch_number)
}

fn is_vm_version_2_and_syscalls_3_enabled(&self) -> bool {
// If the proposal window is allowed to prejudge on the vm version,
// it will cause proposal tx to start a new vm in the blocks before hardfork,
Expand All @@ -551,6 +563,7 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
/// Returns the version of the machine based on the script and the consensus rules.
pub fn select_version(&self, script: &Script) -> Result<ScriptVersion, ScriptError> {
let is_vm_version_2_and_syscalls_3_enabled = self.is_vm_version_2_and_syscalls_3_enabled();
let is_vm_version_1_and_syscalls_2_enabled = self.is_vm_version_1_and_syscalls_2_enabled();
let script_hash_type = ScriptHashType::try_from(script.hash_type())
.map_err(|err| ScriptError::InvalidScriptHashType(err.to_string()))?;
match script_hash_type {
Expand All @@ -566,8 +579,10 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
ScriptHashType::Type => {
if is_vm_version_2_and_syscalls_3_enabled {
Ok(ScriptVersion::V2)
} else {
} else if is_vm_version_1_and_syscalls_2_enabled {
Ok(ScriptVersion::V1)
} else {
Ok(ScriptVersion::V0)
}
}
}
Expand Down
90 changes: 0 additions & 90 deletions script/src/verify/tests/ckb_latest/features_since_v2019.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,96 +190,6 @@ fn check_signature_referenced_via_type_hash() {
assert!(result.is_ok());
}

#[test]
fn check_signature_referenced_via_type_hash_ok_with_multiple_matches() {
let script_version = SCRIPT_VERSION;

let mut file = open_cell_always_success();
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).unwrap();
let data = Bytes::from(buffer);

let (privkey, pubkey) = random_keypair();
let mut args = b"foobar".to_vec();

let signature = sign_args(&args, &privkey);
args.extend(&to_hex_pubkey(&pubkey));
args.extend(&to_hex_signature(&signature));

let dep_out_point = OutPoint::new(h256!("0x123").pack(), 8);
let cell_dep = CellDep::new_builder()
.out_point(dep_out_point.clone())
.build();
let output = CellOutputBuilder::default()
.capacity(Capacity::bytes(data.len()).unwrap().pack())
.type_(
Some(
Script::new_builder()
.code_hash(h256!("0x123456abcd90").pack())
.hash_type(ScriptHashType::Data.into())
.build(),
)
.pack(),
)
.build();
let type_hash = output.type_().to_opt().as_ref().unwrap().calc_script_hash();
let dep_cell = CellMetaBuilder::from_cell_output(output, data.clone())
.transaction_info(default_transaction_info())
.out_point(dep_out_point)
.build();

let dep_out_point2 = OutPoint::new(h256!("0x1234").pack(), 8);
let cell_dep2 = CellDep::new_builder()
.out_point(dep_out_point2.clone())
.build();
let output2 = CellOutputBuilder::default()
.capacity(Capacity::bytes(data.len()).unwrap().pack())
.type_(
Some(
Script::new_builder()
.code_hash(h256!("0x123456abcd90").pack())
.hash_type(ScriptHashType::Data.into())
.build(),
)
.pack(),
)
.build();
let dep_cell2 = CellMetaBuilder::from_cell_output(output2, data)
.transaction_info(default_transaction_info())
.out_point(dep_out_point2)
.build();

let script = Script::new_builder()
.args(Bytes::from(args).pack())
.code_hash(type_hash)
.hash_type(ScriptHashType::Type.into())
.build();
let input = CellInput::new(OutPoint::null(), 0);

let transaction = TransactionBuilder::default()
.input(input)
.cell_dep(cell_dep)
.cell_dep(cell_dep2)
.build();

let output = CellOutputBuilder::default()
.capacity(capacity_bytes!(100).pack())
.lock(script)
.build();
let dummy_cell = create_dummy_cell(output);

let rtx = ResolvedTransaction {
transaction,
resolved_cell_deps: vec![dep_cell, dep_cell2],
resolved_inputs: vec![dummy_cell],
resolved_dep_groups: vec![],
};

let verifier = TransactionScriptsVerifierWithEnv::new();
let result = verifier.verify_without_limit(script_version, &rtx);
assert_eq!(result.unwrap(), 539);
}

#[test]
fn check_invalid_signature() {
let script_version = SCRIPT_VERSION;
Expand Down
96 changes: 95 additions & 1 deletion script/src/verify/tests/ckb_latest/features_since_v2021.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use ckb_vm::Error as VmError;
use proptest::{prelude::*, prop_assert_eq, proptest};
use rand::distributions::Uniform;
use rand::{thread_rng, Rng};
use std::collections::VecDeque;
use std::{collections::VecDeque, io::Read};

use super::SCRIPT_VERSION;
use crate::syscalls::SOURCE_GROUP_FLAG;
Expand Down Expand Up @@ -1694,3 +1694,97 @@ fn exec_slice() {
let res = Ok(2);
test_exec(0b0000, 1, 2, 1, from, res);
}

#[test]
fn check_signature_referenced_via_type_hash_ok_with_multiple_matches() {
let script_version = SCRIPT_VERSION;
if script_version < ScriptVersion::V1 {
// This transaction is restricted by rfc_0029 and not supported in the 2019 version
return;
}

let mut file = open_cell_always_success();
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).unwrap();
let data = Bytes::from(buffer);

let (privkey, pubkey) = random_keypair();
let mut args = b"foobar".to_vec();

let signature = sign_args(&args, &privkey);
args.extend(&to_hex_pubkey(&pubkey));
args.extend(&to_hex_signature(&signature));

let dep_out_point = OutPoint::new(h256!("0x123").pack(), 8);
let cell_dep = CellDep::new_builder()
.out_point(dep_out_point.clone())
.build();
let output = CellOutputBuilder::default()
.capacity(Capacity::bytes(data.len()).unwrap().pack())
.type_(
Some(
Script::new_builder()
.code_hash(h256!("0x123456abcd90").pack())
.hash_type(ScriptHashType::Data.into())
.build(),
)
.pack(),
)
.build();
let type_hash = output.type_().to_opt().as_ref().unwrap().calc_script_hash();
let dep_cell = CellMetaBuilder::from_cell_output(output, data.clone())
.transaction_info(default_transaction_info())
.out_point(dep_out_point)
.build();

let dep_out_point2 = OutPoint::new(h256!("0x1234").pack(), 8);
let cell_dep2 = CellDep::new_builder()
.out_point(dep_out_point2.clone())
.build();
let output2 = CellOutputBuilder::default()
.capacity(Capacity::bytes(data.len()).unwrap().pack())
.type_(
Some(
Script::new_builder()
.code_hash(h256!("0x123456abcd90").pack())
.hash_type(ScriptHashType::Data.into())
.build(),
)
.pack(),
)
.build();
let dep_cell2 = CellMetaBuilder::from_cell_output(output2, data)
.transaction_info(default_transaction_info())
.out_point(dep_out_point2)
.build();

let script = Script::new_builder()
.args(Bytes::from(args).pack())
.code_hash(type_hash)
.hash_type(ScriptHashType::Type.into())
.build();
let input = CellInput::new(OutPoint::null(), 0);

let transaction = TransactionBuilder::default()
.input(input)
.cell_dep(cell_dep)
.cell_dep(cell_dep2)
.build();

let output = CellOutputBuilder::default()
.capacity(capacity_bytes!(100).pack())
.lock(script)
.build();
let dummy_cell = create_dummy_cell(output);

let rtx = ResolvedTransaction {
transaction,
resolved_cell_deps: vec![dep_cell, dep_cell2],
resolved_inputs: vec![dummy_cell],
resolved_dep_groups: vec![],
};

let verifier = TransactionScriptsVerifierWithEnv::new();
let result = verifier.verify_without_limit(script_version, &rtx);
assert_eq!(result.unwrap(), 539);
}
11 changes: 9 additions & 2 deletions script/src/verify/tests/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ pub(crate) struct TransactionScriptsVerifierWithEnv {
// Ref: https://doc.rust-lang.org/reference/destructors.html
store: Arc<ChainDB>,
consensus: Arc<Consensus>,
version_1_enabled_at: EpochNumber,
version_2_enabled_at: EpochNumber,
_tmp_dir: TempDir,
}
Expand All @@ -135,10 +136,15 @@ impl TransactionScriptsVerifierWithEnv {
let tmp_dir = TempDir::new().unwrap();
let db = RocksDB::open_in(&tmp_dir, COLUMNS);
let store = Arc::new(ChainDB::new(db, Default::default()));
let version_1_enabled_at = 5;
let version_2_enabled_at = 10;

let hardfork_switch = HardForks {
ckb2021: CKB2021::new_mirana(),
ckb2021: CKB2021::new_mirana()
.as_builder()
.rfc_0032(version_1_enabled_at)
.build()
.unwrap(),
ckb2023: CKB2023::new_mirana()
.as_builder()
.rfc_0049(version_2_enabled_at)
Expand All @@ -152,6 +158,7 @@ impl TransactionScriptsVerifierWithEnv {
);
Self {
store,
version_1_enabled_at,
version_2_enabled_at,
consensus,
_tmp_dir: tmp_dir,
Expand Down Expand Up @@ -237,7 +244,7 @@ impl TransactionScriptsVerifierWithEnv {
let data_loader = self.store.as_data_loader();
let epoch = match version {
ScriptVersion::V0 => EpochNumberWithFraction::new(0, 0, 1),
ScriptVersion::V1 => EpochNumberWithFraction::new(0, 0, 1),
ScriptVersion::V1 => EpochNumberWithFraction::new(self.version_1_enabled_at, 0, 1),
ScriptVersion::V2 => EpochNumberWithFraction::new(self.version_2_enabled_at, 0, 1),
};
let header = HeaderView::new_advanced_builder()
Expand Down
Loading

0 comments on commit 1c45ea4

Please sign in to comment.