Skip to content

Commit

Permalink
Adds support for 'caller_is_root' (#2332)
Browse files Browse the repository at this point in the history
* Adds support for 'caller_is_root'

* Adds PR to 'CHANGELOG.md'

* Tested CI locally

* Updates Cargo nightly

* Revert "Updates Cargo nightly"

This reverts commit c70c62d.

* Revert "Tested CI locally"

This reverts commit 0e37b8e.

* Close delimiter

* Apply `cargo fmt`

* Move changelog entry to unreleased section

* Implement `caller_is_root` on-chain

* Account for `call_is_root() -> u32` return type

* Panic when `u32 -> bool` not possible

---------

Co-authored-by: Michael Mueller <mich@elmueller.net>
  • Loading branch information
olahfemi and cmichi authored Dec 5, 2024
1 parent 92a62a7 commit 9066a03
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 0 deletions.
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

0 comments on commit 9066a03

Please sign in to comment.