Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: build chain extension method #121

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion pop-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

use ink::env::chain_extension::FromStatusCode;
use ink::env::chain_extension::{ChainExtensionMethod, FromStatusCode};

use constants::DECODING_FAILED;

Expand Down Expand Up @@ -33,6 +33,22 @@ mod constants {
pub(crate) const BALANCES: u8 = 10;
}

/// Helper method to build `ChainExtensionMethod`.
///
/// Parameters:
/// - 'version': The version of the chain extension
/// - 'function': The ID of the function
/// - 'module': The index of the runtime module
/// - 'dispatchable': The index of the module dispatchable functions
fn build_extension_method(
chungquantin marked this conversation as resolved.
Show resolved Hide resolved
version: u8,
function: u8,
module: u8,
dispatchable: u8,
) -> ChainExtensionMethod<(), (), (), false> {
ChainExtensionMethod::build(u32::from_le_bytes([version, function, module, dispatchable]))
}

/// Represents a status code returned by the runtime.
///
/// `StatusCode` encapsulates a `u32` value that indicates the status of an operation performed
Expand Down
56 changes: 33 additions & 23 deletions pop-api/src/v0/assets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode};
use ink::{prelude::vec::Vec, scale::Decode};

use crate::{
constants::{ASSETS, DECODING_FAILED, DISPATCH, READ_STATE},
constants::{ASSETS, DECODING_FAILED},
primitives::{AccountId, AssetId, Balance},
v0::V0,
Result, StatusCode,
};

Expand Down Expand Up @@ -33,6 +32,22 @@ const CANCEL_APPROVAL: u8 = 23;
/// - transfer_approved
const TRANSFER_APPROVED: u8 = 25;

/// Helper method to build a dispatch call `ChainExtensionMethod` for `ASSET` module
///
/// Parameters:
/// - 'dispatchable': The index of the dispatchable functions in `ASSET` module.
fn build_dispatch(dispatchable: u8) -> ChainExtensionMethod<(), (), (), false> {
crate::v0::build_dispatch(ASSETS, dispatchable)
}

/// Helper method to build a dispatch call `ChainExtensionMethod` for `ASSET` module
///
/// Parameters:
/// - 'state_query': The index of the runtime state query.
fn build_read_state(state_query: u8) -> ChainExtensionMethod<(), (), (), false> {
crate::v0::build_read_state(ASSETS, state_query)
}

/// Issue a new class of fungible assets from a public origin.
// pub(crate) fn create(
// id: AssetId,
Expand Down Expand Up @@ -91,17 +106,12 @@ const TRANSFER_APPROVED: u8 = 25;
/// Move some assets from the sender account to another, keeping the sender account alive.
#[inline]
pub fn transfer_keep_alive(id: AssetId, target: AccountId, amount: Balance) -> Result<()> {
ChainExtensionMethod::build(u32::from_le_bytes([
V0,
DISPATCH,
ASSETS,
// E.D. is always respected with transferring tokens via the API.
TRANSFER_KEEP_ALIVE,
]))
.input::<(AssetId, AccountId, Balance)>()
.output::<Result<()>, true>()
.handle_error_code::<StatusCode>()
.call(&(id, target, amount))
// E.D. is always respected with transferring tokens via the API.
build_dispatch(TRANSFER_KEEP_ALIVE)
.input::<(AssetId, AccountId, Balance)>()
.output::<Result<()>, true>()
.handle_error_code::<StatusCode>()
.call(&(id, target, amount))
}

// /// Set the metadata for an asset.
Expand All @@ -122,7 +132,7 @@ pub fn transfer_keep_alive(id: AssetId, target: AccountId, amount: Balance) -> R
/// Approve an amount of asset for transfer by a delegated third-party account.
#[inline]
pub fn approve_transfer(id: AssetId, delegate: AccountId, amount: Balance) -> Result<()> {
ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, ASSETS, APPROVE_TRANSFER]))
build_dispatch(APPROVE_TRANSFER)
.input::<(AssetId, AccountId, Balance)>()
.output::<Result<()>, true>()
.handle_error_code::<StatusCode>()
Expand All @@ -132,7 +142,7 @@ pub fn approve_transfer(id: AssetId, delegate: AccountId, amount: Balance) -> Re
/// Cancel all of some asset approved for delegated transfer by a third-party account.
#[inline]
pub fn cancel_approval(id: AssetId, delegate: AccountId) -> Result<()> {
ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, ASSETS, CANCEL_APPROVAL]))
build_dispatch(CANCEL_APPROVAL)
.input::<(AssetId, AccountId)>()
.output::<Result<()>, true>()
.handle_error_code::<StatusCode>()
Expand All @@ -148,7 +158,7 @@ pub fn transfer_approved(
to: AccountId,
amount: Balance,
) -> Result<()> {
ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, ASSETS, TRANSFER_APPROVED]))
build_dispatch(TRANSFER_APPROVED)
.input::<(AssetId, AccountId, AccountId, Balance)>()
.output::<Result<()>, true>()
.handle_error_code::<StatusCode>()
Expand All @@ -172,7 +182,7 @@ const TOKEN_DECIMALS: u8 = 5;

#[inline]
pub fn total_supply(id: AssetId) -> Result<Balance> {
ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOTAL_SUPPLY]))
build_read_state(TOTAL_SUPPLY)
.input::<AssetId>()
.output::<Result<Vec<u8>>, true>()
.handle_error_code::<StatusCode>()
Expand All @@ -182,7 +192,7 @@ pub fn total_supply(id: AssetId) -> Result<Balance> {

#[inline]
pub fn balance_of(id: AssetId, owner: AccountId) -> Result<Balance> {
ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, BALANCE_OF]))
build_read_state(ASSETS, BALANCE_OF)
.input::<(AssetId, AccountId)>()
.output::<Result<Vec<u8>>, true>()
.handle_error_code::<StatusCode>()
Expand All @@ -192,7 +202,7 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result<Balance> {

#[inline]
pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result<Balance> {
ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, ALLOWANCE]))
build_read_state(ALLOWANCE)
.input::<(AssetId, AccountId, AccountId)>()
.output::<Result<Vec<u8>>, true>()
.handle_error_code::<StatusCode>()
Expand All @@ -202,7 +212,7 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result<Ba

#[inline]
pub fn token_name(id: AssetId) -> Result<Vec<u8>> {
ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOKEN_NAME]))
build_read_state(TOKEN_NAME)
.input::<AssetId>()
.output::<Result<Vec<u8>>, true>()
.handle_error_code::<StatusCode>()
Expand All @@ -212,7 +222,7 @@ pub fn token_name(id: AssetId) -> Result<Vec<u8>> {
//
#[inline]
pub fn token_symbol(id: AssetId) -> Result<Vec<u8>> {
ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOKEN_SYMBOL]))
build_read_state(TOKEN_SYMBOL)
.input::<AssetId>()
.output::<Result<Vec<u8>>, true>()
.handle_error_code::<StatusCode>()
Expand All @@ -222,7 +232,7 @@ pub fn token_symbol(id: AssetId) -> Result<Vec<u8>> {

#[inline]
pub fn token_decimals(id: AssetId) -> Result<u8> {
ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOKEN_DECIMALS]))
build_read_state(TOKEN_DECIMALS)
.input::<AssetId>()
.output::<Result<Vec<u8>>, true>()
.handle_error_code::<StatusCode>()
Expand Down
40 changes: 39 additions & 1 deletion pop-api/src/v0/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
use crate::{primitives::error::Error, StatusCode};
use crate::{
build_extension_method,
constants::{DISPATCH, READ_STATE},
primitives::error::Error,
StatusCode,
};
use ink::env::chain_extension::ChainExtensionMethod;

#[cfg(feature = "assets")]
pub mod assets;
Expand All @@ -16,3 +22,35 @@ impl From<StatusCode> for Error {
value.0.into()
}
}

/// Helper method to build `ChainExtensionMethod` for version `v0`
///
/// Parameters:
/// - 'function': The ID of the function
/// - 'module': The index of the runtime module
/// - 'dispatchable': The index of the module dispatchable functions
fn build_extension_method_v0(
function: u8,
chungquantin marked this conversation as resolved.
Show resolved Hide resolved
module: u8,
dispatchable: u8,
) -> ChainExtensionMethod<(), (), (), false> {
build_extension_method(V0, function, module, dispatchable)
}

/// Helper method to build a dispatch call `ChainExtensionMethod`
///
/// Parameters:
/// - 'module': The index of the runtime module
/// - 'dispatchable': The index of the module dispatchable functions
fn build_dispatch(module: u8, dispatchable: u8) -> ChainExtensionMethod<(), (), (), false> {
build_extension_method_v0(DISPATCH, module, dispatchable)
}

/// Helper method to build a dispatch call `ChainExtensionMethod`
///
/// Parameters:
/// - 'module': The index of the runtime module
/// - 'state_query': The index of the runtime state query
fn build_read_state(module: u8, state_query: u8) -> ChainExtensionMethod<(), (), (), false> {
build_extension_method_v0(READ_STATE, module, state_query)
}
Loading