Unverified Commit 2310400c authored by Michael Müller's avatar Michael Müller Committed by GitHub
Browse files

Implement `seal_rent_status` (#798)

* Implement `seal_rent_status`

* Add `at_refcount: Option<u32>` param

* Fix param

* Improve `at_refcount` comment

* Replace `u32` with `core::num::NonZeroU32`
parent e9dc5420
Pipeline #140940 failed with stages
in 7 minutes and 4 seconds
......@@ -34,7 +34,10 @@ use crate::{
HashOutput,
},
topics::Topics,
types::RentParams,
types::{
RentParams,
RentStatus,
},
Environment,
Result,
};
......@@ -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
......
......@@ -23,7 +23,10 @@ use crate::{
HashOutput,
},
topics::Topics,
types::RentParams,
types::{
RentParams,
RentStatus,
},
Environment,
Result,
};
......@@ -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
......
......@@ -35,6 +35,7 @@ use crate::{
EnvBackend,
Environment,
RentParams,
RentStatus,
Result,
ReturnFlags,
TypedEnvBackend,
......@@ -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)
}
......
......@@ -32,7 +32,10 @@ use crate::{
Sha2x256,
},
topics::Topics,
types::RentParams,
types::{
RentParams,
RentStatus,
},
EnvBackend,
Environment,
Error,
......@@ -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)
......
......@@ -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>,
);
}
}
......@@ -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;
{
......
......@@ -36,7 +36,10 @@ use crate::{
Topics,
TopicsBuilderBackend,
},
types::RentParams,
types::{
RentParams,
RentStatus,
},
Clear,
EnvBackend,
Environment,
......@@ -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, ()>,
......
......@@ -99,5 +99,6 @@ pub use self::{
NoChainExtension,
Perbill,
RentParams,
RentStatus,
},
};
......@@ -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<()>,
}
......@@ -25,6 +25,7 @@ use ink_env::{
},
Environment,
RentParams,
RentStatus,
Result,
};
use ink_primitives::Key;
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment