Skip to content

New Tendermint RPC endpoint: header + commit #407

@ethanfrey

Description

@ethanfrey

When implementing light-client verification of proofs, I discovered it is a bit tricky to get the header and the signatures. Also, that we have to wait for one more block when getting the most signatures for the most recent block. This issue came up again when discussing light client syncing of validator changes, and in fact any place we need to prove the data.

The basic issue is there is currently a blockchain endpoint that returns one or more block headers without any signatures. And there is a block endpoint that returns a header, txs from that block, and the signatures for the previous block. There are some technical reasons why the data is stored in this format, but it makes it rather annoying for the client.

I would propose replacing RPC call, wait 1-2 seconds, RPC call with one single RPC call to speed up all verification of proofs. We want light clients to be secure and if it is too difficult or slow to do it correctly, developers will be lazy.

Proposal 1

Add one more tendermint RPC endpoint, commit that accepts one height, and returns the header with the signatures for this Header:

type BlockCommit struct {
	*Header    `json:"header"`
	*Commit `json:"commit"`
        Canonical bool `json:"canonical"`
}

If the returned block is not the most recent, then Commit will be the same as Block(H+1).LastCommit and Canonical will be true. If the returned block is the most recent, then Commit will be the votes that the queried node had (> 2/3 valid precommits in any case), and Canonical will be false. That means, while we can prove the block is validly signed, there may be other signatures if you later look at Block(H+1).LastCommit.

Proposal 2

If we start worrying about the explosion of tendermint RPC endpoints, then I would suggest just adjusting the block response to include this information as well. However, this would be a breaking change. Just replace LastCommit with Commit and Canonical:

type Block struct {
	*Header    `json:"header"`
	*Data      `json:"data"`
	*Commit `json:"commit"`
        Canonical bool `json:"canonical"`
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions