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
22 changes: 19 additions & 3 deletions client/app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/piplabs/story/client/app/upgrades"
"github.com/piplabs/story/client/app/upgrades/singularity/virgil"
)

var (
// `Upgrades` defines the upgrade handlers and store loaders for the application.
// New upgrades should be added to this slice after they are implemented.
Upgrades = []upgrades.Upgrade{}
Upgrades = []upgrades.Upgrade{
virgil.Upgrade,
}
// Forks are for hard forks that breaks backward compatibility.
Forks = []upgrades.Fork{}
Forks = []upgrades.Fork{
virgil.Fork,
}
)

func (a *App) setupUpgradeHandlers() {
Expand Down Expand Up @@ -54,7 +59,18 @@ func (a *App) setupUpgradeStoreLoaders() {
func (a *App) scheduleForkUpgrade(ctx sdk.Context) {
currentBlockHeight := ctx.BlockHeight()
for _, fork := range Forks {
if currentBlockHeight == fork.UpgradeHeight {
upgradeHeight := fork.UpgradeHeight
// Retrieve the upgrade height dynamically based on the network for virgil upgrade
if fork.UpgradeName == virgil.UpgradeName {
virgilUpgradeHeight, ok := virgil.GetUpgradeHeight(ctx.ChainID())
if !ok {
// Virgil upgrade not needed for current chain, skip
continue
}
upgradeHeight = virgilUpgradeHeight
}

if currentBlockHeight == upgradeHeight {
upgradePlan := upgradetypes.Plan{
Height: currentBlockHeight,
Name: fork.UpgradeName,
Expand Down
6 changes: 6 additions & 0 deletions client/app/upgrades/chains.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package upgrades

const (
AeneidChainID = "devnet-1"
StoryChainID = "story-1"
)
44 changes: 44 additions & 0 deletions client/app/upgrades/singularity/virgil/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package virgil

import (
storetypes "cosmossdk.io/store/types"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/piplabs/story/client/app/keepers"
"github.com/piplabs/story/client/app/upgrades"
)

const (
// UpgradeName defines the on-chain upgrade name for the virgil upgrade.
UpgradeName = "virgil"

// AeneidUpgradeHeight defines the block height at which virgil upgrade is triggered on Aeneid.
AeneidUpgradeHeight = 345158
// StoryUpgradeHeight defines the block height at which virgil upgrade is triggered on Story.
StoryUpgradeHeight = 677886
)

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: storetypes.StoreUpgrades{},
}

var Fork = upgrades.Fork{
UpgradeName: UpgradeName,
UpgradeInfo: "upgrade to change the duration of the short staking period during the singularity period",
// UpgradeHeight is set in `scheduleForkUpgrade`
BeginForkLogic: func(_ sdk.Context, _ *keepers.Keepers) {},
}

func GetUpgradeHeight(chainID string) (int64, bool) {
switch chainID {
case upgrades.AeneidChainID:
return AeneidUpgradeHeight, true
case upgrades.StoryChainID:
return StoryUpgradeHeight, true
default:
return 0, false
}
}
148 changes: 148 additions & 0 deletions client/app/upgrades/singularity/virgil/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package virgil

import (
"context"
"time"

upgradetypes "cosmossdk.io/x/upgrade/types"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"

"github.com/piplabs/story/client/app/keepers"
"github.com/piplabs/story/lib/errors"
"github.com/piplabs/story/lib/log"
)

const (
// NewShortPeriodDuration defines the duration of the new short period.
NewShortPeriodDuration = time.Second * 7776000 // 90 days
)

func CreateUpgradeHandler(
_ *module.Manager,
_ module.Configurator,
keepers *keepers.Keepers,
) upgradetypes.UpgradeHandler {
return func(ctx context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)

blockHeight := sdkCtx.BlockHeight()
log.Info(ctx, "Current block height", "Height", blockHeight)

// Check if the upgrade is needed for current chain
chainID := sdkCtx.ChainID()
if _, ok := GetUpgradeHeight(chainID); !ok {
log.Info(ctx, "Virgil upgrade not needed for current chain, skip", "ChainID", chainID)
return vm, nil
}
log.Info(ctx, "Start Virgil upgrade", "ChainID", chainID)

log.Info(ctx, "Get current staking params...")
stakingParams, err := keepers.StakingKeeper.GetParams(ctx)
if err != nil {
return vm, errors.Wrap(err, "failed to get staking params")
}

log.Info(ctx, "Update staking periods...")
var oldShortPeriodDuration time.Duration
for i := range stakingParams.Periods {
if stakingParams.Periods[i].PeriodType == 1 {
oldShortPeriodDuration = stakingParams.Periods[i].Duration
log.Info(ctx, "Existing short period duration", "Time", oldShortPeriodDuration.String())
log.Info(ctx, "Change short period duration to 90 days (7776000 seconds)")
stakingParams.Periods[i].Duration = NewShortPeriodDuration
} else if stakingParams.Periods[i].PeriodType == 2 {
log.Info(ctx, "Existing medium period duration", "Time", stakingParams.Periods[i].Duration.String())
} else if stakingParams.Periods[i].PeriodType == 3 {
log.Info(ctx, "Existing long period duration", "Time", stakingParams.Periods[i].Duration.String())
}
}

log.Info(ctx, "Apply staking param changes...")
if err := keepers.StakingKeeper.SetParams(ctx, stakingParams); err != nil {
return vm, errors.Wrap(err, "failed to update staking params")
}

log.Info(ctx, "Check new staking params...")
stakingParams, err = keepers.StakingKeeper.GetParams(ctx)
if err != nil {
return vm, errors.Wrap(err, "failed to get staking params")
}

for _, p := range stakingParams.Periods {
if p.PeriodType == 1 {
log.Info(ctx, "New short period duration", "Time", p.Duration.String())
if p.Duration != NewShortPeriodDuration {
return vm, errors.New("new short period duration is not correct")
}
} else if p.PeriodType == 2 {
log.Info(ctx, "New medium period duration", "Time", p.Duration.String())
} else if p.PeriodType == 3 {
log.Info(ctx, "New long period duration", "Time", p.Duration.String())
}
}

periodDelegations, err := keepers.StakingKeeper.GetAllPeriodDelegations(ctx)
if err != nil {
return vm, errors.Wrap(err, "failed to get all period delegations")
}
log.Info(ctx, "Sweep all delegations and modify short period delegations", "Count", len(periodDelegations))
for i := range periodDelegations {
if periodDelegations[i].PeriodType != 1 {
continue
}

log.Info(
ctx, "Find short period delegation",
"Delegator", periodDelegations[i].DelegatorAddress,
"Validator", periodDelegations[i].ValidatorAddress,
"Shares", periodDelegations[i].Shares.String(),
"RewardsShares", periodDelegations[i].RewardsShares.String(),
"PeriodDelegationId", periodDelegations[i].PeriodDelegationId,
"PeriodType", periodDelegations[i].PeriodType,
"EndTime", periodDelegations[i].EndTime.String(),
)

oldEndTime := periodDelegations[i].EndTime
newEndTime := oldEndTime.Add(NewShortPeriodDuration - oldShortPeriodDuration)
log.Info(ctx, "New short period delegation", "EndTime", newEndTime)

log.Info(ctx, "Set new short period delegation")
periodDelegations[i].EndTime = newEndTime
delAddr, err := sdk.AccAddressFromBech32(periodDelegations[i].DelegatorAddress)
if err != nil {
return vm, errors.Wrap(err, "failed to get delegator address")
}
valAddr, err := sdk.ValAddressFromBech32(periodDelegations[i].ValidatorAddress)
if err != nil {
return vm, errors.Wrap(err, "failed to get validator address")
}
if err := keepers.StakingKeeper.SetPeriodDelegation(ctx, delAddr, valAddr, periodDelegations[i]); err != nil {
return vm, errors.Wrap(err, "failed to set period delegation")
}

newPeriodDelegation, err := keepers.StakingKeeper.GetPeriodDelegation(ctx, delAddr, valAddr, periodDelegations[i].PeriodDelegationId)
if err != nil {
return vm, errors.Wrap(err, "failed to get new period delegation")
}
log.Info(
ctx, "Get new short period delegation",
"Delegator", periodDelegations[i].DelegatorAddress,
"Validator", periodDelegations[i].ValidatorAddress,
"Shares", periodDelegations[i].Shares.String(),
"RewardsShares", periodDelegations[i].RewardsShares.String(),
"PeriodDelegationId", periodDelegations[i].PeriodDelegationId,
"PeriodType", periodDelegations[i].PeriodType,
"EndTime", periodDelegations[i].EndTime.String(),
)
if newPeriodDelegation.EndTime != newEndTime {
return vm, errors.New("new period delegation end time is not correct")
}
}

log.Info(ctx, "Virgil upgrade complete")

return vm, nil
}
}
Loading