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