@@ -369,10 +369,24 @@ func (chain *TestChain) GetConsensusState(clientID string, height exported.Heigh
369369 return chain .App .GetIBCKeeper ().ClientKeeper .GetClientConsensusState (chain .GetContext (), clientID , height )
370370}
371371
372- // GetValsAtHeight will return the validator set of the chain at a given height. It will return
372+ // GetValsAtHeight will return the trusted validator set of the chain for the given trusted height. It will return
373373// a success boolean depending on if the validator set exists or not at that height.
374- func (chain * TestChain ) GetValsAtHeight (height int64 ) (* tmtypes.ValidatorSet , bool ) {
375- histInfo , ok := chain .App .GetStakingKeeper ().GetHistoricalInfo (chain .GetContext (), height )
374+ func (chain * TestChain ) GetValsAtHeight (trustedHeight int64 ) (* tmtypes.ValidatorSet , bool ) {
375+ // historical information does not store the validator set which committed the header at
376+ // height h. During BeginBlock, it stores the last updated validator set. This is equivalent to
377+ // the next validator set at height h. This is because cometbft processes the validator set
378+ // as follows:
379+ //
380+ // valSetChanges := endBlock()
381+ // chain.Vals = chain.NextVals
382+ // chain.NextVals = applyValSetChanges(chain.NextVals, valSetChanges)
383+ //
384+ // At height h, the validators in the historical information are the:
385+ // validators used to sign height h + 1 (next validator set)
386+ //
387+ // Since we want to return the trusted validator set, which is the next validator set
388+ // for height h, we can simply query using the trusted height.
389+ histInfo , ok := chain .App .GetStakingKeeper ().GetHistoricalInfo (chain .GetContext (), trustedHeight )
376390 if ! ok {
377391 return nil , false
378392 }
@@ -418,21 +432,12 @@ func (chain *TestChain) ConstructUpdateTMClientHeaderWithTrustedHeight(counterpa
418432 tmTrustedVals * tmtypes.ValidatorSet
419433 ok bool
420434 )
421- // Once we get TrustedHeight from client, we must query the validators from the counterparty chain
422- // If the LatestHeight == LastHeader.Height, then TrustedValidators are current validators
423- // If LatestHeight < LastHeader.Height, we can query the historical validator set from HistoricalInfo
424- if trustedHeight == counterparty .LastHeader .GetHeight () {
425- tmTrustedVals = counterparty .Vals
426- } else {
427- // NOTE: We need to get validators from counterparty at height: trustedHeight+1
428- // since the last trusted validators for a header at height h
429- // is the NextValidators at h+1 committed to in header h by
430- // NextValidatorsHash
431- tmTrustedVals , ok = counterparty .GetValsAtHeight (int64 (trustedHeight .RevisionHeight + 1 ))
432- if ! ok {
433- return nil , sdkerrors .Wrapf (ibctm .ErrInvalidHeaderHeight , "could not retrieve trusted validators at trustedHeight: %d" , trustedHeight )
434- }
435+
436+ tmTrustedVals , ok = counterparty .GetValsAtHeight (int64 (trustedHeight .RevisionHeight ))
437+ if ! ok {
438+ return nil , sdkerrors .Wrapf (ibctm .ErrInvalidHeaderHeight , "could not retrieve trusted validators at trustedHeight: %d" , trustedHeight )
435439 }
440+
436441 // inject trusted fields into last header
437442 // for now assume revision number is 0
438443 header .TrustedHeight = trustedHeight
0 commit comments