constant-fees
feature.pallet_certification
to enhance documentation generation and improve readability for users.Fee paid by the user when executing an extrinsic is computed as:
(base_fee + length_fee + weight_fee) * fee_multiplier
With:
base_fee = weight_to_fee(base_weight)
weight_fee = weight_to_fee(extrinsic_weight)
length_fee = length_to_fee(extrinsic_length_bytes)
fee_multiplier
can be adjusted after each block.Transaction fees should provide an incentive to limit on-chain resource consumption (storage, computation) and avoid malicious attacks.
Common guidelines to set these arbitrary functions (multiplier
, weight_to_fee
and length_to_fee
) are:
A fee too low will make the network vulnerable to attacks, and too high will inhibit the incentive to participate in the network. In our case, with the quota system, members will be refunded after each transaction if the network is not saturated.
Taking some statistics from the Duniter-v1 network over the past year, we observe that the mean transaction frequency is 0.01, representing 0.06 transactions per block of Duniter-v2s. At peak usage (occurring for less than a week cumulatively throughout the year), there were 0.09 transactions per second, equating to 0.54 transactions per Duniter-v2s block.
The maximum wallet value is 269 029 ĞD, while the median value of non-empty wallets is 450 ĞD. Additionally, only 25% of non-empty wallets have currently a balance exceeding 3 700 ĞD and the DU is currently at 10.78 ĞD.
To get an order of magnitude, on the actual reference machine, 26 482 700 base extrinsics can fill a block. The most computationally intensive calls are create_identity
, revoke_membership
, and remove_member
, and will take approximately 2 000 extrinsics to fill the block. Most calls are of the order of magnitude similar to a balance transfer that takes 8 264 calls to fill a block.
To start implementing the logic, a good starting point could be:
WeightToFeePolynomial
with a 1-degree polynomial to map 5 cĞD to 1 base extrinsic weight so that filling a block with base extrinsics will cost 1 324 135 ĞD, and filling a block with the most common extrinsics will cost 1 300 ĞD.FeeMultiplier
can be used to account for the variation of demand on the network. As the data from duniter-v1 shows that we are far from overcharging the network, it can be initially set to one, but it can be adjusted in the future to account for monetary mass and user growth.With these values, a simple balance transfer will cost 17 cĞD (0.016 DU), which is not prohibitively high for legitimate transactions (as it will be refunded). However, a malicious attacker would need to commit (and partially lose) at least 1 400 ĞD (130 DU) to fill one block that is more than 60% of the non-empty wallets in the current network.
This MR will put in place the logic to implement a non-constant weight-to-fee conversion, but the final exact parameters will also need discussion and adjustment, taking into account the final reference machine and the dynamics of the network at deployment.
To do: