Skip to content
Merged
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
2 changes: 2 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
v13 "github.com/classic-terra/core/v4/app/upgrades/v13"
v13_1 "github.com/classic-terra/core/v4/app/upgrades/v13_1"
v14_1 "github.com/classic-terra/core/v4/app/upgrades/v14_1"
v14_2 "github.com/classic-terra/core/v4/app/upgrades/v14_2"
v2 "github.com/classic-terra/core/v4/app/upgrades/v2"
v3 "github.com/classic-terra/core/v4/app/upgrades/v3"
v4 "github.com/classic-terra/core/v4/app/upgrades/v4"
Expand Down Expand Up @@ -105,6 +106,7 @@ var (
v13.Upgrade,
v13_1.Upgrade,
v14_1.Upgrade,
v14_2.Upgrade,
}

// Forks defines forks to be applied to the network
Expand Down
7 changes: 2 additions & 5 deletions app/keepers/keepers.go

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

		appKeepers.TaxExemptionKeeper,
		appKeepers.TreasuryKeeper,
		appKeepers.AccountKeeper,
		appKeepers.TaxKeeper,

Why this is removed ? ( just a question)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It was not used in that module.

Original file line number Diff line number Diff line change
Expand Up @@ -385,13 +385,10 @@ func NewAppKeepers(

wasmMsgHandler := customwasmkeeper.NewMessageHandler(
bApp.MsgServiceRouter(),
&appKeepers.WasmKeeper,
appKeepers.IBCHooksWrapper,
appKeepers.IBCKeeper.ChannelKeeper,
appKeepers.IBCKeeper.ChannelKeeperV2,
appKeepers.BankKeeper,
appKeepers.TaxExemptionKeeper,
appKeepers.TreasuryKeeper,
appKeepers.AccountKeeper,
appKeepers.TaxKeeper,
appCodec,
appKeepers.TransferKeeper,
)
Expand Down
2 changes: 1 addition & 1 deletion app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func appModules(
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName), app.InterfaceRegistry()),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)),
customstaking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.ParamsKeeper, app.GetSubspace(stakingtypes.ModuleName)),
customstaking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.ParamsKeeper, app.GetSubspace(stakingtypes.ModuleName), app.GetKey(stakingtypes.StoreKey), app.GetKey(distrtypes.StoreKey)),
upgrade.NewAppModule(app.UpgradeKeeper, app.AccountKeeper.AddressCodec()),
evidence.NewAppModule(app.EvidenceKeeper),
params.NewAppModule(app.ParamsKeeper),
Expand Down
21 changes: 21 additions & 0 deletions app/upgrades/v14_2/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//nolint:revive
package v14_2

import (
store "cosmossdk.io/store/types"
"github.com/classic-terra/core/v4/app/upgrades"
)

const UpgradeName = "v14_2"

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateV142UpgradeHandler,
// Add new stores introduced since the last upgrade here. If there are
// no new stores for this upgrade, leave this empty.
StoreUpgrades: store.StoreUpgrades{
Added: []string{},
Deleted: []string{},
Renamed: []store.StoreRename{},
},
}
24 changes: 24 additions & 0 deletions app/upgrades/v14_2/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//nolint:revive
package v14_2

import (
"context"

upgradetypes "cosmossdk.io/x/upgrade/types"
"github.com/classic-terra/core/v4/app/keepers"
"github.com/classic-terra/core/v4/app/upgrades"
"github.com/cosmos/cosmos-sdk/types/module"
)

// CreateV142UpgradeHandler wires module migrations for v14_2.
// Add any one-off migration logic here before/after RunMigrations if needed.
func CreateV142UpgradeHandler(
mm *module.Manager,
cfg module.Configurator,
_ upgrades.BaseAppParamManager,
keepers *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx context.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
return mm.RunMigrations(ctx, cfg, fromVM)
}
}
25 changes: 17 additions & 8 deletions custom/staking/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"

storetypes "cosmossdk.io/store/types"
customtypes "github.com/classic-terra/core/v4/custom/staking/types"
core "github.com/classic-terra/core/v4/types"
"github.com/cosmos/cosmos-sdk/codec"
Expand Down Expand Up @@ -44,9 +45,12 @@ func (am AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
type AppModule struct {
staking.AppModule

keeper *keeper.Keeper
paramsKeeper paramskeeper.Keeper
ss paramtypes.Subspace
cdc codec.Codec
keeper *keeper.Keeper
paramsKeeper paramskeeper.Keeper
ss paramtypes.Subspace
storeKey storetypes.StoreKey
distrStoreKey storetypes.StoreKey
}

// NewAppModule creates a new AppModule object
Expand All @@ -56,12 +60,17 @@ func NewAppModule(cdc codec.Codec,
bk stakingtypes.BankKeeper,
pk paramskeeper.Keeper,
ss paramtypes.Subspace,
storeKey storetypes.StoreKey,
distrStoreKey storetypes.StoreKey,
) AppModule {
return AppModule{
AppModule: staking.NewAppModule(cdc, keeper, ak, bk, ss),
keeper: keeper,
paramsKeeper: pk,
ss: ss,
AppModule: staking.NewAppModule(cdc, keeper, ak, bk, ss),
cdc: cdc,
keeper: keeper,
paramsKeeper: pk,
ss: ss,
storeKey: storeKey,
distrStoreKey: distrStoreKey,
}
}

Expand All @@ -72,7 +81,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
querier := keeper.Querier{Keeper: am.keeper}
stakingtypes.RegisterQueryServer(
cfg.QueryServer(),
NewLegacyQueryServer(querier, am.ss, am.keeper),
NewLegacyQueryServer(querier, am.ss, am.keeper, am.cdc, am.storeKey, am.distrStoreKey),
)

m := keeper.NewMigrator(am.keeper, am.ss)
Expand Down
156 changes: 153 additions & 3 deletions custom/staking/query_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@ package staking

import (
"context"
"strconv"

"cosmossdk.io/math"
"cosmossdk.io/store/prefix"
storetypes "cosmossdk.io/store/types"
legacytypes "github.com/classic-terra/core/v4/custom/staking/types"
legacyupgrade "github.com/classic-terra/core/v4/custom/upgrade/legacy"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
"github.com/cosmos/cosmos-sdk/types/query"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

// LegacyQueryServer wraps the staking QueryServer and sets legacy parameters for pre-upgrade height queries
Expand All @@ -18,18 +27,33 @@ type LegacyQueryServer struct {
stakingtypes.QueryServer
keeper *keeper.Keeper
legacySubspace paramtypes.Subspace
cdc codec.BinaryCodec
storeKey storetypes.StoreKey
distrStoreKey storetypes.StoreKey
}

// NewLegacyQueryServer creates a new LegacyQueryServer instance
// NewLegacyQueryServer creates a new LegacyQueryServer instance.
//
// `cdc` and `storeKey` are required for the pre-v5-staking-migration
// ValidatorDelegations fallback path, which uses x/distribution's
// DelegatorStartingInfo prefix (0x04 || valAddr || delAddr) to enumerate a
// validator's delegators when staking's reverse-index (0x71) hasn't been
// backfilled at the queried height.
func NewLegacyQueryServer(
originalServer stakingtypes.QueryServer,
legacySubspace paramtypes.Subspace,
keeper *keeper.Keeper,
cdc codec.BinaryCodec,
storeKey storetypes.StoreKey,
distrStoreKey storetypes.StoreKey,
) stakingtypes.QueryServer {
return &LegacyQueryServer{
QueryServer: originalServer,
keeper: keeper,
legacySubspace: legacySubspace,
cdc: cdc,
storeKey: storeKey,
distrStoreKey: distrStoreKey,
}
}

Expand Down Expand Up @@ -111,7 +135,96 @@ func (q *LegacyQueryServer) Validator(ctx context.Context, req *stakingtypes.Que
}

func (q *LegacyQueryServer) ValidatorDelegations(ctx context.Context, req *stakingtypes.QueryValidatorDelegationsRequest) (*stakingtypes.QueryValidatorDelegationsResponse, error) {
return q.QueryServer.ValidatorDelegations(q.ensureLegacyParams(ctx), req)
ensuredCtx := q.ensureLegacyParams(ctx)
sdkCtx := sdk.UnwrapSDKContext(ensuredCtx)
if legacyupgrade.IsPreStakingV5(sdkCtx.ChainID(), sdkCtx.BlockHeight()) {
return q.validatorDelegationsLegacy(sdkCtx, req)
}
return q.QueryServer.ValidatorDelegations(ensuredCtx, req)
}

// validatorDelegationsLegacy reproduces cosmos-sdk's unexported
// `getValidatorDelegationsLegacy` semantics for archive heights before the
// v4→v5 staking migration. Instead of scanning every staking delegation under
// 0x31, it walks x/distribution's DelegatorStartingInfo prefix for the target
// validator, then fetches each exact staking delegation by (delegator,
// validator). This keeps the query validator-scoped even when staking's 0x71
// reverse-index does not exist yet.
func (q *LegacyQueryServer) validatorDelegationsLegacy(
ctx sdk.Context, req *stakingtypes.QueryValidatorDelegationsRequest,
) (*stakingtypes.QueryValidatorDelegationsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.ValidatorAddr == "" {
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
}
valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}

stakingStore := ctx.KVStore(q.storeKey)
distrStore := ctx.KVStore(q.distrStoreKey)
startingInfoPrefix := append([]byte{}, distrtypes.DelegatorStartingInfoPrefix...)
startingInfoPrefix = append(startingInfoPrefix, address.MustLengthPrefix(valAddr.Bytes())...)
startingInfoStore := prefix.NewStore(distrStore, startingInfoPrefix)

delegatorAddrs := make([]sdk.AccAddress, 0)
pageRes, err := query.Paginate(startingInfoStore, req.Pagination, func(key, _ []byte) error {
delAddr, err := parseLengthPrefixedAccAddress(key)
if err != nil {
return err
}
delegatorAddrs = append(delegatorAddrs, delAddr)
return nil
})
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

bondDenom, err := q.keeper.BondDenom(ctx)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
validator, err := q.keeper.GetValidator(ctx, valAddr)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

delResps := make(stakingtypes.DelegationResponses, 0, len(delegatorAddrs))
for _, delAddr := range delegatorAddrs {
delegationBz := stakingStore.Get(stakingtypes.GetDelegationKey(delAddr, valAddr))
if delegationBz == nil {
continue
}

var delegation stakingtypes.Delegation
if err := q.cdc.Unmarshal(delegationBz, &delegation); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

balance := validator.TokensFromShares(delegation.Shares).TruncateInt()
delResps = append(delResps, stakingtypes.NewDelegationResp(
delegation.GetDelegatorAddr(), delegation.GetValidatorAddr(), delegation.Shares, sdk.NewCoin(bondDenom, balance),
))
}

return &stakingtypes.QueryValidatorDelegationsResponse{
DelegationResponses: delResps,
Pagination: pageRes,
}, nil
}

func parseLengthPrefixedAccAddress(bz []byte) (sdk.AccAddress, error) {
if len(bz) == 0 {
return nil, status.Error(codes.Internal, "empty delegator key")
}
addrLen := int(bz[0])
if len(bz) != 1+addrLen {
return nil, status.Error(codes.Internal, "invalid delegator key length")
}
return sdk.AccAddress(bz[1:]), nil
}

func (q *LegacyQueryServer) ValidatorUnbondingDelegations(ctx context.Context, req *stakingtypes.QueryValidatorUnbondingDelegationsRequest) (*stakingtypes.QueryValidatorUnbondingDelegationsResponse, error) {
Expand Down Expand Up @@ -147,7 +260,44 @@ func (q *LegacyQueryServer) DelegatorValidator(ctx context.Context, req *staking
}

func (q *LegacyQueryServer) HistoricalInfo(ctx context.Context, req *stakingtypes.QueryHistoricalInfoRequest) (*stakingtypes.QueryHistoricalInfoResponse, error) {
return q.QueryServer.HistoricalInfo(q.ensureLegacyParams(ctx), req)
ensuredCtx := q.ensureLegacyParams(ctx)
sdkCtx := sdk.UnwrapSDKContext(ensuredCtx)
if legacyupgrade.IsPreStakingV5(sdkCtx.ChainID(), sdkCtx.BlockHeight()) {
return q.historicalInfoLegacy(sdkCtx, req)
}
return q.QueryServer.HistoricalInfo(ensuredCtx, req)
}

// historicalInfoLegacy reads HistoricalInfo using the pre-v5-staking-migration
// key encoding: prefix 0x50 followed by the ASCII-decimal height string. The
// v5 migration (cosmos-sdk@v0.53.6/x/staking/migrations/v5/store.go:39) re-keys
// every entry to a big-endian uint64; before that migration ran (block
// 28214400 on Columbus, 28917279 on Rebel-2) IAVL state contains only the old
// string-format keys, so the SDK's GetHistoricalInfo — which constructs the
// new binary key — misses and returns NotFound.
func (q *LegacyQueryServer) historicalInfoLegacy(
ctx sdk.Context, req *stakingtypes.QueryHistoricalInfoRequest,
) (*stakingtypes.QueryHistoricalInfoResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.Height < 0 {
return nil, status.Error(codes.InvalidArgument, "height cannot be negative")
}

store := ctx.KVStore(q.storeKey)
legacyKey := append([]byte{}, stakingtypes.HistoricalInfoKey...)
legacyKey = append(legacyKey, []byte(strconv.FormatInt(req.Height, 10))...)
bz := store.Get(legacyKey)
if bz == nil {
return nil, status.Errorf(codes.NotFound, "historical info for height %d not found", req.Height)
}

var hi stakingtypes.HistoricalInfo
if err := q.cdc.Unmarshal(bz, &hi); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &stakingtypes.QueryHistoricalInfoResponse{Hist: &hi}, nil
}

func (q *LegacyQueryServer) Pool(ctx context.Context, req *stakingtypes.QueryPoolRequest) (*stakingtypes.QueryPoolResponse, error) {
Expand Down
Loading
Loading