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 bd97284
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 122 deletions.
2 changes: 1 addition & 1 deletion rpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1662,7 +1662,7 @@ Response
{ "rfc": "0029", "epoch_number": "0x0" },
{ "rfc": "0030", "epoch_number": "0x0" },
{ "rfc": "0031", "epoch_number": "0x0" },
{ "rfc": "0032", "epoch_number": "0x0" },
{ "rfc": "0032", "epoch_number": "0x1526" },
{ "rfc": "0036", "epoch_number": "0x0" },
{ "rfc": "0038", "epoch_number": "0x0" },
{ "rfc": "0048", "epoch_number": null },
Expand Down
2 changes: 1 addition & 1 deletion rpc/src/module/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ pub trait ChainRpc {
/// { "rfc": "0029", "epoch_number": "0x0" },
/// { "rfc": "0030", "epoch_number": "0x0" },
/// { "rfc": "0031", "epoch_number": "0x0" },
/// { "rfc": "0032", "epoch_number": "0x0" },
/// { "rfc": "0032", "epoch_number": "0x1526" },
/// { "rfc": "0036", "epoch_number": "0x0" },
/// { "rfc": "0038", "epoch_number": "0x0" },
/// { "rfc": "0048", "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
22 changes: 7 additions & 15 deletions spec/src/hardfork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl HardForkConfig {
ckb2021 = self.update_2021(
ckb2021,
mainnet::CKB2021_START_EPOCH,
mainnet::RFC0028_START_EPOCH,
mainnet::RFC0028_RFC0032_RFC0033_RFC0034_START_EPOCH,
)?;

Ok(HardForks {
Expand All @@ -39,7 +39,7 @@ impl HardForkConfig {
ckb2021 = self.update_2021(
ckb2021,
testnet::CKB2021_START_EPOCH,
testnet::RFC0028_START_EPOCH,
testnet::RFC0028_RFC0032_RFC0033_RFC0034_START_EPOCH,
)?;
let mut ckb2023 = CKB2023::new_builder();
ckb2023 = self.update_2023(ckb2023, testnet::CKB2023_START_EPOCH)?;
Expand All @@ -54,14 +54,14 @@ impl HardForkConfig {
&self,
builder: CKB2021Builder,
ckb2021: EpochNumber,
rfc_0028_start: EpochNumber,
rfc_0028_0032_0033_0034_start: EpochNumber,
) -> Result<CKB2021Builder, String> {
let builder = builder
.rfc_0028(rfc_0028_start)
.rfc_0028(rfc_0028_0032_0033_0034_start)
.rfc_0029(ckb2021)
.rfc_0030(ckb2021)
.rfc_0031(ckb2021)
.rfc_0032(ckb2021)
.rfc_0032(rfc_0028_0032_0033_0034_start)
.rfc_0036(ckb2021)
.rfc_0038(ckb2021);
Ok(builder)
Expand All @@ -80,22 +80,14 @@ impl HardForkConfig {
///
/// Enable features which are set to `None` at the dev default config.
pub fn complete_with_dev_default(&self) -> Result<HardForks, String> {
let mut ckb2021 = CKB2021::new_builder();
ckb2021 = self.update_2021(
ckb2021,
testnet::CKB2021_START_EPOCH,
testnet::RFC0028_START_EPOCH,
)?;
let ckb2021 = CKB2021::new_dev_default();

let ckb2023 = if let Some(epoch) = self.ckb2023 {
CKB2023::new_with_specified(epoch)
} else {
CKB2023::new_dev_default()
};

Ok(HardForks {
ckb2021: ckb2021.build()?,
ckb2023,
})
Ok(HardForks { ckb2021, ckb2023 })
}
}
4 changes: 2 additions & 2 deletions util/constant/src/hardfork/mainnet.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/// The Chain Specification name.
pub const CHAIN_SPEC_NAME: &str = "ckb";

/// hardcode rfc0028 epoch
pub const RFC0028_START_EPOCH: u64 = 5414;
/// hardcode rfc0028/rfc0032/rfc0033/rfc0034 epoch
pub const RFC0028_RFC0032_RFC0033_RFC0034_START_EPOCH: u64 = 5414;
/// First epoch number for CKB v2021, at about 2022/05/10 1:00 UTC
// pub const CKB2021_START_EPOCH: u64 = 5414;
pub const CKB2021_START_EPOCH: u64 = 0;
Expand Down
4 changes: 2 additions & 2 deletions util/constant/src/hardfork/testnet.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/// The Chain Specification name.
pub const CHAIN_SPEC_NAME: &str = "ckb_testnet";

/// hardcode rfc0028 epoch
pub const RFC0028_START_EPOCH: u64 = 3113;
/// hardcode rfc0028/rfc0032/rfc0033/rfc0034 epoch
pub const RFC0028_RFC0032_RFC0033_RFC0034_START_EPOCH: u64 = 3113;
/// First epoch number for CKB v2021, at about 2021/10/24 3:15 UTC.
// pub const CKB2021_START_EPOCH: u64 = 3113;
pub const CKB2021_START_EPOCH: u64 = 0;
Expand Down
Loading

0 comments on commit bd97284

Please sign in to comment.