dynamicfee

package
v0.0.0-...-5416434 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2025 License: Apache-2.0 Imports: 21 Imported by: 0

README


sidebar_position: 1

x/dynamicfee

Abstract

This document describes the specifications of the AtomOne implementation of the x/dynamicfee module. This module is a fork of the skip-mev/feemarket module (more specifically, of the sdk-47 branch) and includes changes and adaptations to suit the AtomOne project.

Contents

Concepts

Additive Increase Multiplicative Decrease (AIMD) EIP-1559

Please refer to AIMD.md for a detailed description of the AIMD EIP-1559

Fee deduction and naive Tx prioritization

Fee deduction is performed in the anteHandler. The entire user-set fee is deducted from the user's account and sent to the x/distribution module account. In order for a transaction to be included in a block, the transaction's gas price must be at least equat to the current gas price. However, users can also specify an even higher gas price than the current gas price to increase the priority of their transaction. A naive form of transactions prioritization is implemented so that transactions with higher gas prices are included in the block with higher priority.

Module state updates

The dynamicfee module updates the gas consumed in the current block on a per-tx basis relying on the postHandler. Updates to the base fee and learning rate are instead performed in the endBlocker.

State

The x/dynamicfee module keeps state of the following primary objects:

  1. Current base-fee
  2. Current learning rate
  3. Moving window of block gas

In addition, the x/dynamicfee module keeps the following indexes to manage the aforementioned state:

  • State: 0x02 |ProtocolBuffer(State)

GasPrice

GasPrice is the current gas price. This is denominated in the fee per gas unit in the base fee denom.

LearningRate

LearningRate is the current learning rate.

Window

Window contains a list of the last blocks' gas values. This is used to calculate the next base fee. This stores the number of units of gas consumed per block.

Index

Index is the index of the current block in the block gas window.

// State is utilized to track the current state of the dynamic fee pricer. This
// includes the current base fee, learning rate, and block gas within the
// specified AIMD window.
message State {
  // BaseGasPrice is the current base fee. This is denominated in the fee per gas
  // unit.
  string base_gas_price = 1 [
    (cosmos_proto.scalar) = "cosmos.Dec",
    (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
    (gogoproto.nullable) = false
  ];

  // LearningRate is the current learning rate.
  string learning_rate = 2 [
    (cosmos_proto.scalar) = "cosmos.Dec",
    (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
    (gogoproto.nullable) = false
  ];

  // Window contains a list of the last blocks' gas values. This is used
  // to calculate the next base fee. This stores the number of units of gas
  // consumed per block.
  repeated uint64 window = 3;

  // Index is the index of the current block in the block gas window.
  uint64 index = 4;
}

Keeper

The dynamicfee module provides a keeper interface for accessing the KVStore.

type DynamicfeeKeeper interface {
    // Get the current state from the store.
    GetState(ctx sdk.Context) (types.State, error)

    // Set the state in the store.
    SetState(ctx sdk.Context, state types.State) error

    // Get the current params from the store.
    GetParams(ctx sdk.Context) (types.Params, error)

    // Set the params in the store.
    SetParams(ctx sdk.Context, params types.Params) error

    // Get the minimum gas price for a given denom from the store.
    GetMinGasPrice(ctx sdk.Context, denom string) (sdk.DecCoin, error) {

    // Get the current minimum gas prices from the store.
    GetMinGasPrices(ctx sdk.Context) (sdk.DecCoins, error)
}

Messages

MsgParams

The dynamicfee module params can be updated through MsgParams, which can be done using a governance proposal. The signer will always be the gov module account address.

message MsgParams {
  option (cosmos.msg.v1.signer) = "authority";

  // Params defines the new parameters for the dynamicfee module.
  Params params = 1 [ (gogoproto.nullable) = false ];
  // Authority defines the authority that is updating the dynamicfee module
  // parameters.
  string authority = 2 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
}

The message handling can fail if:

  • signer is not the gov module account address.

Events

The dynamicfee module emits the following events:

Tx

{
  "type": "tx",
  "attributes": [
    {
      "key": "fee",
      "value": "{{sdk.Coins being payed}}",
      "index": true
    },
    {
      "key": "fee_payer",
      "value": "{{sdk.AccAddress paying the fees}}",
      "index": true
    }
  ]
}

Parameters

The dynamicfee module stores its params in state with the prefix of 0x01, which can be updated with governance or the address with authority.

  • Params: 0x01 | ProtocolBuffer(Params)

The dynamicfee module contains the following parameters:

Alpha

Alpha is the amount we added to the learning rate when it is above or below the target +/- threshold.

Beta

Beta is the amount we multiplicatively decrease the learning rate when it is within the target +/- threshold.

Gamma

Gamma is the threshold for the learning rate. If the learning rate is above or below the target +/- threshold, we additively increase the learning rate by Alpha. Otherwise, we multiplicatively decrease the learning rate by Beta.

MinBaseGasPrice

MinBaseGasPrice determines the initial gas price of the module and the global minimum for the network. This is denominated in fee per gas unit in the FeeDenom.

TargetBlockUtilization

TargetBlockUtilization is the target block utilization expressed as a percentage of the block gas limit.

MinLearningRate

MinLearningRate is the lower bound for the learning rate.

MaxLearningRate

MaxLearningRate is the upper bound for the learning rate.

Window

Window defines the window size for calculating an adaptive learning rate over a moving window of blocks. The default EIP1559 implementation uses a window of size 1.

FeeDenom

FeeDenom is the denom that will be used for all fee payments.

Enabled

Enabled is a boolean that determines whether the EIP1559 dynamic fee pricing is enabled. This can be used to add the dynamicfee module and enable it through governance at a later time.

// Params contains the required set of parameters for the EIP1559 dynamic fee
// pricing implementation.
message Params {
  // Alpha is the amount we additively increase the learning rate
  // when it is above or below the target +/- threshold.
  //
  // Must be > 0.
  string alpha = 1 [
    (cosmos_proto.scalar) = "cosmos.Dec",
    (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
    (gogoproto.nullable) = false
  ];

  // Beta is the amount we multiplicatively decrease the learning rate
  // when it is within the target +/- threshold.
  //
  // Must be [0, 1].
  string beta = 2 [
    (cosmos_proto.scalar) = "cosmos.Dec",
    (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
    (gogoproto.nullable) = false
  ];

  // Gamma is the threshold for the learning rate. If the learning rate is
  // above or below the target +/- threshold, we additively increase the
  // learning rate by Alpha. Otherwise, we multiplicatively decrease the
  // learning rate by Beta.
  //
  // Must be [0, 0.5].
  string gamma = 3 [
    (cosmos_proto.scalar) = "cosmos.Dec",
    (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
    (gogoproto.nullable) = false
  ];

  // MinBaseGasPrice determines the initial gas price of the module and the
  // global minimum for the network.
  string min_base_gas_price = 5 [
    (cosmos_proto.scalar) = "cosmos.Dec",
    (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
    (gogoproto.nullable) = false
  ];

  // TargetBlockUtilization is the target block utilization expressed as a
  // decimal value between 0 and 1. It is the target percentage utilization
  // of the block in relation to the consensus_params.block.max_gas parameter.
  string target_block_utilization = 6 [
    (cosmos_proto.scalar) = "cosmos.Dec",
    (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
    (gogoproto.nullable) = false
  ];

  // MinLearningRate is the lower bound for the learning rate.
  string min_learning_rate = 7 [
    (cosmos_proto.scalar) = "cosmos.Dec",
    (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
    (gogoproto.nullable) = false
  ];

  // MaxLearningRate is the upper bound for the learning rate.
  string max_learning_rate = 8 [
    (cosmos_proto.scalar) = "cosmos.Dec",
    (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
    (gogoproto.nullable) = false
  ];

  // Window defines the window size for calculating an adaptive learning rate
  // over a moving window of blocks.
  uint64 window = 9;

  // FeeDenom is the denom that will be used for all fee payments.
  string fee_denom = 10;

  // Enabled is a boolean that determines whether the EIP1559 dynamic fee
  // pricing is enabled.
  bool enabled = 11;
}

Client

CLI

A user can query and interact with the dynamicfee module using the CLI.

Query

The query commands allow users to query dynamicfee state.

hikarid query dynamicfee --help
params

The params command allows users to query the on-chain parameters.

hikarid query dynamicfee params [flags]

Example:

hikarid query dynamicfee params

Example Output:

alpha: "0.000000000000000000"
beta: "1.000000000000000000"
enabled: true
fee_denom: uatone
gamma: "0.000000000000000000"
max_learning_rate: "0.125000000000000000"
min_base_gas_price: "1.000000000000000000"
min_learning_rate: "0.125000000000000000"
target_block_utilization: "0.500000000000000000"
window: "1"
state

The state command allows users to query the current on-chain state.

hikarid query dynamicfee state [flags]

Example:

hikarid query dynamicfee state

Example Output:

base_fee: "1.000000000000000000"
index: "0"
learning_rate: "0.125000000000000000"
window:
  - "0"
gas-price

The gas-price command allows users to query the current gas-price for a given denom.

hikarid query dynamicfee gas-price [denom] [flags]

Example:

hikarid query dynamicfee gas-price uatone

Example Output:

1000000uatone
gas-prices

The gas-prices command allows users to query the current gas-price for all supported denoms.

hikarid query dynamicfee gas-prices [flags]

Example:

hikarid query dynamicfee gas-prices

Example Output:

1000000stake,100000uatone

gRPC

A user can query the dynamicfee module using gRPC endpoints.

Params

The Params endpoint allows users to query the on-chain parameters.

atomone.dynamicfee.v1.Query/Params

Example:

grpcurl -plaintext \
    localhost:9090 \
    atomone.dynamicfee.v1.Query/Params

Example Output:

{
  "params": {
    "alpha": "0",
    "beta": "1000000000000000000",
    "gamma": "0",
    "minBaseGasPrice": "1000000",
    "minLearningRate": "125000000000000000",
    "maxLearningRate": "125000000000000000",
    "targetBlockUtilization": "500000000000000000",
    "window": "1",
    "feeDenom": "uatone",
    "enabled": true
  }
}

State

The State endpoint allows users to query the current on-chain state.

atomone.dynamicfee.v1.Query/State

Example:

grpcurl -plaintext \
    localhost:9090 \
    atomone.dynamicfee.v1.Query/State

Example Output:

{
  "state": {
    "baseGasPrice": "1000000",
    "learningRate": "125000000000000000",
    "window": [
      "0"
    ]
  }
}

GasPrice

The GasPrice endpoint allows users to query the current on-chain gas price for a given denom.

atomone.dynamicfee.v1.Query/GasPrice

Example:

grpcurl -plaintext \
    -d '{"denom": "uatone"}' \
    localhost:9090 \
    atomone.dynamicfee.v1.Query/GasPrice/

Example Output:

{
  "price": {
      "denom": "uatone",
      "amount": "1000000"
  }
}

GasPrices

The GasPrices endpoint allows users to query the current on-chain gas prices for all denoms.

atomone.dynamicfee.v1.Query/GasPrices

Example:

grpcurl -plaintext \
    localhost:9090 \
    atomone.dynamicfee.v1.Query/GasPrices

Example Output:

{
  "prices": [
    {
      "denom": "uatone",
      "amount": "1000000"
    }
  ]
}

Documentation

Index

Constants

View Source
const ConsensusVersion = 1

ConsensusVersion is the x/dynamicfee module's consensus version identifier.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppModule

type AppModule struct {
	AppModuleBasic
	// contains filtered or unexported fields
}

AppModule represents an application module for the x/dynamicfee module.

func NewAppModule

func NewAppModule(cdc codec.Codec, k keeper.Keeper) AppModule

NewAppModule returns an application module for the x/dynamicfee module.

func (AppModule) ConsensusVersion

func (AppModule) ConsensusVersion() uint64

ConsensusVersion implements AppModule/ConsensusVersion.

func (AppModule) EndBlock

func (am AppModule) EndBlock(ctx context.Context) error

EndBlock returns an endblocker for the x/feemarket module.

func (AppModule) ExportGenesis

func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage

ExportGenesis returns the dynamicfee module's exported genesis state as raw JSON bytes. This method panics on any error.

func (AppModule) GenerateGenesisState

func (AppModule) GenerateGenesisState(simState *module.SimulationState)

GenerateGenesisState returns a disabled dynamicfee module because the module does not work well with simulations. Especially the dynamicfee ante handler does not accept 0 fee coins which is quite common during simulation's operations.

func (AppModule) InitGenesis

func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, bz json.RawMessage)

InitGenesis performs the genesis initialization for the x/dynamicfee module. This method returns no validator set updates. This method panics on any errors.

func (AppModule) IsAppModule

func (am AppModule) IsAppModule()

IsAppModule implements the appmodule.AppModule interface.

func (AppModule) IsOnePerModuleType

func (am AppModule) IsOnePerModuleType()

IsOnePerModuleType implements the depinject.OnePerModuleType interface.

func (AppModule) RegisterServices

func (am AppModule) RegisterServices(cfc module.Configurator)

RegisterServices registers the module's services with the app's module configurator.

func (AppModule) RegisterStoreDecoder

func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry)

RegisterStoreDecoder registers a decoder.

func (AppModule) WeightedOperations

func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation

WeightedOperations returns the all the module operations with their respective weights.

type AppModuleBasic

type AppModuleBasic struct {
	// contains filtered or unexported fields
}

AppModuleBasic defines the base interface that the x/dynamicfee module exposes to the application.

func (AppModuleBasic) DefaultGenesis

func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage

DefaultGenesis returns default genesis state as raw bytes for the dynamicfee module.

func (AppModuleBasic) GetQueryCmd

func (amb AppModuleBasic) GetQueryCmd() *cobra.Command

GetQueryCmd returns the x/dynamicfee module base query cli-command.

func (AppModuleBasic) GetTxCmd

func (amb AppModuleBasic) GetTxCmd() *cobra.Command

GetTxCmd is a no-op, as no txs are registered for submission (apart from messages that can only be executed by governance).

func (AppModuleBasic) Name

func (amb AppModuleBasic) Name() string

Name returns the name of x/dynamicfee module.

func (AppModuleBasic) RegisterGRPCGatewayRoutes

func (amb AppModuleBasic) RegisterGRPCGatewayRoutes(cliCtx client.Context, mux *runtime.ServeMux)

RegisterGRPCGatewayRoutes registers the necessary REST routes for the GRPC-gateway to the x/dynamicfee module QueryService on mux. This method panics on failure.

func (AppModuleBasic) RegisterInterfaces

func (amb AppModuleBasic) RegisterInterfaces(ir codectypes.InterfaceRegistry)

RegisterInterfaces registers the necessary implementations / interfaces in the x/dynamicfee module w/ the interface-registry.

func (AppModuleBasic) RegisterLegacyAminoCodec

func (amb AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)

RegisterLegacyAminoCodec registers the necessary types from the x/dynamicfee module for amino serialization.

func (AppModuleBasic) ValidateGenesis

ValidateGenesis performs genesis state validation for the dynamicfee module.

type Inputs

type Inputs struct {
	depinject.In

	Config *modulev1.Module
	Cdc    codec.Codec
	Key    *store.KVStoreKey
}

type Outputs

type Outputs struct {
	depinject.Out

	Keeper keeper.Keeper
	Module appmodule.AppModule
}

func ProvideModule

func ProvideModule(in Inputs) Outputs

Directories

Path Synopsis
client
cli
Package types is a reverse proxy.
Package types is a reverse proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL