github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/protocols/blockvotes/bvstream/bvstreamseeder/seeder.go (about) 1 package bvstreamseeder 2 3 import ( 4 "errors" 5 6 "github.com/unicornultrafoundation/go-u2u/rlp" 7 8 "github.com/unicornultrafoundation/go-helios/gossip/basestream" 9 "github.com/unicornultrafoundation/go-helios/gossip/basestream/basestreamseeder" 10 "github.com/unicornultrafoundation/go-helios/hash" 11 12 "github.com/unicornultrafoundation/go-u2u/gossip/protocols/blockvotes/bvstream" 13 ) 14 15 var ( 16 ErrWrongType = errors.New("wrong request type") 17 ErrWrongSelectorLen = errors.New("wrong event selector length") 18 ) 19 20 type Seeder struct { 21 *basestreamseeder.BaseSeeder 22 } 23 24 type Callbacks struct { 25 Iterate func(locator []byte, f func(key []byte, bvs rlp.RawValue) bool) 26 } 27 28 type Peer struct { 29 ID string 30 SendChunk func(bvstream.Response) error 31 Misbehaviour func(error) 32 } 33 34 func New(cfg Config, callbacks Callbacks) *Seeder { 35 return &Seeder{ 36 BaseSeeder: basestreamseeder.New(basestreamseeder.Config(cfg), basestreamseeder.Callbacks{ 37 ForEachItem: func(start basestream.Locator, _ basestream.RequestType, onKey func(key basestream.Locator) bool, onAppended func(items basestream.Payload) bool) basestream.Payload { 38 res := &bvstream.Payload{ 39 Items: []rlp.RawValue{}, 40 Keys: []bvstream.Locator{}, 41 Size: 0, 42 } 43 st := start.(bvstream.Locator) 44 callbacks.Iterate(st, func(bkey []byte, bvs rlp.RawValue) bool { 45 key := bvstream.Locator(bkey) 46 if !onKey(key) { 47 return false 48 } 49 res.AddSignedBlockVotes(key, bvs) 50 return onAppended(res) 51 }) 52 return res 53 }, 54 }), 55 } 56 } 57 58 func (s *Seeder) NotifyRequestReceived(peer Peer, r bvstream.Request) (err error, peerErr error) { 59 if len(r.Session.Start) > len(hash.ZeroEvent)+4+8 || len(r.Session.Stop) > len(hash.ZeroEvent)+4+8 { 60 return nil, ErrWrongSelectorLen 61 } 62 if r.Type != 0 { 63 return nil, ErrWrongType 64 } 65 return s.BaseSeeder.NotifyRequestReceived(basestreamseeder.Peer{ 66 ID: peer.ID, 67 SendChunk: func(response basestream.Response) error { 68 return peer.SendChunk(bvstream.Response{ 69 SessionID: response.SessionID, 70 Done: response.Done, 71 Payload: response.Payload.(*bvstream.Payload).Items, 72 }) 73 }, 74 Misbehaviour: peer.Misbehaviour, 75 }, basestream.Request{ 76 Session: basestream.Session{ 77 ID: r.Session.ID, 78 Start: r.Session.Start, 79 Stop: r.Session.Stop, 80 }, 81 Type: r.Type, 82 MaxPayloadNum: uint32(r.Limit.Num), 83 MaxPayloadSize: r.Limit.Size, 84 MaxChunks: r.MaxChunks, 85 }) 86 }