p2p: push handshake containing chainId for early disconnect. Closes #12

This commit is contained in:
Ethan Buchman 2015-03-17 01:20:39 -07:00 committed by Jae Kwon
parent 9c4692c071
commit 4abca6e963
3 changed files with 36 additions and 3 deletions

View File

@ -65,6 +65,7 @@ func NewNode() *Node {
} }
sw := p2p.NewSwitch([]p2p.Reactor{pexReactor, mempoolReactor, consensusReactor}) sw := p2p.NewSwitch([]p2p.Reactor{pexReactor, mempoolReactor, consensusReactor})
sw.SetChainId(state.Hash(), config.App().GetString("Network"))
return &Node{ return &Node{
sw: sw, sw: sw,

View File

@ -96,6 +96,12 @@ func (pexR *PEXReactor) Receive(chId byte, src *Peer, msgBytes []byte) {
log.Info("Received message", "msg", msg) log.Info("Received message", "msg", msg)
switch msg.(type) { switch msg.(type) {
case *pexHandshakeMessage:
chainId := msg.(*pexHandshakeMessage).ChainId
if chainId != pexR.sw.chainId {
err := fmt.Sprintf("Peer is on a different chain/network. Got %s, expected %s", chainId, pexR.sw.chainId)
pexR.sw.StopPeerForError(src, err)
}
case *pexRequestMessage: case *pexRequestMessage:
// src requested some peers. // src requested some peers.
// TODO: prevent abuse. // TODO: prevent abuse.
@ -201,9 +207,10 @@ func (pexR *PEXReactor) ensurePeers() {
// Messages // Messages
const ( const (
msgTypeUnknown = byte(0x00) msgTypeUnknown = byte(0x00)
msgTypeRequest = byte(0x01) msgTypeRequest = byte(0x01)
msgTypeAddrs = byte(0x02) msgTypeAddrs = byte(0x02)
msgTypeHandshake = byte(0x03)
) )
// TODO: check for unnecessary extra bytes at the end. // TODO: check for unnecessary extra bytes at the end.
@ -213,6 +220,8 @@ func DecodeMessage(bz []byte) (msg interface{}, err error) {
r := bytes.NewReader(bz) r := bytes.NewReader(bz)
// log.Debug(Fmt("decoding msg bytes: %X", bz)) // log.Debug(Fmt("decoding msg bytes: %X", bz))
switch msgType { switch msgType {
case msgTypeHandshake:
msg = binary.ReadBinary(&pexHandshakeMessage{}, r, n, &err)
case msgTypeRequest: case msgTypeRequest:
msg = &pexRequestMessage{} msg = &pexRequestMessage{}
case msgTypeAddrs: case msgTypeAddrs:
@ -223,6 +232,19 @@ func DecodeMessage(bz []byte) (msg interface{}, err error) {
return return
} }
/*
A pexHandshakeMessage contains the peer's chainId
*/
type pexHandshakeMessage struct {
ChainId string
}
func (m *pexHandshakeMessage) TypeByte() byte { return msgTypeHandshake }
func (m *pexHandshakeMessage) String() string {
return "[pexHandshake]"
}
/* /*
A pexRequestMessage requests additional peer addresses. A pexRequestMessage requests additional peer addresses.
*/ */

View File

@ -1,6 +1,7 @@
package p2p package p2p
import ( import (
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"net" "net"
@ -37,6 +38,7 @@ type Switch struct {
quit chan struct{} quit chan struct{}
started uint32 started uint32
stopped uint32 stopped uint32
chainId string
} }
var ( var (
@ -129,6 +131,10 @@ func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, er
// Notify listeners. // Notify listeners.
sw.doAddPeer(peer) sw.doAddPeer(peer)
// Send handshake
msg := &pexHandshakeMessage{ChainId: sw.chainId}
peer.Send(PexCh, msg)
return peer, nil return peer, nil
} }
@ -216,6 +222,10 @@ func (sw *Switch) StopPeerGracefully(peer *Peer) {
sw.doRemovePeer(peer, nil) sw.doRemovePeer(peer, nil)
} }
func (sw *Switch) SetChainId(hash []byte, network string) {
sw.chainId = hex.EncodeToString(hash) + "-" + network
}
func (sw *Switch) IsListening() bool { func (sw *Switch) IsListening() bool {
return sw.listeners.Size() > 0 return sw.listeners.Size() > 0
} }