Skip to content

Commit

Permalink
feat(cell): add CellSlice::new_allow_pruned instead of unsafe
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexagon committed Nov 21, 2024
1 parent 799ca81 commit c8d8d8a
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 40 deletions.
17 changes: 7 additions & 10 deletions benches/mine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,16 @@ fn do_mine(code: &Cell, factory_addr: &StdAddr, recipient: &StdAddr, reward: u12

let mut data = RawDict::<64>::new();

unsafe {
data.set_ext(KEY_ZERO.as_slice_unchecked(), &HashBytes::ZERO, cx)
.unwrap();
data.set_ext(KEY_ZERO.as_slice_allow_pruned(), &HashBytes::ZERO, cx)
.unwrap();

let airdrop_data_child = CellBuilder::build_from_ext((recipient, reward), cx).unwrap();
let airdrop_data =
CellBuilder::build_from_ext((factory_addr, airdrop_data_child), cx).unwrap();
let airdrop_data_child = CellBuilder::build_from_ext((recipient, reward), cx).unwrap();
let airdrop_data = CellBuilder::build_from_ext((factory_addr, airdrop_data_child), cx).unwrap();

data.set_ext(KEY_TWO.as_slice_unchecked(), &airdrop_data, cx)
.unwrap();
}
data.set_ext(KEY_TWO.as_slice_allow_pruned(), &airdrop_data, cx)
.unwrap();

let nonce_key = unsafe { KEY_ONE.as_slice_unchecked() };
let nonce_key = KEY_ONE.as_slice_allow_pruned();

let mut nonce = 0;
loop {
Expand Down
6 changes: 2 additions & 4 deletions src/cell/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,16 +340,14 @@ impl CellBuilder {
///
/// NOTE: intermediate cell hash is undefined.
pub fn as_data_slice(&self) -> CellSlice<'_> {
// SAFETY: we interpret cell builder data as ordinary cell
unsafe { CellSlice::new_unchecked(IntermediateDataCell::wrap(self)) }
CellSlice::new_allow_pruned(IntermediateDataCell::wrap(self))
}

/// Returns a slice which contains builder data and references.
///
/// NOTE: intermediate cell hash is undefined.
pub fn as_full_slice(&self) -> CellSlice<'_> {
// SAFETY: we interpret cell builder data as ordinary cell
unsafe { CellSlice::new_unchecked(IntermediateFullCell::wrap(self)) }
CellSlice::new_allow_pruned(IntermediateFullCell::wrap(self))
}

/// Returns an underlying cell data.
Expand Down
19 changes: 14 additions & 5 deletions src/cell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,24 @@ impl DynCell {
CellSlice::new(self)
}

/// Returns this cell as a cell slice.
///
/// Loads cell as is.
#[inline]
pub fn as_slice_allow_pruned(&'_ self) -> CellSlice<'_> {
CellSlice::new_allow_pruned(self)
}

/// Returns this cell as a cell slice.
///
/// # Safety
///
/// The following must be true:
/// - cell is not pruned
#[inline]
#[deprecated = "use `{Self}::as_slice_allow_pruned` instead"]
pub unsafe fn as_slice_unchecked(&'_ self) -> CellSlice<'_> {
CellSlice::new_unchecked(self)
CellSlice::new_allow_pruned(self)
}

/// Recursively computes the count of distinct cells returning
Expand Down Expand Up @@ -1768,7 +1777,7 @@ mod tests {
assert_eq!(slice.size_bits(), 8 + 32 + 1);
assert_eq!(slice.load_u8().unwrap(), 0x12);
assert_eq!(slice.load_u32().unwrap(), 123);
assert_eq!(slice.load_bit().unwrap(), true);
assert!(slice.load_bit().unwrap());
assert!(slice.is_empty());
}
assert_eq!(
Expand All @@ -1790,7 +1799,7 @@ mod tests {
assert_eq!(slice.load_u8().unwrap(), 0x34);
assert_eq!(slice.load_u32().unwrap(), 123);
assert_eq!(slice.load_u32().unwrap(), 456);
assert_eq!(slice.load_bit().unwrap(), true);
assert!(slice.load_bit().unwrap());
assert!(slice.is_empty());
}
assert_eq!(
Expand All @@ -1812,8 +1821,8 @@ mod tests {
assert_eq!(slice.load_u8().unwrap(), 0x56);
assert_eq!(slice.load_u32().unwrap(), 123);
assert_eq!(slice.load_u32().unwrap(), 0);
assert_eq!(slice.load_bit().unwrap(), true);
assert_eq!(slice.load_bit().unwrap(), true);
assert!(slice.load_bit().unwrap());
assert!(slice.load_bit().unwrap());
assert!(slice.is_empty());
}
assert_eq!(
Expand Down
10 changes: 2 additions & 8 deletions src/cell/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,7 @@ pub struct CellSlice<'a> {
impl Default for CellSlice<'_> {
#[inline]
fn default() -> Self {
// SAFETY: empty cell is an ordinary cell
unsafe { Cell::empty_cell_ref().as_slice_unchecked() }
Cell::empty_cell_ref().as_slice_allow_pruned()
}
}

Expand Down Expand Up @@ -456,12 +455,7 @@ impl<'a> CellSlice<'a> {
}

/// Constructs a new cell slice from the specified cell.
///
/// # Safety
///
/// The following must be true:
/// - cell is not pruned
pub unsafe fn new_unchecked(cell: &'a DynCell) -> Self {
pub fn new_allow_pruned(cell: &'a DynCell) -> Self {
Self {
range: CellSliceRange::full(cell),
cell,
Expand Down
13 changes: 5 additions & 8 deletions src/dict/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,11 +427,10 @@ impl Segment<'_> {
let value = ok!(context.load_cell(value, LoadMode::Resolve));

// Load parent label
let pfx = {
// SAFETY: `self.data` was already checked for pruned branch access.
let mut parent = unsafe { self.data.as_slice_unchecked() };
ok!(read_label(&mut parent, prev_key_bit_len))
};
let pfx = ok!(read_label(
&mut self.data.as_slice_allow_pruned(),
prev_key_bit_len
));

// Load the opposite branch
let mut opposite = match self.data.reference(1 - index) {
Expand Down Expand Up @@ -602,9 +601,7 @@ fn read_hml_same<'a>(label: &mut CellSlice<'a>, bits_for_len: u16) -> Result<Cel
};
let len = ok!(label.load_uint(bits_for_len)) as u16;

// SAFETY: cell is a static ordinary cell
let slice = unsafe { cell.as_slice_unchecked() };
Ok(slice.get_prefix(len, 0))
Ok(cell.as_slice_allow_pruned().get_prefix(len, 0))
}

/// Which branch to take when traversing the tree.
Expand Down
9 changes: 4 additions & 5 deletions src/dict/ops/remove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,10 @@ pub fn dict_remove_bound_owned(
};

// Load parent label
let pfx = {
// SAFETY: `last.data` was already checked for pruned branch access.
let mut parent = unsafe { last.data.as_slice_unchecked() };
ok!(read_label(&mut parent, prev_key_bit_len))
};
let pfx = ok!(read_label(
&mut last.data.as_slice_allow_pruned(),
prev_key_bit_len
));

// Load the opposite branch
let mut opposite = match last.data.reference(1 - index) {
Expand Down

0 comments on commit c8d8d8a

Please sign in to comment.