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

V0.20.0 - CI Tests, Improved Scripts, Register ModuleBasic GRPC #239

Merged
merged 49 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
2cd0d6f
remove versioning
Dec 3, 2024
bc7d4c8
refresh scripts, makefile, dockerfile,add basic e2e & pfm-e2e
Dec 3, 2024
74e41ce
bump config comments
Dec 3, 2024
069928d
add polytone e2e test
Dec 3, 2024
fb6a998
Merge pull request #5 from permissionlessweb/v0.18.2-patch
hard-nett Dec 4, 2024
f366d5a
improve genesis codec customization format, remove RandomGenesisAccou…
Dec 4, 2024
eb713e8
Merge pull request #6 from permissionlessweb/v0.18.2-patch
hard-nett Dec 4, 2024
f58a643
Merge pull request #240 from permissionlessweb/main
hard-nett Dec 4, 2024
1b53da4
slashing cli
Dec 4, 2024
8421f5a
replace cosmos-sdk with bitsong specific distirbution patch fork
Dec 4, 2024
d9de3f7
slashsing codec registry
Dec 5, 2024
75d7f84
docker bump, add v018 cosmos-sdk patch
Dec 5, 2024
f6ef09b
print results to new file
Dec 5, 2024
de600a5
Merge pull request #242 from permissionlessweb/slashed-delegators
hard-nett Dec 5, 2024
b1dc8ec
bump correct patch release
Dec 6, 2024
8d062b2
correct sdk patch
Dec 6, 2024
8d074ce
patch v18 slashing logic error
Dec 7, 2024
1ed4eff
bump sdk patch
Dec 7, 2024
f83725a
format cw-orchestrator into e2e test repo, add polytone msgs command
Dec 7, 2024
d9fcec9
Merge branch 'hard-nett/v0182' into slashed-delegators
hard-nett Dec 7, 2024
d2e6d82
Merge pull request #243 from permissionlessweb/slashed-delegators
hard-nett Dec 7, 2024
b844104
ci bump
Dec 9, 2024
d4a8654
ci bump
Dec 9, 2024
9a28744
revert token types to v114 in ictest
Dec 9, 2024
22d7694
coderabbit bumps
Dec 10, 2024
f145b2b
v19 upgrade handler
Dec 11, 2024
2a95e1a
delete replace cosmos-sdk, add v019 upgrade handler & logic
Dec 11, 2024
f018ac4
prep v019 cli helper
Dec 12, 2024
626a8c3
change to v20 upgrade
Dec 14, 2024
d1bfdc1
format to v020 upgrade
Dec 14, 2024
33e2bc6
Merge branch 'hard-nett/v0182' into hard-nett/v020-rc
hard-nett Dec 14, 2024
29db9ee
Merge pull request #245 from bitsongofficial/hard-nett/v020-rc
hard-nett Dec 14, 2024
fc33b65
register governance msg service router
Dec 14, 2024
a82d175
add legacy proposal context to gov proposal route
Dec 15, 2024
94c2c43
add gov legacy router
Dec 15, 2024
a29c91f
v020 upgrade
Dec 15, 2024
708b9a9
remove v020 from v019
Dec 15, 2024
38c1c89
TokensFromSharesTruncated
Dec 15, 2024
004e76f
bump comments
Dec 16, 2024
b0fb7b2
Merge pull request #246 from permissionlessweb/v019
hard-nett Dec 16, 2024
496fe23
Revert "V019"
hard-nett Dec 16, 2024
28141e5
Merge pull request #247 from bitsongofficial/revert-246-v019
hard-nett Dec 16, 2024
5391eed
Merge pull request #249 from permissionlessweb/v020
hard-nett Dec 16, 2024
d7cf1b5
Merge branch 'main' into hard-nett/v0182
Dec 16, 2024
763fa81
remove bin
Dec 16, 2024
b59b98b
remove v019 cli
Dec 16, 2024
6362e9f
bump cosmos-sdk v0.47.15 - ASA-2024-0012 patch
Dec 17, 2024
a12ce60
take into account multiple slashes
Dec 18, 2024
63db9c8
add changelog
Dec 18, 2024
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
28 changes: 27 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,35 @@ Ref: https://keepachangelog.com/en/1.0.0/
-->

# Changelog
## [v0.20.0]

## Added
- v020 upgrade handler

## Fixed
- certain delegators inability to claim rewards after v018 patch

## [v0.19.0]
### Added
- new ci tests for wasm,packetforwardmiddleware & polytone (ibc-callbacks)
- Introduced a Makefile for managing Docker-related tasks, including commands for building various Docker images.
- Added functionality for validating CosmWasm contracts in a new testing framework.
- Enhanced configuration capabilities for the Bitsong application with additional parameters.
- Introduced commands for verifying slashed delegators and calculating discrepancies in delegator rewards.
- Added a new Makefile for managing a local testnet environment for the Bitsong blockchain.
- Introduced a new script for automating the downloading of Polyone contract.
- Improved docker commands

### Fixed
- Registered legacy gov msgs
- Register ModuleBasics GrpcGatewayRoutes

### Removed
- versioning of app go module
- removed randomGenesisAccounts as param on new apps auth module registration

## [v0.18.x]
### Features
### Added
- Interchaintest package support added
- New CI support to build & release docker image
- New CI support to run interchain tests
Expand Down
2 changes: 2 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
v015 "github.com/bitsongofficial/go-bitsong/app/upgrades/v015"
v016 "github.com/bitsongofficial/go-bitsong/app/upgrades/v016"
v018 "github.com/bitsongofficial/go-bitsong/app/upgrades/v018"
v020 "github.com/bitsongofficial/go-bitsong/app/upgrades/v020"

errorsmod "cosmossdk.io/errors"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
Expand Down Expand Up @@ -94,6 +95,7 @@ var (
v015.Upgrade,
v016.Upgrade,
v018.Upgrade,
v020.Upgrade,
}
)

Expand Down
3 changes: 1 addition & 2 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func NewAppKeepers(
stakingKeeper, authtypes.FeeCollectorName, govModAddress,
)
appKeepers.SlashingKeeper = slashingkeeper.NewKeeper(
appCodec, &codec.LegacyAmino{}, keys[slashingtypes.StoreKey], stakingKeeper, govModAddress,
appCodec, cdc, keys[slashingtypes.StoreKey], stakingKeeper, govModAddress,
)

invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod))
Expand Down Expand Up @@ -288,7 +288,6 @@ func NewAppKeepers(
govConfig,
govModAddress,
)

// Set legacy router for backwards compatibility with gov v1beta1
appKeepers.GovKeeper.SetLegacyRouter(govRouter)

Expand Down
4 changes: 1 addition & 3 deletions app/test_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ func Setup(t *testing.T) *BitsongApp {
type EmptyAppOptions struct{}

// Get implements AppOptions
func (ao EmptyAppOptions) Get(o string) interface{} {
return nil
}
func (ao EmptyAppOptions) Get(o string) interface{} { return nil }

func setup(t *testing.T, withGenesis bool, opts ...wasmkeeper.Option) (*BitsongApp, GenesisState) {
db := dbm.NewMemDB()
Expand Down
19 changes: 19 additions & 0 deletions app/upgrades/v020/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package v020

import (
"github.com/bitsongofficial/go-bitsong/app/upgrades"
store "github.com/cosmos/cosmos-sdk/store/types"
)

const (
UpgradeName = "v020"
)

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateV020UpgradeHandler,
StoreUpgrades: store.StoreUpgrades{
Added: []string{},
Deleted: []string{},
},
}
241 changes: 241 additions & 0 deletions app/upgrades/v020/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
package v020

import (
"fmt"

"cosmossdk.io/math"
"github.com/bitsongofficial/go-bitsong/app/keepers"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

func CreateV020UpgradeHandler(mm *module.Manager, configurator module.Configurator, k *keepers.AppKeepers) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
logger := ctx.Logger().With("upgrade", UpgradeName)
ctx = sdk.UnwrapSDKContext(ctx)
ctx.Logger().Info(`
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
V020 UPGRADE manually claims delegation rewards for all users.
This will refresh the delegation information to the upgrade block.
This prevents the error from occuring in the future.
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
`)
hard-nett marked this conversation as resolved.
Show resolved Hide resolved

// manually claim rewards by calling keeper functions
for _, validator := range k.StakingKeeper.GetAllValidators(ctx) {
for _, del := range k.StakingKeeper.GetValidatorDelegations(ctx, validator.GetOperator()) {
valAddr := del.GetValidatorAddr()
val := k.StakingKeeper.Validator(ctx, valAddr)

// check existence of delegator starting info
if !k.DistrKeeper.HasDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) {
return nil, distrtypes.ErrEmptyDelegationDistInfo
}

// end current period and calculate rewards
endingPeriod := k.DistrKeeper.IncrementValidatorPeriod(ctx, val)
rewardsRaw := customCalculateDelegationRewards(ctx, k, val, del, endingPeriod)
hard-nett marked this conversation as resolved.
Show resolved Hide resolved
outstanding := k.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, del.GetValidatorAddr())

// defensive edge case may happen on the very final digits
// of the decCoins due to operation order of the distribution mechanism.
rewards := rewardsRaw.Intersect(outstanding)
if !rewards.IsEqual(rewardsRaw) {
logger := k.DistrKeeper.Logger(ctx)
logger.Info(
"rounding error withdrawing rewards from validator",
"delegator", del.GetDelegatorAddr().String(),
"validator", val.GetOperator().String(),
"got", rewards.String(),
"expected", rewardsRaw.String(),
)
}

// truncate reward dec coins, return remainder to community pool
finalRewards, remainder := rewards.TruncateDecimal()

// add coins to user account
if !finalRewards.IsZero() {
withdrawAddr := k.DistrKeeper.GetDelegatorWithdrawAddr(ctx, del.GetDelegatorAddr())
err := k.BankKeeper.SendCoinsFromModuleToAccount(ctx, distrtypes.ModuleName, withdrawAddr, finalRewards)
if err != nil {
return nil, err
}
}

// update the outstanding rewards and the community pool only if the
// transaction was successful
k.DistrKeeper.SetValidatorOutstandingRewards(ctx, del.GetValidatorAddr(), distrtypes.ValidatorOutstandingRewards{Rewards: outstanding.Sub(rewards)})
feePool := k.DistrKeeper.GetFeePool(ctx)
feePool.CommunityPool = feePool.CommunityPool.Add(remainder...)
k.DistrKeeper.SetFeePool(ctx, feePool)

// decrement reference count of starting period
startingInfo := k.DistrKeeper.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr())
startingPeriod := startingInfo.PreviousPeriod
customDecrementReferenceCount(ctx, k, del.GetValidatorAddr(), startingPeriod)

// remove delegator starting info
k.DistrKeeper.DeleteDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr())

if finalRewards.IsZero() {
baseDenom, _ := sdk.GetBaseDenom()
if baseDenom == "" {
baseDenom = sdk.DefaultBondDenom
}

// Note, we do not call the NewCoins constructor as we do not want the zero
// coin removed.
finalRewards = sdk.Coins{sdk.NewCoin(baseDenom, math.ZeroInt())}
ctx.Logger().Info("No final rewards", finalRewards)
}

// reinitialize the delegation
// period has already been incremented - we want to store the period ended by this delegation action
previousPeriod := k.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddr).Period - 1

// increment reference count for the period we're going to track
incrementReferenceCount(ctx, k, valAddr, previousPeriod)

validator := k.StakingKeeper.Validator(ctx, valAddr)
delegation := k.StakingKeeper.Delegation(ctx, del.GetDelegatorAddr(), valAddr)

// calculate delegation stake in tokens
// we don't store directly, so multiply delegation shares * (tokens per share)
// note: necessary to truncate so we don't allow withdrawing more rewards than owed
stake := validator.TokensFromSharesTruncated(delegation.GetShares())

// save new delegator starting info to kv store
k.DistrKeeper.SetDelegatorStartingInfo(ctx, valAddr, del.GetDelegatorAddr(), distrtypes.NewDelegatorStartingInfo(previousPeriod, stake, uint64(ctx.BlockHeight())))
}
}

// // confirm patch has been applied by querying rewards again for each delegation
for _, del := range k.StakingKeeper.GetAllDelegations(ctx) {
valAddr := del.GetValidatorAddr()
val := k.StakingKeeper.Validator(ctx, valAddr)
// calculate rewards
k.DistrKeeper.CalculateDelegationRewards(ctx, val, del, uint64(ctx.BlockHeight()))
}
hard-nett marked this conversation as resolved.
Show resolved Hide resolved

ctx.Logger().Info(`
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
Upgrade V020 Patch complete.
All delegation rewards claimed and startingInfo set to this block height
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
`)

// Run migrations
logger.Info(fmt.Sprintf("pre migrate version map: %v", vm))
versionMap, err := mm.RunMigrations(ctx, configurator, vm)
if err != nil {
return nil, err
}
logger.Info(fmt.Sprintf("post migrate version map: %v", versionMap))
return versionMap, err
}
}

func customCalculateDelegationRewards(ctx sdk.Context, k *keepers.AppKeepers, val stakingtypes.ValidatorI, del stakingtypes.DelegationI, endingPeriod uint64) (rewards sdk.DecCoins) {
// fetch starting info for delegation
startingInfo := k.DistrKeeper.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr())
if startingInfo.Height == uint64(ctx.BlockHeight()) {
// started this height, no rewards yet
return
}

startingPeriod := startingInfo.PreviousPeriod
stake := startingInfo.Stake
startingHeight := startingInfo.Height
endingHeight := uint64(ctx.BlockHeight())
if endingHeight > startingHeight {
k.DistrKeeper.IterateValidatorSlashEventsBetween(ctx, del.GetValidatorAddr(), startingHeight, endingHeight,
func(height uint64, event distrtypes.ValidatorSlashEvent) (stop bool) {
endingPeriod := event.ValidatorPeriod
if endingPeriod > startingPeriod {
rewards = rewards.Add(customCalculateDelegationRewardsBetween(ctx, k, val, startingPeriod, endingPeriod, stake)...)
// Note: It is necessary to truncate so we don't allow withdrawing
// more rewards than owed.
stake = stake.MulTruncate(math.LegacyOneDec().Sub(event.Fraction))
startingPeriod = endingPeriod
}
return false
},
)
}
currentStake := val.TokensFromShares(del.GetShares())

if stake.GT(currentStake) {
marginOfErr := currentStake.Mul(sdk.NewDecWithPrec(50, 3)) // 5.0%
if stake.LTE(currentStake.Add(marginOfErr)) {
stake = currentStake
} else {
panic(fmt.Sprintln("current stake is not delgator from slashed validator, and is more than maximum margin of error"))
}
}
// calculate rewards for final period
rewards = rewards.Add(customCalculateDelegationRewardsBetween(ctx, k, val, startingPeriod, endingPeriod, stake)...)
return rewards
}

func customCalculateDelegationRewardsBetween(ctx sdk.Context, k *keepers.AppKeepers, val stakingtypes.ValidatorI,
startingPeriod, endingPeriod uint64, stake sdk.Dec,
) (rewards sdk.DecCoins) {
// sanity check
if startingPeriod > endingPeriod {
panic("startingPeriod cannot be greater than endingPeriod")
}

// sanity check
if stake.IsNegative() {
panic("stake should not be negative")
}

// return staking * (ending - starting)
starting := k.DistrKeeper.GetValidatorHistoricalRewards(ctx, val.GetOperator(), startingPeriod)
ending := k.DistrKeeper.GetValidatorHistoricalRewards(ctx, val.GetOperator(), endingPeriod)
difference := ending.CumulativeRewardRatio.Sub(starting.CumulativeRewardRatio)
if difference.IsAnyNegative() {
panic("negative rewards should not be possible")
}
// note: necessary to truncate so we don't allow withdrawing more rewards than owed
rewards = difference.MulDecTruncate(stake)
return
}

// decrement the reference count for a historical rewards value, and delete if zero references remain
func customDecrementReferenceCount(ctx sdk.Context, k *keepers.AppKeepers, valAddr sdk.ValAddress, period uint64) {
historical := k.DistrKeeper.GetValidatorHistoricalRewards(ctx, valAddr, period)
if historical.ReferenceCount == 0 {
panic("cannot set negative reference count")
}
historical.ReferenceCount--
if historical.ReferenceCount == 0 {

k.DistrKeeper.DeleteValidatorHistoricalReward(ctx, valAddr, period)
} else {
k.DistrKeeper.SetValidatorHistoricalRewards(ctx, valAddr, period, historical)
}
}

// increment the reference count for a historical rewards value
func incrementReferenceCount(ctx sdk.Context, k *keepers.AppKeepers, valAddr sdk.ValAddress, period uint64) {
historical := k.DistrKeeper.GetValidatorHistoricalRewards(ctx, valAddr, period)
if historical.ReferenceCount > 2 {
panic("reference count should never exceed 2")
}
hard-nett marked this conversation as resolved.
Show resolved Hide resolved
historical.ReferenceCount++
k.DistrKeeper.SetValidatorHistoricalRewards(ctx, valAddr, period, historical)
}

// calculate the token worth of provided shares, truncated
func CustommTokensFromSharesTruncated(t math.Int, ds math.LegacyDec, shares sdk.Dec) math.LegacyDec {
return (shares.MulInt(t)).QuoTruncate(ds)
}
hard-nett marked this conversation as resolved.
Show resolved Hide resolved
Binary file removed bin/bitsongd
Binary file not shown.
2 changes: 0 additions & 2 deletions cmd/bitsongd/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,6 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
PrepareGenesisCmd(bitsong.DefaultNodeHome, bitsong.ModuleBasics),
genesisCommand(encodingConfig),
InitFromStateCmd(bitsong.DefaultNodeHome),
V019(bitsong.DefaultNodeHome),
VerifySlashedDelegatorsV018(bitsong.DefaultNodeHome),
queryCommand(),
txCommand(),
keys.Commands(bitsong.DefaultNodeHome),
Expand Down
Loading
Loading