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

feat: api fungibles pallet #113

Merged
merged 22 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ members = [
"runtime/devnet",
"runtime/testnet",
"integration-tests",
"pallets/*",
"primitives",
"scripts/fund-dev-accounts",
]
Expand Down Expand Up @@ -51,6 +52,7 @@ substrate-wasm-builder = "18.0.1"
substrate-build-script-utils = "11.0.0"

# Local
pallet-pop-api = { path = "pallets/api", default-features = false }
pop-runtime-devnet = { path = "runtime/devnet", default-features = true } # default-features=true required for `-p pop-node` builds
pop-runtime-testnet = { path = "runtime/testnet", default-features = true } # default-features=true required for `-p pop-node` builds
pop-runtime-common = { path = "runtime/common", default-features = false }
Expand Down
50 changes: 50 additions & 0 deletions pallets/api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[package]
name = "pallet-pop-api"
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved
authors.workspace = true
description = "Pop api pallet, enabling smart contracts to use the power of Polkadot"
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved
edition.workspace = true
license.workspace = true
version = "0.1.0"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec.workspace = true
scale-info.workspace = true

# Substrate
frame-benchmarking.workspace = true
frame-support.workspace = true
frame-system.workspace = true
pallet-assets.workspace = true
sp-runtime.workspace = true

[dev-dependencies]
sp-core.workspace = true
sp-io.workspace = true

[features]
default = ["std"]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
std = [
"codec/std",
"frame-benchmarking/std",
"frame-support/std",
"frame-system/std",
"pallet-assets/std",
"scale-info/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"sp-runtime/try-runtime",
]
84 changes: 84 additions & 0 deletions pallets/api/src/fungibles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[cfg(test)]
mod mock;

#[cfg(test)]
mod tests;

#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;

#[frame_support::pallet]
pub mod pallet {
use frame_support::{
dispatch::WithPostDispatchInfo, pallet_prelude::*, traits::fungibles::Inspect,
};
use frame_system::pallet_prelude::*;
use pallet_assets::WeightInfo;
use sp_runtime::traits::StaticLookup;

type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
type AssetIdOf<T> = <pallet_assets::Pallet<T, TrustBackedAssetsInstance> as Inspect<
<T as frame_system::Config>::AccountId,
>>::AssetId;
type AssetIdParameterOf<T> =
<T as pallet_assets::Config<TrustBackedAssetsInstance>>::AssetIdParameter;
type Assets<T> = pallet_assets::Pallet<T, TrustBackedAssetsInstance>;
type AssetsWeightInfo<T> = <T as pallet_assets::Config<TrustBackedAssetsInstance>>::WeightInfo;
type BalanceOf<T> = <pallet_assets::Pallet<T, TrustBackedAssetsInstance> as Inspect<
<T as frame_system::Config>::AccountId,
>>::Balance;
// Should be defined in primitives.
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved
type TrustBackedAssetsInstance = pallet_assets::Instance1;

#[pallet::config]
pub trait Config:
frame_system::Config + pallet_assets::Config<TrustBackedAssetsInstance>
{
}

#[pallet::pallet]
pub struct Pallet<T>(_);

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(AssetsWeightInfo::<T>::transfer_keep_alive())]
pub fn transfer(
origin: OriginFor<T>,
id: AssetIdParameterOf<T>,
target: AccountIdLookupOf<T>,
amount: BalanceOf<T>,
) -> DispatchResult {
Assets::<T>::transfer_keep_alive(origin, id, target, amount)
}

#[pallet::call_index(1)]
#[pallet::weight(AssetsWeightInfo::<T>::cancel_approval())]
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved
pub fn approve(
origin: OriginFor<T>,
id: AssetIdParameterOf<T>,
spender: AccountIdLookupOf<T>,
value: BalanceOf<T>,
) -> DispatchResultWithPostInfo {
Assets::<T>::cancel_approval(origin.clone(), id.clone(), spender.clone())
.map_err(|e| e.with_weight(AssetsWeightInfo::<T>::cancel_approval()))?;
Assets::<T>::approve_transfer(origin, id, spender, value).map_err(|e| {
e.with_weight(
AssetsWeightInfo::<T>::cancel_approval()
+ AssetsWeightInfo::<T>::approve_transfer(),
)
})?;
Ok(().into())
}
}

impl<T: Config> Pallet<T> {
pub fn total_supply(id: AssetIdOf<T>) -> BalanceOf<T> {
Assets::<T>::total_supply(id)
}
}
}
22 changes: 22 additions & 0 deletions pallets/api/src/fungibles/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//! Benchmarking setup for pallet-parachain-template
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved

// https://docs.substrate.io/test/benchmark/

use super::*;

#[allow(unused)]
use crate::Pallet as Template;

Check failure on line 8 in pallets/api/src/fungibles/benchmarking.rs

View workflow job for this annotation

GitHub Actions / clippy

unresolved import `crate::Pallet`

error[E0432]: unresolved import `crate::Pallet` --> pallets/api/src/fungibles/benchmarking.rs:8:5 | 8 | use crate::Pallet as Template; | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `Pallet` in the root | help: consider importing one of these items instead | 8 | use crate::fungibles::Pallet as Template; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 | use frame_benchmarking::baseline::Pallet as Template; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 | use frame_system::Pallet as Template; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 | use pallet_assets::Pallet as Template; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, whitelisted_caller};
use frame_system::RawOrigin;

benchmarks! {
do_something {
let s in 0 .. 100;
let caller: T::AccountId = whitelisted_caller();
}: _(RawOrigin::Signed(caller), s)
verify {
assert_eq!(Something::<T>::get(), Some(s));

Check failure on line 18 in pallets/api/src/fungibles/benchmarking.rs

View workflow job for this annotation

GitHub Actions / clippy

failed to resolve: use of undeclared type `Something`

error[E0433]: failed to resolve: use of undeclared type `Something` --> pallets/api/src/fungibles/benchmarking.rs:18:14 | 18 | assert_eq!(Something::<T>::get(), Some(s)); | ^^^^^^^^^ use of undeclared type `Something`
}
}

impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test,);
22 changes: 22 additions & 0 deletions pallets/api/src/fungibles/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::{mock::*, Error};
use frame_support::{assert_noop, assert_ok};

// https://docs.substrate.io/test/

#[test]
fn it_works_for_default_value() {
new_test_ext().execute_with(|| {
// Dispatch a signed extrinsic.
assert_ok!(fungibles::do_something(RuntimeOrigin::signed(1), 42));
// Read pallet storage and assert an expected result.
assert_eq!(fungibles::something(), Some(42));
});
}

#[test]
fn correct_error_for_none_value() {
new_test_ext().execute_with(|| {
// Ensure the expected error is thrown when no value is present.
assert_noop!(fungibles::cause_error(RuntimeOrigin::signed(1)), Error::<Test>::NoneValue);
});
}
3 changes: 3 additions & 0 deletions pallets/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub mod fungibles;
60 changes: 60 additions & 0 deletions pallets/api/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use frame_support::{parameter_types, traits::Everything};
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved
use frame_system as system;
use sp_core::H256;
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
BuildStorage,
};

type Block = frame_system::mocking::MockBlock<Test>;

// Configure a mock runtime to test the pallet.
frame_support::construct_runtime!(
pub enum Test
{
System: frame_system::{Pallet, Call, Config<T>, Storage, Event<T>},
fungibles: crate::{Pallet, Call, Storage, Event<T>},
}
);

parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const SS58Prefix: u8 = 42;
}

#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl system::Config for Test {
type BaseCallFilter = Everything;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type Nonce = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = Block;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = BlockHashCount;
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = SS58Prefix;
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
}

impl crate::Config for Test {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
}

// Build genesis storage according to the mock runtime.
pub fn new_test_ext() -> sp_io::TestExternalities {
system::GenesisConfig::<Test>::default().build_storage().unwrap().into()
}
4 changes: 3 additions & 1 deletion runtime/devnet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ smallvec.workspace = true

# Local
pop-primitives = { workspace = true, features = ["assets", "cross-chain", "nfts"] }
pop-runtime-common = { workspace = true, default-features = false }
pop-runtime-common.workspace = true
pallet-pop-api.workspace = true

# Substrate
frame-benchmarking.workspace = true
Expand Down Expand Up @@ -119,6 +120,7 @@ std = [
"pallet-balances/std",
"pallet-collator-selection/std",
"pallet-contracts/std",
"pallet-pop-api/std",
"pallet-message-queue/std",
"pallet-multisig/std",
"pallet-nft-fractionalization/std",
Expand Down
11 changes: 7 additions & 4 deletions runtime/devnet/src/config/assets.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
use crate::{
deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent,
RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT,
};
use frame_support::{
parameter_types,
traits::{AsEnsureOriginWithArg, ConstU32},
Expand All @@ -12,6 +8,11 @@ use pallet_nfts::PalletFeatures;
use parachains_common::{AssetIdForTrustBackedAssets, CollectionId, ItemId, Signature};
use sp_runtime::traits::Verify;

use crate::{
deposit, fungibles, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime,
Daanvdplas marked this conversation as resolved.
Show resolved Hide resolved
RuntimeEvent, RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT,
};

/// We allow root to execute privileged asset operations.
pub type AssetsForceOrigin = EnsureRoot<AccountId>;

Expand Down Expand Up @@ -119,3 +120,5 @@ impl pallet_assets::Config<TrustBackedAssetsInstance> for Runtime {
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}

impl fungibles::Config for Runtime {}
9 changes: 5 additions & 4 deletions runtime/devnet/src/extensions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use xcm::{
};

use crate::{
config::assets::TrustBackedAssetsInstance, AccountId, AllowedApiCalls, Balance, Runtime,
RuntimeCall, RuntimeOrigin, UNIT,
config::assets::TrustBackedAssetsInstance, fungibles, AccountId, AllowedApiCalls, Balance,
Runtime, RuntimeCall, RuntimeOrigin, UNIT,
};
use pop_primitives::{
cross_chain::CrossChainMessage,
Expand Down Expand Up @@ -174,7 +174,7 @@ fn construct_call(
match pallet_index {
index if index == super::Assets::index() as u8 => {
let call = versioned_construct_assets_call(version, call_index, params)?;
Ok(RuntimeCall::Assets(call))
Ok(RuntimeCall::Fungibles(call))
},
_ => Err(DispatchError::Other("UnknownFunctionId")),
}
Expand All @@ -199,7 +199,8 @@ fn versioned_construct_assets_call(
version: u8,
call_index: u8,
params: Vec<u8>,
) -> Result<pallet_assets::Call<Runtime, TrustBackedAssetsInstance>, DispatchError> {
// ) -> Result<pallet_assets::Call<Runtime, TrustBackedAssetsInstance>, DispatchError> {
) -> Result<fungibles::Call<Runtime>, DispatchError> {
match version {
V0 => v0::assets::construct_assets_call(call_index, params),
_ => Err(DispatchError::Other("UnknownFunctionId")),
Expand Down
Loading
Loading