You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.2 KiB

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