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

feat!: remove token voting upgrades #1629

Merged
merged 17 commits into from
Apr 25, 2023
Merged

Conversation

evan-forbes
Copy link
Member

@evan-forbes evan-forbes commented Apr 14, 2023

Overview

wraps the sdk's standard upgrade module to remove the ability to submit upgrade proposals. The idea being that this maintains compatibility with the IBC module (which requires access to the upgrade module's keeper), while still removing the ability for the upgrade module to work by not registering the upgrade module's msg server or begin block. Also, when we implement #1014 we can progressively flesh this module out with our own logic.

closes #1571

Checklist

  • New and updated code has appropriate documentation
  • New and updated code has new and/or updated testing
  • Required CI checks are passing
  • Visual proof for any user facing features like CLI or documentation updates
  • Linked issues closed with keywords

@evan-forbes evan-forbes added this to the Mainnet milestone Apr 14, 2023
@evan-forbes evan-forbes self-assigned this Apr 14, 2023
Comment on lines 80 to 96
// RegisterInterfaces overwrites the default upgrade module's method with a
// noop.
func (AppModule) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
}

// RegisterServices overwrites the default upgrade module's method with a
// noop.
func (am AppModule) RegisterServices(cfg module.Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { return consensusVersion }

// BeginBlock overwrites the default upgrade module's BeginBlock method with a
// noop.
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the most important state machine changes. By wrapping the upgrade module with our own and then overwriting these methods, we're removing any of the external functionality that's in the msg server/begin block, while preserving keeper access to the upgrade module to maintain 100% functionality with the IBC module.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to also overwrite endBlock?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the same, but I don't think the upgrade module has an endBlock (its abci file)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad, confused it with gov module :D

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just keep the keeper and not the module?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just keep the keeper and not the module?

this is a good idea! I think this would be the simplest approach, but I think we still need some way to register some of the upgrade types.

for example when the governance can upgrade an IBC clients

// NewSoftwareUpgradeProposalHandler creates a governance handler to manage new proposal types.
// It enables SoftwareUpgradeProposal to propose an Upgrade, and CancelSoftwareUpgradeProposal
// to abort a previously voted upgrade.
//
//nolint:staticcheck // we are intentionally using a deprecated proposal here.
func NewSoftwareUpgradeProposalHandler(k *keeper.Keeper) govtypes.Handler {
	return func(ctx sdk.Context, content govtypes.Content) error {
		switch c := content.(type) {
		case *types.SoftwareUpgradeProposal: <--
			return handleSoftwareUpgradeProposal(ctx, k, c)

		case *types.CancelSoftwareUpgradeProposal: <--
			return handleCancelSoftwareUpgradeProposal(ctx, k, c)

		default:
			return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized software upgrade proposal content type: %T", c)
		}
	}
}

Comment on lines 28 to 33
func TestUpgrade(t *testing.T) {
if testing.Short() {
t.Skip("skipping SDK integration test in short mode.")
}
suite.Run(t, new(UpgradeTestSuite))
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This integration test suite is probably overkill, but at least we have a high degree of confidence that submitting governance proposals to upgrade won't work.

there might be another test we could add where we manually force an upgrade into the state and check that it doesn't get picked up by begin block, but I opted to avoid that for now. If we decide that its worth it, I'm happy to add it!

@evan-forbes evan-forbes marked this pull request as ready for review April 17, 2023 23:24
@codecov-commenter
Copy link

codecov-commenter commented Apr 17, 2023

Codecov Report

Merging #1629 (36ed8b8) into main (8c1fcb5) will decrease coverage by 0.03%.
The diff coverage is 27.77%.

@@            Coverage Diff             @@
##             main    #1629      +/-   ##
==========================================
- Coverage   50.96%   50.93%   -0.03%     
==========================================
  Files          92       93       +1     
  Lines        5751     5760       +9     
==========================================
+ Hits         2931     2934       +3     
- Misses       2520     2526       +6     
  Partials      300      300              
Impacted Files Coverage Δ
testutil/testnode/query.go 0.00% <0.00%> (ø)
app/app.go 4.65% <62.50%> (+0.74%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

x/upgrade/test/integration_test.go Outdated Show resolved Hide resolved
Comment on lines 80 to 96
// RegisterInterfaces overwrites the default upgrade module's method with a
// noop.
func (AppModule) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
}

// RegisterServices overwrites the default upgrade module's method with a
// noop.
func (am AppModule) RegisterServices(cfg module.Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { return consensusVersion }

// BeginBlock overwrites the default upgrade module's BeginBlock method with a
// noop.
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to also overwrite endBlock?

@MSevey MSevey requested a review from a team April 18, 2023 00:37
rach-id
rach-id previously approved these changes Apr 18, 2023
Copy link
Member

@rach-id rach-id left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@liamsi
Copy link
Member

liamsi commented Apr 18, 2023

The idea being that this maintains compatibility with the IBC module (which requires access to the upgrade module's keeper)

Can you link to that code or spec? Just curious what the IBC module does with the upgrade module's keeper. I assume it is to upgrade ibc clients?

UpgradeKeeper upgradekeeper.Keeper
UpgradeKeeper sdkupgradekeeper.Keeper
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should also note that we are still selectively using components of the sdk's upgrade module, hence the change in naming to hopefully help differentiate the two. For example, see line 152, where we are using the appupgrade module instead of the sdk's

@evan-forbes
Copy link
Member Author

evan-forbes commented Apr 18, 2023

cc @liamsi

Can you link to that code or spec? Just curious what the IBC module does with the upgrade module's keeper. I assume it is to upgrade ibc clients?

most of the usage afaik is here in the beginblock
https://github.com/cosmos/ibc-go/blob/d7da1b7c5e86648d8142c948ba3d6dd9194d3bf9/modules/core/02-client/abci.go#L11-L42

my current thinking is that we can reuse a lot of the upgrade module as we flesh out #1014. Like fulfilling this same api, and portions of things like upgradetypes.Plan/migrations.

x/upgrade/cli.go Outdated
Comment on lines 10 to 18
// GetTxCmd returns the transaction commands for this module
func GetTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: upgradetypes.ModuleName,
Short: "Upgrade transaction subcommands",
}

return cmd
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only if we decide that we do need the app module, since the AppModuleBasic interface returns a pointer

@cmwaters
Copy link
Contributor

most of the usage afaik is here in the beginblock
https://github.com/cosmos/ibc-go/blob/d7da1b7c5e86648d8142c948ba3d6dd9194d3bf9/modules/core/02-client/abci.go#L11-L42

What about here: https://github.com/cosmos/ibc-go/blob/9e4b0d2f99c18db80db17697ec0875c48d84f328/modules/core/02-client/keeper/proposal.go#L73

Am I correct in thinking that IBC also has a handler that can kick off an upgrade?

@evan-forbes
Copy link
Member Author

Am I correct in thinking that IBC also has a handler that can kick off an upgrade?

yeah it appears that that is used when other chains upgrade. For some reason, some of the ibc client state is stored in the upgrade keeper, which is a bit confusing since the ibc module is the only one that writes to that state.

@damiannolan
Copy link

Am I correct in thinking that IBC also has a handler that can kick off an upgrade?

yeah it appears that that is used when other chains upgrade. For some reason, some of the ibc client state is stored in the upgrade keeper, which is a bit confusing since the ibc module is the only one that writes to that state.

This is currently the only upgrade path for ibc client upgrades. Historically the sdk upgrade plan used to contain a proto Any field which has since been deprecated when x/ibc was migrated to the ibc-go repo.

The proposal handler in ibc-go essentially uses the upgrade keeper to schedule the upgrade plan and store the upgraded client state under an "upgrade path". The path currently being used as the standard/default is under the x/upgrade module at upgrade/UpgradedIBCState/{upgradeHeight}/upgradedClient. Afaik this can be changed but may be a little cumbersome. Essentially its a bit of technical debt from when ibc existed within the sdk.

cc. @AdityaSripal

Comment on lines 159 to +161
// ModuleEncodingRegisters keeps track of all the module methods needed to
// register interfaces and specific type to encoding config
ModuleEncodingRegisters = moduleMapToSlice(ModuleBasics)
ModuleEncodingRegisters = extractRegisters(ModuleBasics, appupgrade.TypeRegister{})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

followed through with @cmwaters 's idea to remove the module all together, and now we're just manually registering the upgrade module's types. 81208f9

This is necessary for the IBC module (#1629 (comment))

rootulp
rootulp previously approved these changes Apr 21, 2023
Copy link
Collaborator

@rootulp rootulp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK. Do we want a x/upgrade/README.md that describes the diff between this repo's upgrade module and the standard SDK upgrade module?

x/upgrade/test/integration_test.go Outdated Show resolved Hide resolved
Co-authored-by: Rootul P <rootulp@gmail.com>
@MSevey MSevey requested a review from a team April 21, 2023 21:50
@evan-forbes
Copy link
Member Author

@rootulp

good point, added a short one, since this module doesn't do much. Perhaps we can add to if we end up doing anything else with it.

cmwaters
cmwaters previously approved these changes Apr 24, 2023
Copy link
Contributor

@cmwaters cmwaters left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

return nil, err
}

return node.Tx(context.Background(), hash, prove)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does clientCtx have an underlying go Context?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm I thought so too, but myself and my IDE could not find it? maybe some other Contetx does and we should refactor to that?

https://github.com/celestiaorg/cosmos-sdk/blob/50f4c49034ee97424a43b32e77715f9c8413bb5d/client/context.go#L25-L63

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the go context wraps around the sdk Context and not the other way around: https://github.com/celestiaorg/cosmos-sdk/blob/50f4c49034ee97424a43b32e77715f9c8413bb5d/x/bank/keeper/msg_server.go#L27

@@ -0,0 +1,8 @@
# `x/upgrade`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think usually READ_ME.md is README

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops lol 0f5dc67

good catch fixed

@evan-forbes evan-forbes enabled auto-merge (squash) April 24, 2023 19:39
Comment on lines +5 to +8
The upgrade module removes the entrypoints to the standard upgrade module by not
registering a message server. It registers the standard upgrade module types to
preserve the ability to marshal them. Note that the keeper of the standard
upgrade module is still added to the application.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@evan-forbes evan-forbes merged commit a69fe55 into main Apr 25, 2023
27 checks passed
@evan-forbes evan-forbes deleted the evan/remove-token-voting branch April 25, 2023 02:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove the upgrade module
7 participants