func (c *Client) restoreTrustedLightBlock() error {
	lastHeight, err := c.trustedStore.LastLightBlockHeight()
	if err != nil {
		return fmt.Errorf("can't get last trusted light block height: %w", err)
	}
	if lastHeight <= 0 {
		return errors.New("trusted store is empty")
	}
	trustedBlock, err := c.trustedStore.LightBlock(lastHeight)
	if err != nil {
		return fmt.Errorf("can't get last trusted light block: %w", err)
	}
	c.latestTrustedBlock = trustedBlock
	c.logger.Info("restored trusted light block", "height", lastHeight)
	return nil
}
restoreTrustedLightBlock loads the latest trusted light block from the store
package light
import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"sort"
	"sync"
	"time"
	tmsync "github.com/tendermint/tendermint/internal/libs/sync"
	"github.com/tendermint/tendermint/libs/log"
	tmmath "github.com/tendermint/tendermint/libs/math"
	"github.com/tendermint/tendermint/light/provider"
	"github.com/tendermint/tendermint/light/store"
	"github.com/tendermint/tendermint/types"
)
type mode byte
const (
	sequential mode = iota + 1
	skipping
	defaultPruningSize = 1000
	verifySkippingNumerator   = 9
	verifySkippingDenominator = 16
	defaultMaxClockDrift = 10 * time.Second
	defaultMaxBlockLag = 10 * time.Second
	defaultProviderTimeout = 10 * time.Second
)
type Option func(*Client)
func SequentialVerification() Option {
	return func(c *Client) { c.verificationMode = sequential }
}
func SkippingVerification(trustLevel tmmath.Fraction) Option {
	return func(c *Client) {
		c.verificationMode = skipping
		c.trustLevel = trustLevel
	}
}
func PruningSize(h uint16) Option {
	return func(c *Client) { c.pruningSize = h }
}
func Logger(l log.Logger) Option {
	return func(c *Client) { c.logger = l }
}
func MaxClockDrift(d time.Duration) Option {
	return func(c *Client) { c.maxClockDrift = d }
}
func MaxBlockLag(d time.Duration) Option {
	return func(c *Client) { c.maxBlockLag = d }
}
func ProviderTimeout(d time.Duration) Option {
	return func(c *Client) { c.providerTimeout = d }
}
type Client struct {
	chainID          string
	trustingPeriod   time.Duration  
	verificationMode mode
	trustLevel       tmmath.Fraction
	maxClockDrift    time.Duration
	maxBlockLag      time.Duration
	providerTimeout  time.Duration
	providerMutex tmsync.Mutex
	primary provider.Provider
	witnesses []provider.Provider
	trustedStore store.Store
	latestTrustedBlock *types.LightBlock
	pruningSize uint16
	logger log.Logger
}
func NewClient(
	ctx context.Context,
	chainID string,
	trustOptions TrustOptions,
	primary provider.Provider,
	witnesses []provider.Provider,
	trustedStore store.Store,
	options ...Option) (*Client, error) {
	lastHeight, err := trustedStore.LastLightBlockHeight()
	if err != nil {
		return nil, err
	}
	if lastHeight > 0 {
		return NewClientFromTrustedStore(
			chainID, trustOptions.Period, primary, witnesses, trustedStore, options...,
		)
	}
	if err := trustOptions.ValidateBasic(); err != nil {
		return nil, fmt.Errorf("invalid TrustOptions: %w", err)
	}
	if len(witnesses) < 1 {
		return nil, ErrNoWitnesses
	}
	c := &Client{
		chainID:          chainID,
		trustingPeriod:   trustOptions.Period,
		verificationMode: skipping,
		primary:          primary,
		witnesses:        witnesses,
		trustedStore:     trustedStore,
		trustLevel:       DefaultTrustLevel,
		maxClockDrift:    defaultMaxClockDrift,
		maxBlockLag:      defaultMaxBlockLag,
		providerTimeout:  defaultProviderTimeout,
		pruningSize:      defaultPruningSize,
		logger:           log.NewNopLogger(),
	}
	for _, o := range options {
		o(c)
	}
	if err := ValidateTrustLevel(c.trustLevel); err != nil {
		return nil, err
	}
	if err := c.initializeWithTrustOptions(ctx, trustOptions); err != nil {
		return nil, err
	}
	return c, nil
}
func NewClientFromTrustedStore(
	chainID string,
	trustingPeriod time.Duration,
	primary provider.Provider,
	witnesses []provider.Provider,
	trustedStore store.Store,
	options ...Option) (*Client, error) {
	c := &Client{
		chainID:          chainID,
		trustingPeriod:   trustingPeriod,
		verificationMode: skipping,
		trustLevel:       DefaultTrustLevel,
		maxClockDrift:    defaultMaxClockDrift,
		maxBlockLag:      defaultMaxBlockLag,
		primary:          primary,
		witnesses:        witnesses,
		trustedStore:     trustedStore,
		pruningSize:      defaultPruningSize,
		logger:           log.NewNopLogger(),
	}
	for _, o := range options {
		o(c)
	}
	if len(c.witnesses) < 1 {
		return nil, ErrNoWitnesses
	}
	if err := ValidateTrustLevel(c.trustLevel); err != nil {
		return nil, err
	}
	if err := c.restoreTrustedLightBlock(); err != nil {
		return nil, err
	}
	return c, nil
}