diff --git a/certifiers/client/provider.go b/certifiers/client/provider.go index d4c170ce9..6240da11c 100644 --- a/certifiers/client/provider.go +++ b/certifiers/client/provider.go @@ -89,6 +89,10 @@ func (p *provider) GetLatestCommit() (*ctypes.ResultCommit, error) { 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) { // now get the commits and build a full commit commit, err := p.node.Commit(&vals.BlockHeight) @@ -96,14 +100,14 @@ func (p *provider) seedFromVals(vals *ctypes.ResultValidators) (certifiers.FullC return certifiers.FullCommit{}, err } fc := certifiers.NewFullCommit( - certifiers.CommitFromResult(commit), + CommitFromResult(commit), types.NewValidatorSet(vals.Validators), ) return fc, nil } 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 vals, err := p.node.Validators(&commit.Header.Height) diff --git a/certifiers/commit.go b/certifiers/commit.go index 3c37b8599..464a48ba2 100644 --- a/certifiers/commit.go +++ b/certifiers/commit.go @@ -5,7 +5,6 @@ import ( "github.com/pkg/errors" - rtypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/tendermint/tendermint/types" 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 must know the current set of validitors by some other means. type Certifier interface { - Certify(check *Commit) error + Certify(check Commit) error 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 // 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 // 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, // the base info you need to update to a given point, // assuming knowledge of some previous validator set type FullCommit struct { - *Commit `json:"commit"` + Commit `json:"commit"` Validators *types.ValidatorSet `json:"validator_set"` } -func NewFullCommit(commit *Commit, vals *types.ValidatorSet) FullCommit { +func NewFullCommit(commit Commit, vals *types.ValidatorSet) FullCommit { return FullCommit{ Commit: commit, Validators: vals, } } -func CommitFromResult(commit *rtypes.ResultCommit) *Commit { - return (*Commit)(commit) -} - -func (c *Commit) Height() int { - if c == nil || c.Header == nil { +func (c Commit) Height() int { + if c.Header == nil { return 0 } return c.Header.Height } -func (c *Commit) ValidatorsHash() []byte { - if c == nil || c.Header == nil { +func (c Commit) ValidatorsHash() []byte { + if c.Header == nil { return nil } 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 // 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 if c.Header == nil { return errors.New("Commit missing header") diff --git a/certifiers/dynamic.go b/certifiers/dynamic.go index a9c1a54f0..b40177949 100644 --- a/certifiers/dynamic.go +++ b/certifiers/dynamic.go @@ -46,7 +46,7 @@ func (c *Dynamic) LastHeight() int { } // Certify handles this with -func (c *Dynamic) Certify(check *Commit) error { +func (c *Dynamic) Certify(check Commit) error { err := c.cert.Certify(check) if err == nil { // update last seen height if input is valid diff --git a/certifiers/files/provider.go b/certifiers/files/provider.go index 8b5c23de6..9dcfb1691 100644 --- a/certifiers/files/provider.go +++ b/certifiers/files/provider.go @@ -2,11 +2,11 @@ Package files defines a Provider that stores all data in the filesystem 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: 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 Note that we do not worry about caching, as that can be achieved by diff --git a/certifiers/helper.go b/certifiers/helper.go index 09c60775e..6f2daa63b 100644 --- a/certifiers/helper.go +++ b/certifiers/helper.go @@ -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, - 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) - check := &Commit{ - Header: header, - Commit: v.signHeader(header, first, last), - CanonicalCommit: true, + check := Commit{ + Header: header, + Commit: v.signHeader(header, first, last), } 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, vals *types.ValidatorSet, appHash []byte, first, last int) FullCommit { header := genHeader(chainID, height, txs, vals, appHash) - commit := &Commit{ - Header: header, - Commit: v.signHeader(header, first, last), - CanonicalCommit: true, + commit := Commit{ + Header: header, + Commit: v.signHeader(header, first, last), } return NewFullCommit(commit, vals) } diff --git a/certifiers/inquirer.go b/certifiers/inquirer.go index 9dd44e89b..460b622ab 100644 --- a/certifiers/inquirer.go +++ b/certifiers/inquirer.go @@ -43,7 +43,7 @@ func (c *Inquiring) LastHeight() int { // for a path to prove the new validators. // // 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()) if err != nil { return err diff --git a/certifiers/static.go b/certifiers/static.go index a2b9b8ae7..787aecb3f 100644 --- a/certifiers/static.go +++ b/certifiers/static.go @@ -47,7 +47,7 @@ func (c *Static) Hash() []byte { return c.vhash } -func (c *Static) Certify(commit *Commit) error { +func (c *Static) Certify(commit Commit) error { // do basic sanity checks err := commit.ValidateBasic(c.chainID) if err != nil { diff --git a/rpc/core/blocks.go b/rpc/core/blocks.go index ad00060f4..6b5e2166f 100644 --- a/rpc/core/blocks.go +++ b/rpc/core/blocks.go @@ -280,7 +280,7 @@ func Commit(heightPtr *int) (*ctypes.ResultCommit, error) { height := blockStore.Height() header := blockStore.LoadBlockMeta(height).Header commit := blockStore.LoadSeenCommit(height) - return &ctypes.ResultCommit{header, commit, false}, nil + return ctypes.NewResultCommit(header, commit, false), nil } height := *heightPtr @@ -298,10 +298,10 @@ func Commit(heightPtr *int) (*ctypes.ResultCommit, error) { // use a non-canonical commit if height == storeHeight { 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) commit := blockStore.LoadBlockCommit(height) - return &ctypes.ResultCommit{header, commit, true}, nil + return ctypes.NewResultCommit(header, commit, true), nil } diff --git a/rpc/core/types/responses.go b/rpc/core/types/responses.go index a5ed6f5a8..874e351d3 100644 --- a/rpc/core/types/responses.go +++ b/rpc/core/types/responses.go @@ -26,9 +26,24 @@ type ResultBlock struct { } type ResultCommit struct { - Header *types.Header `json:"header"` - Commit *types.Commit `json:"commit"` - CanonicalCommit bool `json:"canonical"` + // SignedHeader is header and commit, embedded so we only have + // one level in the json output + 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 { diff --git a/types/block.go b/types/block.go index 24e0f7445..2291de316 100644 --- a/types/block.go +++ b/types/block.go @@ -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 type Data struct {