@@ -361,10 +361,24 @@ func (chain *TestChain) GetConsensusState(clientID string, height exported.Heigh
361361 return chain .App .GetIBCKeeper ().ClientKeeper .GetClientConsensusState (chain .GetContext (), clientID , height )
362362}
363363
364- // GetValsAtHeight will return the validator set of the chain at a given height. It will return
364+ // GetValsAtHeight will return the trusted validator set of the chain for the given trusted height. It will return
365365// a success boolean depending on if the validator set exists or not at that height.
366- func (chain * TestChain ) GetValsAtHeight (height int64 ) (* tmtypes.ValidatorSet , bool ) {
367- histInfo , ok := chain .App .GetStakingKeeper ().GetHistoricalInfo (chain .GetContext (), height )
366+ func (chain * TestChain ) GetValsAtHeight (trustedHeight int64 ) (* tmtypes.ValidatorSet , bool ) {
367+ // historical information does not store the validator set which committed the header at
368+ // height h. During BeginBlock, it stores the last updated validator set. This is equivalent to
369+ // the next validator set at height h. This is because cometbft processes the validator set
370+ // as follows:
371+ //
372+ // valSetChanges := endBlock()
373+ // chain.Vals = chain.NextVals
374+ // chain.NextVals = applyValSetChanges(chain.NextVals, valSetChanges)
375+ //
376+ // At height h, the validators in the historical information are the:
377+ // validators used to sign height h + 1 (next validator set)
378+ //
379+ // Since we want to return the trusted validator set, which is the next validator set
380+ // for height h, we can simply query using the trusted height.
381+ histInfo , ok := chain .App .GetStakingKeeper ().GetHistoricalInfo (chain .GetContext (), trustedHeight )
368382 if ! ok {
369383 return nil , false
370384 }
@@ -410,21 +424,12 @@ func (chain *TestChain) ConstructUpdateTMClientHeaderWithTrustedHeight(counterpa
410424 tmTrustedVals * tmtypes.ValidatorSet
411425 ok bool
412426 )
413- // Once we get TrustedHeight from client, we must query the validators from the counterparty chain
414- // If the LatestHeight == LastHeader.Height, then TrustedValidators are current validators
415- // If LatestHeight < LastHeader.Height, we can query the historical validator set from HistoricalInfo
416- if trustedHeight == counterparty .LastHeader .GetHeight () {
417- tmTrustedVals = counterparty .Vals
418- } else {
419- // NOTE: We need to get validators from counterparty at height: trustedHeight+1
420- // since the last trusted validators for a header at height h
421- // is the NextValidators at h+1 committed to in header h by
422- // NextValidatorsHash
423- tmTrustedVals , ok = counterparty .GetValsAtHeight (int64 (trustedHeight .RevisionHeight + 1 ))
424- if ! ok {
425- return nil , sdkerrors .Wrapf (ibctm .ErrInvalidHeaderHeight , "could not retrieve trusted validators at trustedHeight: %d" , trustedHeight )
426- }
427+
428+ tmTrustedVals , ok = counterparty .GetValsAtHeight (int64 (trustedHeight .RevisionHeight ))
429+ if ! ok {
430+ return nil , sdkerrors .Wrapf (ibctm .ErrInvalidHeaderHeight , "could not retrieve trusted validators at trustedHeight: %d" , trustedHeight )
427431 }
432+
428433 // inject trusted fields into last header
429434 // for now assume revision number is 0
430435 header .TrustedHeight = trustedHeight
0 commit comments