Skip to content

Commit b697a6f

Browse files
authoredDec 22, 2022
chore: prune expired 07-tendermint consensus states on duplicate header updates (#2965)
* move pruning to above duplicate update check * adding test for pruning on duplicate header update * adding additional check - assert that a consensus state exists at the prune height
1 parent a89d5a7 commit b697a6f

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed
 

‎modules/light-clients/07-tendermint/update.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,14 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client
134134
panic(fmt.Errorf("expected type %T, got %T", &Header{}, clientMsg))
135135
}
136136

137+
cs.pruneOldestConsensusState(ctx, cdc, clientStore)
138+
137139
// check for duplicate update
138140
if consensusState, _ := GetConsensusState(clientStore, cdc, header.GetHeight()); consensusState != nil {
139141
// perform no-op
140142
return []exported.Height{header.GetHeight()}
141143
}
142144

143-
cs.pruneOldestConsensusState(ctx, cdc, clientStore)
144-
145145
height := header.GetHeight().(clienttypes.Height)
146146
if height.GT(cs.LatestHeight) {
147147
cs.LatestHeight = height

‎modules/light-clients/07-tendermint/update_test.go

+42
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,48 @@ func (suite *TendermintTestSuite) TestUpdateState() {
420420
suite.Require().False(found)
421421
}, true,
422422
},
423+
{
424+
"success with pruned consensus state using duplicate header", func() {
425+
// this height will be expired and pruned
426+
err := path.EndpointA.UpdateClient()
427+
suite.Require().NoError(err)
428+
pruneHeight = path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height)
429+
430+
// assert that a consensus state exists at the prune height
431+
consensusState, found := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight)
432+
suite.Require().True(found)
433+
suite.Require().NotNil(consensusState)
434+
435+
// Increment the time by a week
436+
suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour)
437+
438+
// create the consensus state that can be used as trusted height for next update
439+
err = path.EndpointA.UpdateClient()
440+
suite.Require().NoError(err)
441+
442+
// Increment the time by another week, then update the client.
443+
// This will cause the first two consensus states to become expired.
444+
suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour)
445+
err = path.EndpointA.UpdateClient()
446+
suite.Require().NoError(err)
447+
448+
// use the same header which just updated the client
449+
clientMessage, err = path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID)
450+
suite.Require().NoError(err)
451+
},
452+
func() {
453+
tmHeader, ok := clientMessage.(*ibctm.Header)
454+
suite.Require().True(ok)
455+
456+
clientState := path.EndpointA.GetClientState()
457+
suite.Require().True(clientState.GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed
458+
suite.Require().True(clientState.GetLatestHeight().EQ(consensusHeights[0]))
459+
460+
// ensure consensus state was pruned
461+
_, found := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight)
462+
suite.Require().False(found)
463+
}, true,
464+
},
423465
{
424466
"invalid ClientMessage type", func() {
425467
clientMessage = &ibctm.Misbehaviour{}

0 commit comments

Comments
 (0)