Skip to main content
Version: Next

ADR 17: Historical Header Module


  • 26 November 2019: Start of first version
  • 2 December 2019: Final draft of first version
  • 7 September 2023: Reduce HistoricalInfo type


In order for the Cosmos SDK to implement the IBC specification, modules within the Cosmos SDK must have the ability to introspect recent consensus states (validator sets & commitment roots) as proofs of these values on other chains must be checked during the handshakes.


The application MUST store the most recent n headers in a persistent store. At first, this store MAY be the current Merklised store. A non-Merklised store MAY be used later as no proofs are necessary.

The application MUST store this information by storing new headers immediately when handling abci.RequestBeginBlock:

func BeginBlock(ctx sdk.Context, keeper HistoricalHeaderKeeper) error {
info := HistoricalInfo{
apphash: ctx.HeaderInfo().AppHash,
Time: ctx.HeaderInfo().Time,
NextValidatorsHash: ctx.CometInfo().NextValidatorsHash,
keeper.SetHistoricalInfo(ctx, ctx.BlockHeight(), info)
n := keeper.GetParamRecentHeadersToStore()
keeper.PruneHistoricalInfo(ctx, ctx.BlockHeight() - n)
// continue handling request

Alternatively, the application MAY store only the hash of the validator set.

The application MUST make these past n committed headers available for querying by Cosmos SDK modules through the Keeper's GetHistoricalInfo function. This MAY be implemented in a new module, or it MAY also be integrated into an existing one (likely x/staking or x/ibc).

n MAY be configured as a parameter store parameter, in which case it could be changed by ParameterChangeProposals, although it will take some blocks for the stored information to catch up if n is increased.




Implementation of this ADR will require changes to the Cosmos SDK. It will not require changes to Tendermint.


  • Easy retrieval of headers & state roots for recent past heights by modules anywhere in the Cosmos SDK.
  • No RPC calls to Tendermint required.
  • No ABCI alterations required.


  • Duplicates n headers data in Tendermint & the application (additional disk usage) - in the long term, an approach such as this might be preferable.


(none known)