Merci @ManUtopiK pour tes tests
Alors les frais de transaction c’est compliqué, il y a 5 composantes à prendre en compte:
- Le coût de base d’un extrinsic (constant par transaction)
- Le coût d’exécution de l’appel (issu des benchmarks, ce sont les fameux « poids »)
- Le multiplicateur, qui varie dynamiquement selon la congestion de la blockchain (valeur 1 en l’absence de congestion)
- Le coût lié à la taille de la transaction (length fees)
- Le don éventuel joint par l’utilisateur (tip)
Les frais sont calculés par la formule :
(coût d’exécution de l’appel × multiplicateur de congestion) + coût lié à la taille + coût de base
Tu as 4 runtime APIs pour récupérer les données liées au frais:
TransactionPaymentApi_query_info(extrinsic, length) -> number
TransactionPaymentApi_query_fee_details(extrinsic, length) -> FeeDetails
TransactionPaymentApi_query_weight_to_fee(weight) -> number
TransactionPaymentApi_query_length_to_fee(length) -> number
Je ne sais pas quelle runtime API la fonction getPaymentInfo()
de PAPI appelle exactement. Avec PAPI, vous pouvez cependant appeler directement la runtime API de votre choix ; je vous recommande de le faire pour maîtriser précisément ce qui est récupéré. Par exemple, pour obtenir le détail de chaque composante des frais :
const api = client.getTypedApi(gdev);
const { inclusion_fee } =
await api.apis.TransactionPaymentApi.queryFeeDetails(tx, length);
console.log(inclusion_fee.base_fee, inclusion_fee.len_fee, inclusion_fee.adjusted_weight_fee);
L’objet inclusion_fee contient trois champs :
base_fee
: coût de base constant par transaction.len_fee
: coût lié à la taille de la transaction en octets.adjusted_weight_fee
: résultat de la multiplication « coût d’exécution de l’appel × multiplicateur de congestion ».
Concernant le remboursement, il y a deux mécanismes qui peuvent déclencher un remboursement :
- Substrate peut rembourser tout ou partie de la composante
adjusted_weight_fee
. En effet, les frais d’exécution ne sont connus précisément qu’après exécution. Substrate prélève d’abord un montant basé sur le pire scénario, puis rembourse la différence si l’exécution réelle est moins coûteuse. - Duniter-v2s peut rembourser tout ou partie des frais effectivement prélevés (après ajustement par Substrate), mais seulement si l’utilisateur dispose de quotas. Le montant disponible dépend du temps écoulé depuis la dernière transaction : plus une transaction est récente, moins l’utilisateur a de quotas. Pour plus de détails, voir : Implémentation des quotas
Avec tous ces paramètres, il est très compliqué de prédire le montant final des frais payés par l’utilisateur après remboursements.
L’implémentation personnalisée des quotas, réalisée par Hugo, Tuxmain et Benjamin Gallois, n’intègre pas de runtime API permettant de simuler le probable remboursement ; de plus, le fait que le taux d’usage des quotas évolue à chaque bloc (pour se recharger entièrement après 1 h, via ReloadRate
) complique l’implémentation d’une telle simulation.
Il faudrait probablement modifier ce comportement pour le rendre plus prévisible (qu’il ne change pas à chaque bloc). Je viens de créer un ticket: Make Quota mechanism more predictable and add a runtime API to simulate refund amount (#308) · Issues · nodes / rust / Duniter v2S · GitLab.