Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!--
Guiding Principles:

Changelogs are for humans, not machines.
There should be an entry for every single version.
The same types of changes should be grouped.
Versions and sections should be linkable.
The latest version comes first.
The release date of each version is displayed.
Mention whether you follow Semantic Versioning.

Usage:

Change log entries are to be added to the Unreleased section under the
appropriate stanza (see below). Each entry should ideally include a tag and
the Github issue reference in the following format:

* (<tag>) \#<issue-number> message

The issue numbers will later be link-ified during the release process so you do
not have to worry about including a link manually, but you can if you wish.

Types of changes (Stanzas):

"Features" for new features.
"Improvements" for changes in existing functionality.
"Deprecated" for soon-to-be removed features.
"Bug Fixes" for any bug fixes.
"Client Breaking" for breaking CLI commands and REST routes used by end-users.
"API Breaking" for breaking exported APIs used by developers building on SDK.
"State Machine Breaking" for any changes that result in a different AppState given same genesisState and txList.
Ref: https://keepachangelog.com/en/1.0.0/
-->

# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## Features

- [#1](https://github.com/pomifer/chihuahua/pull/1) Add a minimum validator commission of 5% based on proposal [#1](https://omniflix.chihuahua.wtf/proposals)

## [v1.0.0](https://github.com/ChihuahuaChain/chihuahua/releases/tag/v1.0.0) - 2021-12-18

Release mainnet
97 changes: 97 additions & 0 deletions app/ante.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package app

import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
channelkeeper "github.com/cosmos/ibc-go/modules/core/04-channel/keeper"
ibcante "github.com/cosmos/ibc-go/modules/core/ante"
)

// HandlerOptions extends the SDK's AnteHandler options by requiring the IBC
// channel keeper.
type HandlerOptions struct {
ante.HandlerOptions

IBCChannelkeeper channelkeeper.Keeper
}

type MinCommissionDecorator struct{}

func NewMinCommissionDecorator() MinCommissionDecorator {
return MinCommissionDecorator{}
}

func (MinCommissionDecorator) AnteHandle(
ctx sdk.Context, tx sdk.Tx,
simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
msgs := tx.GetMsgs()
minCommissionRate := sdk.NewDecWithPrec(5, 2)
for _, m := range msgs {
switch msg := m.(type) {
case *stakingtypes.MsgCreateValidator:
// prevent new validators joining the set with
// commission set below 5%
c := msg.Commission
if c.Rate.LT(minCommissionRate) {
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%")
}
case *stakingtypes.MsgEditValidator:
// if commission rate is nil, it means only
// other fields are affected - skip
if msg.CommissionRate == nil {
continue
}
if msg.CommissionRate.LT(minCommissionRate) {
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%")
}
default:
continue
}
}
return next(ctx, tx, simulate)
}

// NewAnteHandler returns an AnteHandler that checks and increments sequence
// numbers, checks signatures & account numbers, and deducts fees from the first
// signer.
func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
if options.AccountKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder")
}

if options.BankKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder")
}

if options.SignModeHandler == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder")
}

var sigGasConsumer = options.SigGasConsumer
if sigGasConsumer == nil {
sigGasConsumer = ante.DefaultSigVerificationGasConsumer
}

anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
NewMinCommissionDecorator(),
ante.NewRejectExtensionOptionsDecorator(),
ante.NewMempoolFeeDecorator(),
ante.NewValidateBasicDecorator(),
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper),
// SetPubKeyDecorator must be called before all signature verification decorators
ante.NewSetPubKeyDecorator(options.AccountKeeper),
ante.NewValidateSigCountDecorator(options.AccountKeeper),
ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer),
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
ibcante.NewAnteDecorator(options.IBCChannelkeeper),
}

return sdk.ChainAnteDecorators(anteDecorators...), nil
}
71 changes: 63 additions & 8 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
store "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
Expand All @@ -25,6 +26,7 @@ import (
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
Expand Down Expand Up @@ -87,13 +89,14 @@ import (
"github.com/tendermint/spm/openapiconsole"

"github.com/ChihuahuaChain/chihuahua/docs"

// this line is used by starport scaffolding # stargate/app/moduleImport
)

const (
AccountAddressPrefix = "chihuahua"
Name = "chihuahua"
upgradeName = ""

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In #81 they named this "moneta-alpha" but ours doesn't have a name, so I left it blank.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this used? Just to note that we will likely want to point this out when publishing our PR

minComRate = 5
)

// this line is used by starport scaffolding # stargate/wasm/app/enabledProposals
Expand Down Expand Up @@ -296,6 +299,10 @@ func New(
app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper)
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp)

// upgrade handlers
cfg := module.NewConfigurator(appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
app.RegisterUpgradeHandlers(cfg)

// register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
app.StakingKeeper = *stakingKeeper.SetHooks(
Expand Down Expand Up @@ -424,13 +431,16 @@ func New(
app.SetInitChainer(app.InitChainer)
app.SetBeginBlocker(app.BeginBlocker)

anteHandler, err := ante.NewAnteHandler(
ante.HandlerOptions{
AccountKeeper: app.AccountKeeper,
BankKeeper: app.BankKeeper,
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
FeegrantKeeper: app.FeeGrantKeeper,
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
anteHandler, err := NewAnteHandler(
HandlerOptions{
HandlerOptions: ante.HandlerOptions{
AccountKeeper: app.AccountKeeper,
BankKeeper: app.BankKeeper,
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
FeegrantKeeper: app.FeeGrantKeeper,
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
},
IBCChannelkeeper: app.IBCKeeper.ChannelKeeper,
},
)
if err != nil {
Expand All @@ -440,6 +450,19 @@ func New(
app.SetAnteHandler(anteHandler)
app.SetEndBlocker(app.EndBlocker)

upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic(err)
}

if upgradeInfo.Name == upgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := store.StoreUpgrades{
Added: []string{authz.ModuleName, feegrant.ModuleName},
}
// configure store loader that checks if version == upgradeHeight and applies store upgrades
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
}

if loadLatest {
if err := app.LoadLatestVersion(); err != nil {
tmos.Exit(err.Error())
Expand Down Expand Up @@ -572,6 +595,38 @@ func (app *App) RegisterTendermintService(clientCtx client.Context) {
tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry)
}

// RegisterUpgradeHandlers returns upgrade handlers
func (app *App) RegisterUpgradeHandlers(cfg module.Configurator) {
app.UpgradeKeeper.SetUpgradeHandler(upgradeName, func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
return app.mm.RunMigrations(ctx, cfg, vm)
})

app.UpgradeKeeper.SetUpgradeHandler(upgradeName, func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
// force an update of validator min commission
validators := app.StakingKeeper.GetAllValidators(ctx)
// hard code this because we don't want
// a) a fork or
// b) immediate reaction with additional gov props
minCommissionRate := sdk.NewDecWithPrec(minComRate, 2)
for _, v := range validators {
if v.Commission.Rate.LT(minCommissionRate) {
if v.Commission.MaxRate.LT(minCommissionRate) {
v.Commission.MaxRate = minCommissionRate
}

v.Commission.Rate = minCommissionRate
v.Commission.UpdateTime = ctx.BlockHeader().Time

// call the before-modification hook since we're about to update the commission
app.StakingKeeper.BeforeValidatorModified(ctx, v.GetOperator())

app.StakingKeeper.SetValidator(ctx, v)
}
}
return app.mm.RunMigrations(ctx, cfg, vm)
})
}

// GetMaccPerms returns a copy of the module account permissions
func GetMaccPerms() map[string][]string {
dupMaccPerms := make(map[string][]string)
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions single-node.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh

set -o errexit -o nounset

CHAINID="test"

# Build genesis file incl account for passed address
coins="10000000000stake,100000000000samoleans"
chihuahuad init $CHAINID --chain-id $CHAINID
chihuahuad keys add validator --keyring-backend="test"
# this won't work because the some proto types are decalared twice and the logs output to stdout (dependency hell involving iavl)
chihuahuad add-genesis-account $(chihuahuad keys show validator -a --keyring-backend="test") $coins
chihuahuad gentx validator 5000000000stake --keyring-backend="test" --chain-id $CHAINID
chihuahuad collect-gentxs

# Set proper defaults and change ports
sed -i 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.chihuahua/config/config.toml
sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ~/.chihuahua/config/config.toml
sed -i 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ~/.chihuahua/config/config.toml
sed -i 's/index_all_keys = false/index_all_keys = true/g' ~/.chihuahua/config/config.toml

# Start the chihuahua
chihuahuad start
62 changes: 31 additions & 31 deletions testutil/keeper/chihuahua.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
package keeper

import (
"testing"
// import (
// "testing"

"github.com/ChihuahuaChain/chihuahua/x/chihuahua/keeper"
"github.com/ChihuahuaChain/chihuahua/x/chihuahua/types"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/store"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmdb "github.com/tendermint/tm-db"
)
// "github.com/ChihuahuaChain/chihuahua/x/chihuahua/keeper"
// "github.com/ChihuahuaChain/chihuahua/x/chihuahua/types"
// "github.com/cosmos/cosmos-sdk/codec"
// codectypes "github.com/cosmos/cosmos-sdk/codec/types"
// "github.com/cosmos/cosmos-sdk/store"
// storetypes "github.com/cosmos/cosmos-sdk/store/types"
// sdk "github.com/cosmos/cosmos-sdk/types"
// "github.com/stretchr/testify/require"
// "github.com/tendermint/tendermint/libs/log"
// tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
// tmdb "github.com/tendermint/tm-db"
// )

func ChihuahuaKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
storeKey := sdk.NewKVStoreKey(types.StoreKey)
memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey)
// func ChihuahuaKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
// storeKey := sdk.NewKVStoreKey(types.StoreKey)
// memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey)

db := tmdb.NewMemDB()
stateStore := store.NewCommitMultiStore(db)
stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db)
stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil)
require.NoError(t, stateStore.LoadLatestVersion())
// db := tmdb.NewMemDB()
// stateStore := store.NewCommitMultiStore(db)
// stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db)
// stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil)
// require.NoError(t, stateStore.LoadLatestVersion())

registry := codectypes.NewInterfaceRegistry()
k := keeper.NewKeeper(
codec.NewProtoCodec(registry),
storeKey,
memStoreKey,
)
// registry := codectypes.NewInterfaceRegistry()
// k := keeper.NewKeeper(
// codec.NewProtoCodec(registry),
// storeKey,
// memStoreKey,
// )

ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())
return k, ctx
}
// ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())
// return k, ctx
// }
Loading