Skip to content

Commit dc6b0dc

Browse files
authored
Merge pull request #32 from EthanYuan/fix-reorg-no-common-ancestor
fix: add reset operation for Testnet 3
2 parents 6453e4c + 31d0436 commit dc6b0dc

File tree

11 files changed

+87
-62
lines changed

11 files changed

+87
-62
lines changed

Diff for: Cargo.lock

+16-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: checksums.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
6bbea4820329050e1fc65f9c15cab5948b824c73aa3430d7d92b793c53ca66b6 build/release/can-update-without-ownership-lock
2-
cd553a3858df32dbf051957ec97014200e632fed016084b28b25fcbbc49863d1 build/release/ckb-bitcoin-spv-type-lock
2+
57e463512f0899b2523b4ac6a7e717797a92fdb1b3c565cc5f304bb6001f2656 build/release/ckb-bitcoin-spv-type-lock

Diff for: contracts/ckb-bitcoin-spv-type-lock/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ckb-bitcoin-spv-type-lock"
3-
version = "0.2.0"
3+
version = "0.2.1"
44
authors = ["Boyu Yang <[email protected]>"]
55
edition = "2021"
66
license = "MIT"
@@ -15,6 +15,6 @@ ckb-hash = { version = "0.112.1", default-features = false, features = ["ckb-con
1515
[dependencies.ckb-bitcoin-spv-verifier]
1616
version = "0.1.0"
1717
git = "https://github.com/ckb-cell/ckb-bitcoin-spv"
18-
rev = "bfc71d7"
18+
rev = "1ccd114"
1919
default-features = false
2020
features = ["no-std"]

Diff for: contracts/ckb-bitcoin-spv-type-lock/src/entry.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use alloc::vec::Vec;
22

3+
use ckb_bitcoin_spv_verifier::types::core::BitcoinChainType;
34
#[cfg(debug_assertions)]
45
use ckb_std::ckb_types::prelude::*;
56
use ckb_std::{ckb_constants::Source, debug, high_level as hl};
67

78
use crate::{
89
error::{InternalError, Result},
9-
operations,
10+
operations, utilities,
1011
};
1112

1213
pub fn main() -> Result<()> {
@@ -15,6 +16,11 @@ pub fn main() -> Result<()> {
1516
let script_hash = hl::load_script_hash()?;
1617
debug!("script hash = {:#x}", script_hash.pack());
1718

19+
let type_args = utilities::load_spv_type_args()?;
20+
let clients_count = usize::from(type_args.clients_count);
21+
let cells_count = 1 + clients_count;
22+
let flags = type_args.flags;
23+
1824
// Find all input cells which use current script.
1925
let indexes_of_inputs = {
2026
let mut indexes = Vec::new();
@@ -55,28 +61,36 @@ pub fn main() -> Result<()> {
5561
match (indexes_of_inputs.len(), indexes_of_outputs.len()) {
5662
(0, _) => {
5763
debug!("create all cells");
58-
operations::create_cells(&indexes_of_outputs)?;
64+
operations::create_cells(&indexes_of_outputs, type_args)?;
5965
}
6066
(_, 0) => {
6167
debug!("destroy all cells");
62-
operations::destroy_cells(&indexes_of_inputs)?;
68+
operations::destroy_cells(&indexes_of_inputs, type_args)?;
6369
}
6470
(2, 2) => {
6571
debug!("update a client cell and the info cell");
6672
operations::update_client(
6773
(indexes_of_inputs[0], indexes_of_inputs[1]),
6874
(indexes_of_outputs[0], indexes_of_outputs[1]),
6975
script_hash.as_slice(),
76+
type_args,
7077
)?;
7178
}
72-
(m, n) if m == n && m > 2 => {
79+
(m, n) if m == n && m > 2 && m < cells_count => {
7380
debug!("reorg client cells");
7481
operations::reorg_clients(
7582
&indexes_of_inputs,
7683
&indexes_of_outputs,
7784
script_hash.as_slice(),
85+
type_args,
7886
)?;
7987
}
88+
(m, n)
89+
if m == n && m > 2 && m == cells_count && BitcoinChainType::Testnet == flags.into() =>
90+
{
91+
debug!("reset all cells");
92+
operations::reset_cells()?;
93+
}
8094
(_m, _n) => {
8195
debug!("unknown operation: {_m} inputs and {_n} outputs");
8296
return Err(InternalError::UnknownOperation.into());

Diff for: contracts/ckb-bitcoin-spv-type-lock/src/operations/create.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use ckb_bitcoin_spv_verifier::types::{
2-
packed::{SpvBootstrapReader, SpvClientReader, SpvInfoReader, SpvTypeArgsReader},
2+
core::SpvTypeArgs,
3+
packed::{SpvBootstrapReader, SpvClientReader, SpvInfoReader},
34
prelude::*,
45
};
56
use ckb_std::{ckb_constants::Source, debug, error::SysError, high_level as hl};
@@ -9,7 +10,7 @@ use crate::{
910
utilities,
1011
};
1112

12-
pub(crate) fn create_cells(indexes: &[usize]) -> Result<()> {
13+
pub(crate) fn create_cells(indexes: &[usize], type_args: SpvTypeArgs) -> Result<()> {
1314
if indexes.len() < 1 + 1 + 2 {
1415
return Err(InternalError::CreateNotEnoughCells.into());
1516
}
@@ -18,14 +19,6 @@ pub(crate) fn create_cells(indexes: &[usize]) -> Result<()> {
1819
}
1920
// Checks args of the client type script, then returns the clients count;
2021
let clients_count = {
21-
let type_args = {
22-
let script = hl::load_script()?;
23-
let script_args = script.args();
24-
let script_args_slice = script_args.as_reader().raw_data();
25-
SpvTypeArgsReader::from_slice(script_args_slice)
26-
.map_err(|_| SysError::Encoding)?
27-
.unpack()
28-
};
2922
let clients_count = usize::from(type_args.clients_count);
3023
let cells_count = 1 + clients_count;
3124
if indexes.len() != cells_count {

Diff for: contracts/ckb-bitcoin-spv-type-lock/src/operations/destroy.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
1-
use ckb_bitcoin_spv_verifier::types::{packed::SpvTypeArgsReader, prelude::*};
2-
use ckb_std::{debug, error::SysError, high_level as hl};
1+
use ckb_bitcoin_spv_verifier::types::core::SpvTypeArgs;
2+
use ckb_std::debug;
33

44
use crate::error::{InternalError, Result};
55

6-
pub(crate) fn destroy_cells(indexes: &[usize]) -> Result<()> {
6+
pub(crate) fn destroy_cells(indexes: &[usize], type_args: SpvTypeArgs) -> Result<()> {
77
debug!("destroyed count: {}", indexes.len());
8-
let clients_count: u8 = {
9-
let script = hl::load_script()?;
10-
let script_args = script.args();
11-
let script_args_slice = script_args.as_reader().raw_data();
12-
SpvTypeArgsReader::from_slice(script_args_slice)
13-
.map_err(|_| SysError::Encoding)?
14-
.clients_count()
15-
.into()
16-
};
8+
let clients_count = type_args.clients_count;
179
debug!("clients count: {clients_count}");
1810
let cells_count = 1 + usize::from(clients_count);
1911
debug!("cells count: {cells_count}");
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
mod create;
22
mod destroy;
33
mod reorg;
4+
mod reset;
45
mod update;
56

67
pub(crate) use self::create::create_cells;
78
pub(crate) use self::destroy::destroy_cells;
89
pub(crate) use self::reorg::reorg_clients;
10+
pub(crate) use self::reset::reset_cells;
911
pub(crate) use self::update::update_client;

Diff for: contracts/ckb-bitcoin-spv-type-lock/src/operations/reorg.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use alloc::vec::Vec;
22

33
use ckb_bitcoin_spv_verifier::types::{
4-
core::{BitcoinChainType, SpvClient, SpvInfo, U256},
5-
packed::{self, SpvClientReader, SpvInfoReader, SpvTypeArgsReader, SpvUpdateReader},
4+
core::{BitcoinChainType, SpvClient, SpvInfo, SpvTypeArgs, U256},
5+
packed::{self, SpvClientReader, SpvInfoReader, SpvUpdateReader},
66
prelude::*,
77
};
88
#[cfg(debug_assertions)]
@@ -14,7 +14,12 @@ use crate::{
1414
utilities,
1515
};
1616

17-
pub(crate) fn reorg_clients(inputs: &[usize], outputs: &[usize], script_hash: &[u8]) -> Result<()> {
17+
pub(crate) fn reorg_clients(
18+
inputs: &[usize],
19+
outputs: &[usize],
20+
script_hash: &[u8],
21+
type_args: SpvTypeArgs,
22+
) -> Result<()> {
1823
// Checks the ids of the input client cells, then returns
1924
// - expected output info cell base on the input info cell,
2025
// - the new tip client id.
@@ -37,7 +42,7 @@ pub(crate) fn reorg_clients(inputs: &[usize], outputs: &[usize], script_hash: &[
3742
previous_chain_work,
3843
fork_client_id,
3944
flags,
40-
) = load_inputs(inputs)?;
45+
) = load_inputs(inputs, type_args)?;
4146
input_info.tip_client_id = expected_tip_client_id;
4247
(
4348
input_info,
@@ -96,7 +101,10 @@ pub(crate) fn reorg_clients(inputs: &[usize], outputs: &[usize], script_hash: &[
96101
Ok(())
97102
}
98103

99-
fn load_inputs(inputs: &[usize]) -> Result<(SpvInfo, u8, Vec<u8>, U256, u8, u8)> {
104+
fn load_inputs(
105+
inputs: &[usize],
106+
type_args: SpvTypeArgs,
107+
) -> Result<(SpvInfo, u8, Vec<u8>, U256, u8, u8)> {
100108
let mut client_ids_with_indexes = Vec::new();
101109
let mut input_info_opt = None;
102110
for i in inputs {
@@ -153,16 +161,7 @@ fn load_inputs(inputs: &[usize]) -> Result<(SpvInfo, u8, Vec<u8>, U256, u8, u8)>
153161
}
154162
};
155163

156-
let (clients_count, flags) = {
157-
let script = hl::load_script()?;
158-
let script_args = script.args();
159-
let script_args_slice = script_args.as_reader().raw_data();
160-
let args =
161-
SpvTypeArgsReader::from_slice(script_args_slice).map_err(|_| SysError::Encoding)?;
162-
let clients_count: u8 = args.clients_count().into();
163-
let flags: u8 = args.flags().into();
164-
(clients_count, flags)
165-
};
164+
let (clients_count, flags) = (type_args.clients_count, type_args.flags);
166165
debug!("clients count: {clients_count}, flags: {flags:08b}");
167166

168167
let mut client_ids = client_ids_with_indexes
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use crate::error::Result;
2+
3+
pub(crate) fn reset_cells() -> Result<()> {
4+
Ok(())
5+
}

Diff for: contracts/ckb-bitcoin-spv-type-lock/src/operations/update.rs

+7-14
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use alloc::vec::Vec;
22

33
use ckb_bitcoin_spv_verifier::types::{
4-
core::{SpvClient, SpvInfo},
5-
packed::{self, SpvClientReader, SpvInfoReader, SpvTypeArgsReader, SpvUpdateReader},
4+
core::{SpvClient, SpvInfo, SpvTypeArgs},
5+
packed::{self, SpvClientReader, SpvInfoReader, SpvUpdateReader},
66
prelude::*,
77
};
88
#[cfg(debug_assertions)]
@@ -18,13 +18,15 @@ pub(crate) fn update_client(
1818
inputs: (usize, usize),
1919
outputs: (usize, usize),
2020
script_hash: &[u8],
21+
type_args: SpvTypeArgs,
2122
) -> Result<()> {
2223
// Checks the id of the input client cell, then returns
2324
// - expected output info cell base on the input info cell,
2425
// - the tip client id.
2526
// - the expected client id, which will be the next tip client id.
2627
let (expected_info, tip_client_id, expected_client_id, flags) = {
27-
let (mut input_info, tip_client_id, expected_client_id, flags) = load_inputs(inputs)?;
28+
let (mut input_info, tip_client_id, expected_client_id, flags) =
29+
load_inputs(inputs, type_args)?;
2830
input_info.tip_client_id = expected_client_id;
2931
(input_info, tip_client_id, expected_client_id, flags)
3032
};
@@ -57,7 +59,7 @@ pub(crate) fn update_client(
5759
Ok(())
5860
}
5961

60-
fn load_inputs(inputs: (usize, usize)) -> Result<(SpvInfo, u8, u8, u8)> {
62+
fn load_inputs(inputs: (usize, usize), type_args: SpvTypeArgs) -> Result<(SpvInfo, u8, u8, u8)> {
6163
debug!("load cell data of inputs[{}]", inputs.0);
6264
let input_data_0 = hl::load_cell_data(inputs.0, Source::Input)?;
6365
debug!("load cell data of inputs[{}]", inputs.1);
@@ -90,16 +92,7 @@ fn load_inputs(inputs: (usize, usize)) -> Result<(SpvInfo, u8, u8, u8)> {
9092
let input_client_id: u8 = packed_input_client.id().into();
9193
debug!("input client id = {input_client_id}");
9294

93-
let (clients_count, flags) = {
94-
let script = hl::load_script()?;
95-
let script_args = script.args();
96-
let script_args_slice = script_args.as_reader().raw_data();
97-
let args =
98-
SpvTypeArgsReader::from_slice(script_args_slice).map_err(|_| SysError::Encoding)?;
99-
let clients_count: u8 = args.clients_count().into();
100-
let flags: u8 = args.flags().into();
101-
(clients_count, flags)
102-
};
95+
let (clients_count, flags) = (type_args.clients_count, type_args.flags);
10396
debug!("clients count: {clients_count}, flags: {flags:08b}");
10497

10598
let expected_client_id = utilities::next_client_id(input_info.tip_client_id, clients_count);

Diff for: contracts/ckb-bitcoin-spv-type-lock/src/utilities/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
mod type_id;
22

3+
use ckb_bitcoin_spv_verifier::types::{core::SpvTypeArgs, packed::SpvTypeArgsReader, prelude::*};
4+
use ckb_std::{error::SysError, high_level as hl};
5+
6+
use crate::error::Result;
7+
38
pub(crate) use self::type_id::load_then_calculate_type_id;
49

510
pub(crate) fn prev_client_id(current: u8, count: u8) -> u8 {
@@ -17,3 +22,13 @@ pub(crate) fn next_client_id(current: u8, count: u8) -> u8 {
1722
0
1823
}
1924
}
25+
26+
pub(crate) fn load_spv_type_args() -> Result<SpvTypeArgs> {
27+
let script = hl::load_script()?;
28+
let script_args = script.args();
29+
let script_args_slice = script_args.as_reader().raw_data();
30+
let args = SpvTypeArgsReader::from_slice(script_args_slice)
31+
.map_err(|_| SysError::Encoding)?
32+
.unpack();
33+
Ok(args)
34+
}

0 commit comments

Comments
 (0)