Skip to content

Commit

Permalink
💸 USDT transaction payments (#403)
Browse files Browse the repository at this point in the history
## What?
Allow extrinsic fee payment with AssetHub assets that have a price in the oracle

## Why?
Needed for OTM flow

## How?
- Add the pallet_asset_tx_payment which is tightly coupled to pallet_transaction_payment.
- It gets the PLMC fee required for an extrinsic, and converts it to the asset from pallet_assets with our own custom logic.
 
## Testing?
In the next PR

## Anything Else?
- There already were some existing generic structs that implemented this logic, but they assumed the tip and fee to go to the same place. Since we want the fee to go to the Blockchain Operation Treasury, and the tip to go to the block author, we had to reimplement most logic.
 
- The original struct was `FungiblesAdapter<CON, HC>`.
where CON was the converter and HC the crediting of the fee.
Our solution copies that, but also implements a third generic, such that the second pays the fee-tip, and the third the fee. For more info check `pallet_asset_tx_payment::payment::FungiblesAdapter`
  • Loading branch information
JuaniRios authored Oct 10, 2024
1 parent 15efbfa commit 9d81e47
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 38 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ pallet-assets = { version = "36.0.0", default-features = false }
pallet-authorship = { version = "35.0.0", default-features = false }
pallet-session = { version = "35.0.0", default-features = false }
pallet-timestamp = { version = "34.0.0", default-features = false }
pallet-asset-tx-payment = { version = "35.0.0", default-features = false }
pallet-collective = { version = "35.0.0", default-features = false }
pallet-scheduler = { version = "36.0.0", default-features = false }
pallet-sudo = { version = "35.0.0", default-features = false }
Expand All @@ -175,6 +174,7 @@ pallet-vesting = { version = "35.0.0", default-features = false }
pallet-staking = { version = "35.0.0", default-features = false }
pallet-proxy = { version = "35.0.0", default-features = false }
pallet-identity = { version = "35.0.0", default-features = false }
pallet-asset-tx-payment = { version = "35.0.0", default-features = false }

# Polkadot (with default disabled)
pallet-xcm = { version = "14.0.0", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions integration-tests/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ mod governance;
mod oracle;
mod otm_edge_cases;
mod reserve_backed_transfers;
mod transaction_payment;
mod vest;
mod xcm_config;
4 changes: 4 additions & 0 deletions integration-tests/src/tests/transaction_payment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#[test]
fn fee_paid_with_foreign_assets() {
todo!();
}
6 changes: 3 additions & 3 deletions pallets/funding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ std = [
"pallet-balances/std",
"pallet-insecure-randomness-collective-flip/std",
"pallet-linear-release/std",
"pallet-proxy-bonding/std",
"pallet-timestamp/std",
"pallet-xcm/std",
"parachains-common/std",
Expand All @@ -96,7 +97,6 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
"pallet-proxy-bonding/std"
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand All @@ -107,6 +107,7 @@ runtime-benchmarks = [
"pallet-assets/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-linear-release/runtime-benchmarks",
"pallet-proxy-bonding/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-xcm/runtime-benchmarks",
"parachains-common/runtime-benchmarks",
Expand All @@ -117,7 +118,6 @@ runtime-benchmarks = [
"sp-runtime/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
"pallet-proxy-bonding/runtime-benchmarks"
]
try-runtime = [
"frame-support/try-runtime",
Expand All @@ -126,11 +126,11 @@ try-runtime = [
"pallet-balances/try-runtime",
"pallet-insecure-randomness-collective-flip/try-runtime",
"pallet-linear-release/try-runtime",
"pallet-proxy-bonding/try-runtime",
"pallet-timestamp/try-runtime",
"pallet-xcm/try-runtime",
"polimec-common-test-utils?/try-runtime",
"polimec-common/try-runtime",
"sp-runtime/try-runtime",
"pallet-proxy-bonding/try-runtime"
]
on-chain-release-build = []
36 changes: 18 additions & 18 deletions pallets/proxy-bonding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,41 +31,41 @@ pallet-assets.workspace = true


[features]
default = ["std"]
default = [ "std" ]

std = [
"frame-system/std",
"frame-benchmarking?/std",
"frame-support/std",
"sp-runtime/std",
"polimec-common/std",
"frame-system/std",
"pallet-assets/std",
"pallet-balances/std",
"pallet-linear-release/std",
"parity-scale-codec/std",
"polimec-common/std",
"scale-info/std",
"frame-benchmarking?/std",

"serde/std",
"sp-core/std",
"sp-io/std",
"pallet-linear-release/std",
"pallet-balances/std",
"pallet-assets/std",
"serde/std"
"sp-runtime/std",
]

try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"sp-runtime/try-runtime",
"polimec-common/try-runtime",
"pallet-linear-release/try-runtime",
"pallet-assets/try-runtime",
"pallet-balances/try-runtime"
"pallet-balances/try-runtime",
"pallet-linear-release/try-runtime",
"polimec-common/try-runtime",
"sp-runtime/try-runtime",
]

runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"polimec-common/runtime-benchmarks",
"pallet-linear-release/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-balances/runtime-benchmarks"
"pallet-balances/runtime-benchmarks",
"pallet-linear-release/runtime-benchmarks",
"polimec-common/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
11 changes: 7 additions & 4 deletions runtimes/polimec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ sp-transaction-pool.workspace = true
sp-version.workspace = true
sp-genesis-builder.workspace = true
frame-metadata-hash-extension.workspace = true
pallet-asset-tx-payment.workspace = true

# Polkadot
pallet-xcm.workspace = true
Expand Down Expand Up @@ -135,6 +136,7 @@ std = [
"log/std",
"on-slash-vesting/std",
"orml-oracle/std",
"pallet-asset-tx-payment/std",
"pallet-assets/std",
"pallet-aura/std",
"pallet-authorship/std",
Expand All @@ -153,6 +155,7 @@ std = [
"pallet-oracle-ocw/std",
"pallet-parachain-staking/std",
"pallet-preimage/std",
"pallet-proxy-bonding/std",
"pallet-proxy/std",
"pallet-scheduler/std",
"pallet-session/std",
Expand All @@ -175,7 +178,7 @@ std = [
"sp-block-builder/std",
"sp-consensus-aura/std",
"sp-core/std",
# "sp-debug-derive/std",
# "sp-debug-derive/std",
"sp-genesis-builder/std",
"sp-inherents/std",
"sp-offchain/std",
Expand All @@ -188,7 +191,6 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
"pallet-proxy-bonding/std"
]

runtime-benchmarks = [
Expand Down Expand Up @@ -219,6 +221,7 @@ runtime-benchmarks = [
"pallet-oracle-ocw/runtime-benchmarks",
"pallet-parachain-staking/runtime-benchmarks",
"pallet-preimage/runtime-benchmarks",
"pallet-proxy-bonding/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
"pallet-scheduler/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
Expand All @@ -234,7 +237,6 @@ runtime-benchmarks = [
"sp-runtime/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
"pallet-proxy-bonding/runtime-benchmarks"
]

try-runtime = [
Expand All @@ -247,6 +249,7 @@ try-runtime = [
"frame-system/try-runtime",
"frame-try-runtime/try-runtime",
"orml-oracle/try-runtime",
"pallet-asset-tx-payment/try-runtime",
"pallet-assets/try-runtime",
"pallet-aura/try-runtime",
"pallet-authorship/try-runtime",
Expand All @@ -265,6 +268,7 @@ try-runtime = [
"pallet-oracle-ocw/try-runtime",
"pallet-parachain-staking/try-runtime",
"pallet-preimage/try-runtime",
"pallet-proxy-bonding/try-runtime",
"pallet-proxy/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-session/try-runtime",
Expand All @@ -279,7 +283,6 @@ try-runtime = [
"polkadot-runtime-common/try-runtime",
"shared-configuration/try-runtime",
"sp-runtime/try-runtime",
"pallet-proxy-bonding/try-runtime"
]

# A feature that should be enabled when the runtime should be built for on-chain
Expand Down
45 changes: 40 additions & 5 deletions runtimes/polimec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
use frame_support::{
construct_runtime,
genesis_builder_helper::{build_state, get_preset},
instances::Instance1,
ord_parameter_types, parameter_types,
traits::{
fungible::{Credit, HoldConsideration, Inspect},
tokens::{self, PayFromAccount, UnityAssetBalanceConversion},
fungibles,
tokens::{self, ConversionToAssetBalance, PayFromAccount, UnityAssetBalanceConversion},
AsEnsureOriginWithArg, ConstU32, Contains, EitherOfDiverse, InstanceFilter, LinearStoragePrice, PrivilegeCmp,
TransformOrigin,
},
Expand All @@ -41,9 +43,10 @@ use pallet_aura::Authorities;
use pallet_democracy::GetElectorate;
use pallet_funding::{
runtime_api::ProjectParticipationIds, types::AcceptedFundingAsset, BidInfoOf, ContributionInfoOf, DaysToBlocks,
EvaluationInfoOf, ProjectDetailsOf, ProjectId, ProjectMetadataOf,
EvaluationInfoOf, PriceProviderOf, ProjectDetailsOf, ProjectId, ProjectMetadataOf,
};
use parachains_common::{
impls::AssetsToBlockAuthor,
message_queue::{NarrowOriginToSibling, ParaIdToSibling},
AssetIdForTrustBackedAssets as AssetId,
};
Expand All @@ -60,7 +63,7 @@ use sp_runtime::{
IdentifyAccount, IdentityLookup, OpaqueKeys, Verify,
},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult, FixedU128, MultiSignature, SaturatedConversion,
ApplyExtrinsicResult, FixedPointNumber, FixedU128, MultiSignature, SaturatedConversion,
};
use sp_std::{cmp::Ordering, prelude::*};
use sp_version::RuntimeVersion;
Expand All @@ -87,10 +90,13 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
use sp_version::NativeVersion;

use crate::xcm_config::PriceForSiblingParachainDelivery;
use polimec_common::USD_UNIT;
use polimec_common::{ProvideAssetPrice, USD_UNIT};
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;

use sp_runtime::{
traits::{DispatchInfoOf, PostDispatchInfoOf},
transaction_validity::{InvalidTransaction, TransactionValidityError},
};
#[cfg(feature = "runtime-benchmarks")]
mod benchmark_helpers;
mod custom_migrations;
Expand Down Expand Up @@ -1154,6 +1160,34 @@ impl pallet_dispenser::Config for Runtime {
type WhitelistedPolicy = DispenserWhitelistedPolicy;
}

pub struct PLMCToFundingAssetBalance;
impl ConversionToAssetBalance<Balance, AssetId, Balance> for PLMCToFundingAssetBalance {
type Error = InvalidTransaction;

fn to_asset_balance(plmc_balance: Balance, asset_id: AssetId) -> Result<Balance, Self::Error> {
let plmc_price =
<PriceProviderOf<Runtime>>::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS)
.ok_or(InvalidTransaction::Payment)?;
let funding_asset_decimals = <ForeignAssets as fungibles::metadata::Inspect<AccountId>>::decimals(asset_id);
let funding_asset_price =
<PriceProviderOf<Runtime>>::get_decimals_aware_price(asset_id, USD_DECIMALS, funding_asset_decimals)
.ok_or(InvalidTransaction::Payment)?;
let usd_balance = plmc_price.saturating_mul_int(plmc_balance);
let funding_asset_balance =
funding_asset_price.reciprocal().ok_or(InvalidTransaction::Payment)?.saturating_mul_int(usd_balance);
Ok(funding_asset_balance)
}
}
impl pallet_asset_tx_payment::Config for Runtime {
type Fungibles = ForeignAssets;
type OnChargeAssetTransaction = TxFeeFungiblesAdapter<
PLMCToFundingAssetBalance,
CreditFungiblesToAccount<AccountId, ForeignAssets, BlockchainOperationTreasury>,
AssetsToBlockAuthor<Runtime, ForeignAssetsInstance>,
>;
type RuntimeEvent = RuntimeEvent;
}

// Create the runtime by composing the FRAME pallets that were previously configured.
construct_runtime!(
pub enum Runtime
Expand All @@ -1176,6 +1210,7 @@ construct_runtime!(
ContributionTokens: pallet_assets::<Instance1> = 13,
ForeignAssets: pallet_assets::<Instance2> = 14,
Dispenser: pallet_dispenser = 15,
AssetTransactionPayment: pallet_asset_tx_payment = 16,

// Collator support. the order of these 5 are important and shall not change.
Authorship: pallet_authorship::{Pallet, Storage} = 20,
Expand Down
1 change: 1 addition & 0 deletions runtimes/shared-configuration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pallet-authorship.workspace = true
pallet-parachain-staking.workspace = true
pallet-oracle-ocw.workspace = true
pallet-treasury = {workspace = true, optional = true}
pallet-asset-tx-payment.workspace = true

[features]
default = [ "std" ]
Expand Down
Loading

0 comments on commit 9d81e47

Please sign in to comment.