Skip to content

Commit 1c45ea4

Browse files
committed
fix: fix vm version select
1 parent d0a434a commit 1c45ea4

File tree

21 files changed

+272
-164
lines changed

21 files changed

+272
-164
lines changed

ckb-bin/src/subcommand/export.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ pub fn export(args: ExportArgs, async_handle: Handle) -> Result<(), ExitCode> {
1010
&args.config.db,
1111
None,
1212
async_handle,
13+
args.consensus,
1314
)?;
14-
let (shared, _) = builder.consensus(args.consensus).build()?;
15+
let (shared, _) = builder.build()?;
1516
Export::new(shared, args.target).execute().map_err(|err| {
1617
eprintln!("Export error: {err:?}");
1718
ExitCode::Failure

ckb-bin/src/subcommand/import.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ pub fn import(args: ImportArgs, async_handle: Handle) -> Result<(), ExitCode> {
1111
&args.config.db,
1212
None,
1313
async_handle,
14+
args.consensus,
1415
)?;
15-
let (shared, mut pack) = builder.consensus(args.consensus).build()?;
16+
let (shared, mut pack) = builder.build()?;
1617

1718
let chain_service = ChainService::new(shared, pack.take_proposal_table());
1819
let chain_controller = chain_service.start::<&str>(Some("ImportChainService"));

ckb-bin/src/subcommand/migrate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::cmp::Ordering;
66
use crate::helper::prompt;
77

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

1111
{
1212
let read_only_db = migrate.open_read_only_db().map_err(|e| {

ckb-bin/src/subcommand/replay.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ pub fn replay(args: ReplayArgs, async_handle: Handle) -> Result<(), ExitCode> {
1818
&args.config.db,
1919
None,
2020
async_handle.clone(),
21+
args.consensus.clone(),
2122
)?;
2223
let (shared, _) = shared_builder
23-
.consensus(args.consensus.clone())
2424
.tx_pool_config(args.config.tx_pool.clone())
2525
.build()?;
2626

@@ -45,11 +45,9 @@ pub fn replay(args: ReplayArgs, async_handle: Handle) -> Result<(), ExitCode> {
4545
&tmp_db_config,
4646
None,
4747
async_handle,
48+
args.consensus,
4849
)?;
49-
let (tmp_shared, mut pack) = shared_builder
50-
.consensus(args.consensus)
51-
.tx_pool_config(args.config.tx_pool)
52-
.build()?;
50+
let (tmp_shared, mut pack) = shared_builder.tx_pool_config(args.config.tx_pool).build()?;
5351
let chain = ChainService::new(tmp_shared, pack.take_proposal_table());
5452

5553
if let Some((from, to)) = args.profile {

ckb-bin/src/subcommand/stats.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ impl Statics {
3333
&args.config.db,
3434
None,
3535
async_handle,
36+
args.consensus,
3637
)?;
37-
let (shared, _) = shared_builder.consensus(args.consensus).build()?;
38+
let (shared, _) = shared_builder.build()?;
3839

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

rpc/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,12 +1659,12 @@ Response
16591659
"genesis_hash": "0x7978ec7ce5b507cfb52e149e36b1a23f6062ed150503c85bbf825da3599095ed",
16601660
"hardfork_features": [
16611661
{ "rfc": "0028", "epoch_number": "0x1526" },
1662-
{ "rfc": "0029", "epoch_number": "0x0" },
1663-
{ "rfc": "0030", "epoch_number": "0x0" },
1664-
{ "rfc": "0031", "epoch_number": "0x0" },
1665-
{ "rfc": "0032", "epoch_number": "0x0" },
1666-
{ "rfc": "0036", "epoch_number": "0x0" },
1667-
{ "rfc": "0038", "epoch_number": "0x0" },
1662+
{ "rfc": "0029", "epoch_number": "0x1526" },
1663+
{ "rfc": "0030", "epoch_number": "0x1526" },
1664+
{ "rfc": "0031", "epoch_number": "0x1526" },
1665+
{ "rfc": "0032", "epoch_number": "0x1526" },
1666+
{ "rfc": "0036", "epoch_number": "0x1526" },
1667+
{ "rfc": "0038", "epoch_number": "0x1526" },
16681668
{ "rfc": "0048", "epoch_number": null },
16691669
{ "rfc": "0049", "epoch_number": null }
16701670
],

rpc/src/module/chain.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,12 +1341,12 @@ pub trait ChainRpc {
13411341
/// "genesis_hash": "0x7978ec7ce5b507cfb52e149e36b1a23f6062ed150503c85bbf825da3599095ed",
13421342
/// "hardfork_features": [
13431343
/// { "rfc": "0028", "epoch_number": "0x1526" },
1344-
/// { "rfc": "0029", "epoch_number": "0x0" },
1345-
/// { "rfc": "0030", "epoch_number": "0x0" },
1346-
/// { "rfc": "0031", "epoch_number": "0x0" },
1347-
/// { "rfc": "0032", "epoch_number": "0x0" },
1348-
/// { "rfc": "0036", "epoch_number": "0x0" },
1349-
/// { "rfc": "0038", "epoch_number": "0x0" },
1344+
/// { "rfc": "0029", "epoch_number": "0x1526" },
1345+
/// { "rfc": "0030", "epoch_number": "0x1526" },
1346+
/// { "rfc": "0031", "epoch_number": "0x1526" },
1347+
/// { "rfc": "0032", "epoch_number": "0x1526" },
1348+
/// { "rfc": "0036", "epoch_number": "0x1526" },
1349+
/// { "rfc": "0038", "epoch_number": "0x1526" },
13501350
/// { "rfc": "0048", "epoch_number": null },
13511351
/// { "rfc": "0049", "epoch_number": null }
13521352
/// ],

script/src/verify.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,18 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
536536
}
537537
}
538538

539+
fn is_vm_version_1_and_syscalls_2_enabled(&self) -> bool {
540+
// If the proposal window is allowed to prejudge on the vm version,
541+
// it will cause proposal tx to start a new vm in the blocks before hardfork,
542+
// destroying the assumption that the transaction execution only uses the old vm
543+
// before hardfork, leading to unexpected network splits.
544+
let epoch_number = self.tx_env.epoch_number_without_proposal_window();
545+
let hardfork_switch = self.consensus.hardfork_switch();
546+
hardfork_switch
547+
.ckb2021
548+
.is_vm_version_1_and_syscalls_2_enabled(epoch_number)
549+
}
550+
539551
fn is_vm_version_2_and_syscalls_3_enabled(&self) -> bool {
540552
// If the proposal window is allowed to prejudge on the vm version,
541553
// it will cause proposal tx to start a new vm in the blocks before hardfork,
@@ -551,6 +563,7 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
551563
/// Returns the version of the machine based on the script and the consensus rules.
552564
pub fn select_version(&self, script: &Script) -> Result<ScriptVersion, ScriptError> {
553565
let is_vm_version_2_and_syscalls_3_enabled = self.is_vm_version_2_and_syscalls_3_enabled();
566+
let is_vm_version_1_and_syscalls_2_enabled = self.is_vm_version_1_and_syscalls_2_enabled();
554567
let script_hash_type = ScriptHashType::try_from(script.hash_type())
555568
.map_err(|err| ScriptError::InvalidScriptHashType(err.to_string()))?;
556569
match script_hash_type {
@@ -566,8 +579,10 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
566579
ScriptHashType::Type => {
567580
if is_vm_version_2_and_syscalls_3_enabled {
568581
Ok(ScriptVersion::V2)
569-
} else {
582+
} else if is_vm_version_1_and_syscalls_2_enabled {
570583
Ok(ScriptVersion::V1)
584+
} else {
585+
Ok(ScriptVersion::V0)
571586
}
572587
}
573588
}

script/src/verify/tests/ckb_latest/features_since_v2019.rs

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -190,96 +190,6 @@ fn check_signature_referenced_via_type_hash() {
190190
assert!(result.is_ok());
191191
}
192192

193-
#[test]
194-
fn check_signature_referenced_via_type_hash_ok_with_multiple_matches() {
195-
let script_version = SCRIPT_VERSION;
196-
197-
let mut file = open_cell_always_success();
198-
let mut buffer = Vec::new();
199-
file.read_to_end(&mut buffer).unwrap();
200-
let data = Bytes::from(buffer);
201-
202-
let (privkey, pubkey) = random_keypair();
203-
let mut args = b"foobar".to_vec();
204-
205-
let signature = sign_args(&args, &privkey);
206-
args.extend(&to_hex_pubkey(&pubkey));
207-
args.extend(&to_hex_signature(&signature));
208-
209-
let dep_out_point = OutPoint::new(h256!("0x123").pack(), 8);
210-
let cell_dep = CellDep::new_builder()
211-
.out_point(dep_out_point.clone())
212-
.build();
213-
let output = CellOutputBuilder::default()
214-
.capacity(Capacity::bytes(data.len()).unwrap().pack())
215-
.type_(
216-
Some(
217-
Script::new_builder()
218-
.code_hash(h256!("0x123456abcd90").pack())
219-
.hash_type(ScriptHashType::Data.into())
220-
.build(),
221-
)
222-
.pack(),
223-
)
224-
.build();
225-
let type_hash = output.type_().to_opt().as_ref().unwrap().calc_script_hash();
226-
let dep_cell = CellMetaBuilder::from_cell_output(output, data.clone())
227-
.transaction_info(default_transaction_info())
228-
.out_point(dep_out_point)
229-
.build();
230-
231-
let dep_out_point2 = OutPoint::new(h256!("0x1234").pack(), 8);
232-
let cell_dep2 = CellDep::new_builder()
233-
.out_point(dep_out_point2.clone())
234-
.build();
235-
let output2 = CellOutputBuilder::default()
236-
.capacity(Capacity::bytes(data.len()).unwrap().pack())
237-
.type_(
238-
Some(
239-
Script::new_builder()
240-
.code_hash(h256!("0x123456abcd90").pack())
241-
.hash_type(ScriptHashType::Data.into())
242-
.build(),
243-
)
244-
.pack(),
245-
)
246-
.build();
247-
let dep_cell2 = CellMetaBuilder::from_cell_output(output2, data)
248-
.transaction_info(default_transaction_info())
249-
.out_point(dep_out_point2)
250-
.build();
251-
252-
let script = Script::new_builder()
253-
.args(Bytes::from(args).pack())
254-
.code_hash(type_hash)
255-
.hash_type(ScriptHashType::Type.into())
256-
.build();
257-
let input = CellInput::new(OutPoint::null(), 0);
258-
259-
let transaction = TransactionBuilder::default()
260-
.input(input)
261-
.cell_dep(cell_dep)
262-
.cell_dep(cell_dep2)
263-
.build();
264-
265-
let output = CellOutputBuilder::default()
266-
.capacity(capacity_bytes!(100).pack())
267-
.lock(script)
268-
.build();
269-
let dummy_cell = create_dummy_cell(output);
270-
271-
let rtx = ResolvedTransaction {
272-
transaction,
273-
resolved_cell_deps: vec![dep_cell, dep_cell2],
274-
resolved_inputs: vec![dummy_cell],
275-
resolved_dep_groups: vec![],
276-
};
277-
278-
let verifier = TransactionScriptsVerifierWithEnv::new();
279-
let result = verifier.verify_without_limit(script_version, &rtx);
280-
assert_eq!(result.unwrap(), 539);
281-
}
282-
283193
#[test]
284194
fn check_invalid_signature() {
285195
let script_version = SCRIPT_VERSION;

script/src/verify/tests/ckb_latest/features_since_v2021.rs

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use ckb_vm::Error as VmError;
1010
use proptest::{prelude::*, prop_assert_eq, proptest};
1111
use rand::distributions::Uniform;
1212
use rand::{thread_rng, Rng};
13-
use std::collections::VecDeque;
13+
use std::{collections::VecDeque, io::Read};
1414

1515
use super::SCRIPT_VERSION;
1616
use crate::syscalls::SOURCE_GROUP_FLAG;
@@ -1694,3 +1694,97 @@ fn exec_slice() {
16941694
let res = Ok(2);
16951695
test_exec(0b0000, 1, 2, 1, from, res);
16961696
}
1697+
1698+
#[test]
1699+
fn check_signature_referenced_via_type_hash_ok_with_multiple_matches() {
1700+
let script_version = SCRIPT_VERSION;
1701+
if script_version < ScriptVersion::V1 {
1702+
// This transaction is restricted by rfc_0029 and not supported in the 2019 version
1703+
return;
1704+
}
1705+
1706+
let mut file = open_cell_always_success();
1707+
let mut buffer = Vec::new();
1708+
file.read_to_end(&mut buffer).unwrap();
1709+
let data = Bytes::from(buffer);
1710+
1711+
let (privkey, pubkey) = random_keypair();
1712+
let mut args = b"foobar".to_vec();
1713+
1714+
let signature = sign_args(&args, &privkey);
1715+
args.extend(&to_hex_pubkey(&pubkey));
1716+
args.extend(&to_hex_signature(&signature));
1717+
1718+
let dep_out_point = OutPoint::new(h256!("0x123").pack(), 8);
1719+
let cell_dep = CellDep::new_builder()
1720+
.out_point(dep_out_point.clone())
1721+
.build();
1722+
let output = CellOutputBuilder::default()
1723+
.capacity(Capacity::bytes(data.len()).unwrap().pack())
1724+
.type_(
1725+
Some(
1726+
Script::new_builder()
1727+
.code_hash(h256!("0x123456abcd90").pack())
1728+
.hash_type(ScriptHashType::Data.into())
1729+
.build(),
1730+
)
1731+
.pack(),
1732+
)
1733+
.build();
1734+
let type_hash = output.type_().to_opt().as_ref().unwrap().calc_script_hash();
1735+
let dep_cell = CellMetaBuilder::from_cell_output(output, data.clone())
1736+
.transaction_info(default_transaction_info())
1737+
.out_point(dep_out_point)
1738+
.build();
1739+
1740+
let dep_out_point2 = OutPoint::new(h256!("0x1234").pack(), 8);
1741+
let cell_dep2 = CellDep::new_builder()
1742+
.out_point(dep_out_point2.clone())
1743+
.build();
1744+
let output2 = CellOutputBuilder::default()
1745+
.capacity(Capacity::bytes(data.len()).unwrap().pack())
1746+
.type_(
1747+
Some(
1748+
Script::new_builder()
1749+
.code_hash(h256!("0x123456abcd90").pack())
1750+
.hash_type(ScriptHashType::Data.into())
1751+
.build(),
1752+
)
1753+
.pack(),
1754+
)
1755+
.build();
1756+
let dep_cell2 = CellMetaBuilder::from_cell_output(output2, data)
1757+
.transaction_info(default_transaction_info())
1758+
.out_point(dep_out_point2)
1759+
.build();
1760+
1761+
let script = Script::new_builder()
1762+
.args(Bytes::from(args).pack())
1763+
.code_hash(type_hash)
1764+
.hash_type(ScriptHashType::Type.into())
1765+
.build();
1766+
let input = CellInput::new(OutPoint::null(), 0);
1767+
1768+
let transaction = TransactionBuilder::default()
1769+
.input(input)
1770+
.cell_dep(cell_dep)
1771+
.cell_dep(cell_dep2)
1772+
.build();
1773+
1774+
let output = CellOutputBuilder::default()
1775+
.capacity(capacity_bytes!(100).pack())
1776+
.lock(script)
1777+
.build();
1778+
let dummy_cell = create_dummy_cell(output);
1779+
1780+
let rtx = ResolvedTransaction {
1781+
transaction,
1782+
resolved_cell_deps: vec![dep_cell, dep_cell2],
1783+
resolved_inputs: vec![dummy_cell],
1784+
resolved_dep_groups: vec![],
1785+
};
1786+
1787+
let verifier = TransactionScriptsVerifierWithEnv::new();
1788+
let result = verifier.verify_without_limit(script_version, &rtx);
1789+
assert_eq!(result.unwrap(), 539);
1790+
}

script/src/verify/tests/utils.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ pub(crate) struct TransactionScriptsVerifierWithEnv {
126126
// Ref: https://doc.rust-lang.org/reference/destructors.html
127127
store: Arc<ChainDB>,
128128
consensus: Arc<Consensus>,
129+
version_1_enabled_at: EpochNumber,
129130
version_2_enabled_at: EpochNumber,
130131
_tmp_dir: TempDir,
131132
}
@@ -135,10 +136,15 @@ impl TransactionScriptsVerifierWithEnv {
135136
let tmp_dir = TempDir::new().unwrap();
136137
let db = RocksDB::open_in(&tmp_dir, COLUMNS);
137138
let store = Arc::new(ChainDB::new(db, Default::default()));
139+
let version_1_enabled_at = 5;
138140
let version_2_enabled_at = 10;
139141

140142
let hardfork_switch = HardForks {
141-
ckb2021: CKB2021::new_mirana(),
143+
ckb2021: CKB2021::new_mirana()
144+
.as_builder()
145+
.rfc_0032(version_1_enabled_at)
146+
.build()
147+
.unwrap(),
142148
ckb2023: CKB2023::new_mirana()
143149
.as_builder()
144150
.rfc_0049(version_2_enabled_at)
@@ -152,6 +158,7 @@ impl TransactionScriptsVerifierWithEnv {
152158
);
153159
Self {
154160
store,
161+
version_1_enabled_at,
155162
version_2_enabled_at,
156163
consensus,
157164
_tmp_dir: tmp_dir,
@@ -237,7 +244,7 @@ impl TransactionScriptsVerifierWithEnv {
237244
let data_loader = self.store.as_data_loader();
238245
let epoch = match version {
239246
ScriptVersion::V0 => EpochNumberWithFraction::new(0, 0, 1),
240-
ScriptVersion::V1 => EpochNumberWithFraction::new(0, 0, 1),
247+
ScriptVersion::V1 => EpochNumberWithFraction::new(self.version_1_enabled_at, 0, 1),
241248
ScriptVersion::V2 => EpochNumberWithFraction::new(self.version_2_enabled_at, 0, 1),
242249
};
243250
let header = HeaderView::new_advanced_builder()

0 commit comments

Comments
 (0)