Skip to content

Commit

Permalink
refactor: remove read state encoding (#122)
Browse files Browse the repository at this point in the history
Co-authored-by: Frank Bell <frank@r0gue.io>
  • Loading branch information
2 people authored and chungquantin committed Sep 6, 2024
1 parent 08efd49 commit 9c231b2
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 92 deletions.
78 changes: 25 additions & 53 deletions pallets/api/src/fungibles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,61 +180,33 @@ pub mod pallet {
}

impl<T: Config> Pallet<T> {
/// Returns the total token supply for a given asset ID.
/// Reads fungible asset state based on the provided value.
///
/// # Parameters
/// * `id` - The ID of the asset.
pub fn total_supply(id: AssetIdOf<T>) -> BalanceOf<T> {
AssetsOf::<T>::total_supply(id)
}

/// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if
/// the account is non-existent.
/// This function matches the value to determine the type of state query and returns the
/// encoded result.
///
/// # Parameters
/// * `id` - The ID of the asset.
/// * `owner` - The account whose balance is being queried.
pub fn balance_of(id: AssetIdOf<T>, owner: &AccountIdOf<T>) -> BalanceOf<T> {
AssetsOf::<T>::balance(id, owner)
}

/// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given
/// asset ID. Returns `0` if no allowance has been set.
///
/// # Parameters
/// * `id` - The ID of the asset.
/// * `owner` - The account that owns the tokens.
/// * `spender` - The account that is allowed to spend the tokens.
pub fn allowance(
id: AssetIdOf<T>,
owner: &AccountIdOf<T>,
spender: &AccountIdOf<T>,
) -> BalanceOf<T> {
AssetsOf::<T>::allowance(id, owner, spender)
}

/// Returns the token name for a given asset ID.
///
/// # Parameters
/// * `id` - The ID of the asset.
pub fn token_name(id: AssetIdOf<T>) -> Vec<u8> {
<AssetsOf<T> as MetadataInspect<AccountIdOf<T>>>::name(id)
}

/// Returns the token symbol for a given asset ID.
///
/// # Parameters
/// * `id` - The ID of the asset.
pub fn token_symbol(id: AssetIdOf<T>) -> Vec<u8> {
<AssetsOf<T> as MetadataInspect<AccountIdOf<T>>>::symbol(id)
}

/// Returns the token decimals for a given asset ID.
///
/// # Parameters
/// * `id` - The ID of the asset.
pub fn token_decimals(id: AssetIdOf<T>) -> u8 {
<AssetsOf<T> as MetadataInspect<AccountIdOf<T>>>::decimals(id)
/// # Parameter
/// * `value` - An instance of `Read<T>`, which specifies the type of state query and
/// the associated parameters.
pub fn read_state(value: Read<T>) -> Vec<u8> {
use Read::*;

match value {
TotalSupply(id) => AssetsOf::<T>::total_supply(id).encode(),
BalanceOf { id, owner } => AssetsOf::<T>::balance(id, owner).encode(),
Allowance { id, owner, spender } => {
AssetsOf::<T>::allowance(id, &owner, &spender).encode()
},
TokenName(id) => {
<AssetsOf<T> as MetadataInspect<AccountIdOf<T>>>::name(id).encode()
},
TokenSymbol(id) => {
<AssetsOf<T> as MetadataInspect<AccountIdOf<T>>>::symbol(id).encode()
},
TokenDecimals(id) => {
<AssetsOf<T> as MetadataInspect<AccountIdOf<T>>>::decimals(id).encode()
},
}
}
}
}
20 changes: 12 additions & 8 deletions pallets/api/src/fungibles/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::mock::*;
use crate::{fungibles::Read::*, mock::*};
use codec::Encode;
use frame_support::{
assert_ok,
traits::fungibles::{approvals::Inspect, metadata::Inspect as MetadataInspect},
Expand Down Expand Up @@ -60,15 +61,18 @@ fn increase_allowance_works() {
fn total_supply_works() {
new_test_ext().execute_with(|| {
create_asset_and_mint_to(ALICE, ASSET, ALICE, 100);
assert_eq!(Assets::total_supply(ASSET), Fungibles::total_supply(ASSET));
assert_eq!(Assets::total_supply(ASSET).encode(), Fungibles::read_state(TotalSupply(ASSET)));
});
}

#[test]
fn balance_of_works() {
new_test_ext().execute_with(|| {
create_asset_and_mint_to(ALICE, ASSET, ALICE, 100);
assert_eq!(Assets::balance(ASSET, ALICE), Fungibles::balance_of(ASSET, &ALICE));
assert_eq!(
Assets::balance(ASSET, ALICE).encode(),
Fungibles::read_state(BalanceOf { id: ASSET, owner: ALICE })
);
});
}

Expand All @@ -77,8 +81,8 @@ fn allowance_works() {
new_test_ext().execute_with(|| {
create_asset_mint_and_approve(ALICE, ASSET, BOB, 100, ALICE, 50);
assert_eq!(
Assets::allowance(ASSET, &ALICE, &BOB),
Fungibles::allowance(ASSET, &ALICE, &BOB)
Assets::allowance(ASSET, &ALICE, &BOB).encode(),
Fungibles::read_state(Allowance { id: ASSET, owner: ALICE, spender: BOB })
);
});
}
Expand All @@ -90,9 +94,9 @@ fn token_metadata_works() {
let symbol: Vec<u8> = vec![21, 22, 23];
let decimals: u8 = 69;
create_asset_and_set_metadata(ALICE, ASSET, name.clone(), symbol.clone(), decimals);
assert_eq!(Assets::name(ASSET), Fungibles::token_name(ASSET));
assert_eq!(Assets::symbol(ASSET), Fungibles::token_symbol(ASSET));
assert_eq!(Assets::decimals(ASSET), Fungibles::token_decimals(ASSET));
assert_eq!(Assets::name(ASSET).encode(), Fungibles::read_state(TokenName(ASSET)));
assert_eq!(Assets::symbol(ASSET).encode(), Fungibles::read_state(TokenSymbol(ASSET)));
assert_eq!(Assets::decimals(ASSET).encode(), Fungibles::read_state(TokenDecimals(ASSET)));
});
}

Expand Down
4 changes: 1 addition & 3 deletions pop-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

use ink::env::chain_extension::ChainExtensionMethod;

use constants::DECODING_FAILED;
use ink::env::chain_extension::FromStatusCode;
use ink::env::chain_extension::{ChainExtensionMethod, FromStatusCode};
#[cfg(feature = "assets")]
pub use v0::assets;

Expand Down
20 changes: 6 additions & 14 deletions pop-api/src/v0/assets/fungibles.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode};

use crate::{
constants::{ASSETS, BALANCES, DECODING_FAILED, FUNGIBLES},
constants::{ASSETS, BALANCES, FUNGIBLES},
primitives::{AccountId, AssetId, Balance},
v0::V0,
Result, StatusCode,
};
use constants::*;
use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec};
pub use metadata::*;

/// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0`
Expand Down Expand Up @@ -78,10 +76,9 @@ mod constants {
pub fn total_supply(id: AssetId) -> Result<Balance> {
build_read_state(TOTAL_SUPPLY)
.input::<AssetId>()
.output::<Result<Vec<u8>>, true>()
.output::<Result<Balance>, true>()
.handle_error_code::<StatusCode>()
.call(&(id))
.and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED)))
}

/// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if
Expand All @@ -97,10 +94,9 @@ pub fn total_supply(id: AssetId) -> Result<Balance> {
pub fn balance_of(id: AssetId, owner: AccountId) -> Result<Balance> {
build_read_state(BALANCE_OF)
.input::<(AssetId, AccountId)>()
.output::<Result<Vec<u8>>, true>()
.output::<Result<Balance>, true>()
.handle_error_code::<StatusCode>()
.call(&(id, owner))
.and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED)))
}

/// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given
Expand All @@ -117,10 +113,9 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result<Balance> {
pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result<Balance> {
build_read_state(ALLOWANCE)
.input::<(AssetId, AccountId, AccountId)>()
.output::<Result<Vec<u8>>, true>()
.output::<Result<Balance>, true>()
.handle_error_code::<StatusCode>()
.call(&(id, owner, spender))
.and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED)))
}

/// Transfers `value` amount of tokens from the caller's account to account `to`, with additional
Expand Down Expand Up @@ -233,7 +228,6 @@ pub mod metadata {
.output::<Result<Vec<u8>>, true>()
.handle_error_code::<StatusCode>()
.call(&(id))
.and_then(|v| <Vec<u8>>::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED)))
}

/// Returns the token symbol for a given asset ID.
Expand All @@ -250,7 +244,6 @@ pub mod metadata {
.output::<Result<Vec<u8>>, true>()
.handle_error_code::<StatusCode>()
.call(&(id))
.and_then(|v| <Vec<u8>>::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED)))
}

/// Returns the token decimals for a given asset ID.
Expand All @@ -264,10 +257,9 @@ pub mod metadata {
pub fn token_decimals(id: AssetId) -> Result<u8> {
build_read_state(TOKEN_DECIMALS)
.input::<AssetId>()
.output::<Result<Vec<u8>>, true>()
.output::<Result<u8>, true>()
.handle_error_code::<StatusCode>()
.call(&(id))
.and_then(|v| <u8>::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED)))
}
}

Expand Down
1 change: 0 additions & 1 deletion pop-api/src/v0/assets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
#[cfg(feature = "fungibles")]
pub mod fungibles;

35 changes: 24 additions & 11 deletions runtime/devnet/src/config/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,37 @@ pub enum RuntimeRead<T: fungibles::Config> {
Fungibles(fungibles::Read<T>),
}

impl fungibles::Config for Runtime {
type AssetsInstance = TrustBackedAssetsInstance;
type WeightInfo = fungibles::weights::SubstrateWeight<Runtime>;
}

/// A type to identify allowed calls to the Runtime from contracts. Used by Pop API
/// A type to identify allowed calls to the Runtime from the API.
pub struct AllowedApiCalls;

impl Contains<RuntimeCall> for AllowedApiCalls {
/// Allowed runtime calls from the API.
fn contains(c: &RuntimeCall) -> bool {
use fungibles::Call as FungiblesCall;
use fungibles::Call::*;
matches!(
c,
RuntimeCall::Fungibles(transfer { .. } | approve { .. } | increase_allowance { .. })
)
}
}

impl<T: fungibles::Config> Contains<RuntimeRead<T>> for AllowedApiCalls {
/// Allowed state queries from the API.
fn contains(c: &RuntimeRead<T>) -> bool {
use fungibles::Read::*;
matches!(
c,
RuntimeCall::Fungibles(
FungiblesCall::transfer { .. }
| FungiblesCall::approve { .. }
| FungiblesCall::increase_allowance { .. }
RuntimeRead::Fungibles(
TotalSupply(..)
| BalanceOf { .. } | Allowance { .. }
| TokenName(..) | TokenSymbol(..)
| TokenDecimals(..)
)
)
}
}

impl fungibles::Config for Runtime {
type AssetsInstance = TrustBackedAssetsInstance;
type WeightInfo = fungibles::weights::SubstrateWeight<Runtime>;
}
4 changes: 2 additions & 2 deletions runtime/devnet/src/extensions/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ mod tests {
DispatchError::Other(""),
(Other { dispatch_error_index: 0, error_index: 0, error: 0 }),
),
(DispatchError::Other("UnknownFunctionId"), UnknownCall),
(DispatchError::Other("UnknownCall"), UnknownCall),
(DispatchError::Other("DecodingFailed"), DecodingFailed),
(DispatchError::CannotLookup, CannotLookup),
(DispatchError::BadOrigin, BadOrigin),
Expand Down Expand Up @@ -120,7 +120,7 @@ mod tests {
DispatchError::Other("Random"),
(Other { dispatch_error_index: 0, error_index: 0, error: 0 }),
),
(DispatchError::Other("UnknownFunctionId"), UnknownCall),
(DispatchError::Other("UnknownCall"), UnknownCall),
(DispatchError::Other("DecodingFailed"), DecodingFailed),
];
for (dispatch_error, expected) in test_cases {
Expand Down

0 comments on commit 9c231b2

Please sign in to comment.