github.com/adoriasoft/tendermint@v0.34.0-dev1.0.20200722151356-96d84601a75a/light/client.go (about)

     1  package light
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"math/rand"
     8  	"time"
     9  
    10  	"github.com/tendermint/tendermint/libs/log"
    11  	tmmath "github.com/tendermint/tendermint/libs/math"
    12  	tmsync "github.com/tendermint/tendermint/libs/sync"
    13  	"github.com/tendermint/tendermint/light/provider"
    14  	"github.com/tendermint/tendermint/light/store"
    15  	"github.com/tendermint/tendermint/types"
    16  )
    17  
    18  type mode byte
    19  
    20  const (
    21  	sequential mode = iota + 1
    22  	skipping
    23  
    24  	defaultPruningSize      = 1000
    25  	defaultMaxRetryAttempts = 10
    26  	// For bisection, when using the cache of headers from the previous batch,
    27  	// they will always be at a height greater than 1/2 (normal bisection) so to
    28  	// find something in between the range, 9/16 is used.
    29  	bisectionNumerator   = 9
    30  	bisectionDenominator = 16
    31  
    32  	// 10s should cover most of the clients.
    33  	// References:
    34  	// - http://vancouver-webpages.com/time/web.html
    35  	// - https://blog.codinghorror.com/keeping-time-on-the-pc/
    36  	defaultMaxClockDrift = 10 * time.Second
    37  )
    38  
    39  // Option sets a parameter for the light client.
    40  type Option func(*Client)
    41  
    42  // SequentialVerification option configures the light client to sequentially
    43  // check the headers (every header, in ascending height order). Note this is
    44  // much slower than SkippingVerification, albeit more secure.
    45  func SequentialVerification() Option {
    46  	return func(c *Client) {
    47  		c.verificationMode = sequential
    48  	}
    49  }
    50  
    51  // SkippingVerification option configures the light client to skip headers as
    52  // long as {trustLevel} of the old validator set signed the new header. The
    53  // bisection algorithm from the specification is used for finding the minimal
    54  // "trust path".
    55  //
    56  // trustLevel - fraction of the old validator set (in terms of voting power),
    57  // which must sign the new header in order for us to trust it. NOTE this only
    58  // applies to non-adjacent headers. For adjacent headers, sequential
    59  // verification is used.
    60  func SkippingVerification(trustLevel tmmath.Fraction) Option {
    61  	return func(c *Client) {
    62  		c.verificationMode = skipping
    63  		c.trustLevel = trustLevel
    64  	}
    65  }
    66  
    67  // PruningSize option sets the maximum amount of headers & validator set pairs
    68  // that the light client stores. When Prune() is run, all headers (along with
    69  // the associated validator sets) that are earlier than the h amount of headers
    70  // will be removed from the store. Default: 1000. A pruning size of 0 will not
    71  // prune the light client at all.
    72  func PruningSize(h uint16) Option {
    73  	return func(c *Client) {
    74  		c.pruningSize = h
    75  	}
    76  }
    77  
    78  // ConfirmationFunction option can be used to prompt to confirm an action. For
    79  // example, remove newer headers if the light client is being reset with an
    80  // older header. No confirmation is required by default!
    81  func ConfirmationFunction(fn func(action string) bool) Option {
    82  	return func(c *Client) {
    83  		c.confirmationFn = fn
    84  	}
    85  }
    86  
    87  // Logger option can be used to set a logger for the client.
    88  func Logger(l log.Logger) Option {
    89  	return func(c *Client) {
    90  		c.logger = l
    91  	}
    92  }
    93  
    94  // MaxRetryAttempts option can be used to set max attempts before replacing
    95  // primary with a witness.
    96  func MaxRetryAttempts(max uint16) Option {
    97  	return func(c *Client) {
    98  		c.maxRetryAttempts = max
    99  	}
   100  }
   101  
   102  // MaxClockDrift defines how much new (untrusted) header's Time can drift into
   103  // the future. Default: 10s.
   104  func MaxClockDrift(d time.Duration) Option {
   105  	return func(c *Client) {
   106  		c.maxClockDrift = d
   107  	}
   108  }
   109  
   110  // Client represents a light client, connected to a single chain, which gets
   111  // headers from a primary provider, verifies them either sequentially or by
   112  // skipping some and stores them in a trusted store (usually, a local FS).
   113  //
   114  // Default verification: SkippingVerification(DefaultTrustLevel)
   115  type Client struct {
   116  	chainID          string
   117  	trustingPeriod   time.Duration // see TrustOptions.Period
   118  	verificationMode mode
   119  	trustLevel       tmmath.Fraction
   120  	maxRetryAttempts uint16 // see MaxRetryAttempts option
   121  	maxClockDrift    time.Duration
   122  
   123  	// Mutex for locking during changes of the light clients providers
   124  	providerMutex tmsync.Mutex
   125  	// Primary provider of new headers.
   126  	primary provider.Provider
   127  	// See Witnesses option
   128  	witnesses []provider.Provider
   129  
   130  	// Where trusted headers are stored.
   131  	trustedStore store.Store
   132  	// Highest trusted header from the store (height=H).
   133  	latestTrustedHeader *types.SignedHeader
   134  	// Highest validator set from the store (height=H).
   135  	latestTrustedVals *types.ValidatorSet
   136  
   137  	// See RemoveNoLongerTrustedHeadersPeriod option
   138  	pruningSize uint16
   139  	// See ConfirmationFunction option
   140  	confirmationFn func(action string) bool
   141  
   142  	quit chan struct{}
   143  
   144  	logger log.Logger
   145  }
   146  
   147  // NewClient returns a new light client. It returns an error if it fails to
   148  // obtain the header & vals from the primary or they are invalid (e.g. trust
   149  // hash does not match with the one from the header).
   150  //
   151  // Witnesses are providers, which will be used for cross-checking the primary
   152  // provider. At least one witness must be given when skipping verification is
   153  // used (default). A witness can become a primary iff the current primary is
   154  // unavailable.
   155  //
   156  // See all Option(s) for the additional configuration.
   157  func NewClient(
   158  	chainID string,
   159  	trustOptions TrustOptions,
   160  	primary provider.Provider,
   161  	witnesses []provider.Provider,
   162  	trustedStore store.Store,
   163  	options ...Option) (*Client, error) {
   164  
   165  	if err := trustOptions.ValidateBasic(); err != nil {
   166  		return nil, fmt.Errorf("invalid TrustOptions: %w", err)
   167  	}
   168  
   169  	c, err := NewClientFromTrustedStore(chainID, trustOptions.Period, primary, witnesses, trustedStore, options...)
   170  	if err != nil {
   171  		return nil, err
   172  	}
   173  
   174  	if c.latestTrustedHeader != nil {
   175  		c.logger.Info("Checking trusted header using options")
   176  		if err := c.checkTrustedHeaderUsingOptions(trustOptions); err != nil {
   177  			return nil, err
   178  		}
   179  	}
   180  
   181  	if c.latestTrustedHeader == nil || c.latestTrustedHeader.Height < trustOptions.Height {
   182  		c.logger.Info("Downloading trusted header using options")
   183  		if err := c.initializeWithTrustOptions(trustOptions); err != nil {
   184  			return nil, err
   185  		}
   186  	}
   187  
   188  	return c, err
   189  }
   190  
   191  // NewClientFromTrustedStore initializes existing client from the trusted store.
   192  //
   193  // See NewClient
   194  func NewClientFromTrustedStore(
   195  	chainID string,
   196  	trustingPeriod time.Duration,
   197  	primary provider.Provider,
   198  	witnesses []provider.Provider,
   199  	trustedStore store.Store,
   200  	options ...Option) (*Client, error) {
   201  
   202  	c := &Client{
   203  		chainID:          chainID,
   204  		trustingPeriod:   trustingPeriod,
   205  		verificationMode: skipping,
   206  		trustLevel:       DefaultTrustLevel,
   207  		maxRetryAttempts: defaultMaxRetryAttempts,
   208  		maxClockDrift:    defaultMaxClockDrift,
   209  		primary:          primary,
   210  		witnesses:        witnesses,
   211  		trustedStore:     trustedStore,
   212  		pruningSize:      defaultPruningSize,
   213  		confirmationFn:   func(action string) bool { return true },
   214  		quit:             make(chan struct{}),
   215  		logger:           log.NewNopLogger(),
   216  	}
   217  
   218  	for _, o := range options {
   219  		o(c)
   220  	}
   221  
   222  	// Validate the number of witnesses.
   223  	if len(c.witnesses) < 1 && c.verificationMode == skipping {
   224  		return nil, errNoWitnesses{}
   225  	}
   226  
   227  	// Verify witnesses are all on the same chain.
   228  	for i, w := range witnesses {
   229  		if w.ChainID() != chainID {
   230  			return nil, fmt.Errorf("witness #%d: %v is on another chain %s, expected %s",
   231  				i, w, w.ChainID(), chainID)
   232  		}
   233  	}
   234  
   235  	// Validate trust level.
   236  	if err := ValidateTrustLevel(c.trustLevel); err != nil {
   237  		return nil, err
   238  	}
   239  
   240  	if err := c.restoreTrustedHeaderAndVals(); err != nil {
   241  		return nil, err
   242  	}
   243  
   244  	return c, nil
   245  }
   246  
   247  // restoreTrustedHeaderAndVals loads trustedHeader and trustedVals from
   248  // trustedStore.
   249  func (c *Client) restoreTrustedHeaderAndVals() error {
   250  	lastHeight, err := c.trustedStore.LastSignedHeaderHeight()
   251  	if err != nil {
   252  		return fmt.Errorf("can't get last trusted header height: %w", err)
   253  	}
   254  
   255  	if lastHeight > 0 {
   256  		trustedHeader, err := c.trustedStore.SignedHeader(lastHeight)
   257  		if err != nil {
   258  			return fmt.Errorf("can't get last trusted header: %w", err)
   259  		}
   260  
   261  		trustedVals, err := c.trustedStore.ValidatorSet(lastHeight)
   262  		if err != nil {
   263  			return fmt.Errorf("can't get last trusted validators: %w", err)
   264  		}
   265  
   266  		c.latestTrustedHeader = trustedHeader
   267  		c.latestTrustedVals = trustedVals
   268  
   269  		c.logger.Info("Restored trusted header and vals", "height", lastHeight)
   270  	}
   271  
   272  	return nil
   273  }
   274  
   275  // if options.Height:
   276  //
   277  //     1) ahead of trustedHeader.Height => fetch header (same height as
   278  //     trustedHeader) from primary provider and check it's hash matches the
   279  //     trustedHeader's hash (if not, remove trustedHeader and all the headers
   280  //     before)
   281  //
   282  //     2) equals trustedHeader.Height => check options.Hash matches the
   283  //     trustedHeader's hash (if not, remove trustedHeader and all the headers
   284  //     before)
   285  //
   286  //     3) behind trustedHeader.Height => remove all the headers between
   287  //     options.Height and trustedHeader.Height, update trustedHeader, then
   288  //     check options.Hash matches the trustedHeader's hash (if not, remove
   289  //     trustedHeader and all the headers before)
   290  //
   291  // The intuition here is the user is always right. I.e. if she decides to reset
   292  // the light client with an older header, there must be a reason for it.
   293  func (c *Client) checkTrustedHeaderUsingOptions(options TrustOptions) error {
   294  	var primaryHash []byte
   295  	switch {
   296  	case options.Height > c.latestTrustedHeader.Height:
   297  		h, err := c.signedHeaderFromPrimary(c.latestTrustedHeader.Height)
   298  		if err != nil {
   299  			return err
   300  		}
   301  		primaryHash = h.Hash()
   302  	case options.Height == c.latestTrustedHeader.Height:
   303  		primaryHash = options.Hash
   304  	case options.Height < c.latestTrustedHeader.Height:
   305  		c.logger.Info("Client initialized with old header (trusted is more recent)",
   306  			"old", options.Height,
   307  			"trustedHeight", c.latestTrustedHeader.Height,
   308  			"trustedHash", hash2str(c.latestTrustedHeader.Hash()))
   309  
   310  		action := fmt.Sprintf(
   311  			"Rollback to %d (%X)? Note this will remove newer headers up to %d (%X)",
   312  			options.Height, options.Hash,
   313  			c.latestTrustedHeader.Height, c.latestTrustedHeader.Hash())
   314  		if c.confirmationFn(action) {
   315  			// remove all the headers (options.Height, trustedHeader.Height]
   316  			err := c.cleanupAfter(options.Height)
   317  			if err != nil {
   318  				return fmt.Errorf("cleanupAfter(%d): %w", options.Height, err)
   319  			}
   320  
   321  			c.logger.Info("Rolled back to older header (newer headers were removed)",
   322  				"old", options.Height)
   323  		} else {
   324  			return nil
   325  		}
   326  
   327  		primaryHash = options.Hash
   328  	}
   329  
   330  	if !bytes.Equal(primaryHash, c.latestTrustedHeader.Hash()) {
   331  		c.logger.Info("Prev. trusted header's hash (h1) doesn't match hash from primary provider (h2)",
   332  			"h1", hash2str(c.latestTrustedHeader.Hash()), "h2", hash2str(primaryHash))
   333  
   334  		action := fmt.Sprintf(
   335  			"Prev. trusted header's hash %X doesn't match hash %X from primary provider. Remove all the stored headers?",
   336  			c.latestTrustedHeader.Hash(), primaryHash)
   337  		if c.confirmationFn(action) {
   338  			err := c.Cleanup()
   339  			if err != nil {
   340  				return fmt.Errorf("failed to cleanup: %w", err)
   341  			}
   342  		} else {
   343  			return errors.New("refused to remove the stored headers despite hashes mismatch")
   344  		}
   345  	}
   346  
   347  	return nil
   348  }
   349  
   350  // initializeWithTrustOptions fetches the weakly-trusted header and vals from
   351  // primary provider.
   352  func (c *Client) initializeWithTrustOptions(options TrustOptions) error {
   353  	// 1) Fetch and verify the header.
   354  	h, err := c.signedHeaderFromPrimary(options.Height)
   355  	if err != nil {
   356  		return err
   357  	}
   358  
   359  	// NOTE: - Verify func will check if it's expired or not.
   360  	//       - h.Time is not being checked against time.Now() because we don't
   361  	//         want to add yet another argument to NewClient* functions.
   362  	if err := h.ValidateBasic(c.chainID); err != nil {
   363  		return err
   364  	}
   365  
   366  	if !bytes.Equal(h.Hash(), options.Hash) {
   367  		return fmt.Errorf("expected header's hash %X, but got %X", options.Hash, h.Hash())
   368  	}
   369  
   370  	// 2) Fetch and verify the vals.
   371  	vals, err := c.validatorSetFromPrimary(options.Height)
   372  	if err != nil {
   373  		return err
   374  	}
   375  
   376  	if !bytes.Equal(h.ValidatorsHash, vals.Hash()) {
   377  		return fmt.Errorf("expected header's validators (%X) to match those that were supplied (%X)",
   378  			h.ValidatorsHash,
   379  			vals.Hash(),
   380  		)
   381  	}
   382  
   383  	// Ensure that +2/3 of validators signed correctly.
   384  	err = vals.VerifyCommitLight(c.chainID, h.Commit.BlockID, h.Height, h.Commit)
   385  	if err != nil {
   386  		return fmt.Errorf("invalid commit: %w", err)
   387  	}
   388  
   389  	// 3) Persist both of them and continue.
   390  	return c.updateTrustedHeaderAndVals(h, vals)
   391  }
   392  
   393  // TrustedHeader returns a trusted header at the given height (0 - the latest).
   394  //
   395  // Headers along with validator sets, which can't be trusted anymore, are
   396  // removed once a day (can be changed with RemoveNoLongerTrustedHeadersPeriod
   397  // option).
   398  // .
   399  // height must be >= 0.
   400  //
   401  // It returns an error if:
   402  //  - there are some issues with the trusted store, although that should not
   403  //  happen normally;
   404  //  - negative height is passed;
   405  //  - header has not been verified yet and is therefore not in the store
   406  //
   407  // Safe for concurrent use by multiple goroutines.
   408  func (c *Client) TrustedHeader(height int64) (*types.SignedHeader, error) {
   409  	height, err := c.compareWithLatestHeight(height)
   410  	if err != nil {
   411  		return nil, err
   412  	}
   413  	return c.trustedStore.SignedHeader(height)
   414  }
   415  
   416  // TrustedValidatorSet returns a trusted validator set at the given height (0 -
   417  // latest). The second return parameter is the height used (useful if 0 was
   418  // passed; otherwise can be ignored).
   419  //
   420  // height must be >= 0.
   421  //
   422  // Headers along with validator sets are
   423  // removed once a day (can be changed with RemoveNoLongerTrustedHeadersPeriod
   424  // option).
   425  //
   426  // Function returns an error if:
   427  //  - there are some issues with the trusted store, although that should not
   428  //  happen normally;
   429  //  - negative height is passed;
   430  //  - header signed by that validator set has not been verified yet
   431  //
   432  // Safe for concurrent use by multiple goroutines.
   433  func (c *Client) TrustedValidatorSet(height int64) (valSet *types.ValidatorSet, heightUsed int64, err error) {
   434  	heightUsed, err = c.compareWithLatestHeight(height)
   435  	if err != nil {
   436  		return nil, heightUsed, err
   437  	}
   438  	valSet, err = c.trustedStore.ValidatorSet(heightUsed)
   439  	if err != nil {
   440  		return nil, heightUsed, err
   441  	}
   442  	return valSet, heightUsed, err
   443  }
   444  
   445  func (c *Client) compareWithLatestHeight(height int64) (int64, error) {
   446  	latestHeight, err := c.LastTrustedHeight()
   447  	if err != nil {
   448  		return 0, fmt.Errorf("can't get last trusted height: %w", err)
   449  	}
   450  	if latestHeight == -1 {
   451  		return 0, errors.New("no headers exist")
   452  	}
   453  
   454  	switch {
   455  	case height > latestHeight:
   456  		return 0, fmt.Errorf("unverified header/valset requested (latest: %d)", latestHeight)
   457  	case height == 0:
   458  		return latestHeight, nil
   459  	case height < 0:
   460  		return 0, errors.New("negative height")
   461  	}
   462  
   463  	return height, nil
   464  }
   465  
   466  // VerifyHeaderAtHeight fetches header and validators at the given height
   467  // and calls VerifyHeader. It returns header immediately if such exists in
   468  // trustedStore (no verification is needed).
   469  //
   470  // height must be > 0.
   471  //
   472  // It returns provider.ErrSignedHeaderNotFound if header is not found by
   473  // primary.
   474  //
   475  // It will replace the primary provider if an error from a request to the provider occurs
   476  func (c *Client) VerifyHeaderAtHeight(height int64, now time.Time) (*types.SignedHeader, error) {
   477  	if height <= 0 {
   478  		return nil, errors.New("negative or zero height")
   479  	}
   480  
   481  	// Check if header already verified.
   482  	h, err := c.TrustedHeader(height)
   483  	if err == nil {
   484  		c.logger.Info("Header has already been verified", "height", height, "hash", hash2str(h.Hash()))
   485  		// Return already trusted header
   486  		return h, nil
   487  	}
   488  
   489  	// Request the header and the vals.
   490  	newHeader, newVals, err := c.signedHeaderAndValSetFromPrimary(height)
   491  	if err != nil {
   492  		return nil, err
   493  	}
   494  
   495  	return newHeader, c.verifyHeader(newHeader, newVals, now)
   496  }
   497  
   498  // VerifyHeader verifies new header against the trusted state. It returns
   499  // immediately if newHeader exists in trustedStore (no verification is
   500  // needed). Else it performs one of the two types of verification:
   501  //
   502  // SequentialVerification: verifies that 2/3 of the trusted validator set has
   503  // signed the new header. If the headers are not adjacent, **all** intermediate
   504  // headers will be requested. Intermediate headers are not saved to database.
   505  //
   506  // SkippingVerification(trustLevel): verifies that {trustLevel} of the trusted
   507  // validator set has signed the new header. If it's not the case and the
   508  // headers are not adjacent, bisection is performed and necessary (not all)
   509  // intermediate headers will be requested. See the specification for details.
   510  // Intermediate headers are not saved to database.
   511  // https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md
   512  //
   513  // If the header, which is older than the currently trusted header, is
   514  // requested and the light client does not have it, VerifyHeader will perform:
   515  //		a) bisection verification if nearest trusted header is found & not expired
   516  //		b) backwards verification in all other cases
   517  //
   518  // It returns ErrOldHeaderExpired if the latest trusted header expired.
   519  //
   520  // If the primary provides an invalid header (ErrInvalidHeader), it is rejected
   521  // and replaced by another provider until all are exhausted.
   522  //
   523  // If, at any moment, SignedHeader or ValidatorSet are not found by the primary
   524  // provider, provider.ErrSignedHeaderNotFound /
   525  // provider.ErrValidatorSetNotFound error is returned.
   526  func (c *Client) VerifyHeader(newHeader *types.SignedHeader, newVals *types.ValidatorSet, now time.Time) error {
   527  	if newHeader.Height <= 0 {
   528  		return errors.New("negative or zero height")
   529  	}
   530  
   531  	// Check if newHeader already verified.
   532  	h, err := c.TrustedHeader(newHeader.Height)
   533  	if err == nil {
   534  		// Make sure it's the same header.
   535  		if !bytes.Equal(h.Hash(), newHeader.Hash()) {
   536  			return fmt.Errorf("existing trusted header %X does not match newHeader %X", h.Hash(), newHeader.Hash())
   537  		}
   538  		c.logger.Info("Header has already been verified",
   539  			"height", newHeader.Height, "hash", hash2str(newHeader.Hash()))
   540  		return nil
   541  	}
   542  
   543  	return c.verifyHeader(newHeader, newVals, now)
   544  }
   545  
   546  func (c *Client) verifyHeader(newHeader *types.SignedHeader, newVals *types.ValidatorSet, now time.Time) error {
   547  	c.logger.Info("VerifyHeader", "height", newHeader.Height, "hash", hash2str(newHeader.Hash()),
   548  		"vals", hash2str(newVals.Hash()))
   549  
   550  	var err error
   551  
   552  	// 1) If going forward, perform either bisection or sequential verification.
   553  	if newHeader.Height >= c.latestTrustedHeader.Height {
   554  		switch c.verificationMode {
   555  		case sequential:
   556  			err = c.sequence(c.latestTrustedHeader, newHeader, newVals, now)
   557  		case skipping:
   558  			err = c.bisectionAgainstPrimary(c.latestTrustedHeader, c.latestTrustedVals, newHeader, newVals, now)
   559  		default:
   560  			panic(fmt.Sprintf("Unknown verification mode: %b", c.verificationMode))
   561  		}
   562  	} else {
   563  		// 2) If verifying before the first trusted header, perform backwards
   564  		// verification.
   565  		var (
   566  			closestHeader     *types.SignedHeader
   567  			firstHeaderHeight int64
   568  		)
   569  		firstHeaderHeight, err = c.FirstTrustedHeight()
   570  		if err != nil {
   571  			return fmt.Errorf("can't get first header height: %w", err)
   572  		}
   573  		if newHeader.Height < firstHeaderHeight {
   574  			closestHeader, err = c.TrustedHeader(firstHeaderHeight)
   575  			if err != nil {
   576  				return fmt.Errorf("can't get first signed header: %w", err)
   577  			}
   578  			if HeaderExpired(closestHeader, c.trustingPeriod, now) {
   579  				closestHeader = c.latestTrustedHeader
   580  			}
   581  			err = c.backwards(closestHeader, newHeader, now)
   582  		} else {
   583  			// 3) OR if between trusted headers where the nearest has not expired,
   584  			// perform bisection verification, else backwards.
   585  			closestHeader, err = c.trustedStore.SignedHeaderBefore(newHeader.Height)
   586  			if err != nil {
   587  				return fmt.Errorf("can't get signed header before height %d: %w", newHeader.Height, err)
   588  			}
   589  			var closestValidatorSet *types.ValidatorSet
   590  			if c.verificationMode == sequential || HeaderExpired(closestHeader, c.trustingPeriod, now) {
   591  				err = c.backwards(c.latestTrustedHeader, newHeader, now)
   592  			} else {
   593  				closestValidatorSet, _, err = c.TrustedValidatorSet(closestHeader.Height)
   594  				if err != nil {
   595  					return fmt.Errorf("can't get validator set at height %d: %w", closestHeader.Height, err)
   596  				}
   597  				err = c.bisectionAgainstPrimary(closestHeader, closestValidatorSet, newHeader, newVals, now)
   598  			}
   599  		}
   600  	}
   601  	if err != nil {
   602  		c.logger.Error("Can't verify", "err", err)
   603  		return err
   604  	}
   605  
   606  	// 4) Once verified, save and return
   607  	return c.updateTrustedHeaderAndVals(newHeader, newVals)
   608  }
   609  
   610  // see VerifyHeader
   611  func (c *Client) sequence(
   612  	initiallyTrustedHeader *types.SignedHeader,
   613  	newHeader *types.SignedHeader,
   614  	newVals *types.ValidatorSet,
   615  	now time.Time) error {
   616  
   617  	var (
   618  		trustedHeader = initiallyTrustedHeader
   619  
   620  		interimHeader *types.SignedHeader
   621  		interimVals   *types.ValidatorSet
   622  
   623  		err error
   624  	)
   625  
   626  	for height := initiallyTrustedHeader.Height + 1; height <= newHeader.Height; height++ {
   627  		// 1) Fetch interim headers and vals if needed.
   628  		if height == newHeader.Height { // last header
   629  			interimHeader, interimVals = newHeader, newVals
   630  		} else { // intermediate headers
   631  			interimHeader, interimVals, err = c.signedHeaderAndValSetFromPrimary(height)
   632  			if err != nil {
   633  				return ErrVerificationFailed{From: trustedHeader.Height, To: height, Reason: err}
   634  			}
   635  		}
   636  
   637  		// 2) Verify them
   638  		c.logger.Debug("Verify adjacent newHeader against trustedHeader",
   639  			"trustedHeight", trustedHeader.Height,
   640  			"trustedHash", hash2str(trustedHeader.Hash()),
   641  			"newHeight", interimHeader.Height,
   642  			"newHash", hash2str(interimHeader.Hash()))
   643  
   644  		err = VerifyAdjacent(c.chainID, trustedHeader, interimHeader, interimVals,
   645  			c.trustingPeriod, now, c.maxClockDrift)
   646  		if err != nil {
   647  			err := ErrVerificationFailed{From: trustedHeader.Height, To: interimHeader.Height, Reason: err}
   648  
   649  			switch errors.Unwrap(err).(type) {
   650  			case ErrInvalidHeader:
   651  				// If the target header is invalid, return immediately.
   652  				if err.To == newHeader.Height {
   653  					c.logger.Debug("Target header is invalid", "err", err)
   654  					return err
   655  				}
   656  
   657  				// If some intermediate header is invalid, replace the primary and try
   658  				// again.
   659  				c.logger.Error("primary sent invalid header -> replacing", "err", err)
   660  				replaceErr := c.replacePrimaryProvider()
   661  				if replaceErr != nil {
   662  					c.logger.Error("Can't replace primary", "err", replaceErr)
   663  					// return original error
   664  					return err
   665  				}
   666  
   667  				replacementHeader, replacementVals, fErr := c.signedHeaderAndValSetFromPrimary(newHeader.Height)
   668  				if fErr != nil {
   669  					c.logger.Error("Can't fetch header/vals from primary", "err", fErr)
   670  					// return original error
   671  					return err
   672  				}
   673  
   674  				if !bytes.Equal(replacementHeader.Hash(), newHeader.Hash()) ||
   675  					!bytes.Equal(replacementVals.Hash(), newVals.Hash()) {
   676  					c.logger.Error("Replacement provider has a different header/vals",
   677  						"newHash", newHeader.Hash(),
   678  						"newVals", newVals.Hash(),
   679  						"replHash", replacementHeader.Hash(),
   680  						"replVals", replacementVals.Hash())
   681  					// return original error
   682  					return err
   683  				}
   684  
   685  				// attempt to verify header again
   686  				height--
   687  
   688  				continue
   689  			default:
   690  				return err
   691  			}
   692  		}
   693  
   694  		// 3) Update trustedHeader
   695  		trustedHeader = interimHeader
   696  	}
   697  
   698  	return nil
   699  }
   700  
   701  // see VerifyHeader
   702  //
   703  // Bisection finds the middle header between a trusted and new header,
   704  // reiterating the action until it verifies a header. A cache of headers
   705  // requested from source is kept such that when a verification is made, and the
   706  // light client tries again to verify the new header in the middle, the light
   707  // client does not need to ask for all the same headers again.
   708  func (c *Client) bisection(
   709  	source provider.Provider,
   710  	initiallyTrustedHeader *types.SignedHeader,
   711  	initiallyTrustedVals *types.ValidatorSet,
   712  	newHeader *types.SignedHeader,
   713  	newVals *types.ValidatorSet,
   714  	now time.Time) error {
   715  
   716  	type headerSet struct {
   717  		sh     *types.SignedHeader
   718  		valSet *types.ValidatorSet
   719  	}
   720  
   721  	var (
   722  		headerCache = []headerSet{{newHeader, newVals}}
   723  		depth       = 0
   724  
   725  		trustedHeader = initiallyTrustedHeader
   726  		trustedVals   = initiallyTrustedVals
   727  	)
   728  
   729  	for {
   730  		c.logger.Debug("Verify non-adjacent newHeader against trustedHeader",
   731  			"trustedHeight", trustedHeader.Height,
   732  			"trustedHash", hash2str(trustedHeader.Hash()),
   733  			"newHeight", headerCache[depth].sh.Height,
   734  			"newHash", hash2str(headerCache[depth].sh.Hash()))
   735  
   736  		err := Verify(c.chainID, trustedHeader, trustedVals, headerCache[depth].sh, headerCache[depth].valSet,
   737  			c.trustingPeriod, now, c.maxClockDrift, c.trustLevel)
   738  		switch err.(type) {
   739  		case nil:
   740  			// Have we verified the last header
   741  			if depth == 0 {
   742  				return nil
   743  			}
   744  			// If not, update the lower bound to the previous upper bound
   745  			trustedHeader, trustedVals = headerCache[depth].sh, headerCache[depth].valSet
   746  			// Remove the untrusted header at the lower bound in the header cache - it's no longer useful
   747  			headerCache = headerCache[:depth]
   748  			// Reset the cache depth so that we start from the upper bound again
   749  			depth = 0
   750  
   751  		case ErrNewValSetCantBeTrusted:
   752  			// do add another header to the end of the cache
   753  			if depth == len(headerCache)-1 {
   754  				pivotHeight := trustedHeader.Height + (headerCache[depth].sh.Height-trustedHeader.
   755  					Height)*bisectionNumerator/bisectionDenominator
   756  				interimHeader, interimVals, err := c.signedHeaderAndValSetFrom(pivotHeight, source)
   757  				if err != nil {
   758  					return ErrVerificationFailed{From: trustedHeader.Height, To: pivotHeight, Reason: err}
   759  				}
   760  				headerCache = append(headerCache, headerSet{interimHeader, interimVals})
   761  			}
   762  			depth++
   763  
   764  		default:
   765  			return ErrVerificationFailed{From: trustedHeader.Height, To: headerCache[depth].sh.Height, Reason: err}
   766  		}
   767  	}
   768  }
   769  
   770  // bisectionAgainstPrimary does bisection plus it compares new header with
   771  // witnesses and replaces primary if it does not respond after
   772  // MaxRetryAttempts.
   773  func (c *Client) bisectionAgainstPrimary(
   774  	initiallyTrustedHeader *types.SignedHeader,
   775  	initiallyTrustedVals *types.ValidatorSet,
   776  	newHeader *types.SignedHeader,
   777  	newVals *types.ValidatorSet,
   778  	now time.Time) error {
   779  
   780  	err := c.bisection(c.primary, initiallyTrustedHeader, initiallyTrustedVals, newHeader, newVals, now)
   781  
   782  	switch errors.Unwrap(err).(type) {
   783  	case ErrInvalidHeader:
   784  		// If the target header is invalid, return immediately.
   785  		invalidHeaderHeight := err.(ErrVerificationFailed).To
   786  		if invalidHeaderHeight == newHeader.Height {
   787  			c.logger.Debug("Target header is invalid", "err", err)
   788  			return err
   789  		}
   790  
   791  		// If some intermediate header is invalid, replace the primary and try
   792  		// again.
   793  		c.logger.Error("primary sent invalid header -> replacing", "err", err)
   794  		replaceErr := c.replacePrimaryProvider()
   795  		if replaceErr != nil {
   796  			c.logger.Error("Can't replace primary", "err", replaceErr)
   797  			// return original error
   798  			return err
   799  		}
   800  
   801  		replacementHeader, replacementVals, fErr := c.signedHeaderAndValSetFromPrimary(newHeader.Height)
   802  		if fErr != nil {
   803  			c.logger.Error("Can't fetch header/vals from primary", "err", fErr)
   804  			// return original error
   805  			return err
   806  		}
   807  
   808  		if !bytes.Equal(replacementHeader.Hash(), newHeader.Hash()) ||
   809  			!bytes.Equal(replacementVals.Hash(), newVals.Hash()) {
   810  			c.logger.Error("Replacement provider has a different header/vals",
   811  				"newHash", newHeader.Hash(),
   812  				"newVals", newVals.Hash(),
   813  				"replHash", replacementHeader.Hash(),
   814  				"replVals", replacementVals.Hash())
   815  			// return original error
   816  			return err
   817  		}
   818  
   819  		// attempt to verify the header again
   820  		return c.bisectionAgainstPrimary(
   821  			initiallyTrustedHeader,
   822  			initiallyTrustedVals,
   823  			replacementHeader,
   824  			replacementVals,
   825  			now,
   826  		)
   827  	case nil:
   828  		// Compare header with the witnesses to ensure it's not a fork.
   829  		// More witnesses we have, more chance to notice one.
   830  		//
   831  		// CORRECTNESS ASSUMPTION: there's at least 1 correct full node
   832  		// (primary or one of the witnesses).
   833  		if cmpErr := c.compareNewHeaderWithWitnesses(newHeader, now); cmpErr != nil {
   834  			return cmpErr
   835  		}
   836  	default:
   837  		return err
   838  	}
   839  
   840  	return nil
   841  }
   842  
   843  // LastTrustedHeight returns a last trusted height. -1 and nil are returned if
   844  // there are no trusted headers.
   845  //
   846  // Safe for concurrent use by multiple goroutines.
   847  func (c *Client) LastTrustedHeight() (int64, error) {
   848  	return c.trustedStore.LastSignedHeaderHeight()
   849  }
   850  
   851  // FirstTrustedHeight returns a first trusted height. -1 and nil are returned if
   852  // there are no trusted headers.
   853  //
   854  // Safe for concurrent use by multiple goroutines.
   855  func (c *Client) FirstTrustedHeight() (int64, error) {
   856  	return c.trustedStore.FirstSignedHeaderHeight()
   857  }
   858  
   859  // ChainID returns the chain ID the light client was configured with.
   860  //
   861  // Safe for concurrent use by multiple goroutines.
   862  func (c *Client) ChainID() string {
   863  	return c.chainID
   864  }
   865  
   866  // Primary returns the primary provider.
   867  //
   868  // NOTE: provider may be not safe for concurrent access.
   869  func (c *Client) Primary() provider.Provider {
   870  	c.providerMutex.Lock()
   871  	defer c.providerMutex.Unlock()
   872  	return c.primary
   873  }
   874  
   875  // Witnesses returns the witness providers.
   876  //
   877  // NOTE: providers may be not safe for concurrent access.
   878  func (c *Client) Witnesses() []provider.Provider {
   879  	c.providerMutex.Lock()
   880  	defer c.providerMutex.Unlock()
   881  	return c.witnesses
   882  }
   883  
   884  // Cleanup removes all the data (headers and validator sets) stored. Note: the
   885  // client must be stopped at this point.
   886  func (c *Client) Cleanup() error {
   887  	c.logger.Info("Removing all the data")
   888  	c.latestTrustedHeader = nil
   889  	c.latestTrustedVals = nil
   890  	return c.trustedStore.Prune(0)
   891  }
   892  
   893  // cleanupAfter deletes all headers & validator sets after +height+. It also
   894  // resets latestTrustedHeader to the latest header.
   895  func (c *Client) cleanupAfter(height int64) error {
   896  	prevHeight := c.latestTrustedHeader.Height
   897  
   898  	for {
   899  		h, err := c.trustedStore.SignedHeaderBefore(prevHeight)
   900  		if err == store.ErrSignedHeaderNotFound || (h != nil && h.Height <= height) {
   901  			break
   902  		} else if err != nil {
   903  			return fmt.Errorf("failed to get header before %d: %w", prevHeight, err)
   904  		}
   905  
   906  		err = c.trustedStore.DeleteSignedHeaderAndValidatorSet(h.Height)
   907  		if err != nil {
   908  			c.logger.Error("can't remove a trusted header & validator set", "err", err,
   909  				"height", h.Height)
   910  		}
   911  
   912  		prevHeight = h.Height
   913  	}
   914  
   915  	c.latestTrustedHeader = nil
   916  	c.latestTrustedVals = nil
   917  	err := c.restoreTrustedHeaderAndVals()
   918  	if err != nil {
   919  		return err
   920  	}
   921  
   922  	return nil
   923  }
   924  
   925  func (c *Client) updateTrustedHeaderAndVals(h *types.SignedHeader, vals *types.ValidatorSet) error {
   926  	if !bytes.Equal(h.ValidatorsHash, vals.Hash()) {
   927  		return fmt.Errorf("expected validator's hash %X, but got %X", h.ValidatorsHash, vals.Hash())
   928  	}
   929  
   930  	if err := c.trustedStore.SaveSignedHeaderAndValidatorSet(h, vals); err != nil {
   931  		return fmt.Errorf("failed to save trusted header: %w", err)
   932  	}
   933  
   934  	if c.pruningSize > 0 {
   935  		if err := c.trustedStore.Prune(c.pruningSize); err != nil {
   936  			return fmt.Errorf("prune: %w", err)
   937  		}
   938  	}
   939  
   940  	if c.latestTrustedHeader == nil || h.Height > c.latestTrustedHeader.Height {
   941  		c.latestTrustedHeader = h
   942  		c.latestTrustedVals = vals
   943  	}
   944  
   945  	return nil
   946  }
   947  
   948  // 0 - latest header
   949  // Note it swaps the primary with a witness if primary is not responding after
   950  // MaxRetryAttempts.
   951  func (c *Client) signedHeaderAndValSetFromPrimary(height int64) (*types.SignedHeader, *types.ValidatorSet, error) {
   952  	h, err := c.signedHeaderFromPrimary(height)
   953  	if err != nil {
   954  		return nil, nil, fmt.Errorf("can't fetch header: %w", err)
   955  	}
   956  	vals, err := c.validatorSetFromPrimary(height)
   957  	if err != nil {
   958  		return nil, nil, fmt.Errorf("can't fetch vals: %w", err)
   959  	}
   960  	return h, vals, nil
   961  }
   962  
   963  // 0 - latest header
   964  // Note it does not do retries nor swapping.
   965  func (c *Client) signedHeaderAndValSetFromWitness(height int64,
   966  	witness provider.Provider) (*types.SignedHeader, *types.ValidatorSet, *errBadWitness) {
   967  
   968  	h, err := witness.SignedHeader(height)
   969  	if err != nil {
   970  		return nil, nil, &errBadWitness{err, noResponse, -1}
   971  	}
   972  	err = c.validateHeader(h, height)
   973  	if err != nil {
   974  		return nil, nil, &errBadWitness{err, invalidHeader, -1}
   975  	}
   976  
   977  	vals, err := witness.ValidatorSet(height)
   978  	if err != nil {
   979  		return nil, nil, &errBadWitness{err, noResponse, -1}
   980  	}
   981  	err = c.validateValidatorSet(vals)
   982  	if err != nil {
   983  		return nil, nil, &errBadWitness{err, invalidValidatorSet, -1}
   984  	}
   985  
   986  	return h, vals, nil
   987  }
   988  
   989  func (c *Client) signedHeaderAndValSetFrom(height int64,
   990  	source provider.Provider) (*types.SignedHeader, *types.ValidatorSet, error) {
   991  
   992  	c.providerMutex.Lock()
   993  	sourceIsPrimary := (c.primary == source)
   994  	c.providerMutex.Unlock()
   995  
   996  	if sourceIsPrimary {
   997  		return c.signedHeaderAndValSetFromPrimary(height)
   998  	}
   999  	return c.signedHeaderAndValSetFromWitness(height, source)
  1000  }
  1001  
  1002  // backwards verification (see VerifyHeaderBackwards func in the spec) verifies
  1003  // headers before a trusted header. If a sent header is invalid the primary is
  1004  // replaced with another provider and the operation is repeated.
  1005  func (c *Client) backwards(
  1006  	initiallyTrustedHeader *types.SignedHeader,
  1007  	newHeader *types.SignedHeader,
  1008  	now time.Time) error {
  1009  
  1010  	if HeaderExpired(initiallyTrustedHeader, c.trustingPeriod, now) {
  1011  		c.logger.Error("Header Expired")
  1012  		return ErrOldHeaderExpired{initiallyTrustedHeader.Time.Add(c.trustingPeriod), now}
  1013  	}
  1014  
  1015  	var (
  1016  		trustedHeader = initiallyTrustedHeader
  1017  		interimHeader *types.SignedHeader
  1018  		err           error
  1019  	)
  1020  
  1021  	for trustedHeader.Height > newHeader.Height {
  1022  		interimHeader, err = c.signedHeaderFromPrimary(trustedHeader.Height - 1)
  1023  		if err != nil {
  1024  			return fmt.Errorf("failed to obtain the header at height #%d: %w", trustedHeader.Height-1, err)
  1025  		}
  1026  		c.logger.Debug("Verify newHeader against trustedHeader",
  1027  			"trustedHeight", trustedHeader.Height,
  1028  			"trustedHash", hash2str(trustedHeader.Hash()),
  1029  			"newHeight", interimHeader.Height,
  1030  			"newHash", hash2str(interimHeader.Hash()))
  1031  		if err := VerifyBackwards(c.chainID, interimHeader, trustedHeader); err != nil {
  1032  			c.logger.Error("primary sent invalid header -> replacing", "err", err)
  1033  			if replaceErr := c.replacePrimaryProvider(); replaceErr != nil {
  1034  				c.logger.Error("Can't replace primary", "err", replaceErr)
  1035  				// return original error
  1036  				return fmt.Errorf("verify backwards from %d to %d failed: %w",
  1037  					trustedHeader.Height, interimHeader.Height, err)
  1038  			}
  1039  		}
  1040  
  1041  		trustedHeader = interimHeader
  1042  	}
  1043  
  1044  	// Initially trusted header might have expired at this point.
  1045  	if HeaderExpired(initiallyTrustedHeader, c.trustingPeriod, now) {
  1046  		return ErrOldHeaderExpired{initiallyTrustedHeader.Time.Add(c.trustingPeriod), now}
  1047  	}
  1048  
  1049  	return nil
  1050  }
  1051  
  1052  // compare header with all witnesses provided.
  1053  func (c *Client) compareNewHeaderWithWitnesses(h *types.SignedHeader, now time.Time) error {
  1054  	c.providerMutex.Lock()
  1055  	defer c.providerMutex.Unlock()
  1056  
  1057  	// 1. Make sure AT LEAST ONE witness returns the same header.
  1058  	var (
  1059  		headerMatched      bool
  1060  		lastErrConfHeaders error
  1061  	)
  1062  	for attempt := uint16(1); attempt <= c.maxRetryAttempts; attempt++ {
  1063  		if len(c.witnesses) == 0 {
  1064  			return errNoWitnesses{}
  1065  		}
  1066  
  1067  		// launch one goroutine per witness
  1068  		errc := make(chan error, len(c.witnesses))
  1069  		for i, witness := range c.witnesses {
  1070  			go c.compareNewHeaderWithWitness(errc, h, witness, i, now)
  1071  		}
  1072  
  1073  		witnessesToRemove := make([]int, 0)
  1074  
  1075  		// handle errors as they come
  1076  		for i := 0; i < cap(errc); i++ {
  1077  			err := <-errc
  1078  
  1079  			switch e := err.(type) {
  1080  			case nil: // at least one header matched
  1081  				headerMatched = true
  1082  			case ErrConflictingHeaders: // fork detected
  1083  				c.logger.Info("FORK DETECTED", "witness", e.Witness, "err", err)
  1084  				c.sendConflictingHeadersEvidence(&types.ConflictingHeadersEvidence{H1: h, H2: e.H2})
  1085  				lastErrConfHeaders = e
  1086  			case errBadWitness:
  1087  				c.logger.Info("Bad witness", "witness", c.witnesses[e.WitnessIndex], "err", err)
  1088  				// if witness sent us invalid header / vals, remove it
  1089  				if e.Code == invalidHeader || e.Code == invalidValidatorSet {
  1090  					c.logger.Info("Witness sent us invalid header / vals -> removing it", "witness", c.witnesses[e.WitnessIndex])
  1091  					witnessesToRemove = append(witnessesToRemove, e.WitnessIndex)
  1092  				}
  1093  			}
  1094  		}
  1095  
  1096  		for _, idx := range witnessesToRemove {
  1097  			c.removeWitness(idx)
  1098  		}
  1099  
  1100  		if lastErrConfHeaders != nil {
  1101  			// NOTE: all of the potential forks will be reported, but we only return
  1102  			// the last ErrConflictingHeaders error here.
  1103  			return lastErrConfHeaders
  1104  		} else if headerMatched {
  1105  			return nil
  1106  		}
  1107  
  1108  		// 2. Otherwise, sleep
  1109  		time.Sleep(backoffTimeout(attempt))
  1110  	}
  1111  
  1112  	return errors.New("awaiting response from all witnesses exceeded dropout time")
  1113  }
  1114  
  1115  func (c *Client) compareNewHeaderWithWitness(errc chan error, h *types.SignedHeader,
  1116  	witness provider.Provider, witnessIndex int, now time.Time) {
  1117  
  1118  	altH, altVals, err := c.signedHeaderAndValSetFromWitness(h.Height, witness)
  1119  	if err != nil {
  1120  		err.WitnessIndex = witnessIndex
  1121  		errc <- err
  1122  		return
  1123  	}
  1124  
  1125  	if !bytes.Equal(h.Hash(), altH.Hash()) {
  1126  		if bsErr := c.bisection(witness, c.latestTrustedHeader, c.latestTrustedVals, altH, altVals, now); bsErr != nil {
  1127  			errc <- errBadWitness{bsErr, invalidHeader, witnessIndex}
  1128  			return
  1129  		}
  1130  		errc <- ErrConflictingHeaders{H1: h, Primary: c.primary, H2: altH, Witness: witness}
  1131  	}
  1132  
  1133  	errc <- nil
  1134  }
  1135  
  1136  // NOTE: requires a providerMutex locked.
  1137  func (c *Client) removeWitness(idx int) {
  1138  	switch len(c.witnesses) {
  1139  	case 0:
  1140  		panic(fmt.Sprintf("wanted to remove %d element from empty witnesses slice", idx))
  1141  	case 1:
  1142  		c.witnesses = make([]provider.Provider, 0)
  1143  	default:
  1144  		c.witnesses[idx] = c.witnesses[len(c.witnesses)-1]
  1145  		c.witnesses = c.witnesses[:len(c.witnesses)-1]
  1146  	}
  1147  }
  1148  
  1149  // Update attempts to advance the state by downloading the latest header and
  1150  // comparing it with the existing one. It returns a new header on a successful
  1151  // update. Otherwise, it returns nil (plus an error, if any).
  1152  func (c *Client) Update(now time.Time) (*types.SignedHeader, error) {
  1153  	lastTrustedHeight, err := c.LastTrustedHeight()
  1154  	if err != nil {
  1155  		return nil, fmt.Errorf("can't get last trusted height: %w", err)
  1156  	}
  1157  
  1158  	if lastTrustedHeight == -1 {
  1159  		// no headers yet => wait
  1160  		return nil, nil
  1161  	}
  1162  
  1163  	latestHeader, latestVals, err := c.signedHeaderAndValSetFromPrimary(0)
  1164  	if err != nil {
  1165  		return nil, err
  1166  	}
  1167  
  1168  	if latestHeader.Height > lastTrustedHeight {
  1169  		err = c.VerifyHeader(latestHeader, latestVals, now)
  1170  		if err != nil {
  1171  			return nil, err
  1172  		}
  1173  		c.logger.Info("Advanced to new state", "height", latestHeader.Height, "hash", hash2str(latestHeader.Hash()))
  1174  		return latestHeader, nil
  1175  	}
  1176  
  1177  	return nil, nil
  1178  }
  1179  
  1180  // replaceProvider takes the first alternative provider and promotes it as the
  1181  // primary provider.
  1182  func (c *Client) replacePrimaryProvider() error {
  1183  	c.providerMutex.Lock()
  1184  	defer c.providerMutex.Unlock()
  1185  
  1186  	c.logger.Info("Primary is unavailable. Replacing with the first witness")
  1187  	if len(c.witnesses) <= 1 {
  1188  		return errNoWitnesses{}
  1189  	}
  1190  	c.primary = c.witnesses[0]
  1191  	c.witnesses = c.witnesses[1:]
  1192  	c.logger.Info("New primary", "p", c.primary)
  1193  
  1194  	return nil
  1195  }
  1196  
  1197  // signedHeaderFromPrimary retrieves the SignedHeader from the primary provider
  1198  // at the specified height. Handles dropout by the primary provider by swapping
  1199  // with an alternative provider.
  1200  func (c *Client) signedHeaderFromPrimary(height int64) (*types.SignedHeader, error) {
  1201  	for attempt := uint16(1); attempt <= c.maxRetryAttempts; attempt++ {
  1202  		c.providerMutex.Lock()
  1203  		h, providerErr := c.primary.SignedHeader(height)
  1204  		c.providerMutex.Unlock()
  1205  		if providerErr == nil {
  1206  			err := c.validateHeader(h, height)
  1207  			if err != nil {
  1208  				replaceErr := c.replacePrimaryProvider()
  1209  				if replaceErr != nil {
  1210  					return nil, fmt.Errorf("%v. Tried to replace primary but: %w", err.Error(), replaceErr)
  1211  				}
  1212  				// replace primary and request signed header again
  1213  				return c.signedHeaderFromPrimary(height)
  1214  			}
  1215  			// valid header has been received
  1216  			return h, nil
  1217  		}
  1218  		if providerErr == provider.ErrSignedHeaderNotFound {
  1219  			return nil, providerErr
  1220  		}
  1221  		c.logger.Error("Failed to get signed header from primary", "attempt", attempt, "err", providerErr)
  1222  		time.Sleep(backoffTimeout(attempt))
  1223  	}
  1224  
  1225  	err := c.replacePrimaryProvider()
  1226  	if err != nil {
  1227  		return nil, fmt.Errorf("primary dropped out. Tried to replace but: %w", err)
  1228  	}
  1229  
  1230  	return c.signedHeaderFromPrimary(height)
  1231  }
  1232  
  1233  func (c *Client) validateHeader(h *types.SignedHeader, expectedHeight int64) error {
  1234  	if h == nil {
  1235  		return errors.New("nil header")
  1236  	}
  1237  	err := h.ValidateBasic(c.chainID)
  1238  	if err != nil {
  1239  		return err
  1240  	}
  1241  	if expectedHeight > 0 && h.Height != expectedHeight {
  1242  		return errors.New("height mismatch")
  1243  	}
  1244  	return nil
  1245  }
  1246  
  1247  // validatorSetFromPrimary retrieves the ValidatorSet from the primary provider
  1248  // at the specified height. Handles dropout by the primary provider after 5
  1249  // attempts by replacing it with an alternative provider.
  1250  func (c *Client) validatorSetFromPrimary(height int64) (*types.ValidatorSet, error) {
  1251  	for attempt := uint16(1); attempt <= c.maxRetryAttempts; attempt++ {
  1252  		c.providerMutex.Lock()
  1253  		vals, providerErr := c.primary.ValidatorSet(height)
  1254  		c.providerMutex.Unlock()
  1255  		if providerErr == nil {
  1256  			err := c.validateValidatorSet(vals)
  1257  			if err != nil {
  1258  				replaceErr := c.replacePrimaryProvider()
  1259  				if replaceErr != nil {
  1260  					return nil, fmt.Errorf("%v. Tried to replace primary but: %w", err.Error(), replaceErr)
  1261  				}
  1262  				// replace primary and request signed header again
  1263  				return c.validatorSetFromPrimary(height)
  1264  			}
  1265  			return vals, nil
  1266  		}
  1267  
  1268  		if providerErr == provider.ErrValidatorSetNotFound {
  1269  			return vals, providerErr
  1270  		}
  1271  		c.logger.Error("Failed to get validator set from primary", "attempt", attempt, "err", providerErr)
  1272  		time.Sleep(backoffTimeout(attempt))
  1273  	}
  1274  
  1275  	err := c.replacePrimaryProvider()
  1276  	if err != nil {
  1277  		return nil, fmt.Errorf("primary dropped out. Tried to replace but: %w", err)
  1278  	}
  1279  
  1280  	return c.validatorSetFromPrimary(height)
  1281  }
  1282  
  1283  func (c *Client) validateValidatorSet(vals *types.ValidatorSet) error {
  1284  	if vals == nil {
  1285  		return errors.New("validator set is nil")
  1286  	}
  1287  	return vals.ValidateBasic()
  1288  }
  1289  
  1290  // sendConflictingHeadersEvidence sends evidence to all witnesses and primary
  1291  // on best effort basis.
  1292  //
  1293  // Evidence needs to be submitted to all full nodes since there's no way to
  1294  // determine which full node is correct (honest).
  1295  func (c *Client) sendConflictingHeadersEvidence(ev *types.ConflictingHeadersEvidence) {
  1296  	err := c.primary.ReportEvidence(ev)
  1297  	if err != nil {
  1298  		c.logger.Error("Failed to report evidence to primary", "ev", ev, "primary", c.primary)
  1299  	}
  1300  
  1301  	for _, w := range c.witnesses {
  1302  		err := w.ReportEvidence(ev)
  1303  		if err != nil {
  1304  			c.logger.Error("Failed to report evidence to witness", "ev", ev, "witness", w)
  1305  		}
  1306  	}
  1307  }
  1308  
  1309  // exponential backoff (with jitter)
  1310  //		0.5s -> 2s -> 4.5s -> 8s -> 12.5 with 1s variation
  1311  func backoffTimeout(attempt uint16) time.Duration {
  1312  	return time.Duration(500*attempt*attempt)*time.Millisecond + time.Duration(rand.Intn(1000))*time.Millisecond
  1313  }
  1314  
  1315  func hash2str(hash []byte) string {
  1316  	return fmt.Sprintf("%X", hash)
  1317  }