Skip to content

Commit 7331efa

Browse files
mergify[bot]charleenfeicrodriguezvega
authored
feat: allow governance to update the TrustingPeriod of the 07-tendermint light client (backport #1713) (#1761)
* feat: allow governance to update the TrustingPeriod of the 07-tendermint light client (#1713) * initial commit * format imports * update docs * update CHANGELOG * update upgrade dev docs * update re: pr comments (cherry picked from commit c12789d) * position correctly changelog entry Co-authored-by: Charly <charly@interchain.berlin> Co-authored-by: Carlos Rodriguez <carlos@interchain.io>
1 parent ef9c475 commit 7331efa

File tree

5 files changed

+23
-3
lines changed

5 files changed

+23
-3
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
4848
### Improvements
4949

5050
* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal.
51+
* (modules/light-clients/07-tendermint) [\#1713](https://github.com/cosmos/ibc-go/pull/1713) Allow client upgrade proposals to update `TrustingPeriod`. See ADR-026 for context.
5152
* (app/20-transfer) [\#1680](https://github.com/cosmos/ibc-go/pull/1680) Adds migration to correct any malformed trace path information of tokens with denoms that contains slashes. The transfer module consensus version has been bumped to 2.
5253
* (app/20-transfer) [\#1730](https://github.com/cosmos/ibc-go/pull/1730) parse the ics20 denomination provided via a packet using the channel identifier format specified by ibc-go.
5354

docs/architecture/adr-026-ibc-client-recovery-mechanisms.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- 2021/01/15: Revision to support substitute clients for unfreezing
88
- 2021/05/20: Revision to simplify consensus state copying, remove initial height
99
- 2022/04/08: Revision to deprecate AllowUpdateAfterExpiry and AllowUpdateAfterMisbehaviour
10+
- 2022/07/15: Revision to allow updating of TrustingPeriod
1011

1112
## Status
1213

@@ -51,6 +52,9 @@ We elect not to deal with chains which have actually halted, which is necessaril
5152

5253
Previously, `AllowUpdateAfterExpiry` and `AllowUpdateAfterMisbehaviour` were used to signal the recovery options for an expired or frozen client, and governance proposals were not allowed to overwrite the client if these parameters were set to false. However, this has now been deprecated because a code migration can overwrite the client and consensus states regardless of the value of these parameters. If governance would vote to overwrite a client or consensus state, it is likely that governance would also be willing to perform a code migration to do the same.
5354

55+
In addition, `TrustingPeriod` was initally not allowed to be updated by a client upgrade proposal. However, due to the number of situations experienced in production where the `TrustingPeriod` of a client should be allowed to be updated because of ie: initial misconfiguration for a canonical channel, governance should be allowed to update this client parameter.
56+
57+
Note that this should NOT be lightly updated, as there may be a gap in time between when misbehaviour has occured and when the evidence of misbehaviour is submitted. For example, if the `UnbondingPeriod` is 2 weeks and the `TrustingPeriod` has also been set to two weeks, a validator could wait until right before `UnbondingPeriod` finishes, submit false information, then unbond and exit without being slashed for misbehaviour. Therefore, we recommend that the trusting period for the 07-tendermint client be set to 2/3 of the `UnbondingPeriod`.
5458

5559
Note that clients frozen due to misbehaviour must wait for the evidence to expire to avoid becoming refrozen.
5660

docs/ibc/upgrades/developer-guide.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Developers must ensure that the new client adopts all of the new Client paramete
3636

3737
Upgrades must adhere to the IBC Security Model. IBC does not rely on the assumption of honest relayers for correctness. Thus users should not have to rely on relayers to maintain client correctness and security (though honest relayers must exist to maintain relayer liveness). While relayers may choose any set of client parameters while creating a new `ClientState`, this still holds under the security model since users can always choose a relayer-created client that suits their security and correctness needs or create a Client with their desired parameters if no such client exists.
3838

39-
However, when upgrading an existing client, one must keep in mind that there are already many users who depend on this client's particular parameters. We cannot give the upgrading relayer free choice over these parameters once they have already been chosen. This would violate the security model since users who rely on the client would have to rely on the upgrading relayer to maintain the same level of security. Thus, developers must make sure that their upgrade mechanism allows clients to upgrade the chain-specified parameters whenever a chain upgrade changes these parameters (examples in the Tendermint client include `UnbondingPeriod`, `ChainID`, `UpgradePath`, etc.), while ensuring that the relayer submitting the `UpgradeClientMsg` cannot alter the client-chosen parameters that the users are relying upon (examples in Tendermint client include `TrustingPeriod`, `TrustLevel`, `MaxClockDrift`, etc).
39+
However, when upgrading an existing client, one must keep in mind that there are already many users who depend on this client's particular parameters. We cannot give the upgrading relayer free choice over these parameters once they have already been chosen. This would violate the security model since users who rely on the client would have to rely on the upgrading relayer to maintain the same level of security. Thus, developers must make sure that their upgrade mechanism allows clients to upgrade the chain-specified parameters whenever a chain upgrade changes these parameters (examples in the Tendermint client include `UnbondingPeriod`, `TrustingPeriod`, `ChainID`, `UpgradePath`, etc.), while ensuring that the relayer submitting the `UpgradeClientMsg` cannot alter the client-chosen parameters that the users are relying upon (examples in Tendermint client include `TrustLevel`, `MaxClockDrift`, etc).
4040

4141
Developers should maintain the distinction between Client parameters that are uniform across every valid light client of a chain (chain-chosen parameters), and Client parameters that are customizable by each individual client (client-chosen parameters); since this distinction is necessary to implement the `ZeroCustomFields` method in the `ClientState` interface:
4242

modules/light-clients/07-tendermint/types/proposal_handle.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package types
22

33
import (
44
"reflect"
5+
"time"
56

67
"github.com/cosmos/cosmos-sdk/codec"
78
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -70,20 +71,25 @@ func (cs ClientState) CheckSubstituteAndUpdateState(
7071
cs.LatestHeight = substituteClientState.LatestHeight
7172
cs.ChainId = substituteClientState.ChainId
7273

74+
// set new trusting period based on the substitute client state
75+
cs.TrustingPeriod = substituteClientState.TrustingPeriod
76+
7377
// no validation is necessary since the substitute is verified to be Active
7478
// in 02-client.
7579

7680
return &cs, nil
7781
}
7882

7983
// IsMatchingClientState returns true if all the client state parameters match
80-
// except for frozen height, latest height, and chain-id.
84+
// except for frozen height, latest height, trusting period, chain-id.
8185
func IsMatchingClientState(subject, substitute ClientState) bool {
8286
// zero out parameters which do not need to match
8387
subject.LatestHeight = clienttypes.ZeroHeight()
8488
subject.FrozenHeight = clienttypes.ZeroHeight()
89+
subject.TrustingPeriod = time.Duration(0)
8590
substitute.LatestHeight = clienttypes.ZeroHeight()
8691
substitute.FrozenHeight = clienttypes.ZeroHeight()
92+
substitute.TrustingPeriod = time.Duration(0)
8793
subject.ChainId = ""
8894
substitute.ChainId = ""
8995
// sets both sets of flags to true as these flags have been DEPRECATED, see ADR-026 for more information

modules/light-clients/07-tendermint/types/proposal_handle_test.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() {
145145
substitutePath := ibctesting.NewPath(suite.chainA, suite.chainB)
146146
suite.coordinator.SetupClients(substitutePath)
147147
substituteClientState := suite.chainA.GetClientState(substitutePath.EndpointA.ClientID).(*types.ClientState)
148+
// update trusting period of substitute client state
149+
substituteClientState.TrustingPeriod = time.Hour * 24 * 7
148150
suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), substitutePath.EndpointA.ClientID, substituteClientState)
149151

150152
// update substitute a few times
@@ -195,6 +197,7 @@ func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() {
195197
suite.Require().Equal(expectedIterationKey, subjectIterationKey)
196198

197199
suite.Require().Equal(newChainID, updatedClient.(*types.ClientState).ChainId)
200+
suite.Require().Equal(time.Hour*24*7, updatedClient.(*types.ClientState).TrustingPeriod)
198201
} else {
199202
suite.Require().Error(err)
200203
suite.Require().Nil(updatedClient)
@@ -240,9 +243,15 @@ func (suite *TendermintTestSuite) TestIsMatchingClientState() {
240243
}, true,
241244
},
242245
{
243-
"not matching, trusting period is different", func() {
246+
"matching, trusting period is different", func() {
244247
subjectClientState.TrustingPeriod = time.Duration(time.Hour * 10)
245248
substituteClientState.TrustingPeriod = time.Duration(time.Hour * 1)
249+
}, true,
250+
},
251+
{
252+
"not matching, trust level is different", func() {
253+
subjectClientState.TrustLevel = types.Fraction{2, 3}
254+
substituteClientState.TrustLevel = types.Fraction{1, 3}
246255
}, false,
247256
},
248257
}

0 commit comments

Comments
 (0)