forked from cerc-io/laconicd
Add a new token and only allow fees in alnt (#68)
Part of https://www.notion.so/Multiple-tokens-support-and-disable-transfers-for-LSTAKE-1f2a6b22d47280269f87df3fe03e8d64 - Add base token with denoms `alps` and `lps` (`1 lps = 10^18 alps`) - Keep `alnt` as the staking token and for laconic module ops - Accept tx fees only in `alnt` Reviewed-on: cerc-io/laconicd#68 Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com> Co-committed-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
This commit is contained in:
parent
f4cf8ac744
commit
31ef3afb9a
79
app/ante.go
Normal file
79
app/ante.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
errorsmod "cosmossdk.io/errors"
|
||||||
|
sdkmath "cosmossdk.io/math"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
|
||||||
|
"git.vdb.to/cerc-io/laconicd/app/params"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/x/auth/ante/validator_tx_fee.go#L15
|
||||||
|
|
||||||
|
// checkTxFeeWithValidatorMinGasPrices implements the default fee logic, where the minimum price per
|
||||||
|
// unit of gas is fixed and set by each validator, can the tx priority is computed from the gas price.
|
||||||
|
func checkTxFeeWithValidatorMinGasPrices(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) {
|
||||||
|
feeTx, ok := tx.(sdk.FeeTx)
|
||||||
|
if !ok {
|
||||||
|
return nil, 0, errorsmod.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
|
||||||
|
}
|
||||||
|
|
||||||
|
feeCoins := feeTx.GetFee()
|
||||||
|
gas := feeTx.GetGas()
|
||||||
|
|
||||||
|
// Only allow alnt as a fee token
|
||||||
|
for _, coin := range feeCoins {
|
||||||
|
if coin.Denom != params.CoinUnit {
|
||||||
|
return nil, 0, errorsmod.Wrapf(sdkerrors.ErrInvalidCoins, "invalid fee denom %s, only %s is accepted", coin.Denom, params.CoinUnit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the provided fees meet a minimum threshold for the validator,
|
||||||
|
// if this is a CheckTx. This is only for local mempool purposes, and thus
|
||||||
|
// is only ran on check tx.
|
||||||
|
if ctx.IsCheckTx() {
|
||||||
|
minGasPrices := ctx.MinGasPrices()
|
||||||
|
if !minGasPrices.IsZero() {
|
||||||
|
requiredFees := make(sdk.Coins, len(minGasPrices))
|
||||||
|
|
||||||
|
// Determine the required fees by multiplying each required minimum gas
|
||||||
|
// price by the gas limit, where fee = ceil(minGasPrice * gasLimit).
|
||||||
|
glDec := sdkmath.LegacyNewDec(int64(gas))
|
||||||
|
for i, gp := range minGasPrices {
|
||||||
|
fee := gp.Amount.Mul(glDec)
|
||||||
|
requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
if !feeCoins.IsAnyGTE(requiredFees) {
|
||||||
|
return nil, 0, errorsmod.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, requiredFees)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
priority := getTxPriority(feeCoins, int64(gas))
|
||||||
|
return feeCoins, priority, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getTxPriority returns a naive tx priority based on the amount of the smallest denomination of the gas price
|
||||||
|
// provided in a transaction.
|
||||||
|
// NOTE: This implementation should be used with a great consideration as it opens potential attack vectors
|
||||||
|
// where txs with multiple coins could not be prioritize as expected.
|
||||||
|
func getTxPriority(fee sdk.Coins, gas int64) int64 {
|
||||||
|
var priority int64
|
||||||
|
for _, c := range fee {
|
||||||
|
p := int64(math.MaxInt64)
|
||||||
|
gasPrice := c.Amount.QuoRaw(gas)
|
||||||
|
if gasPrice.IsInt64() {
|
||||||
|
p = gasPrice.Int64()
|
||||||
|
}
|
||||||
|
if priority == 0 || p < priority {
|
||||||
|
priority = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return priority
|
||||||
|
}
|
24
app/app.go
24
app/app.go
@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/server/config"
|
"github.com/cosmos/cosmos-sdk/server/config"
|
||||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/module"
|
"github.com/cosmos/cosmos-sdk/types/module"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||||
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
|
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
|
||||||
@ -185,6 +186,9 @@ func NewLaconicApp(
|
|||||||
app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, make(map[string]module.AppModuleSimulation, 0))
|
app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, make(map[string]module.AppModuleSimulation, 0))
|
||||||
app.sm.RegisterStoreDecoders()
|
app.sm.RegisterStoreDecoders()
|
||||||
|
|
||||||
|
// set custom ante handlers
|
||||||
|
app.setCustomAnteHandler()
|
||||||
|
|
||||||
if err := app.Load(loadLatest); err != nil {
|
if err := app.Load(loadLatest); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -232,3 +236,23 @@ func (app *LaconicApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.AP
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setCustomAnteHandler overwrites default ante handlers with custom ante handlers
|
||||||
|
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/x/auth/tx/config/config.go#L149
|
||||||
|
func (app *LaconicApp) setCustomAnteHandler() {
|
||||||
|
anteHandler, err := ante.NewAnteHandler(
|
||||||
|
ante.HandlerOptions{
|
||||||
|
AccountKeeper: app.AccountKeeper,
|
||||||
|
BankKeeper: app.BankKeeper,
|
||||||
|
SignModeHandler: app.txConfig.SignModeHandler(),
|
||||||
|
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
|
||||||
|
TxFeeChecker: checkTxFeeWithValidatorMinGasPrices,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the AnteHandler for the app
|
||||||
|
app.SetAnteHandler(anteHandler)
|
||||||
|
}
|
||||||
|
@ -10,11 +10,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CoinUnit = "lnt"
|
// Registered token
|
||||||
BaseCoinUnit = "alnt"
|
LpsCoinUnit = "lps"
|
||||||
LntExponent = 18
|
LpsBaseCoinUnit = "alps"
|
||||||
|
LpsExponent = 18
|
||||||
|
|
||||||
DefaultBondDenom = BaseCoinUnit
|
// Native token, only denominated in alnt
|
||||||
|
// Used for staking, fees and laconic module ops
|
||||||
|
CoinUnit = "alnt"
|
||||||
|
|
||||||
// Bech32PrefixAccAddr defines the Bech32 prefix of an account's address.
|
// Bech32PrefixAccAddr defines the Bech32 prefix of an account's address.
|
||||||
Bech32PrefixAccAddr = "laconic"
|
Bech32PrefixAccAddr = "laconic"
|
||||||
@ -39,12 +42,11 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RegisterDenoms() {
|
func RegisterDenoms() {
|
||||||
err := sdk.RegisterDenom(CoinUnit, math.LegacyOneDec())
|
err := sdk.RegisterDenom(LpsCoinUnit, math.LegacyOneDec())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
err = sdk.RegisterDenom(LpsBaseCoinUnit, math.LegacyNewDecWithPrec(1, LpsExponent))
|
||||||
err = sdk.RegisterDenom(BaseCoinUnit, math.LegacyNewDecWithPrec(1, LntExponent))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
|
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
"github.com/cosmos/cosmos-sdk/types/module"
|
"github.com/cosmos/cosmos-sdk/types/module"
|
||||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||||
@ -29,6 +28,7 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
|
|
||||||
"git.vdb.to/cerc-io/laconicd/app"
|
"git.vdb.to/cerc-io/laconicd/app"
|
||||||
|
"git.vdb.to/cerc-io/laconicd/app/params"
|
||||||
"git.vdb.to/cerc-io/laconicd/gql"
|
"git.vdb.to/cerc-io/laconicd/gql"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ func NewRootCmd() *cobra.Command {
|
|||||||
|
|
||||||
// overwrite the minimum gas price from the app configuration
|
// overwrite the minimum gas price from the app configuration
|
||||||
srvCfg := serverconfig.DefaultConfig()
|
srvCfg := serverconfig.DefaultConfig()
|
||||||
srvCfg.MinGasPrices = fmt.Sprintf("0%s", sdk.DefaultBondDenom)
|
srvCfg.MinGasPrices = fmt.Sprintf("0%s", params.CoinUnit)
|
||||||
|
|
||||||
// overwrite the block timeout
|
// overwrite the block timeout
|
||||||
cmtCfg := cmtcfg.DefaultConfig()
|
cmtCfg := cmtcfg.DefaultConfig()
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
KEY="alice"
|
KEY="alice"
|
||||||
CHAINID=${CHAINID:-"laconic_9000-1"}
|
CHAINID=${CHAINID:-"laconic_9000-1"}
|
||||||
MONIKER=${MONIKER:-"localtestnet"}
|
MONIKER=${MONIKER:-"localtestnet"}
|
||||||
KEYRING=${KEYRING:-"test"}
|
KEYRING=${KEYRING:-"test"}
|
||||||
DENOM=${DENOM:-"alnt"}
|
DENOM=${DENOM:-"alnt"}
|
||||||
STAKING_AMOUNT=${STAKING_AMOUNT:-"1000000000000000"}
|
BALANCE=${BALANCE:-"1000000000000000000000000000000"} # 10^32 alnt
|
||||||
|
STAKING_AMOUNT=${STAKING_AMOUNT:-"1000000000000000"} # 10^15 alnt
|
||||||
MIN_GAS_PRICE=${MIN_GAS_PRICE:-"0.001"}
|
MIN_GAS_PRICE=${MIN_GAS_PRICE:-"0.001"}
|
||||||
LOGLEVEL=${LOGLEVEL:-"info"}
|
LOGLEVEL=${LOGLEVEL:-"info"}
|
||||||
|
|
||||||
@ -126,11 +129,9 @@ if [ "$1" == "clean" ] || [ ! -d "$HOME/.laconicd/data" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Allocate genesis accounts (cosmos formatted addresses)
|
# Allocate genesis accounts (cosmos formatted addresses)
|
||||||
# 10^30 alnt | 10^12 lnt
|
laconicd genesis add-genesis-account $KEY ${BALANCE}${DENOM} --keyring-backend $KEYRING
|
||||||
laconicd genesis add-genesis-account $KEY 1000000000000000000000000000000$DENOM --keyring-backend $KEYRING
|
|
||||||
|
|
||||||
# Sign genesis transaction
|
# Sign genesis transaction
|
||||||
# 10^15 alnt
|
|
||||||
laconicd genesis gentx $KEY $STAKING_AMOUNT$DENOM --keyring-backend $KEYRING --chain-id $CHAINID
|
laconicd genesis gentx $KEY $STAKING_AMOUNT$DENOM --keyring-backend $KEYRING --chain-id $CHAINID
|
||||||
|
|
||||||
# Collect genesis tx
|
# Collect genesis tx
|
||||||
|
@ -5,11 +5,12 @@ import (
|
|||||||
fmt "fmt"
|
fmt "fmt"
|
||||||
|
|
||||||
sdkmath "cosmossdk.io/math"
|
sdkmath "cosmossdk.io/math"
|
||||||
|
"git.vdb.to/cerc-io/laconicd/app/params"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultMaxBondAmountTokens are the default parameter values.
|
// DefaultMaxBondAmountTokens are the default parameter values.
|
||||||
var DefaultMaxBondAmountTokens = sdkmath.NewInt(1000000000000) // 10^12 alnt
|
var DefaultMaxBondAmountTokens = sdkmath.NewInt(1000000000000) // 10^12
|
||||||
|
|
||||||
func NewParams(maxBondAmount sdk.Coin) Params {
|
func NewParams(maxBondAmount sdk.Coin) Params {
|
||||||
return Params{MaxBondAmount: maxBondAmount}
|
return Params{MaxBondAmount: maxBondAmount}
|
||||||
@ -17,7 +18,7 @@ func NewParams(maxBondAmount sdk.Coin) Params {
|
|||||||
|
|
||||||
// DefaultParams returns default module parameters
|
// DefaultParams returns default module parameters
|
||||||
func DefaultParams() Params {
|
func DefaultParams() Params {
|
||||||
return NewParams(sdk.NewCoin(sdk.DefaultBondDenom, DefaultMaxBondAmountTokens))
|
return NewParams(sdk.NewCoin(params.CoinUnit, DefaultMaxBondAmountTokens))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate checks that the parameters have valid values
|
// Validate checks that the parameters have valid values
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
|
||||||
|
"git.vdb.to/cerc-io/laconicd/app/params"
|
||||||
auctiontypes "git.vdb.to/cerc-io/laconicd/x/auction"
|
auctiontypes "git.vdb.to/cerc-io/laconicd/x/auction"
|
||||||
registrytypes "git.vdb.to/cerc-io/laconicd/x/registry"
|
registrytypes "git.vdb.to/cerc-io/laconicd/x/registry"
|
||||||
"git.vdb.to/cerc-io/laconicd/x/registry/helpers"
|
"git.vdb.to/cerc-io/laconicd/x/registry/helpers"
|
||||||
@ -295,7 +296,7 @@ func (k Keeper) createAuthority(ctx sdk.Context, name string, owner string, isRo
|
|||||||
moduleParams.AuthorityAuctionCommitFee,
|
moduleParams.AuthorityAuctionCommitFee,
|
||||||
moduleParams.AuthorityAuctionRevealFee,
|
moduleParams.AuthorityAuctionRevealFee,
|
||||||
moduleParams.AuthorityAuctionMinimumBid,
|
moduleParams.AuthorityAuctionMinimumBid,
|
||||||
sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(0)),
|
sdk.NewCoin(params.CoinUnit, math.NewInt(0)),
|
||||||
0,
|
0,
|
||||||
ownerAddress,
|
ownerAddress,
|
||||||
)
|
)
|
||||||
|
@ -6,26 +6,28 @@ import (
|
|||||||
|
|
||||||
sdkmath "cosmossdk.io/math"
|
sdkmath "cosmossdk.io/math"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
|
"git.vdb.to/cerc-io/laconicd/app/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default parameter values.
|
// Default parameter values.
|
||||||
var (
|
var (
|
||||||
// DefaultRecordRent is the default record rent for 1 time period (see expiry time).
|
// DefaultRecordRent is the default record rent for 1 time period (see expiry time).
|
||||||
DefaultRecordRent = sdkmath.NewInt(1000000) // 10^6 alnt
|
DefaultRecordRent = sdkmath.NewInt(1000000) // 10^6
|
||||||
|
|
||||||
// DefaultRecordExpiryTime is the default record expiry time (1 year).
|
// DefaultRecordExpiryTime is the default record expiry time (1 year).
|
||||||
DefaultRecordExpiryTime = time.Hour * 24 * 365
|
DefaultRecordExpiryTime = time.Hour * 24 * 365
|
||||||
|
|
||||||
DefaultAuthorityRent = sdkmath.NewInt(1000000) // 10^6 alnt
|
DefaultAuthorityRent = sdkmath.NewInt(1000000) // 10^6
|
||||||
DefaultAuthorityExpiryTime = time.Hour * 24 * 365
|
DefaultAuthorityExpiryTime = time.Hour * 24 * 365
|
||||||
DefaultAuthorityGracePeriod = time.Hour * 24 * 2
|
DefaultAuthorityGracePeriod = time.Hour * 24 * 2
|
||||||
|
|
||||||
DefaultAuthorityAuctionEnabled = false
|
DefaultAuthorityAuctionEnabled = false
|
||||||
DefaultCommitsDuration = time.Hour * 24
|
DefaultCommitsDuration = time.Hour * 24
|
||||||
DefaultRevealsDuration = time.Hour * 24
|
DefaultRevealsDuration = time.Hour * 24
|
||||||
DefaultCommitFee = sdkmath.NewInt(1000000) // 10^6 alnt
|
DefaultCommitFee = sdkmath.NewInt(1000000) // 10^6
|
||||||
DefaultRevealFee = sdkmath.NewInt(1000000) // 10^6 alnt
|
DefaultRevealFee = sdkmath.NewInt(1000000) // 10^6
|
||||||
DefaultMinimumBid = sdkmath.NewInt(5000000) // 5 * 10^6 alnt
|
DefaultMinimumBid = sdkmath.NewInt(5000000) // 5 * 10^6
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewParams creates a new Params instance
|
// NewParams creates a new Params instance
|
||||||
@ -60,13 +62,13 @@ func NewParams(
|
|||||||
// DefaultParams returns a default set of parameters.
|
// DefaultParams returns a default set of parameters.
|
||||||
func DefaultParams() Params {
|
func DefaultParams() Params {
|
||||||
return NewParams(
|
return NewParams(
|
||||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultRecordRent), DefaultRecordExpiryTime,
|
sdk.NewCoin(params.CoinUnit, DefaultRecordRent), DefaultRecordExpiryTime,
|
||||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultAuthorityRent),
|
sdk.NewCoin(params.CoinUnit, DefaultAuthorityRent),
|
||||||
DefaultAuthorityExpiryTime, DefaultAuthorityGracePeriod, DefaultAuthorityAuctionEnabled, DefaultCommitsDuration,
|
DefaultAuthorityExpiryTime, DefaultAuthorityGracePeriod, DefaultAuthorityAuctionEnabled, DefaultCommitsDuration,
|
||||||
DefaultRevealsDuration,
|
DefaultRevealsDuration,
|
||||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultCommitFee),
|
sdk.NewCoin(params.CoinUnit, DefaultCommitFee),
|
||||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultRevealFee),
|
sdk.NewCoin(params.CoinUnit, DefaultRevealFee),
|
||||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultMinimumBid),
|
sdk.NewCoin(params.CoinUnit, DefaultMinimumBid),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user