github.com/number571/tendermint@v0.34.11-gost/light/provider/mock/mock.go (about) 1 package mock 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "strings" 8 "sync" 9 "time" 10 11 "github.com/number571/tendermint/light/provider" 12 "github.com/number571/tendermint/types" 13 ) 14 15 type Mock struct { 16 id string 17 18 mtx sync.Mutex 19 headers map[int64]*types.SignedHeader 20 vals map[int64]*types.ValidatorSet 21 evidenceToReport map[string]types.Evidence // hash => evidence 22 latestHeight int64 23 } 24 25 var _ provider.Provider = (*Mock)(nil) 26 27 // New creates a mock provider with the given set of headers and validator 28 // sets. 29 func New(id string, headers map[int64]*types.SignedHeader, vals map[int64]*types.ValidatorSet) *Mock { 30 height := int64(0) 31 for h := range headers { 32 if h > height { 33 height = h 34 } 35 } 36 return &Mock{ 37 id: id, 38 headers: headers, 39 vals: vals, 40 evidenceToReport: make(map[string]types.Evidence), 41 latestHeight: height, 42 } 43 } 44 45 func (p *Mock) String() string { 46 var headers strings.Builder 47 for _, h := range p.headers { 48 fmt.Fprintf(&headers, " %d:%X", h.Height, h.Hash()) 49 } 50 51 var vals strings.Builder 52 for _, v := range p.vals { 53 fmt.Fprintf(&vals, " %X", v.Hash()) 54 } 55 56 return fmt.Sprintf("Mock{id: %s, headers: %s, vals: %v}", p.id, headers.String(), vals.String()) 57 } 58 59 func (p *Mock) LightBlock(ctx context.Context, height int64) (*types.LightBlock, error) { 60 p.mtx.Lock() 61 defer p.mtx.Unlock() 62 63 select { 64 case <-ctx.Done(): 65 return nil, ctx.Err() 66 case <-time.After(10 * time.Millisecond): 67 } 68 69 var lb *types.LightBlock 70 71 if height > p.latestHeight { 72 return nil, provider.ErrHeightTooHigh 73 } 74 75 if height == 0 && len(p.headers) > 0 { 76 height = p.latestHeight 77 } 78 79 if _, ok := p.headers[height]; ok { 80 sh := p.headers[height] 81 vals := p.vals[height] 82 lb = &types.LightBlock{ 83 SignedHeader: sh, 84 ValidatorSet: vals, 85 } 86 } 87 if lb == nil { 88 return nil, provider.ErrLightBlockNotFound 89 } 90 if lb.SignedHeader == nil || lb.ValidatorSet == nil { 91 return nil, provider.ErrBadLightBlock{Reason: errors.New("nil header or vals")} 92 } 93 if err := lb.ValidateBasic(lb.ChainID); err != nil { 94 return nil, provider.ErrBadLightBlock{Reason: err} 95 } 96 return lb, nil 97 } 98 99 func (p *Mock) ReportEvidence(_ context.Context, ev types.Evidence) error { 100 p.evidenceToReport[string(ev.Hash())] = ev 101 return nil 102 } 103 104 func (p *Mock) HasEvidence(ev types.Evidence) bool { 105 _, ok := p.evidenceToReport[string(ev.Hash())] 106 return ok 107 } 108 109 func (p *Mock) AddLightBlock(lb *types.LightBlock) { 110 p.mtx.Lock() 111 defer p.mtx.Unlock() 112 113 if err := lb.ValidateBasic(lb.ChainID); err != nil { 114 panic(fmt.Sprintf("unable to add light block, err: %v", err)) 115 } 116 p.headers[lb.Height] = lb.SignedHeader 117 p.vals[lb.Height] = lb.ValidatorSet 118 if lb.Height > p.latestHeight { 119 p.latestHeight = lb.Height 120 } 121 } 122 123 func (p *Mock) Copy(id string) *Mock { 124 return New(id, p.headers, p.vals) 125 }