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 }