Skip to content

Commit

Permalink
Implement seal_rent_status (#798)
Browse files Browse the repository at this point in the history
* Implement `seal_rent_status`

* Add `at_refcount: Option<u32>` param

* Fix param

* Improve `at_refcount` comment

* Replace `u32` with `core::num::NonZeroU32`
  • Loading branch information
cmichi committed May 27, 2021
1 parent e9dc542 commit 2310400
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 4 deletions.
27 changes: 26 additions & 1 deletion crates/env/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ use crate::{
HashOutput,
},
topics::Topics,
types::RentParams,
types::{
RentParams,
RentStatus,
},
Environment,
Result,
};
Expand Down Expand Up @@ -170,6 +173,28 @@ where
})
}

/// Returns information about the required deposit and resulting rent.
///
/// # Parameters
///
/// - `at_refcount`: The refcount assumed for the returned `custom_refcount_*` fields.
/// If `None` is supplied the `custom_refcount_*` fields will also be `None`.
///
/// The `current_*` fields of `RentStatus` do **not** consider changes to the code's
/// refcount made during the currently running call.
///
/// # Errors
///
/// If the returned value cannot be properly decoded.
pub fn rent_status<T>(at_refcount: Option<core::num::NonZeroU32>) -> Result<RentStatus<T>>
where
T: Environment,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::rent_status::<T>(instance, at_refcount)
})
}

/// Returns the current block number.
///
/// # Errors
Expand Down
15 changes: 14 additions & 1 deletion crates/env/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ use crate::{
HashOutput,
},
topics::Topics,
types::RentParams,
types::{
RentParams,
RentStatus,
},
Environment,
Result,
};
Expand Down Expand Up @@ -230,6 +233,16 @@ pub trait TypedEnvBackend: EnvBackend {
/// For more details visit: [`RentParams`][`crate::RentParams`]
fn rent_params<T: Environment>(&mut self) -> Result<RentParams<T>>;

/// Returns information about the required deposit and resulting rent.
///
/// # Note
///
/// For more details visit: [`RentStatus`][`crate::RentStatus`]
fn rent_status<T: Environment>(
&mut self,
at_refcount: Option<core::num::NonZeroU32>,
) -> Result<RentStatus<T>>;

/// Returns the current block number.
///
/// # Note
Expand Down
11 changes: 11 additions & 0 deletions crates/env/src/engine/experimental_off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::{
EnvBackend,
Environment,
RentParams,
RentStatus,
Result,
ReturnFlags,
TypedEnvBackend,
Expand Down Expand Up @@ -309,6 +310,16 @@ impl TypedEnvBackend for EnvInstance {
unimplemented!("off-chain environment does not support rent params")
}

fn rent_status<T>(
&mut self,
_at_refcount: Option<core::num::NonZeroU32>,
) -> Result<RentStatus<T>>
where
T: Environment,
{
unimplemented!("off-chain environment does not support rent status")
}

fn block_number<T: Environment>(&mut self) -> Result<T::BlockNumber> {
self.get_property::<T::BlockNumber>(Engine::block_number)
}
Expand Down
15 changes: 14 additions & 1 deletion crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ use crate::{
Sha2x256,
},
topics::Topics,
types::RentParams,
types::{
RentParams,
RentStatus,
},
EnvBackend,
Environment,
Error,
Expand Down Expand Up @@ -391,6 +394,16 @@ impl TypedEnvBackend for EnvInstance {
})
}

fn rent_status<T>(
&mut self,
_at_refcount: Option<core::num::NonZeroU32>,
) -> Result<RentStatus<T>>
where
T: Environment,
{
unimplemented!("off-chain environment does not support rent status")
}

fn block_number<T: Environment>(&mut self) -> Result<T::BlockNumber> {
self.current_block()
.expect(UNINITIALIZED_EXEC_CONTEXT)
Expand Down
20 changes: 20 additions & 0 deletions crates/env/src/engine/on_chain/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,12 @@ mod sys {
output_ptr: Ptr32Mut<[u8]>,
output_len_ptr: Ptr32Mut<u32>,
);

pub fn seal_rent_status(
at_refcount: u32,
output_ptr: Ptr32Mut<[u8]>,
output_len_ptr: Ptr32Mut<u32>,
);
}
}

Expand Down Expand Up @@ -610,6 +616,20 @@ pub fn rent_params(output: &mut &mut [u8]) {
extract_from_slice(output, output_len as usize);
}

pub fn rent_status(at_refcount: Option<core::num::NonZeroU32>, output: &mut &mut [u8]) {
let mut output_len = output.len() as u32;
{
unsafe {
sys::seal_rent_status(
at_refcount.map_or(0, |rc| rc.get()),
Ptr32Mut::from_slice(output),
Ptr32Mut::from_ref(&mut output_len),
)
};
}
extract_from_slice(output, output_len as usize);
}

pub fn random(subject: &[u8], output: &mut &mut [u8]) {
let mut output_len = output.len() as u32;
{
Expand Down
17 changes: 16 additions & 1 deletion crates/env/src/engine/on_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ use crate::{
Topics,
TopicsBuilderBackend,
},
types::RentParams,
types::{
RentParams,
RentStatus,
},
Clear,
EnvBackend,
Environment,
Expand Down Expand Up @@ -363,6 +366,18 @@ impl TypedEnvBackend for EnvInstance {
self.get_property::<RentParams<T>>(ext::rent_params)
}

fn rent_status<T>(
&mut self,
at_refcount: Option<core::num::NonZeroU32>,
) -> Result<RentStatus<T>>
where
T: Environment,
{
let output = &mut self.scoped_buffer().take_rest();
ext::rent_status(at_refcount, output);
scale::Decode::decode(&mut &output[..]).map_err(Into::into)
}

fn invoke_contract<T, Args>(
&mut self,
call_params: &CallParams<T, Args, ()>,
Expand Down
1 change: 1 addition & 0 deletions crates/env/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,6 @@ pub use self::{
NoChainExtension,
Perbill,
RentParams,
RentStatus,
},
};
34 changes: 34 additions & 0 deletions crates/env/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,37 @@ pub struct RentParams<T: Environment> {
/// Reserved for backwards compatible changes to this data structure.
pub _reserved: Option<()>,
}

/// Information about the required deposit and resulting rent.
///
/// The easiest way to guarantee that a contract stays alive is to assert that
/// `max_rent == 0` at the **end** of a contract's execution.
///
/// # Note
///
/// The `current_*` fields do **not** consider changes to the code's refcount made during
/// the currently running call.
#[derive(scale::Decode)]
#[cfg_attr(test, derive(Debug, PartialEq))]
pub struct RentStatus<T: Environment> {
/// Required deposit assuming that this contract is the only user of its code.
pub max_deposit: T::Balance,

/// Required deposit assuming the code's current refcount.
pub current_deposit: T::Balance,

/// Required deposit assuming the specified refcount (`None` if `0` is supplied).
pub custom_refcount_deposit: Option<T::Balance>,

/// Rent that is paid assuming that the contract is the only user of its code.
pub max_rent: T::Balance,

/// Rent that is paid given the code's current refcount.
pub current_rent: T::Balance,

/// Rent that is paid assuming the specified refcount (`None` if `0` is supplied).
pub custom_refcount_rent: Option<T::Balance>,

/// Reserved for backwards compatible changes to this data structure.
pub _reserved: Option<()>,
}
22 changes: 22 additions & 0 deletions crates/lang/src/env_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use ink_env::{
},
Environment,
RentParams,
RentStatus,
Result,
};
use ink_primitives::Key;
Expand Down Expand Up @@ -190,6 +191,27 @@ where
ink_env::rent_params::<T>().expect("couldn't decode contract rent params")
}

/// Returns information about the required deposit and resulting rent.
///
/// # Parameters
///
/// - `at_refcount`: The refcount assumed for the returned `custom_refcount_*` fields.
/// If `None` is supplied the `custom_refcount_*` fields will also be `None`.
///
/// The `current_*` fields of `RentStatus` do **not** consider changes to the code's
/// refcount made during the currently running call.
///
/// # Note
///
/// For more details visit: [`ink_env::RentStatus`]
pub fn rent_status(
self,
at_refcount: Option<core::num::NonZeroU32>,
) -> RentStatus<T> {
ink_env::rent_status::<T>(at_refcount)
.expect("couldn't decode contract rent params")
}

/// Returns the current block number.
///
/// # Note
Expand Down

0 comments on commit 2310400

Please sign in to comment.