Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for 'caller_is_root' #2332

Merged
merged 13 commits into from
Dec 5, 2024
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Changed
- Restrict which `cfg` attributes can be used ‒ [#2313](https://github.com/use-ink/ink/pull/2313)

## Added
- Support for `caller_is_root` - [#2332] (https://github.com/use-ink/ink/pull/2332)

## Fixed
- [E2E] Have port parsing handle comma-separated list ‒ [#2336](https://github.com/use-ink/ink/pull/2336)

Expand Down
20 changes: 20 additions & 0 deletions crates/env/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,26 @@ where
})
}

/// Checks whether the caller of the current contract is root.
///
/// Note that only the origin of the call stack can be root. Hence this function returning
/// `true` implies that the contract is being called by the origin.
///
/// A return value of `true` indicates that this contract is being called by a root
/// origin, and `false` indicates that the caller is a signed origin.
///
/// # Errors
///
/// If the returned value cannot be properly decoded.
pub fn caller_is_root<E>() -> bool
where
E: Environment,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::caller_is_root::<E>(instance)
})
}

/// Replace the contract code at the specified address with new code.
///
/// # Note
Expand Down
9 changes: 9 additions & 0 deletions crates/env/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,15 @@ pub trait TypedEnvBackend: EnvBackend {
where
E: Environment;

/// Checks whether the caller of the current contract is root.
///
/// # Note
///
/// For more details visit: [`caller_is_root`][`crate::caller_is_root`]
fn caller_is_root<E>(&mut self) -> bool
where
E: Environment;

/// Retrieves the code hash of the contract at the given `account` id.
///
/// # Note
Expand Down
7 changes: 7 additions & 0 deletions crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,13 @@ impl TypedEnvBackend for EnvInstance {
unimplemented!("off-chain environment does not support cross-contract calls")
}

fn caller_is_root<E>(&mut self) -> bool
where
E: Environment,
{
unimplemented!("off-chain environment does not support `caller_is_root`")
}

fn code_hash<E>(&mut self, _account: &E::AccountId) -> Result<E::Hash>
where
E: Environment,
Expand Down
14 changes: 14 additions & 0 deletions crates/env/src/engine/on_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,20 @@ impl TypedEnvBackend for EnvInstance {
ext::caller_is_origin()
}

fn caller_is_root<E>(&mut self) -> bool
where
E: Environment,
{
// `ext::caller_is_root()` currently returns `u32`.
// See https://github.com/paritytech/polkadot-sdk/issues/6767 for more details.
let ret = ext::caller_is_root();
match ret {
0u32 => false,
1u32 => true,
_ => panic!("Invalid value for bool conversion: {}", ret),
}
}

fn code_hash<E>(&mut self, account_id: &E::AccountId) -> Result<E::Hash>
where
E: Environment,
Expand Down
31 changes: 31 additions & 0 deletions crates/ink/src/env_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,37 @@ where
ink_env::caller_is_origin::<E>()
}

/// Checks whether the caller of the current contract is root.
///
/// # Example
///
/// ```
/// # #[ink::contract]
/// # pub mod my_contract {
/// # #[ink(storage)]
/// # pub struct MyContract { }
/// #
/// # impl MyContract {
/// # #[ink(constructor)]
/// # pub fn new() -> Self {
/// # Self {}
/// # }
/// #
/// #[ink(message)]
/// pub fn caller_is_root(&mut self) -> bool {
/// self.env().caller_is_root()
/// }
/// # }
/// # }
/// ```
///
/// # Note
///
/// For more details visit: [`ink_env::caller_is_root`]
pub fn caller_is_root(self) -> bool {
ink_env::caller_is_root::<E>()
}

/// Returns the code hash of the contract at the given `account` id.
///
/// # Example
Expand Down
Loading