From fb6ff61730ed92ada68c9c5a5b3a6f9976a78161 Mon Sep 17 00:00:00 2001
From: Maran <maran.hidskes@gmail.com>
Date: Mon, 2 Jun 2014 15:20:27 +0200
Subject: [PATCH] Implemented Public Peer interface

---
 ethchain/state_manager.go | 12 +++++++++++
 ethpub/pub.go             | 13 ++++++++++++
 ethpub/types.go           | 30 +++++++++++++++++++++++++++-
 peer.go                   | 42 ++++++++++++++++++++++++++++++++++-----
 4 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index a57377bee..8479e9f44 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -2,6 +2,7 @@ package ethchain
 
 import (
 	"bytes"
+	"container/list"
 	"fmt"
 	"github.com/ethereum/eth-go/ethutil"
 	"github.com/ethereum/eth-go/ethwire"
@@ -14,6 +15,16 @@ type BlockProcessor interface {
 	ProcessBlock(block *Block)
 }
 
+type Peer interface {
+	Inbound() bool
+	LastSend() time.Time
+	LastPong() int64
+	Host() []byte
+	Port() uint16
+	Version() string
+	Connected() *int32
+}
+
 type EthManager interface {
 	StateManager() *StateManager
 	BlockChain() *BlockChain
@@ -23,6 +34,7 @@ type EthManager interface {
 	PeerCount() int
 	IsMining() bool
 	IsListening() bool
+	Peers() *list.List
 }
 
 type StateManager struct {
diff --git a/ethpub/pub.go b/ethpub/pub.go
index a9a962f14..6d4c230ad 100644
--- a/ethpub/pub.go
+++ b/ethpub/pub.go
@@ -6,6 +6,7 @@ import (
 	"github.com/ethereum/eth-go/ethutil"
 	"math/big"
 	"strings"
+	"sync/atomic"
 )
 
 type PEthereum struct {
@@ -51,6 +52,18 @@ func (lib *PEthereum) GetPeerCount() int {
 	return lib.manager.PeerCount()
 }
 
+func (lib *PEthereum) GetPeers() []PPeer {
+	var peers []PPeer
+	for peer := lib.manager.Peers().Front(); peer != nil; peer = peer.Next() {
+		p := peer.Value.(ethchain.Peer)
+		if atomic.LoadInt32(p.Connected()) != 0 {
+			peers = append(peers, *NewPPeer(p))
+		}
+	}
+
+	return peers
+}
+
 func (lib *PEthereum) GetIsMining() bool {
 	return lib.manager.IsMining()
 }
diff --git a/ethpub/types.go b/ethpub/types.go
index 4e7c44ed4..1079f09b4 100644
--- a/ethpub/types.go
+++ b/ethpub/types.go
@@ -3,12 +3,40 @@ package ethpub
 import (
 	"encoding/hex"
 	"encoding/json"
+	"fmt"
 	"github.com/ethereum/eth-go/ethchain"
 	"github.com/ethereum/eth-go/ethutil"
-	_ "log"
 	"strings"
 )
 
+// Peer interface exposed to QML
+
+type PPeer struct {
+	ref          *ethchain.Peer
+	Inbound      bool   `json:"isInbound"`
+	LastSend     int64  `json:"lastSend"`
+	LastPong     int64  `json:"lastPong"`
+	Ip           string `json:"ip"`
+	Port         int    `json:"port"`
+	Version      string `json:"version"`
+	LastResponse string `json:"lastResponse"`
+}
+
+func NewPPeer(peer ethchain.Peer) *PPeer {
+	if peer == nil {
+		return nil
+	}
+
+	// TODO: There must be something build in to do this?
+	var ip []string
+	for _, i := range peer.Host() {
+		ip = append(ip, fmt.Sprintf("%d", i))
+	}
+	ipAddress := strings.Join(ip, ".")
+
+	return &PPeer{ref: &peer, Inbound: peer.Inbound(), LastSend: peer.LastSend().Unix(), LastPong: peer.LastPong(), Version: peer.Version(), Ip: ipAddress, Port: int(peer.Port())}
+}
+
 // Block interface exposed to QML
 type PBlock struct {
 	ref          *ethchain.Block
diff --git a/peer.go b/peer.go
index 6853a949d..71ad91461 100644
--- a/peer.go
+++ b/peer.go
@@ -129,7 +129,7 @@ type Peer struct {
 	diverted        bool
 	blocksRequested int
 
-	Version string
+	version string
 }
 
 func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
@@ -160,7 +160,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
 		connected:   0,
 		disconnect:  0,
 		caps:        caps,
-		Version:     ethutil.Config.ClientString,
+		version:     ethutil.Config.ClientString,
 	}
 
 	// Set up the connection in another goroutine so we don't block the main thread
@@ -184,6 +184,34 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
 	return p
 }
 
+// Getters
+func (p *Peer) Inbound() bool {
+	return p.inbound
+}
+func (p *Peer) LastSend() time.Time {
+	return p.lastSend
+}
+func (p *Peer) LastPong() int64 {
+	return p.lastPong
+}
+func (p *Peer) Host() []byte {
+	return p.host
+}
+func (p *Peer) Port() uint16 {
+	return p.port
+}
+func (p *Peer) Version() string {
+	return p.version
+}
+func (p *Peer) Connected() *int32 {
+	return &p.connected
+}
+
+// Setters
+func (p *Peer) SetVersion(version string) {
+	p.version = version
+}
+
 // Outputs any RLP encoded data to the peer
 func (p *Peer) QueueMessage(msg *ethwire.Msg) {
 	if atomic.LoadInt32(&p.connected) != 1 {
@@ -531,7 +559,7 @@ func (p *Peer) pushHandshake() error {
 		pubkey := keyRing.PublicKey
 
 		msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{
-			uint32(ProtocolVersion), uint32(0), p.Version, byte(p.caps), p.port, pubkey[1:],
+			uint32(ProtocolVersion), uint32(0), p.version, byte(p.caps), p.port, pubkey[1:],
 		})
 
 		p.QueueMessage(msg)
@@ -588,8 +616,12 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
 
 	// Set the peer's caps
 	p.caps = Caps(c.Get(3).Byte())
+
 	// Get a reference to the peers version
-	p.Version = c.Get(2).Str()
+	versionString := c.Get(2).Str()
+	if len(versionString) > 0 {
+		p.SetVersion(c.Get(2).Str())
+	}
 
 	// Catch up with the connected peer
 	if !p.ethereum.IsUpToDate() {
@@ -615,7 +647,7 @@ func (p *Peer) String() string {
 		strConnectType = "disconnected"
 	}
 
-	return fmt.Sprintf("[%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.Version, p.caps)
+	return fmt.Sprintf("[%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.version, p.caps)
 
 }
 func (p *Peer) SyncWithPeerToLastKnown() {
-- 
GitLab