github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/core/common/selector.go (about) 1 package common 2 3 import ( 4 "errors" 5 "sort" 6 7 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 8 ) 9 10 var ( 11 errDuplicateVersionSelector = errors.New("duplicate version ") 12 errRepeatRegisterSelector = errors.New("repeat register selectors ") 13 ) 14 15 var ( 16 DefaultFactory = func(higherThan func(h int64) bool, version SelectVersion, internal interface{}) SelectorFactory { 17 return func() Selector { 18 return NewCommonHeightSelector(higherThan, version, internal) 19 } 20 } 21 ) 22 23 // TODO,use genesis 24 type Selector interface { 25 Version() SelectVersion 26 Select(ctx sdk.Context) (interface{}, bool) 27 } 28 29 type SelectVersion float64 30 31 type SelectorFactory func() Selector 32 33 type Selectors []Selector 34 35 func (m Selectors) Len() int { 36 return len(m) 37 } 38 39 func (m Selectors) Less(i, j int) bool { 40 return m[i].Version() >= m[j].Version() 41 } 42 43 func (m Selectors) Swap(i, j int) { 44 m[i], m[j] = m[j], m[i] 45 } 46 47 // ////// 48 var ( 49 _ Selector = (*CommonHeightSelector)(nil) 50 ) 51 52 type CommonHeightSelector struct { 53 higherThan func(h int64) bool 54 version SelectVersion 55 internal interface{} 56 } 57 58 func NewCommonHeightSelector(higherThan func(h int64) bool, version SelectVersion, internal interface{}) *CommonHeightSelector { 59 return &CommonHeightSelector{higherThan: higherThan, version: version, internal: internal} 60 } 61 62 func (c *CommonHeightSelector) Version() SelectVersion { 63 return c.version 64 } 65 66 func (c *CommonHeightSelector) Select(ctx sdk.Context) (interface{}, bool) { 67 if c.higherThan(ctx.BlockHeight()) { 68 return c.internal, true 69 } 70 return nil, false 71 } 72 73 /////// 74 75 type SelectorStrategy struct { 76 internal interface{} 77 selectors Selectors 78 seal bool 79 } 80 81 func (f *SelectorStrategy) RegisterSelectors(factories ...SelectorFactory) { 82 if f.Seald() { 83 panic(errDuplicateVersionSelector) 84 } 85 var selectors Selectors 86 set := make(map[SelectVersion]struct{}) 87 88 for _, f := range factories { 89 sel := f() 90 selectors = append(selectors, sel) 91 v := sel.Version() 92 if _, contains := set[v]; contains { 93 panic(errDuplicateVersionSelector) 94 } 95 set[v] = struct{}{} 96 } 97 sort.Sort(selectors) 98 99 f.selectors = selectors 100 } 101 102 func NewSelectorStrategy(internal interface{}) *SelectorStrategy { 103 return &SelectorStrategy{internal: internal} 104 } 105 106 func (f *SelectorStrategy) Seald() bool { 107 return f.seal 108 } 109 func (f *SelectorStrategy) Seal() { 110 f.seal = true 111 } 112 113 func (f *SelectorStrategy) GetProxy(ctx sdk.Context) interface{} { 114 for _, s := range f.selectors { 115 m, ok := s.Select(ctx) 116 if ok { 117 return m 118 } 119 } 120 return f.internal 121 } 122 123 func (f *SelectorStrategy) GetInternal() interface{} { 124 return f.internal 125 }