[contracts] Add docs generator for the contracts API to the #[define_env] macro (#13032)

* macro to expand traits for host functions documentation

* other way: same Doc trait in seal modules

* added docs for macro, and remove `doc` attribute

* fmt

* Apply suggestions from code review

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* make docs to be generated into re-exported `api_doc` module; fix
unrelated elder docs;

* make it compile without `doc` attr passed to macro

* make alias functions indicated explicitly in docs

* tidy up docs

* refactored a bit

* macro to auto-add doc warning for unstable functions

* invoke macro with no doc generation by default

* addressed review comments

* hide api_doc module behind cfg(doc)

Co-authored-by: Alexander Theißen <alex.theissen@me.com>
This commit is contained in:
Sasha Gryaznov
2023-01-06 01:22:43 +02:00
committed by GitHub
parent 876fccc0e5
commit 628efddce1
5 changed files with 242 additions and 116 deletions
+95 -96
View File
@@ -52,7 +52,7 @@ pub trait Environment<HostState> {
/// Type of a storage key.
#[allow(dead_code)]
enum KeyType {
/// Deprecated fix sized key [0;32].
/// Deprecated fix sized key `[u8;32]`.
Fix,
/// Variable sized key used in transparent hashing,
/// cannot be larger than MaxStorageKeyLen.
@@ -996,14 +996,14 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> {
// Any input that leads to a out of bound error (reading or writing) or failing to decode
// data passed to the supervisor will lead to a trap. This is not documented explicitly
// for every function.
#[define_env]
#[define_env(doc)]
pub mod env {
/// Account for used gas. Traps if gas used is greater than gas limit.
///
/// NOTE: This is a implementation defined call and is NOT a part of the public API.
/// This call is supposed to be called only by instrumentation injected code.
///
/// - amount: How much gas is used.
/// - `amount`: How much gas is used.
fn gas(ctx: _, _memory: _, amount: u64) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::MeteringBlock(amount))?;
Ok(())
@@ -1011,8 +1011,8 @@ pub mod env {
/// Set the value at the given key in the contract storage.
///
/// Equivalent to the newer version of `seal_set_storage` with the exception of the return
/// type. Still a valid thing to call when not interested in the return value.
/// Equivalent to the newer version [`super::seal1::Api::set_storage`] with the exception of the
/// return type. Still a valid thing to call when not interested in the return value.
#[prefixed_alias]
fn set_storage(
ctx: _,
@@ -1085,8 +1085,8 @@ pub mod env {
/// Clear the value at the given key in the contract storage.
///
/// Equivalent to the newer version of `seal_clear_storage` with the exception of the return
/// type. Still a valid thing to call when not interested in the return value.
/// Equivalent to the newer version [`super::seal1::Api::clear_storage`] with the exception of
/// the return type. Still a valid thing to call when not interested in the return value.
#[prefixed_alias]
fn clear_storage(ctx: _, memory: _, key_ptr: u32) -> Result<(), TrapReason> {
ctx.clear_storage(memory, KeyType::Fix, key_ptr).map(|_| ())
@@ -1152,7 +1152,7 @@ pub mod env {
///
/// # Errors
///
/// `ReturnCode::KeyNotFound`
/// - `ReturnCode::KeyNotFound`
#[version(1)]
#[prefixed_alias]
fn get_storage(
@@ -1215,7 +1215,7 @@ pub mod env {
///
/// # Errors
///
/// `ReturnCode::KeyNotFound`
/// - `ReturnCode::KeyNotFound`
#[prefixed_alias]
fn take_storage(
ctx: _,
@@ -1245,16 +1245,16 @@ pub mod env {
///
/// # Parameters
///
/// - account_ptr: a pointer to the address of the beneficiary account Should be decodable as an
/// `T::AccountId`. Traps otherwise.
/// - account_len: length of the address buffer.
/// - value_ptr: a pointer to the buffer with value, how much value to send. Should be decodable
/// as a `T::Balance`. Traps otherwise.
/// - value_len: length of the value buffer.
/// - `account_ptr`: a pointer to the address of the beneficiary account Should be decodable as
/// an `T::AccountId`. Traps otherwise.
/// - `account_len`: length of the address buffer.
/// - `value_ptr`: a pointer to the buffer with value, how much value to send. Should be
/// decodable as a `T::Balance`. Traps otherwise.
/// - `value_len`: length of the value buffer.
///
/// # Errors
///
/// `ReturnCode::TransferFailed`
/// - `ReturnCode::TransferFailed`
#[prefixed_alias]
fn transfer(
ctx: _,
@@ -1288,8 +1288,9 @@ pub mod env {
/// # Note
///
/// The values `_callee_len` and `_value_len` are ignored because the encoded sizes
/// of those types are fixed through `[`MaxEncodedLen`]. The fields exist for backwards
/// compatibility. Consider switching to the newest version of this function.
/// of those types are fixed through
/// [`codec::MaxEncodedLen`]. The fields exist
/// for backwards compatibility. Consider switching to the newest version of this function.
#[prefixed_alias]
fn call(
ctx: _,
@@ -1323,16 +1324,16 @@ pub mod env {
///
/// # Parameters
///
/// - flags: See [`CallFlags`] for a documenation of the supported flags.
/// - callee_ptr: a pointer to the address of the callee contract. Should be decodable as an
/// - `flags`: See `crate::wasm::runtime::CallFlags` for a documenation of the supported flags.
/// - `callee_ptr`: a pointer to the address of the callee contract. Should be decodable as an
/// `T::AccountId`. Traps otherwise.
/// - gas: how much gas to devote to the execution.
/// - value_ptr: a pointer to the buffer with value, how much value to send. Should be decodable
/// as a `T::Balance`. Traps otherwise.
/// - input_data_ptr: a pointer to a buffer to be used as input data to the callee.
/// - input_data_len: length of the input data buffer.
/// - output_ptr: a pointer where the output buffer is copied to.
/// - output_len_ptr: in-out pointer to where the length of the buffer is read from and the
/// - `gas`: how much gas to devote to the execution.
/// - `value_ptr`: a pointer to the buffer with value, how much value to send. Should be
/// decodable as a `T::Balance`. Traps otherwise.
/// - `input_data_ptr`: a pointer to a buffer to be used as input data to the callee.
/// - `input_data_len`: length of the input data buffer.
/// - `output_ptr`: a pointer where the output buffer is copied to.
/// - `output_len_ptr`: in-out pointer to where the length of the buffer is read from and the
/// actual length is written to.
///
/// # Errors
@@ -1340,10 +1341,10 @@ pub mod env {
/// An error means that the call wasn't successful output buffer is returned unless
/// stated otherwise.
///
/// `ReturnCode::CalleeReverted`: Output buffer is returned.
/// `ReturnCode::CalleeTrapped`
/// `ReturnCode::TransferFailed`
/// `ReturnCode::NotCallable`
/// - `ReturnCode::CalleeReverted`: Output buffer is returned.
/// - `ReturnCode::CalleeTrapped`
/// - `ReturnCode::TransferFailed`
/// - `ReturnCode::NotCallable`
#[version(1)]
#[prefixed_alias]
fn call(
@@ -1377,12 +1378,12 @@ pub mod env {
///
/// # Parameters
///
/// - flags: See [`CallFlags`] for a documentation of the supported flags.
/// - code_hash: a pointer to the hash of the code to be called.
/// - input_data_ptr: a pointer to a buffer to be used as input data to the callee.
/// - input_data_len: length of the input data buffer.
/// - output_ptr: a pointer where the output buffer is copied to.
/// - output_len_ptr: in-out pointer to where the length of the buffer is read from and the
/// - `flags`: see `crate::wasm::runtime::CallFlags` for a documentation of the supported flags.
/// - `code_hash`: a pointer to the hash of the code to be called.
/// - `input_data_ptr`: a pointer to a buffer to be used as input data to the callee.
/// - `input_data_len`: length of the input data buffer.
/// - `output_ptr`: a pointer where the output buffer is copied to.
/// - `output_len_ptr`: in-out pointer to where the length of the buffer is read from and the
/// actual length is written to.
///
/// # Errors
@@ -1390,9 +1391,9 @@ pub mod env {
/// An error means that the call wasn't successful and no output buffer is returned unless
/// stated otherwise.
///
/// `ReturnCode::CalleeReverted`: Output buffer is returned.
/// `ReturnCode::CalleeTrapped`
/// `ReturnCode::CodeNotFound`
/// - `ReturnCode::CalleeReverted`: Output buffer is returned.
/// - `ReturnCode::CalleeTrapped`
/// - `ReturnCode::CodeNotFound`
#[prefixed_alias]
fn delegate_call(
ctx: _,
@@ -1425,8 +1426,9 @@ pub mod env {
/// # Note
///
/// The values `_code_hash_len` and `_value_len` are ignored because the encoded sizes
/// of those types are fixed through `[`MaxEncodedLen`]. The fields exist for backwards
/// compatibility. Consider switching to the newest version of this function.
/// of those types are fixed through
/// [`codec::MaxEncodedLen`]. The fields exist
/// for backwards compatibility. Consider switching to the newest version of this function.
#[prefixed_alias]
fn instantiate(
ctx: _,
@@ -1474,20 +1476,20 @@ pub mod env {
///
/// # Parameters
///
/// - code_hash_ptr: a pointer to the buffer that contains the initializer code.
/// - gas: how much gas to devote to the execution of the initializer code.
/// - value_ptr: a pointer to the buffer with value, how much value to send. Should be decodable
/// as a `T::Balance`. Traps otherwise.
/// - input_data_ptr: a pointer to a buffer to be used as input data to the initializer code.
/// - input_data_len: length of the input data buffer.
/// - address_ptr: a pointer where the new account's address is copied to.
/// - address_len_ptr: in-out pointer to where the length of the buffer is read from and the
/// - `code_hash_ptr`: a pointer to the buffer that contains the initializer code.
/// - `gas`: how much gas to devote to the execution of the initializer code.
/// - `value_ptr`: a pointer to the buffer with value, how much value to send. Should be
/// decodable as a `T::Balance`. Traps otherwise.
/// - `input_data_ptr`: a pointer to a buffer to be used as input data to the initializer code.
/// - `input_data_len`: length of the input data buffer.
/// - `address_ptr`: a pointer where the new account's address is copied to.
/// - `address_len_ptr`: in-out pointer to where the length of the buffer is read from and the
/// actual length is written to.
/// - output_ptr: a pointer where the output buffer is copied to.
/// - output_len_ptr: in-out pointer to where the length of the buffer is read from and the
/// - `output_ptr`: a pointer where the output buffer is copied to.
/// - `output_len_ptr`: in-out pointer to where the length of the buffer is read from and the
/// actual length is written to.
/// - salt_ptr: Pointer to raw bytes used for address derivation. See `fn contract_address`.
/// - salt_len: length in bytes of the supplied salt.
/// - `salt_ptr`: Pointer to raw bytes used for address derivation. See `fn contract_address`.
/// - `salt_len`: length in bytes of the supplied salt.
///
/// # Errors
///
@@ -1497,10 +1499,10 @@ pub mod env {
/// An error means that the account wasn't created and no address or output buffer
/// is returned unless stated otherwise.
///
/// `ReturnCode::CalleeReverted`: Output buffer is returned.
/// `ReturnCode::CalleeTrapped`
/// `ReturnCode::TransferFailed`
/// `ReturnCode::CodeNotFound`
/// - `ReturnCode::CalleeReverted`: Output buffer is returned.
/// - `ReturnCode::CalleeTrapped`
/// - `ReturnCode::TransferFailed`
/// - `ReturnCode::CodeNotFound`
#[version(1)]
#[prefixed_alias]
fn instantiate(
@@ -1562,7 +1564,7 @@ pub mod env {
/// execution of the destroyed contract is halted. Or it failed during the termination
/// which is considered fatal and results in a trap + rollback.
///
/// - beneficiary_ptr: a pointer to the address of the beneficiary account where all where all
/// - `beneficiary_ptr`: a pointer to the address of the beneficiary account where all where all
/// remaining funds of the caller are transferred. Should be decodable as an `T::AccountId`.
/// Traps otherwise.
///
@@ -1586,7 +1588,7 @@ pub mod env {
///
/// # Note
///
/// This function traps if the input was previously forwarded by a `seal_call`.
/// This function traps if the input was previously forwarded by a [`call()`][`Self::call()`].
#[prefixed_alias]
fn input(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::InputBase)?;
@@ -1606,7 +1608,7 @@ pub mod env {
/// This function never returns as it stops execution of the caller.
/// This is the only way to return a data buffer to the caller. Returning from
/// execution without calling this function is equivalent to calling:
/// ```
/// ```nocompile
/// seal_return(0, 0, 0);
/// ```
///
@@ -1659,10 +1661,10 @@ pub mod env {
///
/// # Parameters
///
/// - account_ptr: a pointer to the address of the beneficiary account Should be decodable as an
/// `T::AccountId`. Traps otherwise.
/// - `account_ptr`: a pointer to the address of the beneficiary account Should be decodable as
/// an `T::AccountId`. Traps otherwise.
///
/// Returned value is a u32-encoded boolean: (0 = false, 1 = true).
/// Returned value is a `u32`-encoded boolean: (0 = false, 1 = true).
#[prefixed_alias]
fn is_contract(ctx: _, memory: _, account_ptr: u32) -> Result<u32, TrapReason> {
ctx.charge_gas(RuntimeCosts::IsContract)?;
@@ -1684,7 +1686,7 @@ pub mod env {
///
/// # Errors
///
/// `ReturnCode::KeyNotFound`
/// - `ReturnCode::KeyNotFound`
#[prefixed_alias]
fn code_hash(
ctx: _,
@@ -1734,14 +1736,14 @@ pub mod env {
/// Checks whether the caller of the current contract is the origin of the whole call stack.
///
/// Prefer this over `seal_is_contract` when checking whether your contract is being called by a
/// contract or a plain account. The reason is that it performs better since it does not need to
/// do any storage lookups.
/// Prefer this over [`is_contract()`][`Self::is_contract`] when checking whether your contract
/// is being called by a contract or a plain account. The reason is that it performs better
/// since it does not need to do any storage lookups.
///
/// A return value of`true` indicates that this contract is being called by a plain account
/// A return value of `true` indicates that this contract is being called by a plain account
/// and `false` indicates that the caller is another contract.
///
/// Returned value is a u32-encoded boolean: (0 = false, 1 = true).
/// Returned value is a `u32`-encoded boolean: (`0 = false`, `1 = true`).
#[prefixed_alias]
fn caller_is_origin(ctx: _, _memory: _) -> Result<u32, TrapReason> {
ctx.charge_gas(RuntimeCosts::CallerIsOrigin)?;
@@ -1774,7 +1776,7 @@ pub mod env {
/// `out_ptr`. This call overwrites it with the size of the value. If the available
/// space at `out_ptr` is less than the size of the value a trap is triggered.
///
/// The data is encoded as T::Balance.
/// The data is encoded as `T::Balance`.
///
/// # Note
///
@@ -1822,14 +1824,14 @@ pub mod env {
)?)
}
/// Stores the **free* balance of the current account into the supplied buffer.
/// Stores the *free* balance of the current account into the supplied buffer.
///
/// The value is stored to linear memory at the address pointed to by `out_ptr`.
/// `out_len_ptr` must point to a u32 value that describes the available space at
/// `out_ptr`. This call overwrites it with the size of the value. If the available
/// space at `out_ptr` is less than the size of the value a trap is triggered.
///
/// The data is encoded as T::Balance.
/// The data is encoded as `T::Balance`.
#[prefixed_alias]
fn balance(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Balance)?;
@@ -1846,11 +1848,11 @@ pub mod env {
/// Stores the value transferred along with this call/instantiate into the supplied buffer.
///
/// The value is stored to linear memory at the address pointed to by `out_ptr`.
/// `out_len_ptr` must point to a u32 value that describes the available space at
/// `out_len_ptr` must point to a `u32` value that describes the available space at
/// `out_ptr`. This call overwrites it with the size of the value. If the available
/// space at `out_ptr` is less than the size of the value a trap is triggered.
///
/// The data is encoded as T::Balance.
/// The data is encoded as `T::Balance`.
#[prefixed_alias]
fn value_transferred(
ctx: _,
@@ -1876,11 +1878,12 @@ pub mod env {
/// `out_ptr`. This call overwrites it with the size of the value. If the available
/// space at `out_ptr` is less than the size of the value a trap is triggered.
///
/// The data is encoded as T::Hash.
/// The data is encoded as `T::Hash`.
///
/// # Deprecation
///
/// This function is deprecated. Users should migrate to the version in the "seal1" module.
/// This function is deprecated. Users should migrate to the [`super::seal1::Api::random()`]
/// version.
#[prefixed_alias]
fn random(
ctx: _,
@@ -1972,7 +1975,7 @@ pub mod env {
/// Stores the minimum balance (a.k.a. existential deposit) into the supplied buffer.
///
/// The data is encoded as T::Balance.
/// The data is encoded as `T::Balance`.
#[prefixed_alias]
fn minimum_balance(
ctx: _,
@@ -2000,7 +2003,7 @@ pub mod env {
///
/// # Deprecation
///
/// There is no longer a tombstone deposit. This function always returns 0.
/// There is no longer a tombstone deposit. This function always returns `0`.
#[prefixed_alias]
fn tombstone_deposit(
ctx: _,
@@ -2067,11 +2070,12 @@ pub mod env {
/// Deposit a contract event with the data buffer and optional list of topics. There is a limit
/// on the maximum number of topics specified by `event_topics`.
///
/// - topics_ptr - a pointer to the buffer of topics encoded as `Vec<T::Hash>`. The value of
/// this is ignored if `topics_len` is set to 0. The topics list can't contain duplicates.
/// - topics_len - the length of the topics buffer. Pass 0 if you want to pass an empty vector.
/// - data_ptr - a pointer to a raw data buffer which will saved along the event.
/// - data_len - the length of the data buffer.
/// - `topics_ptr`: a pointer to the buffer of topics encoded as `Vec<T::Hash>`. The value of
/// this is ignored if `topics_len` is set to `0`. The topics list can't contain duplicates.
/// - `topics_len`: the length of the topics buffer. Pass 0 if you want to pass an empty
/// vector.
/// - `data_ptr`: a pointer to a raw data buffer which will saved along the event.
/// - `data_len`: the length of the data buffer.
#[prefixed_alias]
fn deposit_event(
ctx: _,
@@ -2422,11 +2426,6 @@ pub mod env {
/// - Provide functionality **exclusively** to contracts.
/// - Provide custom weights.
/// - Avoid the need to keep the `Call` data structure stable.
///
/// # Unstable
///
/// This function is unstable and subject to change (or removal) in the future. Do not
/// deploy a contract using it to a production chain.
#[unstable]
#[prefixed_alias]
fn call_runtime(
@@ -2466,7 +2465,7 @@ pub mod env {
///
/// # Errors
///
/// `ReturnCode::EcdsaRecoverFailed`
/// - `ReturnCode::EcdsaRecoverFailed`
#[prefixed_alias]
fn ecdsa_recover(
ctx: _,
@@ -2513,8 +2512,8 @@ pub mod env {
///
/// 3. If a contract calls into itself after changing its code the new call would use
/// the new code. However, if the original caller panics after returning from the sub call it
/// would revert the changes made by `seal_set_code_hash` and the next caller would use
/// the old code.
/// would revert the changes made by [`set_code_hash()`][`Self::set_code_hash`] and the next
/// caller would use the old code.
///
/// # Parameters
///
@@ -2522,7 +2521,7 @@ pub mod env {
///
/// # Errors
///
/// `ReturnCode::CodeNotFound`
/// - `ReturnCode::CodeNotFound`
#[prefixed_alias]
fn set_code_hash(ctx: _, memory: _, code_hash_ptr: u32) -> Result<ReturnCode, TrapReason> {
ctx.charge_gas(RuntimeCosts::SetCodeHash)?;
@@ -2552,7 +2551,7 @@ pub mod env {
///
/// # Errors
///
/// `ReturnCode::EcdsaRecoverFailed`
/// - `ReturnCode::EcdsaRecoverFailed`
#[prefixed_alias]
fn ecdsa_to_eth_address(
ctx: _,
@@ -2578,7 +2577,7 @@ pub mod env {
///
/// # Return Value
///
/// Returns 0 when there is no reentrancy.
/// Returns `0` when there is no reentrancy.
#[unstable]
fn reentrance_count(ctx: _, memory: _) -> Result<u32, TrapReason> {
ctx.charge_gas(RuntimeCosts::ReentrantCount)?;
@@ -2594,7 +2593,7 @@ pub mod env {
///
/// # Return Value
///
/// Returns 0 when the contract does not exist on the call stack.
/// Returns `0` when the contract does not exist on the call stack.
#[unstable]
fn account_reentrance_count(ctx: _, memory: _, account_ptr: u32) -> Result<u32, TrapReason> {
ctx.charge_gas(RuntimeCosts::AccountEntranceCount)?;