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  }