Skip to content

Commit

Permalink
Merge branch 'main' into adam/e2e-upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
czarcas7ic authored May 4, 2022
2 parents b7b76c7 + b71507c commit fd7e073
Show file tree
Hide file tree
Showing 57 changed files with 3,418 additions and 277 deletions.
7 changes: 7 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# CODEOWNERS: https://help.github.com/articles/about-codeowners/

# NOTE: Order is important; the last matching pattern takes the
# most precedence.

# People who get pinged on every PR, request if you'd like to be added
* @osmosis-labs/chain-engineering-core-reviewers
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
*
### Minor improvements & Bug Fixes

* [#1379](https://github.com/osmosis-labs/osmosis/pull/1379) Introduce `Upgrade` and `Fork` structs, to simplify upgrade logic.
* [#1363](https://github.com/osmosis-labs/osmosis/pull/1363) Switch e2e test setup to create genesis and configs via Dockertest
* [#1335](https://github.com/osmosis-labs/osmosis/pull/1335) Add utility for deriving total orderings from partial orderings.
* [#1308](https://github.com/osmosis-labs/osmosis/pull/1308) Make panics inside of epochs no longer chain halt by default.
Expand Down
83 changes: 83 additions & 0 deletions ante/sendblock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package ante

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/spf13/cast"

servertypes "github.com/cosmos/cosmos-sdk/server/types"
)

type SendBlockOptions struct {
PermittedOnlySendTo map[string]string
}

func NewSendBlockOptions(appOpts servertypes.AppOptions) SendBlockOptions {
return SendBlockOptions{
PermittedOnlySendTo: parsePermittedOnlySendTo(appOpts),
}
}

func parsePermittedOnlySendTo(opts servertypes.AppOptions) map[string]string {
valueInterface := opts.Get("permitted-only-send-to")
if valueInterface == nil {
return make(map[string]string)
}
return cast.ToStringMapString(valueInterface) // equal with viper.GetStringMapString
}

type SendBlockDecorator struct {
Options SendBlockOptions
}

func NewSendBlockDecorator(options SendBlockOptions) *SendBlockDecorator {
return &SendBlockDecorator{
Options: options, // TODO: hydrate from configuration
}
}

func (decorator *SendBlockDecorator) AnteHandle(
ctx sdk.Context,
tx sdk.Tx,
simulate bool,
next sdk.AnteHandler,
) (newCtx sdk.Context, err error) {
if ctx.IsReCheckTx() {
return next(ctx, tx, simulate)
}

if ctx.IsCheckTx() && !simulate {
if err := decorator.CheckIfBlocked(tx.GetMsgs()); err != nil {
return ctx, err
}
}

return next(ctx, tx, simulate)
}

// CheckIfBlocked returns error if following are true:
// 1. decorator.permittedOnlySendTo has msg.GetSigners() has its key, and
// 2-1. msg is not a SendMsg, or
// 2-2. msg is SendMsg and the destination is not decorator.permittedOnlySendTo[msg.Sender]
func (decorator *SendBlockDecorator) CheckIfBlocked(msgs []sdk.Msg) error {
if len(decorator.Options.PermittedOnlySendTo) == 0 {
return nil
}
for _, msg := range msgs {
signers := msg.GetSigners()
for _, signer := range signers {
if permittedTo, ok := decorator.Options.PermittedOnlySendTo[signer.String()]; ok {
sendmsg, ok := msg.(*bank.MsgSend)
if !ok {
return fmt.Errorf("signer is not allowed to send transactions: %s", signer)
}
if sendmsg.ToAddress != permittedTo {
return fmt.Errorf("signer is not allowed to send tokens: %s", signer)
}
}
}
}
return nil
}
37 changes: 37 additions & 0 deletions ante/sendblock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ante

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
)

func TestSendBlockDecorator(t *testing.T) {
testCases := []struct {
from sdk.AccAddress
to sdk.AccAddress
expectPass bool
}{
{sdk.AccAddress("honest-sender"), sdk.AccAddress("honest-address"), true},
{sdk.AccAddress("honest-sender"), sdk.AccAddress("recovery-address"), true},
{sdk.AccAddress("malicious-sender"), sdk.AccAddress("recovery-address"), true},
{sdk.AccAddress("malicious-sender"), sdk.AccAddress("random-address"), false},
}

permittedOnlySendTo := map[string]string{
sdk.AccAddress("malicious-sender").String(): sdk.AccAddress("recovery-address").String(),
}
decorator := NewSendBlockDecorator(SendBlockOptions{permittedOnlySendTo})

for _, testCase := range testCases {
err := decorator.CheckIfBlocked([]sdk.Msg{bank.NewMsgSend(testCase.from, testCase.to, sdk.NewCoins(sdk.NewInt64Coin("test", 1)))})
if testCase.expectPass {
require.NoError(t, err)
} else {
require.Error(t, err)
}
}

}
4 changes: 4 additions & 0 deletions app/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
channelkeeper "github.com/cosmos/ibc-go/v2/modules/core/04-channel/keeper"
ibcante "github.com/cosmos/ibc-go/v2/modules/core/ante"

osmoante "github.com/osmosis-labs/osmosis/v7/ante"
txfeeskeeper "github.com/osmosis-labs/osmosis/v7/x/txfees/keeper"
txfeestypes "github.com/osmosis-labs/osmosis/v7/x/txfees/types"
)
Expand All @@ -31,6 +32,8 @@ func NewAnteHandler(
) sdk.AnteHandler {
mempoolFeeOptions := txfeestypes.NewMempoolFeeOptions(appOpts)
mempoolFeeDecorator := txfeeskeeper.NewMempoolFeeDecorator(*txFeesKeeper, mempoolFeeOptions)
sendblockOptions := osmoante.NewSendBlockOptions(appOpts)
sendblockDecorator := osmoante.NewSendBlockDecorator(sendblockOptions)
deductFeeDecorator := txfeeskeeper.NewDeductFeeDecorator(*txFeesKeeper, ak, bankKeeper, nil)
return sdk.ChainAnteDecorators(
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
Expand All @@ -40,6 +43,7 @@ func NewAnteHandler(
// Use Mempool Fee Decorator from our txfees module instead of default one from auth
// https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/middleware/fee.go#L34
mempoolFeeDecorator,
sendblockDecorator,
ante.NewValidateBasicDecorator(),
ante.TxTimeoutHeightDecorator{},
ante.NewValidateMemoDecorator(ak),
Expand Down
82 changes: 20 additions & 62 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
store "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
Expand All @@ -42,12 +41,14 @@ import (

"github.com/osmosis-labs/osmosis/v7/app/keepers"
appparams "github.com/osmosis-labs/osmosis/v7/app/params"
"github.com/osmosis-labs/osmosis/v7/app/upgrades"
v3 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v3"
v4 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v4"
v5 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v5"
v6 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v6"
v7 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v7"
v8 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v8"
_ "github.com/osmosis-labs/osmosis/v7/client/docs/statik"
superfluidtypes "github.com/osmosis-labs/osmosis/v7/x/superfluid/types"
)

const appName = "OsmosisApp"
Expand Down Expand Up @@ -83,6 +84,9 @@ var (
EmptyWasmOpts []wasm.Option

_ App = (*OsmosisApp)(nil)

Upgrades = []upgrades.Upgrade{v4.Upgrade, v5.Upgrade, v7.Upgrade, v8.Upgrade}
Forks = []upgrades.Fork{v3.Fork, v6.Fork}
)

// GetWasmEnabledProposals parses the WasmProposalsEnabled and
Expand Down Expand Up @@ -392,6 +396,7 @@ func (app *OsmosisApp) RegisterTendermintService(clientCtx client.Context) {
tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry)
}

// configure store loader that checks if version == upgradeHeight and applies store upgrades
func (app *OsmosisApp) setupUpgradeStoreLoaders() {
upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
Expand All @@ -402,71 +407,24 @@ func (app *OsmosisApp) setupUpgradeStoreLoaders() {
return
}

storeUpgrades := store.StoreUpgrades{}

if upgradeInfo.Name == v7.UpgradeName {
storeUpgrades = store.StoreUpgrades{
Added: []string{wasm.ModuleName, superfluidtypes.ModuleName},
}
}

if upgradeInfo.Name == v8.UpgradeName {
storeUpgrades = store.StoreUpgrades{
Deleted: []string{v8.ClaimsModuleName},
for _, upgrade := range Upgrades {
if upgradeInfo.Name == upgrade.UpgradeName {
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &upgrade.StoreUpgrades))
}
}

// configure store loader that checks if version == upgradeHeight and applies store upgrades
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
}

func (app *OsmosisApp) setupUpgradeHandlers() {
// this configures a no-op upgrade handler for the v4 upgrade,
// which improves the lockup module's store management.
app.UpgradeKeeper.SetUpgradeHandler(
v4.UpgradeName,
v4.CreateUpgradeHandler(
app.mm,
app.configurator,
*app.BankKeeper,
app.DistrKeeper,
app.GAMMKeeper,
),
)

app.UpgradeKeeper.SetUpgradeHandler(
v5.UpgradeName,
v5.CreateUpgradeHandler(
app.mm,
app.configurator,
&app.IBCKeeper.ConnectionKeeper,
app.TxFeesKeeper,
app.GAMMKeeper,
app.StakingKeeper,
),
)

app.UpgradeKeeper.SetUpgradeHandler(
v7.UpgradeName,
v7.CreateUpgradeHandler(
app.mm,
app.configurator,
app.WasmKeeper,
app.SuperfluidKeeper,
app.EpochsKeeper,
app.LockupKeeper,
app.MintKeeper,
app.AccountKeeper,
),
)

app.UpgradeKeeper.SetUpgradeHandler(
v8.UpgradeName,
v8.CreateUpgradeHandler(
app.mm,
app.configurator,
),
)
for _, upgrade := range Upgrades {
app.UpgradeKeeper.SetUpgradeHandler(
upgrade.UpgradeName,
upgrade.CreateUpgradeHandler(
app.mm,
app.configurator,
&app.AppKeepers,
),
)
}
}

// RegisterSwaggerAPI registers swagger route with API Server.
Expand Down
18 changes: 5 additions & 13 deletions app/forks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,14 @@ package app

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

v3 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v3"
v6 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v6"
)

// BeginBlockForks is intended to be ran in.
func BeginBlockForks(ctx sdk.Context, app *OsmosisApp) {
switch ctx.BlockHeight() {
case v3.UpgradeHeight:
v3.RunForkLogic(ctx, app.GovKeeper, app.StakingKeeper)

case v6.UpgradeHeight:
v6.RunForkLogic(ctx)

default:
// do nothing
return
for _, fork := range Forks {
if ctx.BlockHeight() == fork.UpgradeHeight {
fork.BeginForkLogic(ctx, &app.AppKeepers)
return
}
}
}
1 change: 0 additions & 1 deletion app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,6 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
appKeepers.IBCKeeper.SetRouter(ibcRouter)

// register the proposal types
// TODO: This appears to be missing tx fees proposal type
govRouter := govtypes.NewRouter()
govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(*appKeepers.ParamsKeeper)).
Expand Down
35 changes: 33 additions & 2 deletions app/upgrades/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Osmosis Upgrades

This folder contains logic for every osmosis upgrade. (Both state migrations, and hard forks)
This folder contains sub-folders for every osmosis upgrade. (Both state migrations, and hard forks)
It also defines upgrade & hard fork structs, that each upgrade implements.
These then get included in the application app.go to run the upgrade.

## Version History

* v1 - Initial version
* v3 - short blurb on prop19 and the fork
Expand All @@ -10,4 +14,31 @@ This folder contains logic for every osmosis upgrade. (Both state migrations, an
* v7 - Carbon State migration
* v8 - Nitrogen State migration

## TODO: Make a fork-upgrade struct and a state-migration upgrade struct
## Upgrade types

There are two upgrade types exposed, `Upgrade` and `Fork`.
An `Upgrade` defines an upgrade that is to be acted upon by state migrations from the SDK `x/upgrade` module.
A `Fork` defines a hard fork that changes some logic at a block height.
If the goal is to have a new binary be compatible with the old binary prior to the upgrade height,
as is the case for all osmosis `Fork`s, then all logic changes must be height-gated or in the `BeginForkLogic` code.

```go
type Upgrade struct {
// Upgrade version name, for the upgrade handler, e.g. `v7`
UpgradeName string
// Function that creates an upgrade handler
CreateUpgradeHandler func(mm *module.Manager, configurator module.Configurator, keepers *keepers.AppKeepers) upgradetypes.UpgradeHandler
// Store upgrades, should be used for any new modules introduced, new modules deleted, or store names renamed.
StoreUpgrades store.StoreUpgrades
}

type Fork struct {
// Upgrade version name, for the upgrade handler, e.g. `v7`
UpgradeName string
// height the upgrade occurs at
UpgradeHeight int64

// Function that runs some custom state transition code at the beginning of a fork.
BeginForkLogic func(ctx sdk.Context, keepers *keepers.AppKeepers)
}
```
Loading

0 comments on commit fd7e073

Please sign in to comment.