Welcome to the new Provenance Blockchain developer documentation portal!
logo
The Provenance Blockchain message fees module manages additional fees that can be applied to transaction messages specified through governance, providing an important economic tool for securing the proof-of-stake network by incentivizing staking and preventing spam. These additional fees are assessed based on message types and fee schedules persisted on-chain, can be denominated in any currency with optional distribution splits, and work alongside base gas fees to create a comprehensive fee structure that maintains backwards compatibility while enabling enhanced network economics and custom fee assessment capabilities for smart contracts.

Concepts

Additional Msg Fees

Fees is one of the most important tools available to secure a PoS network since it incentives staking and encourages spam prevention etc.
As part of the provenance blockchain economics certain messages may require an additional fee to be paid in addition to the normal gas consumption.
Additional fees are assessed and finally consumed based on msgType of the msgs contained in the transaction, and the fee schedule that is persisted on chain. These additional fees are created/updated/removed by governance through AddMsgFeeProposal, UpdateMsgFeeProposal, and RemoveMsgFeeProposal proposals.
Additional fee can be in any denom. This can be split to an optional bech32 account address with basis points.

Adding Custom Additional Fee from Wasm Contract

Creators of wasm contracts have the ability to dispatch an MsgAssessCustomMsgFeeRequest that charges a custom fee defined by the creator of the contract. The set fee will be split between the fee module and a specified address in the msg.

Base Fee

Base fee is the current fee implementation. Fees are paid in base denom and determined by gas value passed into the Tx. The value collected remains the same.

Total Fees

Total fees = Additional Fees (if any) + Base Fee
Total fees continue to be passed as sdk.Coins the Tx accepts for fee entry currently.
Example: usd.example is the denom (assuming there is a marker/coin of type usd.example) in which additional fee is being charged in:
shell
--fees 382199010nhash,99usd.example

Additional Fee Assessed in Base Denom (nhash)

To preserve backwards compatibility of all invokes, clients continue accepting fees in sdk.Coins type Coins []Coin, and because the code needs to distinguish between base fee and additional fee, the msgfees module introduces an additional param, called DefaultFloorGasPrice to differentiate between base fee and additional fee when additional fee is in same denom as default base denom (nhash).
This fee is charged initially by the antehandler, if any excess fee is left, once additional fee are paid, that's collected at the end of the Tx also (same as current behavior).
Example:
  • Additional fee = 10000nhash
  • Gas = 10000
  • Fee passed in = 19070000nhash
In this client passes in an extra 10000nhash (1905 * 10000 + 10000 = 19060000nhash). Current behavior is maintained and tx passes and charges 19050000 initially and 1000 nhash plus 1000nhash extra fee passed in the deliverTx stage. Thus, this will protect against future changes like priority mempool as well as keep current behavior same as current production.

Authz and Wasmd Messages

Authz and wasmd messages are dispatched via the submessages route, so they get charged and assessed the same additional fee if set on a submessage, caveat being they forfeit all their fees if they fail (since we have no way upfront of knowing what the submessages maybe).
Example: Let's say a MsgSend has a fee of 100usd.local and a smart contract does 3 MsgSend operations as per the logic of the smart contract, the code will expect additional fees of 300 usd.local (3 msgs x 100usd.local) to be present for the Tx to be successful.

Simulation and Calculating the Additional Fee to be Paid

Current simulation method looks like this:
java
// Source: https://github.com/provenance-io/provenance val cosmosService = cosmos.tx.v1beta1.ServiceGrpc.newBlockingStub(channel) cosmosService.simulate(SimulateRequest.newBuilder().setTx(txFinal).build()).gasInfo.gasUsed
In the future we recommend using the method:
java
// Source: https://github.com/provenance-io/provenance val msgFeeClient = io.provenance.msgfees.v1.QueryGrpc.newBlockingStub(channel) msgFeeClient.calculateTxFees(CalculateTxFeesRequest.newBuilder().setTx(txFinal).build())
Or from the command line as:
shell
provenanced tx simulate <required params>

Related Resources

State

The Provenance Blockchain message fees module stores its state using the MsgFee structure, which defines message-based fees on the blockchain and includes the message type URL, additional fee amount in any denomination, optional recipient address for fee distribution, and basis points for calculating the recipient's portion of the fee. This state is created and managed through governance proposals and enables flexible fee structures where fees can be split between recipients and the fee collector using a basis points system that supports up to 10,000 basis points for precise percentage allocations.

MsgFee Structure

The core of what gets stored on the blockchain to define a message-based fee:
protobuf
// Source: https://github.com/provenance-io/provenance // MsgFee is the core of what gets stored on the blockchain to define a msg-based fee. message MsgFee { // msg_type_url is the type-url of the message with the added fee, e.g. "/cosmos.bank.v1beta1.MsgSend". string msg_type_url = 1; // additional_fee is the extra fee that is required for the given message type (can be in any denom). cosmos.base.v1beta1.Coin additional_fee = 2 [(gogoproto.nullable) = false]; // recipient is an option address that will receive a portion of the additional fee. // There can only be a recipient if the recipient_basis_points is not zero. string recipient = 3; // recipient_basis_points is an optional portion of the additional fee to be sent to the recipient. // Must be between 0 and 10,000 (inclusive). // // If there is a recipient, this must not be zero. If there is not a recipient, this must be zero. // // The recipient will receive additional_fee * recipient_basis_points / 10,000. // The fee collector will receive the rest, i.e. additional_fee * (10,000 - recipient_basis_points) / 10,000. uint32 recipient_basis_points = 4; }

State Management

This state is created via governance proposals.

Field Details

msg_type_url

The type-url of the message with the added fee, e.g. /cosmos.bank.v1beta1.MsgSend.

additional_fee

The extra fee that is required for the given message type (can be in any denom).

recipient

An optional address that will receive a portion of the additional fee. There can only be a recipient if the recipient_basis_points is not zero.

recipient_basis_points

An optional portion of the additional fee to be sent to the recipient. Must be between 0 and 10,000 (inclusive).
Fee Distribution Logic:
  • If there is a recipient, this must not be zero
  • If there is not a recipient, this must be zero
  • The recipient will receive: additional_fee * recipient_basis_points / 10,000
  • The fee collector will receive the rest: additional_fee * (10,000 - recipient_basis_points) / 10,000

Messages

The Provenance Blockchain message fees module provides the MsgAssessCustomMsgFeeRequest message that enables smart contracts and applications to charge custom fees for their usage. This message allows for flexible fee assessment with optional recipient addresses and basis points distribution, supporting both USD and nhash denominations with automatic conversion capabilities, where USD amounts are specified in mils (1234 = $1.234) and can be automatically converted to nhash using the configured conversion rate parameter.

MsgAssessCustomMsgFeeRequest

A custom fee is applied when this message is broadcast. This would be used in a smart contract to charge a custom fee for the usage.
protobuf
// Source: https://github.com/provenance-io/provenance // MsgAssessCustomMsgFeeRequest defines an sdk.Msg type message MsgAssessCustomMsgFeeRequest { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_stringer) = true; // optional short name for custom msg fee, this will be emitted as a property of the event string name = 1; // amount of additional fee that must be paid cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false]; // optional recipient address, the basis points amount is sent to the recipient string recipient = 3; // the signer of the msg string from = 4; // optional basis points 0 - 10,000 for recipient defaults to 10,000 string recipient_basis_points = 5; }

Field Details

name

Optional short name for custom message fee. This will be emitted as a property of the event.

amount

Amount of additional fee that must be paid. The amount must be in usd or nhash else the message will not pass validation.
If the amount is specified as usd this will be converted to nhash using the UsdConversionRate parameter.
Note: usd and UsdConversionRate are specified in mils. Example: 1234 = $1.234

recipient

Optional bech32 address of an account that will receive the amount calculated from the recipient_basis_points.
If the recipient_basis_points is left empty the whole amount will be sent to the recipient. The remainder is sent to the Fee Module.

from

The signer of the message.

recipient_basis_points

Optional basis points 0 - 10,000 for recipient defaults to 10,000.

Related Resources

Events

The Provenance Blockchain message fees module emits comprehensive events to track fee collection and distribution throughout transaction processing. These events include standard fee tracking for all transactions showing total fees and minimum fees charged, additional fee breakdown events for transactions with message-specific fees, detailed summary events that provide JSON-formatted lists of fee information by message type and recipient, and governance proposal events for fee management operations, ensuring complete transparency and auditability of the fee system.

Any Tx

If a Tx was successful, or if it failed, but the min fee was charged, these two events are emitted:
Type
Attribute Key
Attribute Value
tx
fee
total fee (coins)
tx
min_fee_charged
floor gas price * gas (coins)

Tx with Additional Fee

If there are tx msgs that have additional fees, and those fees were successfully charged, a breakdown event will be emitted.
Type: tx
Attribute Key
Attribute Value
additionalfee
additional fee charged (coins)
basefee
total fee - additional fee, should always cover gas costs (coins)

Tx Summary Event

If there are tx msgs that have additional fees, and those fees were successfully charged, a summary event will be emitted.
Type: provenance.msgfees.v1.EventMsgFees
Type
Attribute Key
Attribute Value
EventMsgFees
MsgFees
A JSON list of EventMsgFee entries summarizing each msg type and recipient.

EventMsgFee Fields

Each EventMsgFee has the following fields:
Field Name
Field Value
type_url
The type url for the tx msg that has a msg fee.
count
A count of txs with this msg type.
total
The total amount of additional fees for this msg type and recipient (type_url count * msg fee = total)
recipient
the bech32 address that the fee was sent to. An empty string indicates the module is the recipient.

Add/Update/Remove Proposal

Governance proposals events (for proposed msg fees) will continue to be emitted by cosmos sdk.
go
// Source: https://github.com/cosmos/cosmos-sdk/blob/master/x/gov/spec/04_events.md // Governance events documentation available at the above GitHub link

Related Resources

Queries

Message Fees Query Messages

The Provenance Blockchain message fees module provides a comprehensive query service for accessing fee-related information and calculating transaction costs. The query service includes endpoints for retrieving module parameters, querying all message fees configured on the blockchain, and calculating estimated fees for transactions including both additional message-based fees and gas costs, enabling developers to accurately estimate and plan for transaction expenses before execution.

Params

Queries the parameters for the x/msgfees module.
HTTP Endpoint: GET /provenance/msgfees/v1/params
Request: QueryParamsRequestResponse: QueryParamsResponse

QueryParamsRequest

protobuf
// Source: https://github.com/provenance-io/provenance // QueryParamsRequest is the request type for the Query/Params RPC method. message QueryParamsRequest {}

QueryParamsResponse

protobuf
// Source: https://github.com/provenance-io/provenance // QueryParamsResponse is the response type for the Query/Params RPC method. message QueryParamsResponse { // params defines the parameters of the module. Params params = 1 [(gogoproto.nullable) = false]; }

QueryAllMsgFees

Query all messages which have fees associated with them.
HTTP Endpoint: GET /provenance/msgfees/v1/all
Request: QueryAllMsgFeesRequestResponse: QueryAllMsgFeesResponse

QueryAllMsgFeesRequest

protobuf
// Source: https://github.com/provenance-io/provenance // QueryAllMsgFeesRequest queries all Msg which have fees associated with them. message QueryAllMsgFeesRequest { // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageRequest pagination = 2; }

QueryAllMsgFeesResponse

protobuf
// Source: https://github.com/provenance-io/provenance // response for querying all msg's with fees associated with them message QueryAllMsgFeesResponse { repeated MsgFee msg_fees = 1; // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageResponse pagination = 2; }

CalculateTxFees

Simulates executing a transaction for estimating gas usage and additional fees.
HTTP Endpoint: POST /provenance/tx/v1/calculate_msg_based_fee
Request: CalculateTxFeesRequestResponse: CalculateTxFeesResponse

CalculateTxFeesRequest

protobuf
// Source: https://github.com/provenance-io/provenance // CalculateTxFeesRequest is the request type for the Query RPC method. message CalculateTxFeesRequest { // tx_bytes is the transaction to simulate. bytes tx_bytes = 1; // default_base_denom is used to set the denom used for gas fees // if not set it will default to nhash. string default_base_denom = 2; // gas_adjustment is the adjustment factor to be multiplied against the estimate returned by the tx simulation float gas_adjustment = 3; }

CalculateTxFeesResponse

protobuf
// Source: https://github.com/provenance-io/provenance // CalculateTxFeesResponse is the response type for the Query RPC method. message CalculateTxFeesResponse { // additional_fees are the amount of coins to be for addition msg fees repeated cosmos.base.v1beta1.Coin additional_fees = 1 [ (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (amino.dont_omitempty) = true, (amino.encoding) = "legacy_coins" ]; // total_fees are the total amount of fees needed for the transactions (msg fees + gas fee) // note: the gas fee is calculated with the floor gas price module param. repeated cosmos.base.v1beta1.Coin total_fees = 2 [ (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (amino.dont_omitempty) = true, (amino.encoding) = "legacy_coins" ]; // estimated_gas is the amount of gas needed for the transaction uint64 estimated_gas = 3; }
protobuf
// Example Query Service Definition // Source: https://github.com/provenance-io/provenance service Query { // Params queries the parameters for x/msgfees rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = "/provenance/msgfees/v1/params"; } // Query all Msgs which have fees associated with them. rpc QueryAllMsgFees(QueryAllMsgFeesRequest) returns (QueryAllMsgFeesResponse) { option (google.api.http).get = "/provenance/msgfees/v1/all"; } // CalculateTxFees simulates executing a transaction for estimating gas usage and additional fees. rpc CalculateTxFees(CalculateTxFeesRequest) returns (CalculateTxFeesResponse) { option (google.api.http) = { post: "/provenance/tx/v1/calculate_msg_based_fee" body: "*" }; } }

Params

The Provenance Blockchain message fees module contains configurable parameters that control fee calculation and currency conversion within the fee system. These parameters include the FloorGasPrice which sets the base denomination value for calculating base fees when both base and additional fees are charged in the same denomination, and NhashPerUsdMil which establishes the conversion rate between nhash and USD denominated in mils, enabling flexible fee structures and accurate currency conversions for transaction cost calculations.

Parameters

The MsgFee module contains the following parameters:
Key
Type
Example
FloorGasPrice
uint32
"1905"
NhashPerUsdMil
uint64
"14285714"

Parameter Details

FloorGasPrice

FloorGasPrice is the value of base denom that is charged for calculating base fees, for when base fee and additional fee are charged in the base denom.
Type: uint32Example: "1905"

NhashPerUsdMil

NhashPerUsdMil is the number of nhash per usd mil.
Type: uint64Example: "14285714"
go
// Example parameter structure // Source: https://github.com/provenance-io/provenance type Params struct { FloorGasPrice uint32 `json:"floor_gas_price"` NhashPerUsdMil uint64 `json:"nhash_per_usd_mil"` }

Special Topics

Governance