Skip to content

Commit

Permalink
Merge pull request #3 from Galactica-corp/fix/upgrade-v0_1_2
Browse files Browse the repository at this point in the history
Upgrade v0.1.2, network halt fix.
  • Loading branch information
yakud authored Apr 5, 2024
2 parents 6cbe466 + 4cbed9f commit fc20406
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 0 deletions.
6 changes: 6 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ func New(
panic(err)
}

app.applyUpgrades()

return app
}

Expand Down Expand Up @@ -655,3 +657,7 @@ func initParamsKeeper(

return paramsKeeper
}

func (app *App) applyUpgrades() {
app.applyUpgrade_v0_1_2()
}
102 changes: 102 additions & 0 deletions app/upgrade_v0_1_2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright 2024 Galactica Network
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package app

import (
"bytes"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/Galactica-corp/galactica/app/upgrades/v0_1_2"
)

// applyUpgrade_v0_1_2 checks and applies the upgrade plan if necessary.
func (app *App) applyUpgrade_v0_1_2() {
latestBlock := app.LastBlockHeight()
logger := app.Logger().With("upgrade", v0_1_2.UpgradeName)

ctx, err := app.CreateQueryContext(latestBlock, false)
if err != nil {
logger.Error("Failed to create query context with block", "error", err, "block", latestBlock)
return
}

plan, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil || plan.Height < v0_1_2.UpgradeBlockHeight {
logger.Info("Applying upgrade plan", "info", plan.Info)
app.UpgradeKeeper.SetUpgradeHandler(v0_1_2.UpgradeName, app.upgradeHandler_v0_1_2())
app.UpgradeKeeper.ApplyUpgrade(ctx, v0_1_2.Plan)
}
}

// upgradeHandler_v0_1_2 returns a handler function for processing the upgrade.
func (app *App) upgradeHandler_v0_1_2() func(
ctx sdk.Context,
_ upgradetypes.Plan,
fromVM module.VersionMap,
) (module.VersionMap, error) {
return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
logger := ctx.Logger().With("upgrade", plan.Name)

if plan.Name != v0_1_2.UpgradeName {
logger.Error("Invalid upgrade plan", "expected", v0_1_2.UpgradeName, "got", plan.Name)
return app.ModuleManager.RunMigrations(ctx, app.Configurator(), fromVM)
}

validators := app.StakingKeeper.GetAllValidators(ctx)

for _, validator := range validators {
if err := app.updateValidatorPowerIndex(ctx, validator); err != nil {
logger.Error("Failed to update validator power index", "error", err, "validator", validator.OperatorAddress)
return nil, err
}
logger.Info("Validator power index updated", "validator", validator.OperatorAddress)
}

logger.Info("All validators updated successfully.")

if err := app.UpgradeKeeper.DumpUpgradeInfoToDisk(plan.Height, plan); err != nil {
logger.Error("Failed to dump upgrade info to disk", "error", err)
return nil, err
}

return app.ModuleManager.RunMigrations(ctx, app.Configurator(), fromVM)
}
}

// updateValidatorPowerIndex updates the power index for a single validator.
func (app *App) updateValidatorPowerIndex(ctx sdk.Context, validator stakingtypes.Validator) error {
store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey))
iterator := sdk.KVStorePrefixIterator(store, stakingtypes.ValidatorsByPowerIndexKey)
defer iterator.Close()

for ; iterator.Valid(); iterator.Next() {
valAddr := stakingtypes.ParseValidatorPowerRankKey(iterator.Key())
if bytes.Equal(valAddr, validator.GetOperator()) {
store.Delete(iterator.Key())
break // Assuming unique power index key per validator.
}
}

app.StakingKeeper.SetValidatorByPowerIndex(ctx, validator)
if _, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx); err != nil {
return err
}

return nil
}
36 changes: 36 additions & 0 deletions app/upgrades/v0_1_2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Upgrade to v0.1.2

## Guide for Upgrading from v0.1.1 to v0.1.2

1. Halt the currently running `galacticad` process.
2. **!!! Backup the data directory.** !!!
3. Fetch the latest updates from the repository and switch to the `v0.1.2` tag.
```bash
git fetch --all --tags
git checkout v0.1.2
```
4. Build the updated source code.
```bash
make install
```
5. Execute the upgrade script located at ./scripts/upgrade_v0_1_2.sh
```bash
./scripts/upgrade_v0_1_2.sh
```
Ensure the following environment variable is defined:
- `GALACTICA_HOME`: Specifies the home directory for the `galacticad` node.

The script executes the following operations:
- Updates the node storage to version v0.1.2.
- Roll back the state of the most recent block.
- Backup of the current priv_validator_state.json and replaces it with a new version with default settings.

Alternatively, these steps can be performed manually:
```bash
galacticad --home $GALACTICA_HOME rollback --hard
echo '{"height":"0","round":0,"step":0}' > $GALACTICA_HOME/data/priv_validator_state.json
```
Executing the rollback command will also automatically execute the storage upgrade.

6. Restart the `galacticad` node.

32 changes: 32 additions & 0 deletions app/upgrades/v0_1_2/upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2024 Galactica Network
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package v0_1_2

import (
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

const (
UpgradeName = "0.1.2"
UpgradeBlockHeight = 16951
)

// Plan defines the upgrade plan for addressing the staking PowerReduction issue.
var Plan = upgradetypes.Plan{
Name: UpgradeName,
Height: UpgradeBlockHeight,
Info: "Addresses a critical staking PowerReduction issue by mutating validators' " +
"power for accurate voting power recalibration and network integrity.",
}
6 changes: 6 additions & 0 deletions cmd/galacticad/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package cmd

import (
"math/big"

"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"

Expand Down Expand Up @@ -73,6 +75,10 @@ func initSDKConfig() {

RegisterDenoms()

sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(
new(big.Int).Exp(big.NewInt(10), big.NewInt(BaseDenomUnit), nil),
)

config.Seal()
}

Expand Down
65 changes: 65 additions & 0 deletions scripts/upgrade_v0_1_2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright 2024 Galactica Network
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#!/bin/bash

# This script is used to prepare the upgrade from v0.1.1 to v0.1.2

GALACTICAD_VERSION=$(galacticad version)
if [[ $GALACTICAD_VERSION != *"0.1.2"* ]]; then
echo "Galactica version must be 0.1.2"
exit 1
fi

# check env var GALACTICA_HOME and if not exists exit
if [ -z "$GALACTICA_HOME" ]; then
echo "GALACTICA_HOME is not set, using default path"
GALACTICA_HOME="$HOME/.galactica"
fi

# ask user to confirm:
echo "GALACTICA_HOME: $GALACTICA_HOME"
echo "\nThis script will perform the following actions:\n\
- Backup the existing priv_validator_state.json and replace it with a new one containing default values\n\
- Upgrade the node storage to v0.1.2\n\
- Rollback the latest block state\n"

if [ "$1" != "-y" ]; then
read -p "Do you want to continue? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "User cancelled the script"
exit 1
fi
fi

PRIV_VAL_STATE=$GALACTICA_HOME/data/priv_validator_state.json

UPGRADE_INFO_FILE=$GALACTICA_HOME/data/upgrade-info.json
if [ -f "$UPGRADE_INFO_FILE" ]; then
echo "upgrade v0.1.2 already applied"
exit 1
fi

if [ ! -f "$PRIV_VAL_STATE" ]; then
echo "priv_validator_state.json not found at $PRIV_VAL_STATE"
exit 1
fi

cp $PRIV_VAL_STATE $PRIV_VAL_STATE.bkp

galacticad --home $GALACTICA_HOME rollback --hard

echo '{"height":"0","round":0,"step":0}' > $PRIV_VAL_STATE

0 comments on commit fc20406

Please sign in to comment.