diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index ecc121407..fd3e3020a 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -341,7 +341,7 @@ ApplicationWindow { } Label { - id: peerLabel + id: peerCounterLabel font.pixelSize: 10 text: "0 / 0" } @@ -926,7 +926,6 @@ ApplicationWindow { } } - function setWalletValue(value) { walletValueLabel.text = value } @@ -936,17 +935,11 @@ ApplicationWindow { var view = mainView.addPlugin(name) } - function setPeers(text) { - peerLabel.text = text - } + function clearPeers() { peerModel.clear() } + function addPeer(peer) { peerModel.append(peer) } - function addPeer(peer) { - // We could just append the whole peer object but it cries if you try to alter them - peerModel.append({ip: peer.ip, port: peer.port, lastResponse:timeAgo(peer.lastSend), latency: peer.latency, version: peer.version, caps: peer.caps}) - } - - function resetPeers(){ - peerModel.clear() + function setPeerCounters(text) { + peerCounterLabel.text = text } function timeAgo(unixTs){ @@ -984,9 +977,9 @@ ApplicationWindow { anchors.fill: parent id: peerTable model: peerModel - TableViewColumn{width: 200; role: "ip" ; title: "IP" } - TableViewColumn{width: 260; role: "version" ; title: "Version" } - TableViewColumn{width: 180; role: "caps" ; title: "Capabilities" } + TableViewColumn{width: 180; role: "addr" ; title: "Remote Address" } + TableViewColumn{width: 280; role: "nodeID" ; title: "Node ID" } + TableViewColumn{width: 180; role: "caps" ; title: "Capabilities" } } } } diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index c4ce1d463..208b553d2 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -31,6 +31,7 @@ import ( "os" "path" "runtime" + "sort" "strconv" "time" @@ -449,6 +450,7 @@ func (gui *Gui) update() { case <-peerUpdateTicker.C: gui.setPeerInfo() + case <-generalUpdateTicker.C: statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number().String() lastBlockLabel.Set("text", statusText) @@ -499,12 +501,34 @@ NumGC: %d )) } +type qmlpeer struct{ Addr, NodeID, Caps string } + +type peersByID []*qmlpeer + +func (s peersByID) Len() int { return len(s) } +func (s peersByID) Less(i, j int) bool { return s[i].NodeID < s[j].NodeID } +func (s peersByID) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + func (gui *Gui) setPeerInfo() { - gui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", gui.eth.PeerCount(), gui.eth.MaxPeers)) - gui.win.Root().Call("resetPeers") - //for _, peer := range gui.xeth.Peers() { - //gui.win.Root().Call("addPeer", peer) - //} + peers := gui.eth.Peers() + qpeers := make(peersByID, len(peers)) + for i, p := range peers { + qpeers[i] = &qmlpeer{ + NodeID: p.ID().String(), + Addr: p.RemoteAddr().String(), + Caps: fmt.Sprint(p.Caps()), + } + } + // we need to sort the peers because they jump around randomly + // otherwise. order returned by eth.Peers is random because they + // are taken from a map. + sort.Sort(qpeers) + + gui.win.Root().Call("setPeerCounters", fmt.Sprintf("%d / %d", len(peers), gui.eth.MaxPeers())) + gui.win.Root().Call("clearPeers") + for _, p := range qpeers { + gui.win.Root().Call("addPeer", p) + } } func (gui *Gui) privateKey() string { diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index ab48386f4..368fb002b 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -73,11 +73,6 @@ func (self *UiLib) Notef(args []interface{}) { guilogger.Infoln(args...) } -func (self *UiLib) PastPeers() *ethutil.List { - return ethutil.NewList([]string{}) - //return ethutil.NewList(eth.PastPeers()) -} - func (self *UiLib) ImportTx(rlpTx string) { tx := types.NewTransactionFromBytes(ethutil.Hex2Bytes(rlpTx)) err := self.eth.TxPool().Add(tx) diff --git a/p2p/protocol.go b/p2p/protocol.go index fe359fc54..5fa395eda 100644 --- a/p2p/protocol.go +++ b/p2p/protocol.go @@ -1,5 +1,7 @@ package p2p +import "fmt" + // Protocol represents a P2P subprotocol implementation. type Protocol struct { // Name should contain the official protocol name, @@ -37,6 +39,10 @@ func (cap Cap) RlpData() interface{} { return []interface{}{cap.Name, cap.Version} } +func (cap Cap) String() string { + return fmt.Sprintf("%s/%d", cap.Name, cap.Version) +} + type capsByName []Cap func (cs capsByName) Len() int { return len(cs) }