Skip to content

Commit

Permalink
Release/v1.4.x (#296)
Browse files Browse the repository at this point in the history
* x/interchainstaking/keeper: preallocate slice capacity in CalculateDeltas

Given that types.ValidatorIntents is already a slice, this change
just extracts its length and uses that as a slice capacity hint
to improve performance.

Fixes #97

* x/interchainstaking/keeper: use .IncrementBalanceWaitgroup() instead of naked ++

Instead of using a naked increment for an exported struct, this change
uses its .IncrementBalanceWaitgroup() which helps in logical checks.

Fixes #98

* make docker build process use makefile

* fix BeforeEpochStart bug

* refactor self consensus state update for testability

* make decimals mandatory in validateBasic; more verbose errors if key not supported

* handle failed redelegation messages

* handle failed unbondings

* bump cosmos-sdk v0.46.9; tendermint v0.34.26; gofumpt + lint; handle deprecated fields

* add distance_to_target (euclidean distance between N-dimensional representations of aggregated_intent and current_delegations) to stats output, as measure of redelegation performance

* add rc5 upgrade handler

* redemptions logic v2

* comment out unused helpers

* return early if there are no unbondings to attempt

* reduce noise; remove unneccessary re-sorting

* on dev/testnet reset RR that was affected by failed unbondings

* rebased

* rc6

---------

Co-authored-by: Emmanuel T Odeke <[email protected]>
Co-authored-by: Ajaz Ahmed Ansari <[email protected]>
  • Loading branch information
3 people authored Feb 15, 2023
1 parent 3c296c3 commit 0bf2733
Show file tree
Hide file tree
Showing 38 changed files with 2,612 additions and 1,017 deletions.
19 changes: 3 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,14 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
# Cosmwasm - download correct libwasmvm version
RUN WASMVM_VERSION=$(go list -m github.com/CosmWasm/wasmvm | cut -d ' ' -f 2) && \
wget https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/libwasmvm_muslc.$(uname -m).a \
-O /lib/libwasmvm_muslc.a && \
wget https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/checksums.txt -O /tmp/checksums.txt && \
-O /lib/libwasmvm_muslc.a && \
wget https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/checksums.txt -O /tmp/checksums.txt && \
sha256sum /lib/libwasmvm_muslc.a | grep $(cat /tmp/checksums.txt | grep $(uname -m) | cut -d ' ' -f 1)

COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/root/go/pkg/mod \
VERSION=$(echo $(git describe --tags) | sed 's/^v//') && \
COMMIT=$(git log -1 --format='%H') && \
go build \
-mod=readonly \
-tags "netgo,ledger,muslc,pebbledb" \
-ldflags "-X github.com/cosmos/cosmos-sdk/version.Name="quicksilver" \
-X github.com/cosmos/cosmos-sdk/version.AppName="quicksilverd" \
-X github.com/cosmos/cosmos-sdk/version.Version=$VERSION \
-X github.com/cosmos/cosmos-sdk/version.Commit=$COMMIT \
-X github.com/cosmos/cosmos-sdk/version.BuildTags='netgo,ledger,muslc' \
-w -s -linkmode=external -extldflags '-Wl,-z,muldefs -static'" \
-trimpath \
-o /src/app/build/ \
./...
LINK_STATICALLY=true make build

# Add to a distroless container
FROM alpine:3.17
Expand Down
11 changes: 6 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
DOCKER_BUILDKIT=1
COSMOS_BUILD_OPTIONS ?= "pebbledb"
COSMOS_BUILD_OPTIONS ?= ""
PACKAGES_NOSIMULATION=$(shell go list ./... | grep -v '/simulation')
PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation')
VERSION=$(shell git describe --tags | head -n1)
Expand Down Expand Up @@ -94,6 +94,7 @@ endif

ifeq ($(LINK_STATICALLY),true)
ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static"
build_tags += muslc
endif

build_tags += $(BUILD_TAGS)
Expand Down Expand Up @@ -438,11 +439,11 @@ proto-check-breaking:
@$(DOCKER_BUF) breaking --against $(HTTPS_GIT)#branch=main


TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.21/proto/tendermint
TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.25/proto/tendermint
GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos
CONFIO_URL = https://raw.githubusercontent.com/confio/ics23/v0.7.1
SDK_PROTO_URL = https://raw.githubusercontent.com/cosmos/cosmos-sdk/v0.46.1/proto/cosmos
IBC_PROTO_URL = https://raw.githubusercontent.com/cosmos/ibc-go/v5.0.0-rc2/proto
CONFIO_URL = https://raw.githubusercontent.com/confio/ics23/v0.9.0
SDK_PROTO_URL = https://raw.githubusercontent.com/cosmos/cosmos-sdk/v0.46.8/proto/cosmos
IBC_PROTO_URL = https://raw.githubusercontent.com/cosmos/ibc-go/v5.2.0/proto

TM_CRYPTO_TYPES = third_party/proto/tendermint/crypto
TM_ABCI_TYPES = third_party/proto/tendermint/abci
Expand Down
166 changes: 83 additions & 83 deletions app/upgrades.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,53 @@
package app

import (
"errors"
"fmt"
"strings"
"time"

sdkmath "cosmossdk.io/math"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
icqtypes "github.com/ingenuity-build/quicksilver/x/interchainquery/types"
"github.com/ingenuity-build/quicksilver/utils"
icskeeper "github.com/ingenuity-build/quicksilver/x/interchainstaking/keeper"
"github.com/ingenuity-build/quicksilver/x/interchainstaking/types"
icstypes "github.com/ingenuity-build/quicksilver/x/interchainstaking/types"
tokenfactorytypes "github.com/ingenuity-build/quicksilver/x/tokenfactory/types"
)

// upgrade name consts: vMMmmppUpgradeName (M=Major, m=minor, p=patch)
const (
ProductionChainID = "quicksilver-2"
InnuendoChainID = "innuendo-4"
InnuendoChainID = "innuendo-5"
DevnetChainID = "quicktest-1"
TestChainID = "testchain1"

v010300UpgradeName = "v1.3.0"
v010400UpgradeName = "v1.4.0"
v010300UpgradeName = "v1.3.0"
v010400UpgradeName = "v1.4.0"
v010400rc6UpgradeName = "v1.4.0-rc6"
)

func isTest(ctx sdk.Context) bool {
return ctx.ChainID() == TestChainID
}

func isDevnet(ctx sdk.Context) bool {
return ctx.ChainID() == DevnetChainID
}

func isTestnet(ctx sdk.Context) bool {
return ctx.ChainID() == InnuendoChainID
}

//nolint:all //function useful for writing network specific upgrade handlers
func isMainnet(ctx sdk.Context) bool {
return ctx.ChainID() == ProductionChainID
}

func setUpgradeHandlers(app *Quicksilver) {
app.UpgradeKeeper.SetUpgradeHandler(v010300UpgradeName, noOpHandler(app))
app.UpgradeKeeper.SetUpgradeHandler(v010400UpgradeName, v010400UpgradeHandler(app))
app.UpgradeKeeper.SetUpgradeHandler(v010400rc6UpgradeName, v010400rc6UpgradeHandler(app))

// When a planned update height is reached, the old binary will panic
// writing on disk the height and name of the update that triggered it
Expand Down Expand Up @@ -68,7 +87,7 @@ func noOpHandler(app *Quicksilver) upgradetypes.UpgradeHandler {
func v010400UpgradeHandler(app *Quicksilver) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
// upgrade zones
app.InterchainstakingKeeper.IterateZones(ctx, func(index int64, zone types.Zone) (stop bool) {
app.InterchainstakingKeeper.IterateZones(ctx, func(index int64, zone icstypes.Zone) (stop bool) {
zone.DepositsEnabled = true
zone.ReturnToSender = false
zone.UnbondingEnabled = false
Expand All @@ -84,72 +103,16 @@ func v010400UpgradeHandler(app *Quicksilver) upgradetypes.UpgradeHandler {
r.Completed = &time
app.InterchainstakingKeeper.SetReceipt(ctx, r)
}
if ctx.ChainID() == "innuendo-5" || ctx.ChainID() == "testchain1" {

// clear uni-5 unbondings
app.InterchainstakingKeeper.IteratePrefixedUnbondingRecords(ctx, []byte("uni-5"), func(_ int64, record types.UnbondingRecord) (stop bool) {
app.InterchainstakingKeeper.DeleteUnbondingRecord(ctx, record.ChainId, record.Validator, record.EpochNumber)
return false
})

// clear uni-5 redelegations
app.InterchainstakingKeeper.IteratePrefixedRedelegationRecords(ctx, []byte("uni-5"), func(_ int64, _ []byte, record types.RedelegationRecord) (stop bool) {
app.InterchainstakingKeeper.DeleteRedelegationRecord(ctx, record.ChainId, record.Source, record.Destination, record.EpochNumber)
return false
})

// remove uni-5 zone and related records
app.InterchainstakingKeeper.IterateZones(ctx, func(index int64, zone types.Zone) (stop bool) {
if zone.ChainId == "uni-5" {
// remove uni-5 delegation records
app.InterchainstakingKeeper.IterateAllDelegations(ctx, &zone, func(delegation types.Delegation) (stop bool) {
err := app.InterchainstakingKeeper.RemoveDelegation(ctx, &zone, delegation)
if err != nil {
panic(err)
}
return false
})

// remove uni-5 performance delegation records
app.InterchainstakingKeeper.IterateAllPerformanceDelegations(ctx, &zone, func(delegation types.Delegation) (stop bool) {
err := app.InterchainstakingKeeper.RemoveDelegation(ctx, &zone, delegation)
if err != nil {
panic(err)
}
return false
})
// remove uni-5 receipts
app.InterchainstakingKeeper.IterateZoneReceipts(ctx, &zone, func(index int64, receiptInfo types.Receipt) (stop bool) {
app.InterchainstakingKeeper.DeleteReceipt(ctx, icskeeper.GetReceiptKey(receiptInfo.ChainId, receiptInfo.Txhash))
return false
})

// remove zone withdrawal records
app.InterchainstakingKeeper.IterateZoneWithdrawalRecords(ctx, zone.ChainId, func(index int64, record types.WithdrawalRecord) (stop bool) {
app.InterchainstakingKeeper.DeleteWithdrawalRecord(ctx, zone.ChainId, record.Txhash, record.Status)
return false
})

app.InterchainstakingKeeper.DeleteZone(ctx, zone.ChainId)

}
return false
})
if isTestnet(ctx) || isTest(ctx) {

// remove uni-5 queries in state
app.InterchainQueryKeeper.IterateQueries(ctx, func(_ int64, queryInfo icqtypes.Query) (stop bool) {
if queryInfo.ChainId == "uni-5" {
app.InterchainQueryKeeper.DeleteQuery(ctx, queryInfo.Id)
}
return false
})
app.InterchainstakingKeeper.RemoveZoneAndAssociatedRecords(ctx, "uni-5")

// burn uqjunox
addr1, err := AccAddressFromBech32("quick17v9kk34km3w6hdjs2sn5s5qjdu2zrm0m3rgtmq", "quick")
addr1, err := utils.AccAddressFromBech32("quick17v9kk34km3w6hdjs2sn5s5qjdu2zrm0m3rgtmq", "quick")
if err != nil {
return nil, err
}
addr2, err := AccAddressFromBech32("quick16x03wcp37kx5e8ehckjxvwcgk9j0cqnhcccnty", "quick")
addr2, err := utils.AccAddressFromBech32("quick16x03wcp37kx5e8ehckjxvwcgk9j0cqnhcccnty", "quick")
if err != nil {
return nil, err
}
Expand All @@ -164,7 +127,7 @@ func v010400UpgradeHandler(app *Quicksilver) upgradetypes.UpgradeHandler {
return nil, err
}

err = app.BankKeeper.SendCoinsFromModuleToModule(ctx, types.EscrowModuleAccount, tokenfactorytypes.ModuleName, sdk.NewCoins(sdk.NewCoin("uqjunox", sdkmath.NewInt(400000))))
err = app.BankKeeper.SendCoinsFromModuleToModule(ctx, icstypes.EscrowModuleAccount, tokenfactorytypes.ModuleName, sdk.NewCoins(sdk.NewCoin("uqjunox", sdkmath.NewInt(400000))))
if err != nil {
return nil, err
}
Expand All @@ -178,21 +141,58 @@ func v010400UpgradeHandler(app *Quicksilver) upgradetypes.UpgradeHandler {
}
}

// AccAddressFromBech32 creates an AccAddress from a Bech32 string.
func AccAddressFromBech32(address, prefix string) (addr sdk.AccAddress, err error) {
if len(strings.TrimSpace(address)) == 0 {
return sdk.AccAddress{}, errors.New("empty address string is not allowed")
}
func v010400rc6UpgradeHandler(app *Quicksilver) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
if isTestnet(ctx) {
app.InterchainstakingKeeper.RemoveZoneAndAssociatedRecords(ctx, "regen-redwood-1")
// re-register regen-redwood-1 with new connection
regenProp := icstypes.NewRegisterZoneProposal("register regen-redwood-1 zone",
"register regen-redwood-1 (regen-testnet) zone with multisend and lsm disabled",
"connection-8",
"uregen",
"uqregen",
"regen",
false,
true,
true,
false,
6)
err := icskeeper.HandleRegisterZoneProposal(ctx, app.InterchainstakingKeeper, regenProp)
if err != nil {
return nil, err
}
}

bz, err := sdk.GetFromBech32(address, prefix)
if err != nil {
return nil, err
}
// remove expired failed redelegation records
app.InterchainstakingKeeper.IterateRedelegationRecords(ctx, func(_ int64, key []byte, record icstypes.RedelegationRecord) (stop bool) {
if record.CompletionTime.Equal(time.Time{}) {
app.InterchainstakingKeeper.DeleteRedelegationRecord(ctx, record.ChainId, record.Source, record.Destination, record.EpochNumber)
}
return false
})

err = sdk.VerifyAddressFormat(bz)
if err != nil {
return nil, err
}
// remove and refund failed unbondings
app.InterchainstakingKeeper.IterateWithdrawalRecords(ctx, func(index int64, record icstypes.WithdrawalRecord) (stop bool) {
if record.Status == icskeeper.WithdrawStatusUnbond && record.CompletionTime.Equal(time.Time{}) {
delegatorAcc, err := utils.AccAddressFromBech32(record.Delegator, "quick")
if err != nil {
panic(err)
}
if err = app.InterchainstakingKeeper.BankKeeper.SendCoinsFromModuleToAccount(ctx, icstypes.EscrowModuleAccount, delegatorAcc, sdk.NewCoins(record.BurnAmount)); err != nil {
panic(err)
}
app.InterchainstakingKeeper.DeleteWithdrawalRecord(ctx, record.ChainId, record.Txhash, record.Status)
}
return false
})

return bz, nil
if isTestnet(ctx) || isDevnet(ctx) {
app.InterchainstakingKeeper.IterateZones(ctx, func(index int64, zoneInfo icstypes.Zone) (stop bool) {
app.InterchainstakingKeeper.OverrideRedemptionRateNoCap(ctx, zoneInfo)
return false
})
}

return app.mm.RunMigrations(ctx, app.configurator, fromVM)
}
}
35 changes: 30 additions & 5 deletions app/upgrades_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package app

import (
"testing"
"time"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ingenuity-build/quicksilver/utils"
icskeeper "github.com/ingenuity-build/quicksilver/x/interchainstaking/keeper"
tokenfactorytypes "github.com/ingenuity-build/quicksilver/x/tokenfactory/types"
"testing"
"time"

"github.com/cosmos/cosmos-sdk/x/upgrade/types"
ibctesting "github.com/cosmos/ibc-go/v5/testing"
Expand Down Expand Up @@ -149,6 +150,16 @@ func (suite *AppTestSuite) initTestZone() {
}
suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.SetRedelegationRecord(suite.chainA.GetContext(), rdRecord)

rdRecord = icstypes.RedelegationRecord{
ChainId: "osmosis-1",
EpochNumber: 1,
Source: "osmovaloper1zxavllftfx3a3y5ldfyze7jnu5uyuktsfx2jcc",
Destination: "osmovaloper13eq5c99ym05jn02e78l8cac2fagzgdhh4294zk",
Amount: 3000000,
CompletionTime: time.Time{},
}
suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.SetRedelegationRecord(suite.chainA.GetContext(), rdRecord)

delRecord := icstypes.Delegation{
Amount: sdk.NewCoin(zone.BaseDenom, sdk.NewInt(17000)),
DelegationAddress: "juno1z89utvygweg5l56fsk8ak7t6hh88fd0azcjpz5",
Expand Down Expand Up @@ -177,11 +188,11 @@ func (suite *AppTestSuite) initTestZone() {
if err != nil {
return
}
addr1, err := AccAddressFromBech32("quick17v9kk34km3w6hdjs2sn5s5qjdu2zrm0m3rgtmq", "quick")
addr1, err := utils.AccAddressFromBech32("quick17v9kk34km3w6hdjs2sn5s5qjdu2zrm0m3rgtmq", "quick")
if err != nil {
return
}
addr2, err := AccAddressFromBech32("quick16x03wcp37kx5e8ehckjxvwcgk9j0cqnhcccnty", "quick")
addr2, err := utils.AccAddressFromBech32("quick16x03wcp37kx5e8ehckjxvwcgk9j0cqnhcccnty", "quick")
if err != nil {
return
}
Expand All @@ -198,7 +209,6 @@ func (suite *AppTestSuite) initTestZone() {
if err != nil {
return
}

}

func (s *AppTestSuite) TestV010400UpgradeHandler() {
Expand Down Expand Up @@ -253,5 +263,20 @@ func (s *AppTestSuite) TestV010400UpgradeHandler() {

_, found = app.InterchainstakingKeeper.GetWithdrawalRecord(ctx, "uni-5", "7C8B95EEE82CB63771E02EBEB05E6A80076D70B2E0A1C457F1FD1A0EF2EA961D", icskeeper.WithdrawStatusQueued)
s.Require().False(found)
}

func (s *AppTestSuite) TestV010400rc6UpgradeHandler() {
app := s.GetQuicksilverApp(s.chainA)
handler := v010400rc6UpgradeHandler(app)
ctx := s.chainA.GetContext()

redelegations := app.InterchainstakingKeeper.ZoneRedelegationRecords(ctx, "osmosis-1")
s.Require().Equal(1, len(redelegations))

_, err := handler(ctx, types.Plan{}, app.mm.GetVersionMap())
s.Require().NoError(err)

redelegations = app.InterchainstakingKeeper.ZoneRedelegationRecords(ctx, "osmosis-1")
s.Require().Equal(0, len(redelegations))

}
Loading

0 comments on commit 0bf2733

Please sign in to comment.