Separated out certifiers.Commit from rpc structs

This commit is contained in:
Ethan Frey 2017-10-25 16:43:18 +02:00
parent 0396b6d521
commit f653ba63bf
10 changed files with 59 additions and 39 deletions

View File

@ -89,6 +89,10 @@ func (p *provider) GetLatestCommit() (*ctypes.ResultCommit, error) {
return p.node.Commit(&status.LatestBlockHeight) return p.node.Commit(&status.LatestBlockHeight)
} }
func CommitFromResult(result *ctypes.ResultCommit) certifiers.Commit {
return (certifiers.Commit)(result.SignedHeader)
}
func (p *provider) seedFromVals(vals *ctypes.ResultValidators) (certifiers.FullCommit, error) { func (p *provider) seedFromVals(vals *ctypes.ResultValidators) (certifiers.FullCommit, error) {
// now get the commits and build a full commit // now get the commits and build a full commit
commit, err := p.node.Commit(&vals.BlockHeight) commit, err := p.node.Commit(&vals.BlockHeight)
@ -96,14 +100,14 @@ func (p *provider) seedFromVals(vals *ctypes.ResultValidators) (certifiers.FullC
return certifiers.FullCommit{}, err return certifiers.FullCommit{}, err
} }
fc := certifiers.NewFullCommit( fc := certifiers.NewFullCommit(
certifiers.CommitFromResult(commit), CommitFromResult(commit),
types.NewValidatorSet(vals.Validators), types.NewValidatorSet(vals.Validators),
) )
return fc, nil return fc, nil
} }
func (p *provider) seedFromCommit(commit *ctypes.ResultCommit) (fc certifiers.FullCommit, err error) { func (p *provider) seedFromCommit(commit *ctypes.ResultCommit) (fc certifiers.FullCommit, err error) {
fc.Commit = certifiers.CommitFromResult(commit) fc.Commit = CommitFromResult(commit)
// now get the proper validators // now get the proper validators
vals, err := p.node.Validators(&commit.Header.Height) vals, err := p.node.Validators(&commit.Header.Height)

View File

@ -5,7 +5,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
rtypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
certerr "github.com/tendermint/tendermint/certifiers/errors" certerr "github.com/tendermint/tendermint/certifiers/errors"
@ -14,46 +13,42 @@ import (
// Certifier checks the votes to make sure the block really is signed properly. // Certifier checks the votes to make sure the block really is signed properly.
// Certifier must know the current set of validitors by some other means. // Certifier must know the current set of validitors by some other means.
type Certifier interface { type Certifier interface {
Certify(check *Commit) error Certify(check Commit) error
ChainID() string ChainID() string
} }
// *Commit is basically the rpc /commit response, but extended // Commit is basically the rpc /commit response, but extended
// //
// This is the basepoint for proving anything on the blockchain. It contains // This is the basepoint for proving anything on the blockchain. It contains
// a signed header. If the signatures are valid and > 2/3 of the known set, // a signed header. If the signatures are valid and > 2/3 of the known set,
// we can store this checkpoint and use it to prove any number of aspects of // we can store this checkpoint and use it to prove any number of aspects of
// the system: such as txs, abci state, validator sets, etc... // the system: such as txs, abci state, validator sets, etc...
type Commit rtypes.ResultCommit type Commit types.SignedHeader
// FullCommit is a commit and the actual validator set, // FullCommit is a commit and the actual validator set,
// the base info you need to update to a given point, // the base info you need to update to a given point,
// assuming knowledge of some previous validator set // assuming knowledge of some previous validator set
type FullCommit struct { type FullCommit struct {
*Commit `json:"commit"` Commit `json:"commit"`
Validators *types.ValidatorSet `json:"validator_set"` Validators *types.ValidatorSet `json:"validator_set"`
} }
func NewFullCommit(commit *Commit, vals *types.ValidatorSet) FullCommit { func NewFullCommit(commit Commit, vals *types.ValidatorSet) FullCommit {
return FullCommit{ return FullCommit{
Commit: commit, Commit: commit,
Validators: vals, Validators: vals,
} }
} }
func CommitFromResult(commit *rtypes.ResultCommit) *Commit { func (c Commit) Height() int {
return (*Commit)(commit) if c.Header == nil {
}
func (c *Commit) Height() int {
if c == nil || c.Header == nil {
return 0 return 0
} }
return c.Header.Height return c.Header.Height
} }
func (c *Commit) ValidatorsHash() []byte { func (c Commit) ValidatorsHash() []byte {
if c == nil || c.Header == nil { if c.Header == nil {
return nil return nil
} }
return c.Header.ValidatorsHash return c.Header.ValidatorsHash
@ -64,7 +59,7 @@ func (c *Commit) ValidatorsHash() []byte {
// //
// Make sure to use a Verifier to validate the signatures actually provide // Make sure to use a Verifier to validate the signatures actually provide
// a significantly strong proof for this header's validity. // a significantly strong proof for this header's validity.
func (c *Commit) ValidateBasic(chainID string) error { func (c Commit) ValidateBasic(chainID string) error {
// make sure the header is reasonable // make sure the header is reasonable
if c.Header == nil { if c.Header == nil {
return errors.New("Commit missing header") return errors.New("Commit missing header")

View File

@ -46,7 +46,7 @@ func (c *Dynamic) LastHeight() int {
} }
// Certify handles this with // Certify handles this with
func (c *Dynamic) Certify(check *Commit) error { func (c *Dynamic) Certify(check Commit) error {
err := c.cert.Certify(check) err := c.cert.Certify(check)
if err == nil { if err == nil {
// update last seen height if input is valid // update last seen height if input is valid

View File

@ -2,11 +2,11 @@
Package files defines a Provider that stores all data in the filesystem Package files defines a Provider that stores all data in the filesystem
We assume the same validator hash may be reused by many different We assume the same validator hash may be reused by many different
headers/*Commits, and thus store it separately. This leaves us headers/Commits, and thus store it separately. This leaves us
with three issues: with three issues:
1. Given a validator hash, retrieve the validator set if previously stored 1. Given a validator hash, retrieve the validator set if previously stored
2. Given a block height, find the *Commit with the highest height <= h 2. Given a block height, find the Commit with the highest height <= h
3. Given a FullCommit, store it quickly to satisfy 1 and 2 3. Given a FullCommit, store it quickly to satisfy 1 and 2
Note that we do not worry about caching, as that can be achieved by Note that we do not worry about caching, as that can be achieved by

View File

@ -122,28 +122,26 @@ func genHeader(chainID string, height int, txs types.Txs,
} }
} }
// GenCommit calls genHeader and signHeader and combines them into a *Commit // GenCommit calls genHeader and signHeader and combines them into a Commit
func (v ValKeys) GenCommit(chainID string, height int, txs types.Txs, func (v ValKeys) GenCommit(chainID string, height int, txs types.Txs,
vals *types.ValidatorSet, appHash []byte, first, last int) *Commit { vals *types.ValidatorSet, appHash []byte, first, last int) Commit {
header := genHeader(chainID, height, txs, vals, appHash) header := genHeader(chainID, height, txs, vals, appHash)
check := &Commit{ check := Commit{
Header: header, Header: header,
Commit: v.signHeader(header, first, last), Commit: v.signHeader(header, first, last),
CanonicalCommit: true,
} }
return check return check
} }
// GenFullCommit calls genHeader and signHeader and combines them into a *Commit // GenFullCommit calls genHeader and signHeader and combines them into a Commit
func (v ValKeys) GenFullCommit(chainID string, height int, txs types.Txs, func (v ValKeys) GenFullCommit(chainID string, height int, txs types.Txs,
vals *types.ValidatorSet, appHash []byte, first, last int) FullCommit { vals *types.ValidatorSet, appHash []byte, first, last int) FullCommit {
header := genHeader(chainID, height, txs, vals, appHash) header := genHeader(chainID, height, txs, vals, appHash)
commit := &Commit{ commit := Commit{
Header: header, Header: header,
Commit: v.signHeader(header, first, last), Commit: v.signHeader(header, first, last),
CanonicalCommit: true,
} }
return NewFullCommit(commit, vals) return NewFullCommit(commit, vals)
} }

View File

@ -43,7 +43,7 @@ func (c *Inquiring) LastHeight() int {
// for a path to prove the new validators. // for a path to prove the new validators.
// //
// On success, it will store the checkpoint in the store for later viewing // On success, it will store the checkpoint in the store for later viewing
func (c *Inquiring) Certify(commit *Commit) error { func (c *Inquiring) Certify(commit Commit) error {
err := c.useClosestTrust(commit.Height()) err := c.useClosestTrust(commit.Height())
if err != nil { if err != nil {
return err return err

View File

@ -47,7 +47,7 @@ func (c *Static) Hash() []byte {
return c.vhash return c.vhash
} }
func (c *Static) Certify(commit *Commit) error { func (c *Static) Certify(commit Commit) error {
// do basic sanity checks // do basic sanity checks
err := commit.ValidateBasic(c.chainID) err := commit.ValidateBasic(c.chainID)
if err != nil { if err != nil {

View File

@ -280,7 +280,7 @@ func Commit(heightPtr *int) (*ctypes.ResultCommit, error) {
height := blockStore.Height() height := blockStore.Height()
header := blockStore.LoadBlockMeta(height).Header header := blockStore.LoadBlockMeta(height).Header
commit := blockStore.LoadSeenCommit(height) commit := blockStore.LoadSeenCommit(height)
return &ctypes.ResultCommit{header, commit, false}, nil return ctypes.NewResultCommit(header, commit, false), nil
} }
height := *heightPtr height := *heightPtr
@ -298,10 +298,10 @@ func Commit(heightPtr *int) (*ctypes.ResultCommit, error) {
// use a non-canonical commit // use a non-canonical commit
if height == storeHeight { if height == storeHeight {
commit := blockStore.LoadSeenCommit(height) commit := blockStore.LoadSeenCommit(height)
return &ctypes.ResultCommit{header, commit, false}, nil return ctypes.NewResultCommit(header, commit, false), nil
} }
// Return the canonical commit (comes from the block at height+1) // Return the canonical commit (comes from the block at height+1)
commit := blockStore.LoadBlockCommit(height) commit := blockStore.LoadBlockCommit(height)
return &ctypes.ResultCommit{header, commit, true}, nil return ctypes.NewResultCommit(header, commit, true), nil
} }

View File

@ -26,9 +26,24 @@ type ResultBlock struct {
} }
type ResultCommit struct { type ResultCommit struct {
Header *types.Header `json:"header"` // SignedHeader is header and commit, embedded so we only have
Commit *types.Commit `json:"commit"` // one level in the json output
CanonicalCommit bool `json:"canonical"` types.SignedHeader
CanonicalCommit bool `json:"canonical"`
}
// NewResultCommit is a helper to initialize the ResultCommit with
// the embedded struct
func NewResultCommit(header *types.Header, commit *types.Commit,
canonical bool) *ResultCommit {
return &ResultCommit{
SignedHeader: types.SignedHeader{
Header: header,
Commit: commit,
},
CanonicalCommit: canonical,
}
} }
type ResultStatus struct { type ResultStatus struct {

View File

@ -368,6 +368,14 @@ func (commit *Commit) StringIndented(indent string) string {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// SignedHeader is a header along with the commits that prove it
type SignedHeader struct {
Header *Header `json:"header"`
Commit *Commit `json:"commit"`
}
//-----------------------------------------------------------------------------
// Data contains the set of transactions included in the block // Data contains the set of transactions included in the block
type Data struct { type Data struct {