mirror of
https://github.com/tendermint/tendermint.git
synced 2026-08-22 07:06:14 +00:00
refactor verifying/provider
- mention unbonding period - use log.Logger instead of fmt
This commit is contained in:
+47
-37
@@ -30,6 +30,7 @@ const (
|
||||
// TrustOptions are the trust parameters.
|
||||
type TrustOptions struct {
|
||||
// Required: only trust commits up to this old.
|
||||
// Should be equal to the unbonding period.
|
||||
TrustPeriod time.Duration `json:"trust-period"`
|
||||
|
||||
// Option 1: TrustHeight and TrustHash can both be provided
|
||||
@@ -44,6 +45,11 @@ type TrustOptions struct {
|
||||
Callback func(height int64, hash []byte) error
|
||||
}
|
||||
|
||||
// HeightAndHashPresent returns true if TrustHeight and TrustHash are present.
|
||||
func (opts TrustOptions) HeightAndHashPresent() bool {
|
||||
return opts.TrustHeight > 0 && opts.TrustHash != 0
|
||||
}
|
||||
|
||||
// Provider implements a persistent caching Provider that auto-validates. It
|
||||
// uses a "source" Provider to obtain the needed FullCommits to securely sync
|
||||
// with validator set changes. It stores properly validated data on the
|
||||
@@ -83,7 +89,7 @@ func NewProvider(chainID, rootDir string, client lclient.SignStatusClient,
|
||||
vp := initProvider(chainID, rootDir, client, logger, cacheSize, options)
|
||||
|
||||
// Get the latest source commit, or the one provided in options.
|
||||
trustCommit, err := getTrustedCommit(client, options)
|
||||
trustCommit, err := getTrustedCommit(vp.logger, client, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -94,16 +100,19 @@ func NewProvider(chainID, rootDir string, client lclient.SignStatusClient,
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if time.Now().Sub(trustCommit.Time) <= 0 {
|
||||
panic(fmt.Sprintf("impossible time %v vs %v", time.Now(), trustCommit.Time))
|
||||
// FIXME: Can't it happen that the local clock is a bit off and the
|
||||
// trustCommit.Time is a few seconds in the future?
|
||||
now := time.Now()
|
||||
if now.Sub(trustCommit.Time) <= 0 {
|
||||
panic(fmt.Sprintf("impossible time %v vs %v", now, trustCommit.Time))
|
||||
}
|
||||
|
||||
// Otherwise we're syncing within the unbonding period.
|
||||
// NOTE: There is a duplication of fetching this latest commit (since
|
||||
// UpdateToHeight() will fetch it again, and latestCommit isn't used), but
|
||||
// it's only once upon initialization of a validator so it's not a big
|
||||
// deal.
|
||||
if options.TrustHeight > 0 {
|
||||
// it's only once upon initialization so it's not a big deal.
|
||||
if options.HeightAndHashPresent() {
|
||||
// Fetch latest commit (nil means latest height).
|
||||
latestCommit, err := client.Commit(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -139,7 +148,9 @@ func initProvider(chainID, rootDir string, client lclient.SignStatusClient,
|
||||
//
|
||||
// The trusted Provider should be a DBProvider.
|
||||
// The source Provider should be a client.HTTPProvider.
|
||||
func makeProvider(chainID string, trustPeriod time.Duration, trusted lite.PersistentProvider, source lite.Provider, logger log.Logger) *Provider {
|
||||
func makeProvider(chainID string, trustPeriod time.Duration,
|
||||
trusted lite.PersistentProvider, source lite.Provider, logger log.Logger) *Provider {
|
||||
|
||||
if trustPeriod == 0 {
|
||||
panic("Provider must have non-zero trust period")
|
||||
}
|
||||
@@ -162,47 +173,46 @@ func makeProvider(chainID string, trustPeriod time.Duration, trusted lite.Persis
|
||||
// 2. Trusts the remote node and gets the latest commit
|
||||
// 3. Returns an error if the height provided in trust option is too old to
|
||||
// sync to latest.
|
||||
func getTrustedCommit(client lclient.SignStatusClient, options TrustOptions) (types.SignedHeader, error) {
|
||||
|
||||
// Get the latest commit always
|
||||
latestBlock, err := client.Commit(nil)
|
||||
func getTrustedCommit(logger log.Logger, client lclient.SignStatusClient, options TrustOptions) (types.SignedHeader, error) {
|
||||
// Get the latest commit always.
|
||||
latestCommit, err := client.Commit(nil)
|
||||
if err != nil {
|
||||
return types.SignedHeader{}, err
|
||||
}
|
||||
|
||||
// If the user has set a root of trust, confirm it then update to newest
|
||||
if options.TrustHeight != 0 && options.TrustHash != nil {
|
||||
trustBlock, err := client.Commit(&options.TrustHeight)
|
||||
// If the user has set a root of trust, confirm it then update to newest.
|
||||
if options.HeightAndHashPresent() {
|
||||
trustCommit, err := client.Commit(&options.TrustHeight)
|
||||
if err != nil {
|
||||
return types.SignedHeader{}, err
|
||||
}
|
||||
|
||||
if latestBlock.Time.Sub(trustBlock.Time) > options.TrustPeriod {
|
||||
return types.SignedHeader{}, fmt.Errorf("Your Trusted Block Height is older than the trust period from Latest Block")
|
||||
if latestCommit.Time.Sub(trustCommit.Time) > options.TrustPeriod {
|
||||
return types.SignedHeader{},
|
||||
fmt.Errorf("your trusted block height is older than the trust period from latest block")
|
||||
}
|
||||
|
||||
trustCommit := trustBlock.SignedHeader
|
||||
if !bytes.Equal(trustCommit.Hash(), options.TrustHash) {
|
||||
return types.SignedHeader{}, fmt.Errorf("WARNING!!! Expected height/hash %v/%X but got %X",
|
||||
options.TrustHeight, options.TrustHash, trustCommit.Hash())
|
||||
signedHeader := trustCommit.SignedHeader
|
||||
if !bytes.Equal(signedHeader.Hash(), options.TrustHash) {
|
||||
return types.SignedHeader{},
|
||||
fmt.Errorf("WARNING: expected hash %X but got %X", options.TrustHash, signedHeader.Hash())
|
||||
}
|
||||
return trustCommit, nil
|
||||
} else {
|
||||
|
||||
latestCommit := latestBlock.SignedHeader
|
||||
|
||||
// NOTE: This should really belong in the callback.
|
||||
// WARN THE USER IN ALL CAPS THAT THE LITE CLIENT IS NEW,
|
||||
// AND THAT WE WILL SYNC TO AND VERIFY LATEST COMMIT.
|
||||
fmt.Printf("trusting source at height %v and hash %X...\n", latestCommit.Height, latestCommit.Hash())
|
||||
if options.Callback != nil {
|
||||
err := options.Callback(latestCommit.Height, latestCommit.Hash())
|
||||
if err != nil {
|
||||
return types.SignedHeader{}, err
|
||||
}
|
||||
}
|
||||
return latestCommit, nil
|
||||
return signedHeader, nil
|
||||
}
|
||||
|
||||
signedHeader := latestCommit.SignedHeader
|
||||
|
||||
// NOTE: This should really belong in the callback.
|
||||
// WARN THE USER IN ALL CAPS THAT THE LITE CLIENT IS NEW, AND THAT WE WILL
|
||||
// SYNC TO AND VERIFY LATEST COMMIT.
|
||||
logger.Info("WARNING: trusting source at height %d and hash %X...\n", signedHeader.Height, signedHeader.Hash())
|
||||
if options.Callback != nil {
|
||||
err := options.Callback(signedHeader.Height, signedHeader.Hash())
|
||||
if err != nil {
|
||||
return types.SignedHeader{}, err
|
||||
}
|
||||
}
|
||||
return signedHeader, nil
|
||||
}
|
||||
|
||||
func (vp *Provider) Verify(signedHeader types.SignedHeader) error {
|
||||
@@ -258,7 +268,7 @@ func (vp *Provider) UpdateToHeight(chainID string, height int64) error {
|
||||
return nil
|
||||
} else if !lerr.IsErrCommitNotFound(err) {
|
||||
// Return error if it is not CommitNotFound error
|
||||
vp.logger.Info(fmt.Sprintf("Encountered unknown error in loading full commit at height %d.", height))
|
||||
vp.logger.Error("Encountered unknown error while loading full commit", "height", height)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user