Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADR 17: Historical header module #5340

Merged
merged 13 commits into from
Dec 4, 2019
Merged

Conversation

cwgoes
Copy link
Contributor

@cwgoes cwgoes commented Nov 26, 2019

Closes #5078

  • Linked to github-issue with discussion and accepted design OR link to spec that describes this work.
  • Updated relevant documentation (docs/)
  • Re-reviewed Files changed in the github PR explorer

For Admin Use:

  • Added appropriate labels to PR (ex. wip, ready-for-review, docs)
  • Reviewers Assigned
  • Squashed all commits, uses message "Merge pull request #XYZ: [title]" (coding standards)

@cwgoes cwgoes changed the title Copy template, start ADR WIP: ADR 16: Historical header module Nov 26, 2019
@codecov
Copy link

codecov bot commented Nov 26, 2019

Codecov Report

Merging #5340 into master will increase coverage by 0.01%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##           master    #5340      +/-   ##
==========================================
+ Coverage    54.8%   54.81%   +0.01%     
==========================================
  Files         311      311              
  Lines       18385    18385              
==========================================
+ Hits        10075    10077       +2     
+ Misses       7539     7537       -2     
  Partials      771      771

@cwgoes cwgoes changed the title WIP: ADR 16: Historical header module WIP: ADR 17: Historical header module Dec 2, 2019
@cwgoes cwgoes changed the title WIP: ADR 17: Historical header module ADR 17: Historical header module Dec 2, 2019
@cwgoes cwgoes marked this pull request as ready for review December 2, 2019 11:44
@cwgoes
Copy link
Contributor Author

cwgoes commented Dec 2, 2019

Decided to scrap this in favour of just duplicating state. I will revise.

@alexanderbez alexanderbez added T: ADR An issue or PR relating to an architectural decision record WIP labels Dec 2, 2019
@alexanderbez alexanderbez self-assigned this Dec 2, 2019
@AdityaSripal
Copy link
Member

AdityaSripal commented Dec 2, 2019

Seems like we're scrapping this idea for a new one? Is there a short description of the new approach anywhere?

Seems pretty trivial to handle this completely on the application side rather than making any changes to ABCI.

Since n is an application-parameter and the current BlockHeader and ValidatorSet is introspectable by application using the Context, we can simply save ctx.BlockHeader and the current ValidatorSet on each BeginBlock under the current height and then prune the store to ensure we always have n most recent historical information. So we have some module history with a BeginBlocker like:

func BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
    h := HistoricalInfo{
         Header: ctx.BlockHeader(),
         ValSet: keeper.StakingKeeper.GetAllValidators(ctx),
    }
    keeper.SetHistoricalInfo(ctx, key=ctx.BlockHeight(), val=encode(h))
    keeper.PruneHistoricalInfo(ctx, key = ctx.BlockHeight() - params.N)
}

This can then be queried by the IBC modules. If this is already the new approach we're going for, I'm in favor of it 👍

@cwgoes
Copy link
Contributor Author

cwgoes commented Dec 3, 2019

Seems like we're scrapping this idea for a new one? Is there a short description of the new approach anywhere?

Seems pretty trivial to handle this completely on the application side rather than making any changes to ABCI.

Since n is an application-parameter and the current BlockHeader and ValidatorSet is introspectable by application using the Context, we can simply save ctx.BlockHeader and the current ValidatorSet on each BeginBlock under the current height and then prune the store to ensure we always have n most recent historical information. So we have some module history with a BeginBlocker like:

func BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
    h := HistoricalInfo{
         Header: ctx.BlockHeader(),
         ValSet: keeper.StakingKeeper.GetAllValidators(ctx),
    }
    keeper.SetHistoricalInfo(ctx, key=ctx.BlockHeight(), val=encode(h))
    keeper.PruneHistoricalInfo(ctx, key = ctx.BlockHeight() - params.N)
}

This can then be queried by the IBC modules. If this is already the new approach we're going for, I'm in favor of it

Yes; precisely. I might just copy your code!

(I had written the previous version in an attempt to save space, since we will now be storing headers on disk in both Tendermint and the SDK - duplicating data - but after discussion with the Tendermint team we agreed that the complexity wasn't worth it.)

@cwgoes
Copy link
Contributor Author

cwgoes commented Dec 3, 2019

Technically we don't need to store the validator set; we can just store the hash and have the handshake require the validator set be provided as an additional parameter (store abstraction in rc5 of the IBC spec makes this easier). We can store it if we want though; it makes the life of a relayer a wee bit easier.

Thoughts @AdityaSripal?

@cwgoes cwgoes added R4R and removed WIP labels Dec 3, 2019
Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
@AdityaSripal
Copy link
Member

Agreed, we can just store the hash if there's a simple way to retrieve the validator set for a given height. How would the relayer get the validator set. Is there already a query for it on the staking store?

Copy link
Collaborator

@fedekunze fedekunze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

@cwgoes
Copy link
Contributor Author

cwgoes commented Dec 3, 2019

Agreed, we can just store the hash if there's a simple way to retrieve the validator set for a given height. How would the relayer get the validator set. Is there already a query for it on the staking store?

It needs to be queried from Tendermint, I expect, as the SDK can't necessarily calculate it (information is lost if a validator unbonds, rebonds, for example).

@AdityaSripal
Copy link
Member

OK, so long as its queryable by the relayer as-needed rather than forcing the relayer to keep track of the validator sets themselves in their own local db; I am ok with storing hash

Copy link
Member

@AdityaSripal AdityaSripal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

@cwgoes
Copy link
Contributor Author

cwgoes commented Dec 3, 2019

I think I've addressed all the comments - not sure what the SDK merge process is these days - @alexanderbez did you want to quickly review (+ merge if satisfactory)?

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK.

  1. Can you add the ADR to the TOC in docs/architecture/README.MD?
  2. Since this doesn't process any txs, is it worth having it as a new module or can we retrofit into x/staking? Not a blocker, mainly just a question of best design.

@cwgoes
Copy link
Contributor Author

cwgoes commented Dec 4, 2019

ACK.

  1. Can you add the ADR to the TOC in docs/architecture/README.MD?
  2. Since this doesn't process any txs, is it worth having it as a new module or can we retrofit into x/staking? Not a blocker, mainly just a question of best design.
  1. Done.
  2. Noted that x/staking would be a good existing module to use.


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 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`).
Copy link
Collaborator

@fedekunze fedekunze Dec 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about storing it on the canonical IBC Keeper? I don't see the need for blockchains that are not using IBC to store the extra headers. @alexanderbez

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, added x/ibc as another suggestion.

@cwgoes
Copy link
Contributor Author

cwgoes commented Dec 4, 2019

(also, why does the simulation fail in some of the above CI runs? this PR only alters docs)

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 🎉

@alexanderbez
Copy link
Contributor

@cwgoes most likely because each successive commit kills any previous CI pipeline (so we only have 1 CI pipeline running per commit/per PR).

@alexanderbez alexanderbez merged commit 202cb9b into master Dec 4, 2019
@alexanderbez alexanderbez deleted the cwgoes/adr-historical-headers branch December 4, 2019 15:18
xiangjianmeng pushed a commit to xiangjianmeng/cosmos-sdk that referenced this pull request Dec 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T: ADR An issue or PR relating to an architectural decision record
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ICS03: Historical header module for Handshaking
5 participants