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(api): decoding example #114

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
7 changes: 0 additions & 7 deletions pop-api/integration-tests/src/local_fungibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ fn token_decimals_asset(asset_id: AssetId) -> u8 {
/// - decrease_allowance

#[test]
#[ignore]
fn total_supply_works() {
new_test_ext().execute_with(|| {
let _ = env_logger::try_init();
Expand All @@ -285,7 +284,6 @@ fn total_supply_works() {
}

#[test]
#[ignore]
fn balance_of_works() {
new_test_ext().execute_with(|| {
let _ = env_logger::try_init();
Expand All @@ -304,7 +302,6 @@ fn balance_of_works() {
}

#[test]
#[ignore]
fn allowance_works() {
new_test_ext().execute_with(|| {
let _ = env_logger::try_init();
Expand All @@ -329,7 +326,6 @@ fn allowance_works() {
}

#[test]
#[ignore]
fn transfer_works() {
new_test_ext().execute_with(|| {
let _ = env_logger::try_init();
Expand Down Expand Up @@ -382,7 +378,6 @@ fn transfer_works() {
}

#[test]
#[ignore]
fn transfer_from_works() {
new_test_ext().execute_with(|| {
let _ = env_logger::try_init();
Expand Down Expand Up @@ -435,7 +430,6 @@ fn transfer_from_works() {
}

#[test]
#[ignore]
fn increase_allowance_works() {
new_test_ext().execute_with(|| {
let _ = env_logger::try_init();
Expand Down Expand Up @@ -493,7 +487,6 @@ fn increase_allowance_works() {
/// - token_decimals

#[test]
#[ignore]
fn token_metadata_works() {
new_test_ext().execute_with(|| {
let _ = env_logger::try_init();
Expand Down
10 changes: 10 additions & 0 deletions primitives/src/storage_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
use super::nfts::*;
use super::*;

// This should be moved to the runtime, it is no longer required in primitives if we are just using
// a chainextensionmethod call where we encode the first four bytes to channel the request
#[derive(Encode, Decode, Debug, MaxEncodedLen)]
pub enum RuntimeStateKeys {
#[cfg(feature = "cross-chain")]
Expand Down Expand Up @@ -42,15 +44,23 @@ pub enum NftsKeys {
CollectionAttribute(CollectionId, BoundedVec<u8, KeyLimit>),
}

// This should be moved to the runtime, it is no longer required in primitives if we are just using
// a chainextensionmethod call where we encode the first four bytes to channel the request
/// The required input for state queries in pallet assets.
#[cfg(feature = "assets")]
#[derive(Encode, Decode, Debug, MaxEncodedLen)]
pub enum AssetsKeys {
#[codec(index = 0)]
TotalSupply(AssetId),
#[codec(index = 1)]
BalanceOf(AssetId, AccountId),
#[codec(index = 2)]
Allowance(AssetId, AccountId, AccountId),
#[codec(index = 3)]
TokenName(AssetId),
#[codec(index = 4)]
TokenSymbol(AssetId),
#[codec(index = 5)]
TokenDecimals(AssetId),
// AssetExists(AssetId),
}
53 changes: 22 additions & 31 deletions runtime/devnet/src/extensions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
>,
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
fn call<E: Ext>(&mut self, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>

Check warning on line 66 in runtime/devnet/src/extensions/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

bound is defined in more than one place

warning: bound is defined in more than one place --> runtime/devnet/src/extensions/mod.rs:66:10 | 66 | fn call<E: Ext>(&mut self, env: Environment<E, InitState>) -> Result<RetVal, DispatchError> | ^ 67 | where 68 | E: Ext<T = T>, | ^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#multiple_bound_locations = note: `#[warn(clippy::multiple_bound_locations)]` on by default
where
E: Ext<T = T>,
{
Expand Down Expand Up @@ -180,21 +180,6 @@
}
}

fn construct_key(
version: u8,
pallet_index: u8,
call_index: u8,
params: Vec<u8>,
) -> Result<RuntimeStateKeys, DispatchError> {
match pallet_index {
52 => {
let key = versioned_construct_assets_key(version, call_index, params)?;
Ok(RuntimeStateKeys::Assets(key))
},
_ => Err(DispatchError::Other("UnknownFunctionId")),
}
}

fn versioned_construct_assets_call(
version: u8,
call_index: u8,
Expand All @@ -206,23 +191,12 @@
}
}

fn versioned_construct_assets_key(
version: u8,
call_index: u8,
params: Vec<u8>,
) -> Result<AssetsKeys, DispatchError> {
match version {
V0 => v0::assets::construct_assets_key(call_index, params),
_ => Err(DispatchError::Other("UnknownFunctionId")),
}
}

fn read_state<T, E>(
env: &mut Environment<E, BufInBufOutState>,
version: u8,
pallet_index: u8,
call_index: u8,
params: Vec<u8>,
mut params: Vec<u8>,
) -> Result<(), DispatchError>
where
T: pallet_contracts::Config
Expand All @@ -233,11 +207,21 @@
E: Ext<T = T>,
{
const LOG_PREFIX: &str = " read_state |";
let key = construct_key(version, pallet_index, call_index, params)?;

// Prefix params with version, pallet, index to simplify decoding
params.insert(0, version);
params.insert(1, pallet_index);
params.insert(2, call_index);

let key = <VersionedRuntimeStateKeys>::decode(&mut &params[..])
.map_err(|_| DispatchError::Other("DecodingFailed"))?;

let result = match key {
RuntimeStateKeys::Nfts(key) => read_nfts_state::<T, E>(key, env),
RuntimeStateKeys::ParachainSystem(key) => read_parachain_system_state::<T, E>(key, env),
RuntimeStateKeys::Assets(key) => read_assets_state::<T, E>(key, env),
VersionedRuntimeStateKeys::V0(key) => match key {
RuntimeStateKeys::Nfts(key) => read_nfts_state::<T, E>(key, env),
RuntimeStateKeys::ParachainSystem(key) => read_parachain_system_state::<T, E>(key, env),
RuntimeStateKeys::Assets(key) => read_assets_state::<T, E>(key, env),
},
}?
.encode();
log::trace!(
Expand All @@ -247,6 +231,13 @@
env.write(&result, false, None)
}

// Example wrapper to enable versioning of state read keys
#[derive(Encode, Decode, Debug, MaxEncodedLen)]
enum VersionedRuntimeStateKeys {
#[codec(index = 0)]
V0(RuntimeStateKeys),
}

fn send_xcm<T, E>(env: &mut Environment<E, BufInBufOutState>) -> Result<(), DispatchError>
where
T: pallet_contracts::Config
Expand Down
40 changes: 0 additions & 40 deletions runtime/devnet/src/extensions/v0/assets.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,11 @@
use crate::extensions::{
AccountId as AccountId32, AssetId,
AssetsKeys::{self, *},

Check warning on line 3 in runtime/devnet/src/extensions/v0/assets.rs

View workflow job for this annotation

GitHub Actions / clippy

unused imports: `*`, `self`

warning: unused imports: `*`, `self` --> runtime/devnet/src/extensions/v0/assets.rs:3:15 | 3 | AssetsKeys::{self, *}, | ^^^^ ^ | = note: `#[warn(unused_imports)]` on by default
Balance, Compact, Decode, DispatchError, MultiAddress, Runtime, TrustBackedAssetsInstance,
};
use pop_primitives::AccountId;

Check warning on line 6 in runtime/devnet/src/extensions/v0/assets.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `pop_primitives::AccountId`

warning: unused import: `pop_primitives::AccountId` --> runtime/devnet/src/extensions/v0/assets.rs:6:5 | 6 | use pop_primitives::AccountId; | ^^^^^^^^^^^^^^^^^^^^^^^^^
use sp_std::vec::Vec;

pub(crate) fn construct_assets_key(
call_index: u8,
params: Vec<u8>,
) -> Result<AssetsKeys, DispatchError> {
match call_index {
0 => {
let id = <AssetId>::decode(&mut &params[..])
.map_err(|_| DispatchError::Other("DecodingFailed"))?;
Ok(TotalSupply(id))
},
1 => {
let (id, owner) = <(AssetId, AccountId)>::decode(&mut &params[..])
.map_err(|_| DispatchError::Other("DecodingFailed"))?;
Ok(BalanceOf(id, owner))
},
2 => {
let (id, owner, spender) = <(AssetId, AccountId, AccountId)>::decode(&mut &params[..])
.map_err(|_| DispatchError::Other("DecodingFailed"))?;
Ok(Allowance(id, owner, spender))
},
3 => {
let id = <AssetId>::decode(&mut &params[..])
.map_err(|_| DispatchError::Other("DecodingFailed"))?;
Ok(TokenName(id))
},
4 => {
let id = <AssetId>::decode(&mut &params[..])
.map_err(|_| DispatchError::Other("DecodingFailed"))?;
Ok(TokenSymbol(id))
},
5 => {
let id = <AssetId>::decode(&mut &params[..])
.map_err(|_| DispatchError::Other("DecodingFailed"))?;
Ok(TokenDecimals(id))
},
// other calls
_ => Err(DispatchError::Other("UnknownFunctionId")),
}
}

pub(crate) fn construct_assets_call(
call_index: u8,
params: Vec<u8>,
Expand Down
Loading