Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store migration for slashing, auth and authz #746

Merged
merged 13 commits into from
Aug 7, 2023
133 changes: 132 additions & 1 deletion app/upgrade_handler.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
package app

import (
"errors"
"fmt"
"time"

storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
sdkauthtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/feegrant"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/shentufoundation/shentu/v2/common"
authtypes "github.com/shentufoundation/shentu/v2/x/auth/types"
)

const (
Expand Down Expand Up @@ -57,7 +62,16 @@
if err = transAddrPrefixForFeegrant(ctx, app); err != nil {
return err
}
err = transAddrPrefixForGov(ctx, app)
if err = transAddrPrefixForGov(ctx, app); err != nil {
return err
}

Check warning on line 67 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L66-L67

Added lines #L66 - L67 were not covered by tests
if err = runSlashingMigration(ctx, app); err != nil {
return err
}

Check warning on line 70 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L69-L70

Added lines #L69 - L70 were not covered by tests
if err = runAuthMigration(ctx, app); err != nil {
return err
}

Check warning on line 73 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L72-L73

Added lines #L72 - L73 were not covered by tests
err = runAuthzMigration(ctx, app)
return err
}

Expand Down Expand Up @@ -241,3 +255,120 @@
})
return err
}

func runSlashingMigration(ctx sdk.Context, app ShentuApp) (err error) {
sk := app.SlashingKeeper
sk.IterateValidatorSigningInfos(ctx, func(address sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) {
info.Address, err = common.PrefixToShentu(info.Address)
if err != nil {
return true
}

Check warning on line 265 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L264-L265

Added lines #L264 - L265 were not covered by tests
sk.SetValidatorSigningInfo(ctx, address, info)

return false
})

return err
}

func runAuthMigration(ctx sdk.Context, app ShentuApp) (err error) {
ak := app.AccountKeeper
ak.IterateAccounts(ctx, func(acc sdkauthtypes.AccountI) (stop bool) {
switch account := acc.(type) {
case *sdkauthtypes.BaseAccount:
var newAddr string
newAddr, err = common.PrefixToShentu(account.Address)
if err != nil {
return true
}

Check warning on line 283 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L282-L283

Added lines #L282 - L283 were not covered by tests
account.Address = newAddr
ak.SetAccount(ctx, account)
case *sdkauthtypes.ModuleAccount:
var newAddr string
newAddr, err = common.PrefixToShentu(account.Address)
if err != nil {
return true
}

Check warning on line 291 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L290-L291

Added lines #L290 - L291 were not covered by tests
account.Address = newAddr
ak.SetAccount(ctx, account)
case *authtypes.ManualVestingAccount:
var newAddr string
newAddr, err = common.PrefixToShentu(account.Address)
if err != nil {
return true
}

Check warning on line 299 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L298-L299

Added lines #L298 - L299 were not covered by tests
var newUnlocker string
newUnlocker, err = common.PrefixToShentu(account.Unlocker)
if err != nil {
return true
}

Check warning on line 304 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L303-L304

Added lines #L303 - L304 were not covered by tests
account.Address = newAddr
account.Unlocker = newUnlocker
ak.SetAccount(ctx, account)
default:
err = errors.New("unknown account type")
return true

Check warning on line 310 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L308-L310

Added lines #L308 - L310 were not covered by tests
}
return false
})
return err
}

func runAuthzMigration(ctx sdk.Context, app ShentuApp) (err error) {
ak := app.AuthzKeeper
ak.IterateGrants(ctx, func(granterAddr sdk.AccAddress, granteeAddr sdk.AccAddress, grant authz.Grant) bool {
authorization := grant.Authorization

switch authorization.GetCachedValue().(type) {
case *authz.GenericAuthorization:
case *stakingtypes.StakeAuthorization:
stakeAuthorization := &stakingtypes.StakeAuthorization{}
if err = stakeAuthorization.Unmarshal(authorization.Value); err != nil {
return true
}

Check warning on line 328 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L327-L328

Added lines #L327 - L328 were not covered by tests
if err = processStakeAuthorization(stakeAuthorization); err != nil {
return true
}

Check warning on line 331 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L330-L331

Added lines #L330 - L331 were not covered by tests
if err := ak.SaveGrant(ctx, granteeAddr, granterAddr, stakeAuthorization, grant.Expiration); err != nil {
return true
}
default:
Copy link
Contributor

Choose a reason for hiding this comment

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

just for your info:
it seems there is another Authorization, which is bank.types.SendAuthorization. But it looks like we don't have it on mainnet state.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the current data on the chain does not have this status.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add

err = errors.New("unknown authorization types")
return true

Check warning on line 337 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L333-L337

Added lines #L333 - L337 were not covered by tests
}
return false
})
return err
}

func processStakeAuthorization(stakeAuthorization *stakingtypes.StakeAuthorization) error {
denyList := stakeAuthorization.GetDenyList()
allowList := stakeAuthorization.GetAllowList()
if denyList.Size() > 0 {
newList, err := prefixToShentuAddrs(denyList.GetAddress())
if err != nil {
return err
}
stakeAuthorization.Validators = &stakingtypes.StakeAuthorization_DenyList{DenyList: &stakingtypes.StakeAuthorization_Validators{Address: newList}}

Check warning on line 352 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L348-L352

Added lines #L348 - L352 were not covered by tests
}
if allowList.Size() > 0 {
newList, err := prefixToShentuAddrs(allowList.GetAddress())
if err != nil {
return err
}

Check warning on line 358 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L357-L358

Added lines #L357 - L358 were not covered by tests
stakeAuthorization.Validators = &stakingtypes.StakeAuthorization_AllowList{AllowList: &stakingtypes.StakeAuthorization_Validators{Address: newList}}
}
return nil
}

func prefixToShentuAddrs(addrs []string) (newAddrs []string, err error) {
for _, addr := range addrs {
var newAddr string
newAddr, err = common.PrefixToShentu(addr)
if err != nil {
return newAddrs, err
}

Check warning on line 370 in app/upgrade_handler.go

View check run for this annotation

Codecov / codecov/patch

app/upgrade_handler.go#L369-L370

Added lines #L369 - L370 were not covered by tests
newAddrs = append(newAddrs, newAddr)
}
return newAddrs, err
}
92 changes: 85 additions & 7 deletions app/upgrade_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@ package app

import (
"encoding/json"
"io/ioutil"
"strings"
"testing"
"time"

"io/ioutil"
"github.com/test-go/testify/require"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkauthtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/authz"
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
fgtypes "github.com/cosmos/cosmos-sdk/x/feegrant"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
sktypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/shentufoundation/shentu/v2/common"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/test-go/testify/require"

"github.com/shentufoundation/shentu/v2/common"
authtypes "github.com/shentufoundation/shentu/v2/x/auth/types"
)

func setConfig(prefix string) {
Expand All @@ -38,20 +46,29 @@ func TestMigrateStore(t *testing.T) {
ctx := app.BaseApp.NewContext(false, tmproto.Header{Time: time.Now().UTC()})
setConfig("certik")

for _, m := range []string{"auth", "bank", "staking", "gov", "feegrant"} {
for _, m := range []string{"auth", "authz", "bank", "staking", "slashing", "gov", "feegrant"} {
app.mm.Modules[m].InitGenesis(ctx, app.appCodec, genesisState[m])
}

checkStaking(t, ctx, app, true)
checkFeegrant(t, ctx, app, true)
checkGov(t, ctx, app, true)
checkSlashing(t, ctx, app, true)
checkAuth(t, ctx, app, true)
checkAuthz(t, ctx, app, true)

setConfig("shentu")
transAddrPrefix(ctx, *app)
err := transAddrPrefix(ctx, *app)
if err != nil {
panic(err)
}

checkStaking(t, ctx, app, false)
checkFeegrant(t, ctx, app, false)
checkGov(t, ctx, app, false)
checkSlashing(t, ctx, app, false)
checkAuth(t, ctx, app, false)
checkAuthz(t, ctx, app, false)

//check for error cases
require.Error(t, transAddrPrefix(ctx, *app))
Expand Down Expand Up @@ -104,8 +121,8 @@ func (c Checker) checkForOneKey(keyPrefix []byte, v any) {
panic("failed to cast to codec.ProtoMarshaler")
}
c.app.appCodec.MustUnmarshal(iter.Value(), iv)
jsonstr := MustMarshalJSON(v)
c.checkStr(jsonstr)
jsonStr := MustMarshalJSON(v)
c.checkStr(jsonStr)
}
}

Expand Down Expand Up @@ -148,3 +165,64 @@ func checkFeegrant(t *testing.T, ctx sdk.Context, app *ShentuApp, old bool) {
return false
})
}

func checkAuth(t *testing.T, ctx sdk.Context, app *ShentuApp, old bool) {
store := ctx.KVStore(app.keys[sdkauthtypes.StoreKey])
ck := NewChecker(t, app, store, old)
ck.checkForAuth(sdkauthtypes.AddressStoreKeyPrefix)
}

func checkSlashing(t *testing.T, ctx sdk.Context, app *ShentuApp, old bool) {
store := ctx.KVStore(app.keys[slashingtypes.StoreKey])
ck := NewChecker(t, app, store, old)
ck.checkForOneKey(slashingtypes.ValidatorSigningInfoKeyPrefix, &slashingtypes.ValidatorSigningInfo{})
}

func checkAuthz(t *testing.T, ctx sdk.Context, app *ShentuApp, old bool) {
store := ctx.KVStore(app.keys[authzkeeper.StoreKey])
ck := NewChecker(t, app, store, old)
ck.checkForAuthz(authzkeeper.GrantKey)
}

func (c Checker) checkForAuth(keyPrefix []byte) {
ak := c.app.AccountKeeper
iter := sdk.KVStorePrefixIterator(c.store, keyPrefix)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
acc, err := ak.UnmarshalAccount(iter.Value())
if err != nil {
panic(err)
}

switch account := acc.(type) {
case *sdkauthtypes.BaseAccount:
c.checkStr(account.Address)
case *sdkauthtypes.ModuleAccount:
c.checkStr(account.Address)
case *authtypes.ManualVestingAccount:
c.checkStr(account.Address + account.Unlocker)
default:
panic("unknown account type")
}
}
}

func (c Checker) checkForAuthz(keyPrefix []byte) {
iter := sdk.KVStorePrefixIterator(c.store, keyPrefix)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
var grant authz.Grant
c.app.appCodec.MustUnmarshal(iter.Value(), &grant)
authorization := grant.Authorization
value := authorization.GetValue()

switch authorization.GetTypeUrl() {
case "/cosmos.staking.v1beta1.StakeAuthorization":
stakeAuthorization := &stakingtypes.StakeAuthorization{}
if err := stakeAuthorization.Unmarshal(value); err != nil {
panic(err)
}
c.checkStr(stakeAuthorization.String())
}
}
}
2 changes: 1 addition & 1 deletion tests/pruned-state.json

Large diffs are not rendered by default.

Loading