Skip to content
Snippets Groups Projects
Unverified Commit 74177ae7 authored by bgallois's avatar bgallois
Browse files

add user documentation

parent 2bdecf86
No related branches found
No related tags found
1 merge request!268Fix #232
## Weights and Fees Calculation
### Introduction
Transaction weights and fees ensure network efficiency, fairness, and security in Substrate-based blockchains. These concepts are designed to manage resource allocation and incentivize proper usage of the blockchain infrastructure.
### Transaction Weights
Transaction weight measures the computational resources required to process a transaction. It is determined by factors such as the complexity of the transaction logic and the amount of data involved. Transactions with higher weights consume more resources and thus contribute to the overall load on the network.
### Transaction Fees
Transaction fees in Substrate-based blockchains are crucial for efficiently managing network resources and sustaining economic viability. They regulate resource allocation by ensuring transactions consuming more computational resources incur higher fees, discouraging spam, and promoting fair use of network capacity.
The fees are computed as follows:
`fee = base_fee + weight2fee * fee_multiplier + length2fee + tip`
## Fees in Duniter
### Fees Implementation Details
Implementing a zero-fee chain in Duniter involves configuring the blockchain to waive transaction fees when the current block weight is below a specified target. This approach aims to promote accessibility and encourage participation by eliminating fees during periods of lower network activity.
However, transaction fees are applied when the block weight surpasses the defined target to ensure network security and stability during increased usage. Additionally, leveraging the fee multiplier mechanism helps deter potential prolonged network attacks by dynamically adjusting fee levels based on previous network conditions.
Duniter members benefit from the quota system, which refunds transaction fees during high network activity periods.
Fees are computed as follows:
* If `current_weight < 0.25 * max_weight` and `fee_multiplier = 1`, ie. normal load:
`fee = 0`
* If `current_weight > 0.25 * max_weight`, ie. heavy usage (approximately more than 25 transactions per second):
`fee = `5cĞ1 + extrinsic_weight * (5cĞ1/base_extrinsic_weight)* fee_multiplier + extrinsic_length/100 + tip`
The multiplier is updated as follows:
* If `current_weight > 0.25 * max_weight`:
`Min(fee_multiplier += 1, 10)`
* If `current_weight < 0.25 * max_weight`:
`Max(fee_multiplier -= 1, 1)`
......@@ -64,7 +64,7 @@ where
/// Function to convert weight to fee when "constant-fees" feature is not enabled.
///
/// This function calculates the fee based on the length of the transaction in bytes.
/// If the current block weight is less than a fraction of the max block weight and the fee multiplier is zero,
/// If the current block weight is less than a fraction of the max block weight and the fee multiplier is one,
/// it returns a zero fee. Otherwise, it calculates the fee based on the length in bytes.
#[cfg(not(feature = "constant-fees"))]
fn weight_to_fee(length_in_bytes: &Weight) -> Self::Balance {
......@@ -120,7 +120,7 @@ where
/// Function to get the polynomial coefficients for weight to fee conversion.
///
/// This function calculates the polynomial coefficients for converting transaction weight to fee.
/// If the current block weight is less than a fraction of the block max weight and the fee multiplier is zero,
/// If the current block weight is less than a fraction of the block max weight and the fee multiplier is one,
/// it returns zero. Otherwise, it calculates the coefficients based on the extrinsic base weight mapped to 5 cents.
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
let weights = U::BlockWeights::get();
......
......@@ -190,7 +190,7 @@ macro_rules! pallets_config {
pub struct OnChargeTransaction;
parameter_types! {
pub Target: Perquintill = Perquintill::from_percent(10);
pub Target: Perquintill = Perquintill::from_percent(25);
pub MaxMultiplier: sp_runtime::FixedU128 = 10.into();
}
impl pallet_transaction_payment::Config for Runtime {
......
......@@ -91,6 +91,8 @@ fn test_fees_full() {
Balances::free_balance(AccountKeyring::Alice.to_account_id()),
10_000 - 5 * transactions
);
// Ensure that the next extrinsic exceeds the limit.
System::set_block_consumed_resources(Target::get() * normal_max_weight, 100_usize);
// The block will reach the fee limit, so the next extrinsic should start incurring fees.
let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death {
dest: AccountKeyring::Eve.to_account_id().into(),
......@@ -152,7 +154,7 @@ fn test_fees_multiplier() {
let mut current = 10u128;
for i in 20..50u32 {
run_to_block(i);
current = current.saturating_sub(1).max(1u128.into());
current = current.saturating_sub(1).max(1u128);
assert_eq!(
pallet_transaction_payment::Pallet::<Runtime>::next_fee_multiplier(),
current.into()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment