aboutsummaryrefslogtreecommitdiffstats
path: root/peer.go
diff options
context:
space:
mode:
Diffstat (limited to 'peer.go')
-rw-r--r--peer.go93
1 files changed, 59 insertions, 34 deletions
diff --git a/peer.go b/peer.go
index 89032364e..ffba695ca 100644
--- a/peer.go
+++ b/peer.go
@@ -121,10 +121,8 @@ type Peer struct {
versionKnown bool
// Last received pong message
- lastPong int64
- // Indicates whether a MsgGetPeersTy was requested of the peer
- // this to prevent receiving false peers.
- requestedPeerList bool
+ lastPong int64
+ lastBlockReceived time.Time
host []byte
port uint16
@@ -180,10 +178,9 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
// Set up the connection in another goroutine so we don't block the main thread
go func() {
- conn, err := net.DialTimeout("tcp", addr, 10*time.Second)
-
+ conn, err := p.Connect(addr)
if err != nil {
- peerlogger.Debugln("Connection to peer failed", err)
+ peerlogger.Debugln("Connection to peer failed. Giving up.", err)
p.Stop()
return
}
@@ -199,6 +196,21 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
return p
}
+func (self *Peer) Connect(addr string) (conn net.Conn, err error) {
+ for attempts := 0; attempts < 5; attempts++ {
+ conn, err = net.DialTimeout("tcp", addr, 10*time.Second)
+ if err != nil {
+ peerlogger.Debugf("Peer connection failed. Retrying (%d/5)\n", attempts+1)
+ continue
+ }
+
+ // Success
+ return
+ }
+
+ return
+}
+
// Getters
func (p *Peer) PingTime() string {
return p.pingTime.String()
@@ -397,10 +409,7 @@ func (p *Peer) HandleInbound() {
for i := msg.Data.Len() - 1; i >= 0; i-- {
block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i))
- //p.ethereum.StateManager().PrepareDefault(block)
- //state := p.ethereum.StateManager().CurrentState()
err = p.ethereum.StateManager().Process(block, false)
-
if err != nil {
if ethutil.Config.Debug {
peerlogger.Infof("Block %x failed\n", block.Hash())
@@ -411,6 +420,8 @@ func (p *Peer) HandleInbound() {
} else {
lastBlock = block
}
+
+ p.lastBlockReceived = time.Now()
}
if msg.Data.Len() <= 1 {
@@ -463,30 +474,21 @@ func (p *Peer) HandleInbound() {
p.ethereum.TxPool().QueueTransaction(tx)
}
case ethwire.MsgGetPeersTy:
- // Flag this peer as a 'requested of new peers' this to
- // prevent malicious peers being forced.
- p.requestedPeerList = true
// Peer asked for list of connected peers
p.pushPeers()
case ethwire.MsgPeersTy:
// Received a list of peers (probably because MsgGetPeersTy was send)
- // Only act on message if we actually requested for a peers list
- if p.requestedPeerList {
- data := msg.Data
- // Create new list of possible peers for the ethereum to process
- peers := make([]string, data.Len())
- // Parse each possible peer
- for i := 0; i < data.Len(); i++ {
- value := data.Get(i)
- peers[i] = unpackAddr(value.Get(0), value.Get(1).Uint())
- }
-
- // Connect to the list of peers
- p.ethereum.ProcessPeerList(peers)
- // Mark unrequested again
- p.requestedPeerList = false
-
+ data := msg.Data
+ // Create new list of possible peers for the ethereum to process
+ peers := make([]string, data.Len())
+ // Parse each possible peer
+ for i := 0; i < data.Len(); i++ {
+ value := data.Get(i)
+ peers[i] = unpackAddr(value.Get(0), value.Get(1).Uint())
}
+
+ // Connect to the list of peers
+ p.ethereum.ProcessPeerList(peers)
case ethwire.MsgGetChainTy:
var parent *ethchain.Block
// Length minus one since the very last element in the array is a count
@@ -559,6 +561,25 @@ func (p *Peer) HandleInbound() {
p.Stop()
}
+// General update method
+func (self *Peer) update() {
+ serviceTimer := time.NewTicker(5 * time.Second)
+
+out:
+ for {
+ select {
+ case <-serviceTimer.C:
+ if time.Since(self.lastBlockReceived) > 10*time.Second {
+ self.catchingUp = false
+ }
+ case <-self.quit:
+ break out
+ }
+ }
+
+ serviceTimer.Stop()
+}
+
func (p *Peer) Start() {
peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String())
servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String())
@@ -581,6 +602,8 @@ func (p *Peer) Start() {
go p.HandleOutbound()
// Run the inbound handler in a new goroutine
go p.HandleInbound()
+ // Run the general update handler
+ go p.update()
// Wait a few seconds for startup and then ask for an initial ping
time.Sleep(2 * time.Second)
@@ -698,11 +721,13 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
ethlogger.Infof("Added peer (%s) %d / %d\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers)
- // Catch up with the connected peer
- if !p.ethereum.IsUpToDate() {
- peerlogger.Debugln("Already syncing up with a peer; sleeping")
- time.Sleep(10 * time.Second)
- }
+ /*
+ // Catch up with the connected peer
+ if !p.ethereum.IsUpToDate() {
+ peerlogger.Debugln("Already syncing up with a peer; sleeping")
+ time.Sleep(10 * time.Second)
+ }
+ */
p.SyncWithPeerToLastKnown()
peerlogger.Debugln(p)