github.com/status-im/status-go@v1.1.0/t/helpers/peers.go (about)

     1  package helpers
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  
     7  	"github.com/ethereum/go-ethereum/p2p"
     8  	"github.com/ethereum/go-ethereum/p2p/enode"
     9  )
    10  
    11  var (
    12  	// ErrNoRunningNode node is not running.
    13  	ErrNoRunningNode = errors.New("there is no running node")
    14  	// ErrEmptyPeerURL provided peer URL is empty
    15  	ErrEmptyPeerURL = errors.New("empty peer url")
    16  )
    17  
    18  // waitForPeer waits for a peer to be added
    19  func waitForPeer(p *p2p.Server, u string, e p2p.PeerEventType, t time.Duration, subscribed chan struct{}) error {
    20  	if p == nil {
    21  		return ErrNoRunningNode
    22  	}
    23  	if u == "" {
    24  		return ErrEmptyPeerURL
    25  	}
    26  	parsedPeer, err := enode.ParseV4(u)
    27  	if err != nil {
    28  		return err
    29  	}
    30  
    31  	ch := make(chan *p2p.PeerEvent)
    32  	subscription := p.SubscribeEvents(ch)
    33  	defer subscription.Unsubscribe()
    34  	close(subscribed)
    35  
    36  	for {
    37  		select {
    38  		case ev := <-ch:
    39  			if ev.Type == e && ev.Peer == parsedPeer.ID() {
    40  				return nil
    41  			}
    42  		case err := <-subscription.Err():
    43  			if err != nil {
    44  				return err
    45  			}
    46  		case <-time.After(t):
    47  			return errors.New("wait for peer: timeout")
    48  		}
    49  	}
    50  }
    51  
    52  // WaitForPeerAsync waits for a peer to be added asynchronously
    53  func WaitForPeerAsync(p *p2p.Server, u string, e p2p.PeerEventType, t time.Duration) <-chan error {
    54  	subscribed := make(chan struct{})
    55  	errCh := make(chan error)
    56  	go func() {
    57  		errCh <- waitForPeer(p, u, e, t, subscribed)
    58  	}()
    59  	<-subscribed
    60  	return errCh
    61  }