github.com/cranelv/ethereum_mpc@v0.0.0-20191031014521-23aeb1415092/mpcService/peer.go (about)

     1  package mpcService
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/ethereum/go-ethereum/p2p"
     6  	"github.com/ethereum/go-ethereum/p2p/discover"
     7  	"github.com/ethereum/go-ethereum/rlp"
     8  	"gopkg.in/fatih/set.v0"
     9  	"github.com/ethereum/go-ethereum/mpcService/protocol"
    10  	"github.com/ethereum/go-ethereum/log"
    11  )
    12  
    13  // peer represents a whisper protocol peer connection.
    14  type Peer struct {
    15  //	host    *Storeman
    16  	*p2p.Peer
    17  	ws      p2p.MsgReadWriter
    18  	trusted bool
    19  
    20  	known *set.Set // Messages already known by the peer to avoid wasting bandwidth
    21  
    22  }
    23  
    24  // newPeer creates a new whisper peer object, but does not run the handshake itself.
    25  func newPeer( remote *p2p.Peer, rw p2p.MsgReadWriter) *Peer {
    26  	return &Peer{
    27  		Peer:    remote,
    28  		ws:      rw,
    29  		trusted: false,
    30  		known:   set.New(),
    31  	}
    32  }
    33  
    34  
    35  // handshake sends the protocol initiation status message to the remote peer and
    36  // verifies the remote status too.
    37  func (p *Peer) handshake() error {
    38  	// Send the handshake status message asynchronously
    39  	errc := make(chan error, 1)
    40  	go func() {
    41  		errc <- p2p.Send(p.ws, protocol.StatusCode, protocol.ProtocolVersion)
    42  	}()
    43  	// Fetch the remote status packet and verify protocol match
    44  	packet, err := p.ws.ReadMsg()
    45  	if err != nil {
    46  		log.Error("storeman peer read msg fail.", "peer",p.ID(), "error" ,err)
    47  		return err
    48  	}
    49  	defer packet.Discard()
    50  
    51  	log.Info("storeman received handshake. ", "peer",p.ID(), "packet code" ,packet.Code)
    52  	if packet.Code != protocol.StatusCode {
    53  		log.Error("storeman peer sent packet before status packet", "peer",p.ID(), "packet code" ,packet.Code)
    54  		return fmt.Errorf("storman peer [%s] sent packet %x before status packet", p.ID().String(), packet.Code)
    55  	}
    56  	s := rlp.NewStream(packet.Payload, uint64(packet.Size))
    57  	peerVersion, err := s.Uint()
    58  	if err != nil {
    59  		log.Error("storman peer sent bad status message:","peer",p.ID(), "error" ,err)
    60  		return fmt.Errorf("storman peer [%s] sent bad status message: %v", p.ID().String(), err)
    61  	}
    62  	if peerVersion != protocol.ProtocolVersion {
    63  		log.Error("storman peer : protocol version mismatch ", "peer",p.ID(),  peerVersion, protocol.ProtocolVersion)
    64  		return fmt.Errorf("storman peer [%s]: protocol version mismatch %d != %d", p.ID().String(), peerVersion, protocol.ProtocolVersion)
    65  	}
    66  	// Wait until out own status is consumed too
    67  	if err := <-errc; err != nil {
    68  		log.Error("storman peer failed to send status packet:", "peer",p.ID(), "error" ,err)
    69  		return fmt.Errorf("storman peer [%s] failed to send status packet: %v", p.ID().String(), err)
    70  	}
    71  	return nil
    72  }
    73  
    74  func (p *Peer) ID() discover.NodeID {
    75  	id := p.Peer.ID()
    76  	return id
    77  }