Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions soroban-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,28 @@ pub mod reexports_for_macros {
pub use ctor;
}

/// `debug_assert_in_contract!` asserts that the contract is currently executing within a
/// contract. The macro expands to an assertion when testutils are enabled or in tests,
/// otherwise it expands to nothing.
macro_rules! debug_assert_in_contract {
($env:expr $(,)?) => {{
{
#[cfg(any(test, feature = "testutils"))]
assert!(
($env).in_contract(),
"this function is not accessible outside of a contract, wrap \
the call with `env.as_contract()` to access it from a \
particular contract"
);
}
}};
}

// For internal use, use `debug_assert_in_contract!` instead.
/// Assert in contract asserts that the contract is currently executing within a
/// contract. The macro maps to code when testutils are enabled or in tests,
/// otherwise maps to nothing.
#[deprecated(note = "this macro is deprecated and will be removed in a future release")]
#[macro_export]
macro_rules! assert_in_contract {
($env:expr $(,)?) => {{
Expand Down
18 changes: 9 additions & 9 deletions soroban-sdk/src/prng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl Prng {
/// low risk tolerance, see the module-level comment.**
pub fn seed(&self, seed: Bytes) {
let env = self.env();
assert_in_contract!(env);
debug_assert_in_contract!(env);
internal::Env::prng_reseed(env, seed.into()).unwrap_infallible();
}

Expand Down Expand Up @@ -380,7 +380,7 @@ impl Prng {
impl<T> Shuffle for Vec<T> {
fn shuffle(&mut self, prng: &Prng) {
let env = prng.env();
assert_in_contract!(env);
debug_assert_in_contract!(env);
let obj = internal::Env::prng_vec_shuffle(env, self.to_object()).unwrap_infallible();
*self = unsafe { Self::unchecked_new(env.clone(), obj) };
}
Expand Down Expand Up @@ -456,7 +456,7 @@ impl Fill for u64 {
impl Gen for u64 {
fn gen(prng: &Prng) -> Self {
let env = prng.env();
assert_in_contract!(env);
debug_assert_in_contract!(env);
internal::Env::prng_u64_in_inclusive_range(env, u64::MIN, u64::MAX).unwrap_infallible()
}
}
Expand All @@ -466,7 +466,7 @@ impl GenRange for u64 {

fn gen_range(prng: &Prng, r: impl RangeBounds<Self::RangeBound>) -> Self {
let env = prng.env();
assert_in_contract!(env);
debug_assert_in_contract!(env);
let start_bound = match r.start_bound() {
Bound::Included(b) => *b,
Bound::Excluded(b) => b
Expand All @@ -493,7 +493,7 @@ impl Fill for Bytes {
/// If the length of Bytes is greater than u32::MAX in length.
fn fill(&mut self, prng: &Prng) {
let env = prng.env();
assert_in_contract!(env);
debug_assert_in_contract!(env);
let len: u32 = self.len();
let obj = internal::Env::prng_bytes_new(env, len.into()).unwrap_infallible();
*self = unsafe { Bytes::unchecked_new(env.clone(), obj) };
Expand All @@ -505,7 +505,7 @@ impl GenLen for Bytes {
/// Generates the Bytes with the Prng of the given length.
fn gen_len(prng: &Prng, len: u32) -> Self {
let env = prng.env();
assert_in_contract!(env);
debug_assert_in_contract!(env);
let obj = internal::Env::prng_bytes_new(env, len.into()).unwrap_infallible();
unsafe { Bytes::unchecked_new(env.clone(), obj) }
}
Expand All @@ -531,7 +531,7 @@ impl<const N: usize> Gen for BytesN<N> {
/// If the length of BytesN is greater than u32::MAX in length.
fn gen(prng: &Prng) -> Self {
let env = prng.env();
assert_in_contract!(env);
debug_assert_in_contract!(env);
let len: u32 = N.try_into().unwrap_optimized();
let obj = internal::Env::prng_bytes_new(env, len.into()).unwrap_infallible();
unsafe { BytesN::unchecked_new(env.clone(), obj) }
Expand All @@ -546,7 +546,7 @@ impl Fill for [u8] {
/// If the slice is greater than u32::MAX in length.
fn fill(&mut self, prng: &Prng) {
let env = prng.env();
assert_in_contract!(env);
debug_assert_in_contract!(env);
let len: u32 = self.len().try_into().unwrap_optimized();
let bytes: Bytes = internal::Env::prng_bytes_new(env, len.into())
.unwrap_infallible()
Expand All @@ -563,7 +563,7 @@ impl<const N: usize> Fill for [u8; N] {
/// If the array is greater than u32::MAX in length.
fn fill(&mut self, prng: &Prng) {
let env = prng.env();
assert_in_contract!(env);
debug_assert_in_contract!(env);
let len: u32 = N.try_into().unwrap_optimized();
let bytes: Bytes = internal::Env::prng_bytes_new(env, len.into())
.unwrap_infallible()
Expand Down
6 changes: 3 additions & 3 deletions soroban-sdk/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl Storage {
/// This should be used for data that requires persistency, such as token
/// balances, user properties etc.
pub fn persistent(&self) -> Persistent {
assert_in_contract!(self.env);
debug_assert_in_contract!(self.env);

Persistent {
storage: self.clone(),
Expand All @@ -105,7 +105,7 @@ impl Storage {
/// This should be used for data that needs to only exist for a limited
/// period of time, such as oracle data, claimable balances, offer, etc.
pub fn temporary(&self) -> Temporary {
assert_in_contract!(self.env);
debug_assert_in_contract!(self.env);

Temporary {
storage: self.clone(),
Expand Down Expand Up @@ -138,7 +138,7 @@ impl Storage {
/// operates on etc. Do not use this with any data that can scale in
/// unbounded fashion (such as user balances).
pub fn instance(&self) -> Instance {
assert_in_contract!(self.env);
debug_assert_in_contract!(self.env);

Instance {
storage: self.clone(),
Expand Down
Loading