Skip to content

Commit

Permalink
fixed consensus states iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
mtsitrin committed Jan 17, 2025
1 parent 0fdd5de commit e8ac4db
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
53 changes: 53 additions & 0 deletions ibctesting/light_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,59 @@ func (s *lightClientSuite) TestSetCanonicalClient_Succeeds() {
s.Equal(endpointA.ClientID, canonClientID)
}

func (s *lightClientSuite) TestSetCanonicalClient_MultipleClients_Succeeds() {
s.createRollapp(false, nil)
s.registerSequencer()

// Create multiple IBC endpoints
endpointA := ibctesting.NewEndpoint(s.hubChain(), &canonicalClientConfig, ibctesting.NewConnectionConfig(), ibctesting.NewChannelConfig())
endpointB := ibctesting.NewEndpoint(s.rollappChain(), ibctesting.NewTendermintConfig(), ibctesting.NewConnectionConfig(), ibctesting.NewChannelConfig())
endpointC := ibctesting.NewEndpoint(s.rollappChain(), ibctesting.NewTendermintConfig(), ibctesting.NewConnectionConfig(), ibctesting.NewChannelConfig()) // Additional client
endpointD := ibctesting.NewEndpoint(s.hubChain(), &canonicalClientConfig, ibctesting.NewConnectionConfig(), ibctesting.NewChannelConfig()) // Additional client

endpointA.Counterparty = endpointB
endpointB.Counterparty = endpointA
s.path = &ibctesting.Path{EndpointA: endpointA, EndpointB: endpointB}

// create dummy channels
endpointC.Counterparty = endpointD
endpointD.Counterparty = endpointC
s.NoError(endpointC.CreateClient())
s.NoError(endpointD.CreateClient())

currentHeader := s.rollappChain().CurrentHeader
startHeight := uint64(currentHeader.Height)
bd := rollapptypes.BlockDescriptor{Height: startHeight, StateRoot: currentHeader.AppHash, Timestamp: currentHeader.Time}

// Create the IBC clients
s.NoError(s.path.EndpointA.CreateClient())

currentHeader = s.rollappChain().CurrentHeader
bdNext := rollapptypes.BlockDescriptor{Height: uint64(currentHeader.Height), StateRoot: currentHeader.AppHash, Timestamp: currentHeader.Time}

// Update the rollapp state
msgUpdateState := rollapptypes.NewMsgUpdateState(
s.hubChain().SenderAccount.GetAddress().String(),
rollappChainID(),
"mock-da-path",
startHeight,
2,
&rollapptypes.BlockDescriptors{BD: []rollapptypes.BlockDescriptor{bd, bdNext}},
)
_, err := s.rollappMsgServer().UpdateState(s.hubCtx(), msgUpdateState)
s.Require().NoError(err)

setCanonMsg := &types.MsgSetCanonicalClient{
Signer: s.hubChain().SenderAccount.GetAddress().String(), ClientId: s.path.EndpointA.ClientID,
}
_, err = s.lightclientMsgServer().SetCanonicalClient(s.hubCtx(), setCanonMsg)
s.Require().NoError(err)

canonClientID, found := s.hubApp().LightClientKeeper.GetCanonicalClient(s.hubCtx(), s.rollappChain().ChainID)
s.Require().True(found)
s.Equal(endpointA.ClientID, canonClientID)
}

func (s *lightClientSuite) TestMsgUpdateClient_StateUpdateDoesntExist() {
s.createRollapp(false, nil)
s.registerSequencer()
Expand Down
6 changes: 3 additions & 3 deletions x/lightclient/keeper/canonical_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (k *Keeper) TrySetCanonicalClient(ctx sdk.Context, clientID string) error {

err := k.validClient(ctx, clientID, clientState, rollappID)
if err != nil {
return errorsmod.Wrap(err, "unsafe to mark client canonical")
return errorsmod.Wrapf(err, "set client canonical")
}

k.SetCanonicalClient(ctx, rollappID, clientID)
Expand Down Expand Up @@ -124,8 +124,8 @@ func (k Keeper) validClient(ctx sdk.Context, clientID string, cs *ibctm.ClientSt
atLeastOneMatch = true
}

// break point with the lowest height of the consensus states
if sInfo.StartHeight > baseHeight {
// break point when we validate the state info for the first height of the client
if sInfo.StartHeight < baseHeight {
break
}
}
Expand Down
5 changes: 4 additions & 1 deletion x/lightclient/keeper/client_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ func deleteIterationKey(clientStore sdk.KVStore, height exported.Height) {
// GetFirstHeight returns the lowest height available for a client.
func (k Keeper) GetFirstConsensusStateHeight(ctx sdk.Context, clientID string) uint64 {
height := clienttypes.Height{}
k.ibcClientKeeper.IterateConsensusStates(ctx, func(clientID string, cs clienttypes.ConsensusStateWithHeight) bool {
k.ibcClientKeeper.IterateConsensusStates(ctx, func(id string, cs clienttypes.ConsensusStateWithHeight) bool {
if id != clientID {
return false
}
height = cs.Height
return true
})
Expand Down

0 comments on commit e8ac4db

Please sign in to comment.