github.com/okex/exchain@v1.8.0/libs/tendermint/lite/multiprovider.go (about)

     1  package lite
     2  
     3  import (
     4  	log "github.com/okex/exchain/libs/tendermint/libs/log"
     5  	lerr "github.com/okex/exchain/libs/tendermint/lite/errors"
     6  	"github.com/okex/exchain/libs/tendermint/types"
     7  )
     8  
     9  var _ PersistentProvider = (*multiProvider)(nil)
    10  
    11  // multiProvider allows you to place one or more caches in front of a source
    12  // Provider.  It runs through them in order until a match is found.
    13  type multiProvider struct {
    14  	logger    log.Logger
    15  	providers []PersistentProvider
    16  }
    17  
    18  // NewMultiProvider returns a new provider which wraps multiple other providers.
    19  func NewMultiProvider(providers ...PersistentProvider) PersistentProvider {
    20  	return &multiProvider{
    21  		logger:    log.NewNopLogger(),
    22  		providers: providers,
    23  	}
    24  }
    25  
    26  // SetLogger sets logger on self and all subproviders.
    27  func (mc *multiProvider) SetLogger(logger log.Logger) {
    28  	mc.logger = logger
    29  	for _, p := range mc.providers {
    30  		p.SetLogger(logger)
    31  	}
    32  }
    33  
    34  // SaveFullCommit saves on all providers, and aborts on the first error.
    35  func (mc *multiProvider) SaveFullCommit(fc FullCommit) (err error) {
    36  	for _, p := range mc.providers {
    37  		err = p.SaveFullCommit(fc)
    38  		if err != nil {
    39  			return
    40  		}
    41  	}
    42  	return
    43  }
    44  
    45  // LatestFullCommit loads the latest from all providers and provides
    46  // the latest FullCommit that satisfies the conditions.
    47  // Returns the first error encountered.
    48  func (mc *multiProvider) LatestFullCommit(chainID string, minHeight, maxHeight int64) (fc FullCommit, err error) {
    49  	for _, p := range mc.providers {
    50  		var commit FullCommit
    51  		commit, err = p.LatestFullCommit(chainID, minHeight, maxHeight)
    52  		if lerr.IsErrCommitNotFound(err) {
    53  			err = nil
    54  			continue
    55  		} else if err != nil {
    56  			return
    57  		}
    58  		if fc == (FullCommit{}) {
    59  			fc = commit
    60  		} else if commit.Height() > fc.Height() {
    61  			fc = commit
    62  		}
    63  		if fc.Height() == maxHeight {
    64  			return
    65  		}
    66  	}
    67  	if fc == (FullCommit{}) {
    68  		err = lerr.ErrCommitNotFound()
    69  		return
    70  	}
    71  	return
    72  }
    73  
    74  // ValidatorSet returns validator set at height as provided by the first
    75  // provider which has it, or an error otherwise.
    76  func (mc *multiProvider) ValidatorSet(chainID string, height int64) (valset *types.ValidatorSet, err error) {
    77  	for _, p := range mc.providers {
    78  		valset, err = p.ValidatorSet(chainID, height)
    79  		if err == nil {
    80  			// TODO Log unexpected types of errors.
    81  			return valset, nil
    82  		}
    83  	}
    84  	return nil, lerr.ErrUnknownValidators(chainID, height)
    85  }