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  }