Skip to content

Commit

Permalink
feat: backport KYVE changes to v0.47.x
Browse files Browse the repository at this point in the history
  • Loading branch information
johnletey committed Mar 19, 2023
1 parent 9acdbb9 commit 4c86bb7
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 42 deletions.
4 changes: 2 additions & 2 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ func NewSimApp(
app.StakingKeeper = stakingkeeper.NewKeeper(
appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
app.MintKeeper = mintkeeper.NewKeeper(appCodec, keys[minttypes.StoreKey], app.StakingKeeper, app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.MintKeeper = mintkeeper.NewKeeper(appCodec, keys[minttypes.StoreKey], app.StakingKeeper, nil, app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())

app.DistrKeeper = distrkeeper.NewKeeper(appCodec, keys[distrtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.StakingKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())

Expand Down Expand Up @@ -365,7 +365,7 @@ func NewSimApp(
*/
govKeeper := govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.AccountKeeper, app.BankKeeper,
app.StakingKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
app.StakingKeeper, nil, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

// Set legacy router for backwards compatibility with gov v1beta1
Expand Down
2 changes: 1 addition & 1 deletion x/gov/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func setupGovKeeper(t *testing.T) (
stakingKeeper.EXPECT().TotalBondedTokens(gomock.Any()).Return(math.NewInt(10000000)).AnyTimes()

// Gov keeper initializations
govKeeper := keeper.NewKeeper(encCfg.Codec, key, acctKeeper, bankKeeper, stakingKeeper, msr, types.DefaultConfig(), govAcct.String())
govKeeper := keeper.NewKeeper(encCfg.Codec, key, acctKeeper, bankKeeper, stakingKeeper, nil, msr, types.DefaultConfig(), govAcct.String())
govKeeper.SetProposalID(ctx, 1)
govRouter := v1beta1.NewRouter() // Also register legacy gov handlers to test them too.
govRouter.AddRoute(types.RouterKey, v1beta1.ProposalHandler)
Expand Down
22 changes: 13 additions & 9 deletions x/gov/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type Keeper struct {
// The reference to the DelegationSet and ValidatorSet to get information about validators and delegators
sk types.StakingKeeper

// The reference to the Protocol DelegationSet and ValidatorSet to get information about KYVE protocol validators and delegators
protocolStakingKeeper types.ProtocolStakingKeeper

// GovHooks
hooks types.GovHooks

Expand Down Expand Up @@ -60,7 +63,7 @@ func (k Keeper) GetAuthority() string {
// CONTRACT: the parameter Subspace must have the param key table already initialized
func NewKeeper(
cdc codec.BinaryCodec, key storetypes.StoreKey, authKeeper types.AccountKeeper,
bankKeeper types.BankKeeper, sk types.StakingKeeper,
bankKeeper types.BankKeeper, sk types.StakingKeeper, psk types.ProtocolStakingKeeper,
router *baseapp.MsgServiceRouter, config types.Config, authority string,
) *Keeper {
// ensure governance module account is set
Expand All @@ -78,14 +81,15 @@ func NewKeeper(
}

return &Keeper{
storeKey: key,
authKeeper: authKeeper,
bankKeeper: bankKeeper,
sk: sk,
cdc: cdc,
router: router,
config: config,
authority: authority,
storeKey: key,
authKeeper: authKeeper,
bankKeeper: bankKeeper,
sk: sk,
protocolStakingKeeper: psk,
cdc: cdc,
router: router,
config: config,
authority: authority,
}
}

Expand Down
47 changes: 45 additions & 2 deletions x/gov/keeper/tally.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (

// TODO: Break into several smaller functions for clarity

// NOTE: We have to check if the KYVE Protocol staking keeper is defined to ensure minimal changes.

// Tally iterates over the votes and updates the tally of a proposal based on the voting power of the
// voters
func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes bool, burnDeposits bool, tallyResults v1.TallyResult) {
Expand All @@ -34,6 +36,18 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes bool,
return false
})

// Fetch and insert all KYVE Protocol validators into list of current validators.
// NOTE: The key used is a normal "kyve1blah" address.
if keeper.protocolStakingKeeper != nil {
for _, rawVal := range keeper.protocolStakingKeeper.GetActiveValidators(ctx) {
// NOTE: We have to typecast to avoid creating import cycles when defining the function interfaces.
if val, ok := rawVal.(v1.ValidatorGovInfo); ok {
address := sdk.AccAddress(val.Address).String()
currValidators[address] = val
}
}
}

keeper.IterateVotes(ctx, proposal.Id, func(vote v1.Vote) bool {
// if validator, just record it in the map
voter := sdk.MustAccAddressFromBech32(vote.Voter)
Expand All @@ -43,6 +57,11 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes bool,
val.Vote = vote.Options
currValidators[valAddrStr] = val
}
// Check if the voter is a KYVE Protocol validator.
if val, ok := currValidators[voter.String()]; ok {
val.Vote = vote.Options
currValidators[voter.String()] = val
}

// iterate over all delegations from voter, deduct from any delegated-to validators
keeper.sk.IterateDelegations(ctx, voter, func(index int64, delegation stakingtypes.DelegationI) (stop bool) {
Expand All @@ -68,6 +87,23 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes bool,
return false
})

if keeper.protocolStakingKeeper != nil {
validators, amounts := keeper.protocolStakingKeeper.GetDelegations(ctx, voter.String())
for idx, address := range validators {
if val, ok := currValidators[address]; ok {
val.DelegatorDeductions = val.DelegatorDeductions.Add(amounts[idx])
currValidators[address] = val

for _, option := range vote.Options {
weight, _ := math.LegacyNewDecFromStr(option.Weight)
subPower := amounts[idx].Mul(weight)
results[option.Option] = results[option.Option].Add(subPower)
}
totalVotingPower = totalVotingPower.Add(amounts[idx])
}
}
}

keeper.deleteVote(ctx, vote.ProposalId, voter)
return false
})
Expand All @@ -92,14 +128,21 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes bool,
params := keeper.GetParams(ctx)
tallyResults = v1.NewTallyResultFromMap(results)

totalBondedTokens := keeper.sk.TotalBondedTokens(ctx)
if keeper.protocolStakingKeeper != nil {
totalBondedTokens = totalBondedTokens.Add(
keeper.protocolStakingKeeper.TotalBondedTokens(ctx),
)
}

// TODO: Upgrade the spec to cover all of these cases & remove pseudocode.
// If there is no staked coins, the proposal fails
if keeper.sk.TotalBondedTokens(ctx).IsZero() {
if totalBondedTokens.IsZero() {
return false, false, tallyResults
}

// If there is not enough quorum of votes, the proposal fails
percentVoting := totalVotingPower.Quo(sdk.NewDecFromInt(keeper.sk.TotalBondedTokens(ctx)))
percentVoting := totalVotingPower.Quo(math.LegacyNewDecFromInt(totalBondedTokens))
quorum, _ := sdk.NewDecFromStr(params.Quorum)
if percentVoting.LT(quorum) {
return false, params.BurnVoteQuorum, tallyResults
Expand Down
1 change: 1 addition & 0 deletions x/gov/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ func ProvideModule(in GovInputs) GovOutputs {
in.AccountKeeper,
in.BankKeeper,
in.StakingKeeper,
nil,
in.MsgServiceRouter,
kConfig,
authority.String(),
Expand Down
8 changes: 8 additions & 0 deletions x/gov/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ type StakingKeeper interface {
)
}

// ProtocolStakingKeeper expected KYVE protocol staking keeper (Protocol Validator and Delegator sets) (noalias)
type ProtocolStakingKeeper interface {
GetActiveValidators(sdk.Context) []interface{}

TotalBondedTokens(sdk.Context) math.Int
GetDelegations(sdk.Context, string) ([]string, []math.LegacyDec)
}

// AccountKeeper defines the expected account keeper (noalias)
type AccountKeeper interface {
GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.AccountI
Expand Down
2 changes: 1 addition & 1 deletion x/mint/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (s *GenesisTestSuite) SetupTest() {
accountKeeper.EXPECT().GetModuleAddress(minterAcc.Name).Return(minterAcc.GetAddress())
accountKeeper.EXPECT().GetModuleAccount(s.sdkCtx, minterAcc.Name).Return(minterAcc)

s.keeper = keeper.NewKeeper(s.cdc, key, stakingKeeper, accountKeeper, bankKeeper, "", "")
s.keeper = keeper.NewKeeper(s.cdc, key, stakingKeeper, nil, accountKeeper, bankKeeper, "", "")
}

func (s *GenesisTestSuite) TestImportExportGenesis() {
Expand Down
1 change: 1 addition & 0 deletions x/mint/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func (suite *MintTestSuite) SetupTest() {
encCfg.Codec,
key,
stakingKeeper,
nil,
accountKeeper,
bankKeeper,
authtypes.FeeCollectorName,
Expand Down
38 changes: 26 additions & 12 deletions x/mint/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import (

// Keeper of the mint store
type Keeper struct {
cdc codec.BinaryCodec
storeKey storetypes.StoreKey
stakingKeeper types.StakingKeeper
bankKeeper types.BankKeeper
feeCollectorName string
cdc codec.BinaryCodec
storeKey storetypes.StoreKey
stakingKeeper types.StakingKeeper
protocolStakingKeeper types.ProtocolStakingKeeper
bankKeeper types.BankKeeper
feeCollectorName string

// the address capable of executing a MsgUpdateParams message. Typically, this
// should be the x/gov module account.
Expand All @@ -30,6 +31,7 @@ func NewKeeper(
cdc codec.BinaryCodec,
key storetypes.StoreKey,
sk types.StakingKeeper,
psk types.ProtocolStakingKeeper,
ak types.AccountKeeper,
bk types.BankKeeper,
feeCollectorName string,
Expand All @@ -41,12 +43,13 @@ func NewKeeper(
}

return Keeper{
cdc: cdc,
storeKey: key,
stakingKeeper: sk,
bankKeeper: bk,
feeCollectorName: feeCollectorName,
authority: authority,
cdc: cdc,
storeKey: key,
stakingKeeper: sk,
protocolStakingKeeper: psk,
bankKeeper: bk,
feeCollectorName: feeCollectorName,
authority: authority,
}
}

Expand Down Expand Up @@ -113,7 +116,18 @@ func (k Keeper) StakingTokenSupply(ctx sdk.Context) math.Int {
// BondedRatio implements an alias call to the underlying staking keeper's
// BondedRatio to be used in BeginBlocker.
func (k Keeper) BondedRatio(ctx sdk.Context) math.LegacyDec {
return k.stakingKeeper.BondedRatio(ctx)
totalSupply := k.StakingTokenSupply(ctx)
if !totalSupply.IsPositive() {
return sdk.ZeroDec()
}

bondedTokens := math.LegacyNewDecFromInt(k.stakingKeeper.TotalBondedTokens(ctx))
protocolBondedTokens := math.LegacyZeroDec()
if k.protocolStakingKeeper != nil {
protocolBondedTokens = math.LegacyNewDecFromInt(k.protocolStakingKeeper.TotalBondedTokens(ctx))
}

return bondedTokens.Add(protocolBondedTokens).QuoInt(totalSupply)
}

// MintCoins implements an alias call to the underlying supply keeper's
Expand Down
5 changes: 4 additions & 1 deletion x/mint/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/suite"

"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
Expand Down Expand Up @@ -49,6 +50,7 @@ func (s *IntegrationTestSuite) SetupTest() {
encCfg.Codec,
key,
stakingKeeper,
nil,
accountKeeper,
bankKeeper,
authtypes.FeeCollectorName,
Expand Down Expand Up @@ -124,7 +126,8 @@ func (s *IntegrationTestSuite) TestAliasFunctions() {
s.Require().Equal(s.mintKeeper.StakingTokenSupply(s.ctx), stakingTokenSupply)

bondedRatio := sdk.NewDecWithPrec(15, 2)
s.stakingKeeper.EXPECT().BondedRatio(s.ctx).Return(bondedRatio)
s.stakingKeeper.EXPECT().StakingTokenSupply(s.ctx).Return(stakingTokenSupply)
s.stakingKeeper.EXPECT().TotalBondedTokens(s.ctx).Return(math.NewInt(15000000000))
s.Require().Equal(s.mintKeeper.BondedRatio(s.ctx), bondedRatio)

coins := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000000)))
Expand Down
1 change: 1 addition & 0 deletions x/mint/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ func ProvideModule(in MintInputs) MintOutputs {
in.Cdc,
in.Key,
in.StakingKeeper,
nil,
in.AccountKeeper,
in.BankKeeper,
feeCollectorName,
Expand Down
63 changes: 50 additions & 13 deletions x/mint/testutil/expected_keepers_mocks.go

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

7 changes: 6 additions & 1 deletion x/mint/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import (
// StakingKeeper defines the expected staking keeper
type StakingKeeper interface {
StakingTokenSupply(ctx sdk.Context) math.Int
BondedRatio(ctx sdk.Context) sdk.Dec
TotalBondedTokens(ctx sdk.Context) math.Int
}

// ProtocolStakingKeeper defines the expected KYVE protocol staking keeper
type ProtocolStakingKeeper interface {
TotalBondedTokens(ctx sdk.Context) math.Int
}

// AccountKeeper defines the contract required for account APIs.
Expand Down

0 comments on commit 4c86bb7

Please sign in to comment.