Skip to content

Commit

Permalink
helper function for validating a counterparty upgrade against the sel…
Browse files Browse the repository at this point in the history
…fupgrade (#4016)
  • Loading branch information
chatton authored Jul 5, 2023
1 parent 118cb71 commit c249e1e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 19 deletions.
6 changes: 3 additions & 3 deletions modules/core/04-channel/keeper/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (k Keeper) StartFlushUpgradeHandshake(
return k.startFlushUpgradeHandshake(ctx, portID, channelID, proposedUpgradeFields, counterpartyChannel, counterpartyUpgrade, proofCounterpartyChannel, proofCounterpartyUpgrade, proofHeight)
}

// ValidateUpgradeFields is a wrapper around validateUpgradeFields to allow the function to be directly called in tests.
func (k Keeper) ValidateUpgradeFields(ctx sdk.Context, proposedUpgrade types.UpgradeFields, currentChannel types.Channel) error {
return k.validateUpgradeFields(ctx, proposedUpgrade, currentChannel)
// ValidateSelfUpgradeFields is a wrapper around validateSelfUpgradeFields to allow the function to be directly called in tests.
func (k Keeper) ValidateSelfUpgradeFields(ctx sdk.Context, proposedUpgrade types.UpgradeFields, currentChannel types.Channel) error {
return k.validateSelfUpgradeFields(ctx, proposedUpgrade, currentChannel)
}
33 changes: 18 additions & 15 deletions modules/core/04-channel/keeper/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (k Keeper) ChanUpgradeInit(
return types.Upgrade{}, errorsmod.Wrapf(types.ErrInvalidChannelState, "expected %s, got %s", types.OPEN, channel.State)
}

if err := k.validateUpgradeFields(ctx, upgradeFields, channel); err != nil {
if err := k.validateSelfUpgradeFields(ctx, upgradeFields, channel); err != nil {
return types.Upgrade{}, err
}

Expand Down Expand Up @@ -699,47 +699,50 @@ func (k Keeper) startFlushUpgradeHandshake(
)
}

if err := k.checkForUpgradeCompatibility(ctx, proposedUpgradeFields, counterpartyUpgrade); err != nil {
return types.NewUpgradeError(channel.UpgradeSequence, err)
}

return nil
}

// checkForUpgradeCompatibility checks performs stateful validation of self upgrade fields relative to counterparty upgrade.
func (k Keeper) checkForUpgradeCompatibility(ctx sdk.Context, proposedUpgradeFields types.UpgradeFields, counterpartyUpgrade types.Upgrade) error {
// assert that both sides propose the same channel ordering
if proposedUpgradeFields.Ordering != counterpartyUpgrade.Fields.Ordering {
return types.NewUpgradeError(channel.UpgradeSequence, errorsmod.Wrapf(
types.ErrIncompatibleCounterpartyUpgrade, "expected upgrade ordering (%s) to match counterparty upgrade ordering (%s)", proposedUpgradeFields.Ordering, counterpartyUpgrade.Fields.Ordering),
)
return errorsmod.Wrapf(types.ErrIncompatibleCounterpartyUpgrade, "expected upgrade ordering (%s) to match counterparty upgrade ordering (%s)", proposedUpgradeFields.Ordering, counterpartyUpgrade.Fields.Ordering)
}

proposedConnection, err := k.GetConnection(ctx, proposedUpgradeFields.ConnectionHops[0])
if err != nil {
// NOTE: this error is expected to be unreachable as the proposed upgrade connectionID should have been
// validated in the upgrade INIT and TRY handlers
return types.NewUpgradeError(channel.UpgradeSequence, errorsmod.Wrap(
err, "expected proposed connection to be found"),
)
return errorsmod.Wrap(err, "expected proposed connection to be found")
}

if proposedConnection.GetState() != int32(connectiontypes.OPEN) {
// NOTE: this error is expected to be unreachable as the proposed upgrade connectionID should have been
// validated in the upgrade INIT and TRY handlers
return types.NewUpgradeError(channel.UpgradeSequence, errorsmod.Wrapf(
connectiontypes.ErrInvalidConnectionState, "expected proposed connection to be OPEN (got %s)", connectiontypes.State(proposedConnection.GetState()).String()),
)
return errorsmod.Wrapf(connectiontypes.ErrInvalidConnectionState, "expected proposed connection to be OPEN (got %s)", connectiontypes.State(proposedConnection.GetState()).String())
}

// connectionHops can change in a channelUpgrade, however both sides must still be each other's counterparty.
if counterpartyUpgrade.Fields.ConnectionHops[0] != proposedConnection.GetCounterparty().GetConnectionID() {
return types.NewUpgradeError(channel.UpgradeSequence, errorsmod.Wrapf(
types.ErrIncompatibleCounterpartyUpgrade, "counterparty upgrade connection end is not a counterparty of self proposed connection end (%s != %s)", counterpartyUpgrade.Fields.ConnectionHops[0], proposedConnection.GetCounterparty().GetConnectionID()),
)
return errorsmod.Wrapf(
types.ErrIncompatibleCounterpartyUpgrade, "counterparty upgrade connection end is not a counterparty of self proposed connection end (%s != %s)", counterpartyUpgrade.Fields.ConnectionHops[0], proposedConnection.GetCounterparty().GetConnectionID())
}

return nil
}

// validateUpgradeFields validates the proposed upgrade fields against the existing channel.
// validateSelfUpgradeFields validates the proposed upgrade fields against the existing channel.
// It returns an error if the following constraints are not met:
// - there exists at least one valid proposed change to the existing channel fields
// - the proposed order is a subset of the existing order
// - the proposed connection hops do not exist
// - the proposed version is non-empty (checked in UpgradeFields.ValidateBasic())
// - the proposed connection hops are not open
func (k Keeper) validateUpgradeFields(ctx sdk.Context, proposedUpgrade types.UpgradeFields, currentChannel types.Channel) error {
func (k Keeper) validateSelfUpgradeFields(ctx sdk.Context, proposedUpgrade types.UpgradeFields, currentChannel types.Channel) error {
currentFields := extractUpgradeFields(currentChannel)

if reflect.DeepEqual(proposedUpgrade, currentFields) {
Expand Down
2 changes: 1 addition & 1 deletion modules/core/04-channel/keeper/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,7 @@ func (suite *KeeperTestSuite) TestValidateUpgradeFields() {

tc.malleate()

err := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.ValidateUpgradeFields(suite.chainA.GetContext(), *proposedUpgrade, existingChannel)
err := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.ValidateSelfUpgradeFields(suite.chainA.GetContext(), *proposedUpgrade, existingChannel)
if tc.expPass {
suite.Require().NoError(err)
} else {
Expand Down

0 comments on commit c249e1e

Please sign in to comment.