Skip to content

Commit

Permalink
Merge branch 'grarco/updates-fees' (#385)
Browse files Browse the repository at this point in the history
Update fees docs
  • Loading branch information
brentstone authored Sep 11, 2024
2 parents 44bc370 + ec6de73 commit 8aa60a4
Showing 1 changed file with 97 additions and 47 deletions.
144 changes: 97 additions & 47 deletions packages/docs/pages/users/fees.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,74 @@ import { Callout } from "nextra-theme-docs";

# Fees on Namada

In order to settle the market for Namada blockspace demand, fees are coupled with transactions. In order for any namada transaction to be considered valid, the correct corresponding fee must be paid. The exact fee is set by the user, and must be greater than or equal to the minimum `gas-price` set by governance, which is included in the genesis file under `gas_cost`.
In order to settle the market for Namada blockspace demand, fees are coupled with transactions.
In order for any namada transaction to be considered valid, the correct corresponding fee must be paid.
The exact fee is set by the user, and must be greater than or equal to the minimum `gas-price` set by governance, which is included in the genesis file under `gas_cost`.

## How fees are paid
When explicitly stated, the gas fee is paid by the `--gas-payer` flag. If no `--gas-payer` flag is specified, the gas fee is paid by the first key in the `--signing-keys` flag.

<Callout type="info" emoji="🤡">
Note the use of the placeholder `keysha` for the key parameter. This is a completely configurable parameter, and should just refer to the alias of the key signing the transaction (that has a positive nam balance).
</Callout>
Fees are **always** paid from the balance of an **implicit** address. When explicitly stated, the gas fee is paid by the `--gas-payer` flag.
If no `--gas-payer` flag is specified, the gas fee is paid by the first key in the `--signing-keys` flag, if those are specified.
If no `--signing-keys` flag is specified, the client will try to infer the signer from the source of the transaction and use that account as the fee payer.

This means that in the transaction
First consider the example of a simple transfer:
```shell copy
namada client transfer \
--source my-new-acc \
namadac transparent-transfer \
--source my-acc \
--target validator-1 \
--token NAM \
--amount 10 \
--signing-keys keysha
```

the account associated with key `keysha` will be required to pay the fee. This means that even though the account `accountant` may have a positive NAM balance, `keysha` will need to have the associated NAM in order to pay the transaction fee.
With no `--gas-payer` or `--signing-keys` explicitly provided, the client will infer the proper account related to `my-acc` from which to take the fees.
If `my-acc` is an implicit address, the fees will be taken directly from it.
If it is an established address, the fees will be taken from the implicit address associated with `my-acc` (usually the account used to initialize the established address).

A user can also specify a `--gas-payer` flag to specify a different account to pay the fee. This is useful in cases where the account that is signing the transaction does not have enough NAM to pay the fee. For example, if `keysha` has a balance of 5 NAM, but `accountant` has a balance of 100 NAM, then the following transaction will be valid:
However, another gas payer can be specified in this transaction by providing another implicit address for which the user owns the private key:
```shell copy
namadac transparent-transfer \
--source my-acc \
--target validator-1 \
--token NAM \
--amount 10 \
--gas-payer my-other-acc
```

Now consider the example of a transfer from a 2-of-n multisignature account:
```shell copy
namada client transfer \
--source my-new-acc \
namadac transparent-transfer \
--source my-multisig \
--target validator-1 \
--token NAM \
--amount 10 \
--signing-keys keysha \
--gas-payer accountant
```
--signing-keys key1,key2
```

(Assuming that `accountant` exists and is in the wallet of the user)
In this case, the fees will be taken from the first key provided to `--signing-keys`: `key1`.
As before, any gas payer can be specified by supplying the desired key to the `--gas-payer` argument like such:
```shell copy
namadac transparent-transfer \
--source my-multisig \
--target validator-1 \
--token NAM \
--amount 10 \
--signing-keys key1,key2 \
--gas-payer key2
```

For testnet purposes, we recommend [using the faucet](../networks/testnets/faucet.mdx) to source NAM for transaction fees.

## How fees are calculated

The fee for a transaction is calculated by multiplying `gas-limit` by the gas price.
Both the `--gas-limit` and the `--gas-price` can be specified by the user. If neither is specified, the default gas limit and minimum gas price is used. The default gas limit for any transaction is currently set to `20_000`.
Both the `--gas-limit` and the `--gas-price` can be specified by the user. If neither is specified, the default gas limit and minimum gas price is used.
The default gas limit for any transaction is currently set to `200_000`.

The minimum gas price is set in the genesis file under `gas_cost`.
The minimum gas price is set in the genesis file under `minimum_gas_price`.
One can query the minimum gas prices for all tokens accepted for gas payment in a network with:
```shell copy
namadac query-protocol-parameters
```

## How to set the gas price and gas limit

Expand All @@ -53,84 +79,108 @@ For example, the following command will simulate a transfer transaction, and ret

```shell copy
namadac transfer \
--source my-new-acc \
--source my-acc \
--target validator-1 \
--token NAM \
--amount 10 \
--signing-keys keysha \
--gas-payer accountant \
--signing-keys key1 \
--dry-run-wrapper
```

Which will output something along the lines of

```md
Dry-run result: Transaction is valid. Gas used: 1785;
Dry-run result: Transaction consumed 147850 gas. Inner transaction <tx-hash> was successfully applied.
```
This means that we could reasonably make this transfer transaction with a `gas-limit` of 2000.
This means that we could reasonably make this transfer transaction with a `gas-limit` of 150000.

Hence, when making the transfer, we could specify the `gas-limit` as follows:

```shell copy
namadac transfer \
--source my-new-acc \
--source my-acc \
--target validator-1 \
--token NAM \
--amount 10 \
--signing-keys keysha \
--gas-payer accountant \
--gas-limit 2000
--signing-keys key1 \
--gas-limit 150000
```

If for some reason, we wanted to pay a higher gas fee, we could also specify that as follows:

```shell copy
namadac transfer \
--source my-new-acc \
--source my-acc \
--target validator-1 \
--token NAM \
--amount 10 \
--signing-keys keysha \
--gas-payer accountant \
--gas-limit 2000 \
--signing-keys key1 \
--gas-limit 150000 \
--gas-price 0.01
```
This will incentivise validators to prioritise this transaction above those with a lower gas price.

This **might** incentivise validators to prioritise this transaction above those with a lower gas price.

## Paying fees with tokens in the MASP

It is also possible to pay for fees using the MASP. The purpose of this is to ensure that even though a user may not have NAM in their transparent balance, they can still make transparent transactions on chain. This is yet another incentive for users to keep the maximum amount of assets in the MASP.
It is also possible to pay for fees using the MASP when dealing with a transfer transaction involving shielded inputs (shielding, shielded, and unshielding transfers both natively and with IBC).
The purpose of this is to ensure that a user can make transactions on-chain even if they may not have NAM in their transparent balance.
This is yet another incentive for users to keep the maximum amount of assets in the MASP.
On top of this, paying fees via the MASP is required to prevent information leakage that could defy the purpose of the shielded pool.

When dealing with MASP fee payment, the client will try to deduct the fees from the source of the shielded transaction and unshield them to the transparent balance of the `--gas-payer` (or the address corresponding to the first key in the `--signing-keys`) before being paid to the block proposer.
If the shielded account does not have enough funds to cover the gas cost, the user must specify the `--gas-spending-key` flag and set it the alias of another spending key in your wallet.
The client will try to combine the residual balances of the original sender and this extra key to cover the entirety of the fees.

In order to pay for fees using the MASP, the user must specify the `--gas-spending-key` flag, and set it the alias of a spending key in your wallet. This will mean that the fees will be deducted from the shielded balance of the spending key, and unshielded to the transparent balance of the `--gas-payer` (or the address corresponding to the first key in the `--signing-keys`), before being paid for by the `--gas-payer`.
For example, if the user has a spending key `spending-key-1` in their wallet, and they want to pay for the fees of a shielded transfer transaction using the MASP, they would run the following command:

```shell copy
namadac transfer \
--source spending-key-1 \
--target payment-addr-b \
--token OSMO \
--amount 10 \
--gas-payer my-implicit \
```

For example, if the user has a spending key `spending-key-1` in their wallet, and they want to pay for the fees of a transaction using the MASP, they would run the following command:
If `spending-key-1` cannot cover for the entire cost, the user can specify an additional spending key for fee payment:

```shell copy
namadac transfer \
--source keysha \
--target address-b \
--source spending-key-1 \
--target payment-addr-b \
--token OSMO \
--amount 10 \
--gas-payer keysha \
--gas-spending-key spending-key-1
--gas-payer my-implicit \
--gas-spending-key spending-key-2
```

In this example, `keysha` may only have an OSMO balance in their transparent balance, but `spending-key-1` may have a positive NAM balance in their shielded balance. In this case, the NAM will be unshielded to the transparent balance of `keysha`, and then used to pay for the transaction fee.
In these examples, `my-implicit` may only have an OSMO balance in their transparent balance, but `spending-key-1` (and possibly `spending-key-2`) may have a positive NAM balance in their shielded balance.
In this case, the NAM will be unshielded to the transparent balance of `my-implicit` and then used to pay for the transaction fee.
So it is requried to unshield just the difference between the gas cost and the transparent balance of the gas payer implicit address.

<Callout type="info">
It is also possible to use MASP fee payment to pay fees for non-MASP transactions.
To do so, the user should create a transaction batch where the first transaction is a MASP transaction that unshields the funds for fee payment to the fee payer's address.
The actual intended transaction can then be attached as the second transaction of the batch.
</Callout>

### Using a disposable gas payer

It is also possible to use a disposable gas payer to pay for transaction fees. This is useful in cases where the user does not want to reveal the identity of the `--gas-payer`. In order to use a disposable gas payer, the user must include the `--disposable-gas-payer` flag, AND also must specify a `--gas-spending-key` . This will mean that the fees will be deducted from the shielded balance of the `--gas-spending-key`, and unshielded to the transparent balance of an ephemeral transparent address before being paid for by the ephemeral address.
It is also possible to use a disposable gas payer to pay for transaction fees.
This is useful (and recommended) in cases where the user does not want to leak information and reveal the identity of the `--gas-payer` to prevent correlation.
In order to use a disposable gas payer, the user must include the `--disposable-gas-payer` flag.
The fees will be deducted from the shielded balance of the shielded transactions source (and optionally from the balance of the `--gas-spending-key` when provided) and unshielded to the transparent balance of an ephemeral transparent address before being paid by the ephemeral address.

For example, if the user has a spending key `spending-key-1` in their wallet, and they want to pay for the fees of a transaction using a disposable address, they would run the following command:
For example, if the user has the same two spending keys from the previous example in their wallet, and they want to pay for the fees of an unshield transfer transaction using a disposable address, they would run the following command:

```shell copy
namadac transfer \
--source keysha \
--target address-b \
namadac unshield \
--source spending-key-1 \
--target addr-b \
--token OSMO \
--amount 10 \
--gas-spending-key spending-key-1 \
--gas-spending-key spending-key-2 \
--disposable-gas-payer
```

0 comments on commit 8aa60a4

Please sign in to comment.