Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(header/p2p): add trivial retrying for trustedPeer requested #1647

Merged
merged 10 commits into from
Jan 31, 2023
35 changes: 26 additions & 9 deletions libs/header/p2p/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,15 @@ type Exchange[H header.Header] struct {

func NewExchange[H header.Header](
host host.Host,
peers peer.IDSlice,
trustedPeers peer.IDSlice,
protocolSuffix string,
connGater *conngater.BasicConnectionGater,
opts ...Option[ClientParameters],
) (*Exchange[H], error) {
if len(trustedPeers) == 0 {
return nil, fmt.Errorf("no trusted peers")
}

params := DefaultClientParameters()
for _, opt := range opts {
opt(&params)
Expand All @@ -58,7 +62,7 @@ func NewExchange[H header.Header](
return &Exchange[H]{
host: host,
protocolID: protocolID(protocolSuffix),
trustedPeers: peers,
trustedPeers: trustedPeers,
peerTracker: newPeerTracker(
host,
connGater,
Expand All @@ -77,7 +81,12 @@ func (ex *Exchange[H]) Start(context.Context) error {
// Try to pre-connect to trusted peers.
// We don't really care if we succeed at this point
// and just need any peers in the peerTracker asap
go ex.host.Connect(ex.ctx, peer.AddrInfo{ID: p}) //nolint:errcheck
go func(p peer.ID) {
err := ex.host.Connect(ex.ctx, peer.AddrInfo{ID: p}) //nolint:errcheck
if err != nil {
log.Debugw("err connecting to a bootstrap peer", "err", err, "peer", p)
walldiss marked this conversation as resolved.
Show resolved Hide resolved
}
}(p)
}
go ex.peerTracker.gc()
go ex.peerTracker.track()
Expand Down Expand Up @@ -220,13 +229,21 @@ func (ex *Exchange[H]) performRequest(
return make([]H, 0), nil
}

if len(ex.trustedPeers) == 0 {
return nil, fmt.Errorf("no trusted peers")
walldiss marked this conversation as resolved.
Show resolved Hide resolved
for {
//nolint:gosec // G404: Use of weak random number generator
idx := rand.Intn(len(ex.trustedPeers))
walldiss marked this conversation as resolved.
Show resolved Hide resolved
ctx, cancel := context.WithTimeout(ctx, ex.Params.TrustedPeersRequestTimeout)

h, err := ex.request(ctx, ex.trustedPeers[idx], req)
renaynay marked this conversation as resolved.
Show resolved Hide resolved
cancel()
switch err {
default:
log.Debug(err)
renaynay marked this conversation as resolved.
Show resolved Hide resolved
continue
case context.Canceled, context.DeadlineExceeded, nil:
return h, err
}
}

//nolint:gosec // G404: Use of weak random number generator
index := rand.Intn(len(ex.trustedPeers))
return ex.request(ctx, ex.trustedPeers[index], req)
}

// request sends the HeaderRequest to a remote peer.
Expand Down
10 changes: 7 additions & 3 deletions libs/header/p2p/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,24 @@ func WithRequestTimeout[T parameters](duration time.Duration) Option[T] {
}

// ClientParameters is the set of parameters that must be configured for the exchange.
// TODO: #1667
type ClientParameters struct {
// the target minimum amount of responses with the same chain head
MinResponses int
// MaxRequestSize defines the max amount of headers that can be handled at once.
MaxRequestSize uint64
MaxRequestSize uint64 // TODO: Rename to MaxRangeRequestSize
// MaxHeadersPerRequest defines the max amount of headers that can be requested per 1 request.
MaxHeadersPerRequest uint64
MaxHeadersPerRequest uint64 // TODO: Rename to MaxHeadersPerRangeRequest
// MaxAwaitingTime specifies the duration that gives to the disconnected peer to be back online,
// otherwise it will be removed on the next GC cycle.
MaxAwaitingTime time.Duration
// DefaultScore specifies the score for newly connected peers.
DefaultScore float32
// RequestTimeout defines a timeout after which the session will try to re-request headers
// from another peer.
RequestTimeout time.Duration
RequestTimeout time.Duration // TODO: Rename to RangeRequestTimeout
// TrustedPeersRequestTimeout a timeout for any request to a trusted peer.
TrustedPeersRequestTimeout time.Duration
// MaxTrackerSize specifies the max amount of peers that can be added to the peerTracker.
MaxPeerTrackerSize int
}
Expand All @@ -132,6 +135,7 @@ func DefaultClientParameters() ClientParameters {
MaxAwaitingTime: time.Hour,
DefaultScore: 1,
RequestTimeout: time.Second * 3,
TrustedPeersRequestTimeout: time.Millisecond * 300,
MaxPeerTrackerSize: 100,
}
}
Expand Down