Skip to content

Commit

Permalink
feat(models): add support for base64-encoded StdAddr
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexagon committed Sep 20, 2024
1 parent 14066a4 commit 3e7dcf6
Show file tree
Hide file tree
Showing 10 changed files with 367 additions and 26 deletions.
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ harness = false
members = ["proc"]

[dependencies]
ahash = "0.8"
ahash = "0.8.11"
anyhow = { version = "1.0", optional = true }
base64 = { version = "0.22", optional = true }
bitflags = "2.3"
blake3 = { version = "1.5", optional = true }
bytes = { version = "1.4", optional = true }
crc32c = "0.6"
ed25519-dalek = { version = "2.0", optional = true }
crc32c = "0.6.8"
ed25519-dalek = { version = "2.1.1", optional = true }
everscale-crypto = { version = "0.2", features = ["tl-proto"], optional = true }
hex = "0.4"
num-bigint = { version = "0.4", optional = true }
Expand Down Expand Up @@ -112,3 +112,6 @@ opt-level = 1

[package.metadata.docs.rs]
features = ["base64", "serde", "models", "sync", "stats", "abi"]

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
4 changes: 3 additions & 1 deletion benches/mine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ fn mine_address(c: &mut Criterion) {
group.bench_with_input(BenchmarkId::from_parameter(nonce), &nonce, move |b, _| {
b.iter(|| {
thread_local! {
static CODE_CELL: std::cell::UnsafeCell<Option<Cell>> = std::cell::UnsafeCell::new(None);
static CODE_CELL: std::cell::UnsafeCell<Option<Cell>> = const {
std::cell::UnsafeCell::new(None)
};
}

CODE_CELL.with(|code_cell| {
Expand Down
7 changes: 7 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@ libfuzzer-sys = "0.4"

[dependencies.everscale-types]
path = ".."
features = ["base64"]

# Prevent this from interfering with workspaces
[workspace]
members = ["."]

[[bin]]
name = "base64_addr"
path = "fuzz_targets/base64_addr.rs"
test = false
doc = false

[[bin]]
name = "boc_decode"
path = "fuzz_targets/boc_decode.rs"
Expand Down
14 changes: 14 additions & 0 deletions fuzz/fuzz_targets/base64_addr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![no_main]
use libfuzzer_sys::fuzz_target;

use everscale_types::models::{StdAddr, StdAddrFormat};
use libfuzzer_sys::Corpus;

fuzz_target!(|data: &[u8]| -> Corpus {
if let Ok(s) = std::str::from_utf8(data) {
if StdAddr::from_str_ext(s, StdAddrFormat::any()).is_ok() {
return Corpus::Keep;
}
}
Corpus::Reject
});
4 changes: 2 additions & 2 deletions src/dict/aug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ where
///
/// [`values`]: Dict::values
/// [`raw_values`]: Dict::raw_values
pub fn iter<'a>(&'a self) -> AugIter<'_, K, A, V>
pub fn iter<'a>(&'a self) -> AugIter<'a, K, A, V>
where
V: Load<'a>,
{
Expand Down Expand Up @@ -1017,7 +1017,7 @@ mod tests {
(4258889371, SomeValue(4956495), 3256452222),
],
] {
let result = AugDict::<u32, SomeValue, u32>::try_from_sorted_slice(&entries).unwrap();
let result = AugDict::<u32, SomeValue, u32>::try_from_sorted_slice(entries).unwrap();

let mut dict = AugDict::<u32, SomeValue, u32>::new();
for (k, a, v) in entries {
Expand Down
4 changes: 2 additions & 2 deletions src/dict/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ where
///
/// [`values`]: Dict::values
/// [`raw_values`]: Dict::raw_values
pub fn iter<'a>(&'a self) -> Iter<'_, K, V>
pub fn iter<'a>(&'a self) -> Iter<'a, K, V>
where
V: Load<'a>,
{
Expand All @@ -478,7 +478,7 @@ where
///
/// In the current implementation, iterating over dictionary builds a key
/// for each element.
pub fn iter_union<'a>(&'a self, other: &'a Self) -> UnionIter<'_, K, V>
pub fn iter_union<'a>(&'a self, other: &'a Self) -> UnionIter<'a, K, V>
where
V: Load<'a>,
{
Expand Down
3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ pub enum ParseAddrError {
/// Too many address parts.
#[error("unexpected address part")]
UnexpectedPart,
/// Unexpected or invalid address format.
#[error("invalid address format")]
BadFormat,
}

/// Error type for block id parsing related errors.
Expand Down
36 changes: 18 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@
//! ## `Cell` vs `CellSlice` vs `CellBuilder`
//!
//! - [`Cell`] is an immutable tree and provides only basic methods for accessing
//! nodes and some meta info.
//! nodes and some meta info.
//!
//! - [`CellSlice`] is a read-only view for a part of some cell. It can only
//! be obtained from an existing cell. A cell contains **up to 1023 bits** and
//! **up to 4 references**. Minimal data unit is bit, so a cell slice is similar
//! to a couple of ranges (bit range and refs range).
//! be obtained from an existing cell. A cell contains **up to 1023 bits** and
//! **up to 4 references**. Minimal data unit is bit, so a cell slice is similar
//! to a couple of ranges (bit range and refs range).
//!
//! - [`CellBuilder`] is used to create a new cell. It is used as an append-only
//! data structure and is the only way to create a new cell with the provided data.
//! Cell creation depends on a context (e.g. message creation in a wallet or a
//! TVM execution with gas tracking), so [`CellBuilder::build_ext`] accepts
//! a [`CellContext`] parameter which can be used to track and modify cells creation.
//! data structure and is the only way to create a new cell with the provided data.
//! Cell creation depends on a context (e.g. message creation in a wallet or a
//! TVM execution with gas tracking), so [`CellBuilder::build_ext`] accepts
//! a [`CellContext`] parameter which can be used to track and modify cells creation.
//!
//! ## BOC
//!
Expand All @@ -36,15 +36,15 @@
//! ### Merkle stuff
//!
//! - Pruned branch is a "building block" of merkle structures. A single pruned branch
//! cell replaces a whole subtree and contains just the hash of its root cell hash.
//! cell replaces a whole subtree and contains just the hash of its root cell hash.
//!
//! - [`MerkleProof`] contains a subset of original tree of cells. In most cases
//! it is created from [`UsageTree`] of some visited cells. Merkle proof is used
//! to proof that something was presented in the origin tree and provide some additional
//! context.
//! it is created from [`UsageTree`] of some visited cells. Merkle proof is used
//! to proof that something was presented in the origin tree and provide some additional
//! context.
//!
//! - [`MerkleUpdate`] describes a difference between two trees of cells. It can be
//! applied to old cell to create a new cell.
//! applied to old cell to create a new cell.
//!
//! ### Numeric stuff
//!
Expand All @@ -69,15 +69,15 @@
//! All models implement [`Load`] and [`Store`] traits for conversion from/to cells.
//!
//! - [`RawDict`] constrains only key size in bits. It is useful when a dictionary
//! can contain multiple types of values.
//! can contain multiple types of values.
//!
//! - [`Dict`] is a strongly typed version of definition and is a preferable way
//! of working with this data structure. Key type must implement [`DictKey`] trait,
//! which is implemented for numbers and addresses.
//! of working with this data structure. Key type must implement [`DictKey`] trait,
//! which is implemented for numbers and addresses.
//!
//! - [`AugDict`] adds additional values for all nodes. You can use it to quickly
//! access a subtotal of values for each subtree.
//! NOTE: this type is partially implemented due to its complexity.
//! access a subtotal of values for each subtree.
//! NOTE: this type is partially implemented due to its complexity.
//!
//! ## Supported Rust Versions
//!
Expand Down
Loading

0 comments on commit 3e7dcf6

Please sign in to comment.