Macro sp_api::decl_runtime_apis

source ·
decl_runtime_apis!() { /* proc-macro */ }
Expand description

Declares given traits as runtime apis.

The macro will create two declarations, one for using on the client side and one for using on the runtime side. The declaration for the runtime side is hidden in its own module. The client side declaration gets two extra parameters per function, &self and at: Block::Hash. The runtime side declaration will match the given trait declaration. Besides one exception, the macro adds an extra generic parameter Block: BlockT to the client side and the runtime side. This generic parameter is usable by the user.

For implementing these macros you should use the impl_runtime_apis! macro.

§Example

sp_api::decl_runtime_apis! {
    /// Declare the api trait.
    pub trait Balance {
        /// Get the balance.
        fn get_balance() -> u64;
        /// Set the balance.
        fn set_balance(val: u64);
    }

    /// You can declare multiple api traits in one macro call.
    /// In one module you can call the macro at maximum one time.
    pub trait BlockBuilder {
        /// The macro adds an explicit `Block: BlockT` generic parameter for you.
        /// You can use this generic parameter as you would defined it manually.
        fn build_block() -> Block;
    }
}

§Runtime api trait versioning

To support versioning of the traits, the macro supports the attribute #[api_version(1)]. The attribute supports any u32 as version. By default, each trait is at version 1, if no version is provided. We also support changing the signature of a method. This signature change is highlighted with the #[changed_in(2)] attribute above a method. A method that is tagged with this attribute is callable by the name METHOD_before_version_VERSION. This method will only support calling into wasm, trying to call into native will fail (change the spec version!). Such a method also does not need to be implemented in the runtime. It is required that there exist the “default” of the method without the #[changed_in(_)] attribute, this method will be used to call the current default implementation.

sp_api::decl_runtime_apis! {
    /// Declare the api trait.
    #[api_version(2)]
    pub trait Balance {
        /// Get the balance.
        fn get_balance() -> u64;
        /// Set balance.
        fn set_balance(val: u64);
        /// Set balance, old version.
        ///
        /// Is callable by `set_balance_before_version_2`.
        #[changed_in(2)]
        fn set_balance(val: u16);
        /// In version 2, we added this new function.
        fn increase_balance(val: u64);
    }
}

To check if a given runtime implements a runtime api trait, the RuntimeVersion has the function has_api<A>(). Also the ApiExt provides a function has_api<A>(at: Hash) to check if the runtime at the given block id implements the requested runtime api trait.

§Declaring multiple api versions

Optionally multiple versions of the same api can be declared. This is useful for development purposes. For example you want to have a testing version of the api which is available only on a testnet. You can define one stable and one development version. This can be done like this:

sp_api::decl_runtime_apis! {
    /// Declare the api trait.
	#[api_version(2)]
    pub trait Balance {
        /// Get the balance.
        fn get_balance() -> u64;
        /// Set the balance.
        fn set_balance(val: u64);
        /// Transfer the balance to another user id
        #[api_version(3)]
        fn transfer_balance(uid: u64);
    }
}

The example above defines two api versions - 2 and 3. Version 2 contains get_balance and set_balance. Version 3 additionally contains transfer_balance, which is not available in version 2. Version 2 in this case is considered the default/base version of the api. More than two versions can be defined this way. For example:

sp_api::decl_runtime_apis! {
    /// Declare the api trait.
    #[api_version(2)]
    pub trait Balance {
        /// Get the balance.
        fn get_balance() -> u64;
        /// Set the balance.
        fn set_balance(val: u64);
        /// Transfer the balance to another user id
        #[api_version(3)]
        fn transfer_balance(uid: u64);
        /// Clears the balance
        #[api_version(4)]
        fn clear_balance();
    }
}

Note that the latest version (4 in our example above) always contains all methods from all the versions before.