peer discovery enhancement for more info about connected peer
This commit is contained in:
parent
07245866bb
commit
7768107386
|
@ -4,7 +4,7 @@ import org.ethereum.core.Transaction;
|
|||
import org.ethereum.core.Wallet;
|
||||
import org.ethereum.listener.EthereumListener;
|
||||
import org.ethereum.net.client.PeerClient;
|
||||
import org.ethereum.net.peerdiscovery.PeerData;
|
||||
import org.ethereum.net.peerdiscovery.PeerInfo;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
|
@ -25,7 +25,7 @@ public interface Ethereum {
|
|||
* @param excludePeer - peer to exclude
|
||||
* @return online peer if available otherwise null
|
||||
*/
|
||||
public PeerData findOnlinePeer(PeerData excludePeer) ;
|
||||
public PeerInfo findOnlinePeer(PeerInfo excludePeer) ;
|
||||
|
||||
/**
|
||||
* Find an online peer but not from excluded list
|
||||
|
@ -33,12 +33,12 @@ public interface Ethereum {
|
|||
* @param excludePeerSet - peers to exclude
|
||||
* @return online peer if available otherwise null
|
||||
*/
|
||||
public PeerData findOnlinePeer(Set<PeerData> excludePeerSet) ;
|
||||
public PeerInfo findOnlinePeer(Set<PeerInfo> excludePeerSet) ;
|
||||
|
||||
/**
|
||||
* @return online peer if available
|
||||
*/
|
||||
public PeerData findOnlinePeer();
|
||||
public PeerInfo findOnlinePeer();
|
||||
|
||||
|
||||
/**
|
||||
|
@ -46,7 +46,7 @@ public interface Ethereum {
|
|||
*
|
||||
* @return online peer.
|
||||
*/
|
||||
public PeerData waitForOnlinePeer();
|
||||
public PeerInfo waitForOnlinePeer();
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -59,7 +59,7 @@ public interface Ethereum {
|
|||
* }
|
||||
*
|
||||
*/
|
||||
public Set<PeerData> getPeers();
|
||||
public Set<PeerInfo> getPeers();
|
||||
|
||||
public void startPeerDiscovery();
|
||||
public void stopPeerDiscovery();
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.ethereum.core.Wallet;
|
|||
import org.ethereum.listener.EthereumListener;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.net.client.PeerClient;
|
||||
import org.ethereum.net.peerdiscovery.PeerData;
|
||||
import org.ethereum.net.peerdiscovery.PeerInfo;
|
||||
import org.ethereum.net.submit.TransactionExecutor;
|
||||
import org.ethereum.net.submit.TransactionTask;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
|
@ -39,20 +39,20 @@ public class EthereumImpl implements Ethereum {
|
|||
* @return online peer
|
||||
*/
|
||||
@Override
|
||||
public PeerData findOnlinePeer(PeerData peer) {
|
||||
Set<PeerData> excludePeers = new HashSet<>();
|
||||
public PeerInfo findOnlinePeer(PeerInfo peer) {
|
||||
Set<PeerInfo> excludePeers = new HashSet<>();
|
||||
excludePeers.add(peer);
|
||||
return findOnlinePeer(excludePeers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeerData findOnlinePeer() {
|
||||
Set<PeerData> excludePeers = new HashSet<>();
|
||||
public PeerInfo findOnlinePeer() {
|
||||
Set<PeerInfo> excludePeers = new HashSet<>();
|
||||
return findOnlinePeer(excludePeers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeerData findOnlinePeer(Set<PeerData> excludePeers) {
|
||||
public PeerInfo findOnlinePeer(Set<PeerInfo> excludePeers) {
|
||||
logger.info("Looking for online peers...");
|
||||
|
||||
final EthereumListener listener = WorldManager.getInstance().getListener();
|
||||
|
@ -62,9 +62,9 @@ public class EthereumImpl implements Ethereum {
|
|||
|
||||
WorldManager.getInstance().startPeerDiscovery();
|
||||
|
||||
final Set<PeerData> peers = WorldManager.getInstance().getPeerDiscovery().getPeers();
|
||||
final Set<PeerInfo> peers = WorldManager.getInstance().getPeerDiscovery().getPeers();
|
||||
synchronized (peers) {
|
||||
for (PeerData peer : peers) { // it blocks until a peer is available.
|
||||
for (PeerInfo peer : peers) { // it blocks until a peer is available.
|
||||
if (peer.isOnline() && !excludePeers.contains(peer)) {
|
||||
logger.info("Found peer: {}", peer.toString());
|
||||
if (listener != null)
|
||||
|
@ -77,8 +77,8 @@ public class EthereumImpl implements Ethereum {
|
|||
}
|
||||
|
||||
@Override
|
||||
public PeerData waitForOnlinePeer() {
|
||||
PeerData peer = null;
|
||||
public PeerInfo waitForOnlinePeer() {
|
||||
PeerInfo peer = null;
|
||||
while (peer == null) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
|
@ -91,7 +91,7 @@ public class EthereumImpl implements Ethereum {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<PeerData> getPeers() {
|
||||
public Set<PeerInfo> getPeers() {
|
||||
return WorldManager.getInstance().getPeerDiscovery().getPeers();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,15 +10,15 @@ import org.ethereum.manager.WorldManager;
|
|||
import org.ethereum.net.MessageQueue;
|
||||
import org.ethereum.net.PeerListener;
|
||||
import org.ethereum.net.eth.EthHandler;
|
||||
import org.ethereum.net.eth.StatusMessage;
|
||||
import org.ethereum.net.p2p.HelloMessage;
|
||||
import org.ethereum.net.shh.ShhHandler;
|
||||
import org.ethereum.net.wire.MessageDecoder;
|
||||
import org.ethereum.net.wire.MessageEncoder;
|
||||
import org.ethereum.net.p2p.P2pHandler;
|
||||
import org.ethereum.net.peerdiscovery.PeerData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
|
@ -68,7 +68,7 @@ public class PeerClient {
|
|||
p2pHandler = new P2pHandler(peerListener, msgQueue);
|
||||
p2pHandler.activate();
|
||||
|
||||
ethHandler = new EthHandler(msgQueue, peerListener);
|
||||
ethHandler = new EthHandler(msgQueue, peerListener, peerDiscoveryMode);
|
||||
shhHandler = new ShhHandler(msgQueue, peerListener);
|
||||
|
||||
try {
|
||||
|
@ -144,4 +144,12 @@ public class PeerClient {
|
|||
return false;
|
||||
|
||||
}
|
||||
|
||||
public HelloMessage getHelloHandshake(){
|
||||
return p2pHandler.getHandshakeHelloMessage();
|
||||
}
|
||||
|
||||
public StatusMessage getStatusHandshake(){
|
||||
return ethHandler.getHandshakeStatusMessage();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.ethereum.net.eth;
|
||||
|
||||
import com.sun.org.apache.xerces.internal.util.Status;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import org.ethereum.core.Block;
|
||||
|
@ -51,13 +52,18 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
|||
|
||||
private SyncSatus syncStatus = SyncSatus.INIT;
|
||||
private boolean active = false;
|
||||
private StatusMessage handshakeStatusMessage = null;
|
||||
|
||||
private boolean peerDiscovery = true;
|
||||
|
||||
|
||||
private Timer getBlocksTimer = new Timer("GetBlocksTimer");
|
||||
|
||||
//
|
||||
private Timer getTxTimer = new Timer("GetTransactionsTimer");
|
||||
|
||||
public EthHandler(MessageQueue msgQueue, PeerListener peerListener) {
|
||||
public EthHandler(MessageQueue msgQueue, PeerListener peerListener, boolean peerDiscovery) {
|
||||
this.peerDiscovery = true;
|
||||
this.msgQueue = msgQueue;
|
||||
}
|
||||
|
||||
|
@ -156,7 +162,16 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
|||
* @param msg is the StatusMessage
|
||||
* @param ctx the ChannelHandlerContext
|
||||
*/
|
||||
public void processStatus(StatusMessage msg, ChannelHandlerContext ctx) {
|
||||
public void processStatus(StatusMessage msg, ChannelHandlerContext ctx) throws InterruptedException {
|
||||
|
||||
this.handshakeStatusMessage = msg;
|
||||
if (peerDiscovery) {
|
||||
msgQueue.sendMessage(new DisconnectMessage(ReasonCode.REQUESTED));
|
||||
killTimers();
|
||||
ctx.close().sync();
|
||||
ctx.disconnect().sync();
|
||||
return;
|
||||
}
|
||||
|
||||
Blockchain blockchain = WorldManager.getInstance().getBlockchain();
|
||||
|
||||
|
@ -382,4 +397,8 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
|||
BLOCK_RETRIEVING,
|
||||
SYNC_DONE;
|
||||
}
|
||||
|
||||
public StatusMessage getHandshakeStatusMessage(){
|
||||
return handshakeStatusMessage;
|
||||
}
|
||||
}
|
|
@ -6,12 +6,7 @@ import static org.ethereum.net.message.StaticMessages.HELLO_MESSAGE;
|
|||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.*;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
|
@ -24,9 +19,9 @@ import org.ethereum.net.client.Capability;
|
|||
import org.ethereum.net.eth.EthHandler;
|
||||
import org.ethereum.net.eth.EthMessageCodes;
|
||||
import org.ethereum.net.eth.TransactionsMessage;
|
||||
import org.ethereum.net.peerdiscovery.PeerInfo;
|
||||
import org.ethereum.net.shh.ShhHandler;
|
||||
import org.ethereum.net.message.*;
|
||||
import org.ethereum.net.peerdiscovery.PeerData;
|
||||
import org.ethereum.net.shh.ShhMessageCodes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -58,9 +53,10 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
|||
private boolean tearDown = false;
|
||||
|
||||
private boolean active = false;
|
||||
|
||||
private boolean peerDiscoveryMode = false;
|
||||
|
||||
private HelloMessage handshakeHelloMessage = null;
|
||||
|
||||
public P2pHandler(MessageQueue msgQueue) {
|
||||
this.msgQueue = msgQueue;
|
||||
}
|
||||
|
@ -103,8 +99,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
|||
switch (msg.getCommand()) {
|
||||
case HELLO:
|
||||
msgQueue.receivedMessage(msg);
|
||||
if (!peerDiscoveryMode)
|
||||
setHandshake((HelloMessage) msg, ctx);
|
||||
setHandshake((HelloMessage) msg, ctx);
|
||||
sendGetPeers();
|
||||
break;
|
||||
case DISCONNECT:
|
||||
|
@ -125,7 +120,8 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
|||
msgQueue.receivedMessage(msg);
|
||||
processPeers(ctx, (PeersMessage) msg);
|
||||
|
||||
if (peerDiscoveryMode){
|
||||
if (peerDiscoveryMode &&
|
||||
!handshakeHelloMessage.getCapabilities().contains(Capability.ETH)){
|
||||
msgQueue.sendMessage(new DisconnectMessage(ReasonCode.REQUESTED));
|
||||
killTimers();
|
||||
ctx.close().sync();
|
||||
|
@ -167,13 +163,21 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
|||
}
|
||||
|
||||
private void sendPeers() {
|
||||
Set<PeerData> peers = WorldManager.getInstance().getPeerDiscovery().getPeers();
|
||||
PeersMessage msg = new PeersMessage(peers);
|
||||
Set<PeerInfo> peers = WorldManager.getInstance().getPeerDiscovery().getPeers();
|
||||
|
||||
Set<Peer> peerSet = new HashSet<>();
|
||||
for (PeerInfo peer : peers){
|
||||
new Peer(peer.getAddress(), peer.getPort(), peer.getPeerId());
|
||||
}
|
||||
|
||||
PeersMessage msg = new PeersMessage(peerSet);
|
||||
msgQueue.sendMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
private void setHandshake(HelloMessage msg, ChannelHandlerContext ctx) {
|
||||
|
||||
this.handshakeHelloMessage = msg;
|
||||
if (msg.getP2PVersion() != P2pHandler.VERSION)
|
||||
msgQueue.sendMessage(new DisconnectMessage(ReasonCode.INCOMPATIBLE_PROTOCOL));
|
||||
else {
|
||||
|
@ -205,7 +209,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
|||
|
||||
InetAddress address = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress();
|
||||
int port = msg.getListenPort();
|
||||
PeerData confirmedPeer = new PeerData(address, port, msg.getPeerId());
|
||||
PeerInfo confirmedPeer = new PeerInfo(address, port, msg.getPeerId());
|
||||
confirmedPeer.setOnline(true);
|
||||
confirmedPeer.getCapabilities().addAll(msg.getCapabilities());
|
||||
|
||||
|
@ -243,6 +247,10 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
|||
}
|
||||
}
|
||||
|
||||
public HelloMessage getHandshakeHelloMessage() {
|
||||
return handshakeHelloMessage;
|
||||
}
|
||||
|
||||
private void startTimers() {
|
||||
// sample for pinging in background
|
||||
|
||||
|
@ -268,4 +276,6 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
|||
msgQueue.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.ethereum.net.peerdiscovery;
|
||||
package org.ethereum.net.p2p;
|
||||
|
||||
import org.ethereum.net.client.Capability;
|
||||
import org.ethereum.util.RLP;
|
||||
|
@ -11,7 +11,7 @@ import java.util.List;
|
|||
/**
|
||||
* This class models a peer in the network
|
||||
*/
|
||||
public class PeerData {
|
||||
public class Peer {
|
||||
|
||||
private InetAddress address;
|
||||
private int port;
|
||||
|
@ -19,10 +19,7 @@ public class PeerData {
|
|||
|
||||
private List<Capability> capabilities;
|
||||
|
||||
private transient boolean isOnline = false;
|
||||
private transient long lastCheckTime = 0;
|
||||
|
||||
public PeerData(InetAddress ip, int port, String peerId) {
|
||||
public Peer(InetAddress ip, int port, String peerId) {
|
||||
this.address = ip;
|
||||
this.port = port;
|
||||
this.peerId = peerId;
|
||||
|
@ -41,24 +38,6 @@ public class PeerData {
|
|||
return peerId == null ? "" : peerId;
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
if (getCapabilities().size() < 0)
|
||||
return false;
|
||||
return isOnline;
|
||||
}
|
||||
|
||||
public void setOnline(boolean online) {
|
||||
isOnline = online;
|
||||
}
|
||||
|
||||
public long getLastCheckTime() {
|
||||
return lastCheckTime;
|
||||
}
|
||||
|
||||
public void setLastCheckTime(long lastCheckTime) {
|
||||
this.lastCheckTime = lastCheckTime;
|
||||
}
|
||||
|
||||
public List<Capability> getCapabilities() {
|
||||
return capabilities;
|
||||
}
|
||||
|
@ -86,7 +65,7 @@ public class PeerData {
|
|||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) return false;
|
||||
PeerData peerData = (PeerData) obj;
|
||||
Peer peerData = (Peer) obj;
|
||||
return peerData.peerId.equals(this.peerId)
|
||||
|| this.getAddress().equals(peerData.getAddress());
|
||||
}
|
|
@ -8,7 +8,7 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import org.ethereum.net.p2p.P2pMessage;
|
||||
import org.ethereum.net.peerdiscovery.PeerData;
|
||||
import org.ethereum.net.p2p.Peer;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.ethereum.util.RLP;
|
||||
import org.ethereum.util.RLPList;
|
||||
|
@ -23,13 +23,13 @@ public class PeersMessage extends P2pMessage {
|
|||
|
||||
private boolean parsed = false;
|
||||
|
||||
private Set<PeerData> peers;
|
||||
private Set<Peer> peers;
|
||||
|
||||
public PeersMessage(byte[] payload) {
|
||||
super(payload);
|
||||
}
|
||||
|
||||
public PeersMessage(Set<PeerData> peers) {
|
||||
public PeersMessage(Set<Peer> peers) {
|
||||
this.peers = peers;
|
||||
parsed = true;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class PeersMessage extends P2pMessage {
|
|||
InetAddress address = InetAddress.getByAddress(ipBytes);
|
||||
|
||||
String peerId = peerIdRaw == null ? "" : Hex.toHexString(peerIdRaw);
|
||||
PeerData peer = new PeerData(address, peerPort, peerId);
|
||||
Peer peer = new Peer(address, peerPort, peerId);
|
||||
peers.add(peer);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException("Malformed ip", e);
|
||||
|
@ -61,7 +61,7 @@ public class PeersMessage extends P2pMessage {
|
|||
private void encode() {
|
||||
byte[][] encodedByteArrays = new byte[this.peers.size() + 1][];
|
||||
encodedByteArrays[0] = RLP.encodeByte(this.getCommand().asByte());
|
||||
List<PeerData> peerList = new ArrayList<>(this.peers);
|
||||
List<Peer> peerList = new ArrayList<>(this.peers);
|
||||
for (int i = 0; i < peerList.size(); i++) {
|
||||
encodedByteArrays[i + 1] = peerList.get(i).getEncoded();
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public class PeersMessage extends P2pMessage {
|
|||
return encoded;
|
||||
}
|
||||
|
||||
public Set<PeerData> getPeers() {
|
||||
public Set<Peer> getPeers() {
|
||||
if (!parsed) this.parse();
|
||||
return peers;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public class PeersMessage extends P2pMessage {
|
|||
if (!parsed) this.parse();
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (PeerData peerData : peers) {
|
||||
for (Peer peerData : peers) {
|
||||
sb.append("\n ").append(peerData);
|
||||
}
|
||||
return "[" + this.getCommand().name() + sb.toString() + "]";
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.ethereum.net.peerdiscovery;
|
||||
|
||||
import org.ethereum.net.p2p.Peer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -19,7 +20,7 @@ public class PeerDiscovery {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger("peerdiscovery");
|
||||
|
||||
private final Set<PeerData> peers = Collections.synchronizedSet(new HashSet<PeerData>());
|
||||
private final Set<PeerInfo> peers = Collections.synchronizedSet(new HashSet<PeerInfo>());
|
||||
|
||||
private PeerMonitorThread monitor;
|
||||
private ThreadFactory threadFactory;
|
||||
|
@ -47,10 +48,10 @@ public class PeerDiscovery {
|
|||
monitorThread.start();
|
||||
|
||||
// Initialize PeerData
|
||||
List<PeerData> peerDataList = parsePeerDiscoveryIpList(CONFIG.peerDiscoveryIPList());
|
||||
List<PeerInfo> peerDataList = parsePeerDiscoveryIpList(CONFIG.peerDiscoveryIPList());
|
||||
peers.addAll(peerDataList);
|
||||
|
||||
for (PeerData peerData : this.peers) {
|
||||
for (PeerInfo peerData : this.peers) {
|
||||
executorPool.execute(new WorkerThread(peerData, executorPool));
|
||||
}
|
||||
|
||||
|
@ -67,7 +68,7 @@ public class PeerDiscovery {
|
|||
return started.get();
|
||||
}
|
||||
|
||||
public Set<PeerData> getPeers() {
|
||||
public Set<PeerInfo> getPeers() {
|
||||
return peers;
|
||||
}
|
||||
|
||||
|
@ -77,26 +78,28 @@ public class PeerDiscovery {
|
|||
*
|
||||
* @param newPeers to be added to the list of known peers
|
||||
*/
|
||||
public void addPeers(final Set<PeerData> newPeers) {
|
||||
public void addPeers(Set<Peer> newPeers) {
|
||||
synchronized (peers) {
|
||||
for (final PeerData newPeer : newPeers) {
|
||||
if (started.get() && !peers.contains(newPeer)){
|
||||
startWorker(newPeer);
|
||||
for (final Peer newPeer : newPeers) {
|
||||
PeerInfo peerInfo =
|
||||
new PeerInfo(newPeer.getAddress(), newPeer.getPort(), newPeer.getPeerId());
|
||||
if (started.get() && !peers.contains(peerInfo )){
|
||||
startWorker(peerInfo);
|
||||
}
|
||||
peers.add(newPeer);
|
||||
peers.add(peerInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startWorker(PeerData peer) {
|
||||
private void startWorker(PeerInfo peer) {
|
||||
logger.debug("Add new peer for discovery: {}", peer);
|
||||
executorPool.execute(new WorkerThread(peer, executorPool));
|
||||
}
|
||||
|
||||
public List<PeerData> parsePeerDiscoveryIpList(final String peerDiscoveryIpList){
|
||||
public List<PeerInfo> parsePeerDiscoveryIpList(final String peerDiscoveryIpList){
|
||||
|
||||
final List<String> ipList = Arrays.asList( peerDiscoveryIpList.split(",") );
|
||||
final List<PeerData> peers = new ArrayList<>();
|
||||
final List<PeerInfo> peers = new ArrayList<>();
|
||||
|
||||
for (String ip : ipList){
|
||||
String[] addr = ip.trim().split(":");
|
||||
|
@ -107,7 +110,7 @@ public class PeerDiscovery {
|
|||
InetAddress iAddr = InetAddress.getByName(ip_trim);
|
||||
int port = Integer.parseInt(port_trim);
|
||||
|
||||
PeerData peerData = new PeerData(iAddr, port, "");
|
||||
PeerInfo peerData = new PeerInfo(iAddr, port, "");
|
||||
peers.add(peerData);
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package org.ethereum.net.peerdiscovery;
|
||||
|
||||
import org.ethereum.net.client.Capability;
|
||||
import org.ethereum.net.eth.StatusMessage;
|
||||
import org.ethereum.net.p2p.HelloMessage;
|
||||
import org.ethereum.util.RLP;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class models a peer in the network
|
||||
*/
|
||||
public class PeerInfo {
|
||||
|
||||
private InetAddress address;
|
||||
private int port;
|
||||
private String peerId;
|
||||
|
||||
private List<Capability> capabilities;
|
||||
private HelloMessage handshakeHelloMessage;
|
||||
private StatusMessage statusMessage;
|
||||
|
||||
private transient boolean isOnline = false;
|
||||
private transient long lastCheckTime = 0;
|
||||
|
||||
public PeerInfo(InetAddress ip, int port, String peerId) {
|
||||
this.address = ip;
|
||||
this.port = port;
|
||||
this.peerId = peerId;
|
||||
this.capabilities = new ArrayList<>();
|
||||
}
|
||||
|
||||
public InetAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public String getPeerId() {
|
||||
return peerId == null ? "" : peerId;
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
if (getCapabilities().size() < 0)
|
||||
return false;
|
||||
return isOnline;
|
||||
}
|
||||
|
||||
public void setOnline(boolean online) {
|
||||
isOnline = online;
|
||||
}
|
||||
|
||||
public long getLastCheckTime() {
|
||||
return lastCheckTime;
|
||||
}
|
||||
|
||||
public void setLastCheckTime(long lastCheckTime) {
|
||||
this.lastCheckTime = lastCheckTime;
|
||||
}
|
||||
|
||||
public List<Capability> getCapabilities() {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("PeerInfo: [ ip=").append(getAddress().getHostAddress())
|
||||
.append(" port=").append(getPort())
|
||||
.append(" peerId=").append(getPeerId()).append("] \n")
|
||||
.append(this.handshakeHelloMessage == null ? "" : handshakeHelloMessage + "\n")
|
||||
.append(this.statusMessage == null ? "" : statusMessage + "\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) return false;
|
||||
PeerInfo peerData = (PeerInfo) obj;
|
||||
return peerData.peerId.equals(this.peerId)
|
||||
|| this.getAddress().equals(peerData.getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return -1; // override for equals function
|
||||
}
|
||||
|
||||
public HelloMessage getHandshakeHelloMessage() {
|
||||
return handshakeHelloMessage;
|
||||
}
|
||||
|
||||
public void setHandshakeHelloMessage(HelloMessage handshakeHelloMessage) {
|
||||
this.handshakeHelloMessage = handshakeHelloMessage;
|
||||
}
|
||||
|
||||
public StatusMessage getStatusMessage() {
|
||||
return statusMessage;
|
||||
}
|
||||
|
||||
public void setStatusMessage(StatusMessage statusMessage) {
|
||||
this.statusMessage = statusMessage;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package org.ethereum.net.peerdiscovery;
|
||||
|
||||
import org.ethereum.net.client.PeerClient;
|
||||
import org.ethereum.net.peerdiscovery.PeerData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -15,12 +14,12 @@ public class WorkerThread implements Runnable {
|
|||
|
||||
private final static Logger logger = LoggerFactory.getLogger("peerdiscovery");
|
||||
|
||||
private PeerData peer;
|
||||
private PeerInfo peerInfo;
|
||||
private PeerClient clientPeer;
|
||||
private ThreadPoolExecutor poolExecutor;
|
||||
|
||||
public WorkerThread(PeerData peer, ThreadPoolExecutor poolExecutor) {
|
||||
this.peer = peer;
|
||||
public WorkerThread(PeerInfo peer, ThreadPoolExecutor poolExecutor) {
|
||||
this.peerInfo = peer;
|
||||
this.poolExecutor = poolExecutor;
|
||||
}
|
||||
|
||||
|
@ -37,26 +36,29 @@ public class WorkerThread implements Runnable {
|
|||
|
||||
try {
|
||||
clientPeer = new PeerClient(true);
|
||||
clientPeer.connect(peer.getAddress().getHostAddress(), peer.getPort());
|
||||
peer.setOnline(true);
|
||||
logger.info("Peer is online: [{}] ", peer
|
||||
.getAddress().getHostAddress());
|
||||
clientPeer.connect(peerInfo.getAddress().getHostAddress(), peerInfo.getPort());
|
||||
peerInfo.setOnline(true);
|
||||
|
||||
peerInfo.setHandshakeHelloMessage(clientPeer.getHelloHandshake());
|
||||
peerInfo.setStatusMessage( clientPeer.getStatusHandshake() );
|
||||
|
||||
logger.info("Peer is online: [{}] ", peerInfo);
|
||||
|
||||
} catch (Throwable e) {
|
||||
if (peer.isOnline())
|
||||
logger.info("Peer: [{}] went offline, due to: [{}]", peer
|
||||
if (peerInfo.isOnline())
|
||||
logger.info("Peer: [{}] went offline, due to: [{}]", peerInfo
|
||||
.getAddress().getHostAddress(), e);
|
||||
peer.setOnline(false);
|
||||
peerInfo.setOnline(false);
|
||||
} finally {
|
||||
logger.info("Peer: " + peer.toString() + " is "
|
||||
+ (peer.isOnline() ? "online" : "offline"));
|
||||
peer.setLastCheckTime(System.currentTimeMillis());
|
||||
logger.info("Peer: " + peerInfo.toString() + " is "
|
||||
+ (peerInfo.isOnline() ? "online" : "offline"));
|
||||
peerInfo.setLastCheckTime(System.currentTimeMillis());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Worker for: " + this.peer.toString();
|
||||
return "Worker for: " + this.peerInfo.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,9 @@ import java.util.Set;
|
|||
|
||||
import org.ethereum.net.p2p.GetPeersMessage;
|
||||
import org.ethereum.net.p2p.P2pMessageCodes;
|
||||
import org.ethereum.net.p2p.Peer;
|
||||
import org.ethereum.net.p2p.PeersMessage;
|
||||
import org.ethereum.net.peerdiscovery.PeerData;
|
||||
import org.ethereum.net.peerdiscovery.PeerInfo;
|
||||
import org.junit.Test;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
|
@ -51,8 +52,8 @@ public class PeersMessageTest {
|
|||
|
||||
assertEquals(2, peersMessage.getPeers().size());
|
||||
|
||||
Iterator<PeerData> it = peersMessage.getPeers().iterator(); it.next();
|
||||
PeerData peer = it.next();
|
||||
Iterator<Peer> it = peersMessage.getPeers().iterator(); it.next();
|
||||
Peer peer = it.next();
|
||||
|
||||
assertEquals(P2pMessageCodes.PEERS, peersMessage.getCommand());
|
||||
assertEquals("/81.99.225.18", peer.getAddress().toString());
|
||||
|
@ -63,9 +64,9 @@ public class PeersMessageTest {
|
|||
|
||||
@Test /* PeersMessage 2 from constructor */
|
||||
public void testPeers_2() throws UnknownHostException {
|
||||
Set<PeerData> peers = new HashSet<>();
|
||||
peers.add(new PeerData(InetAddress.getByName("82.217.72.169"), 30303, "585764a3c49a3838c69ad0855abfeb5672f71b072af62082b5679961781100814b8de88a8fbc1da7c73791f88159d73b5d2a13a5579535d603e045c3db5cbb75"));
|
||||
peers.add(new PeerData(InetAddress.getByName("192.168.1.193"), 30303, ""));
|
||||
Set<Peer> peers = new HashSet<>();
|
||||
peers.add(new Peer(InetAddress.getByName("82.217.72.169"), 30303, "585764a3c49a3838c69ad0855abfeb5672f71b072af62082b5679961781100814b8de88a8fbc1da7c73791f88159d73b5d2a13a5579535d603e045c3db5cbb75"));
|
||||
peers.add(new Peer(InetAddress.getByName("192.168.1.193"), 30303, ""));
|
||||
PeersMessage peersMessage = new PeersMessage(peers);
|
||||
System.out.println(peersMessage.toString());
|
||||
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package org.ethereum.gui;
|
||||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.net.PeerListener;
|
||||
import org.ethereum.net.client.PeerClient;
|
||||
import org.fife.ui.rsyntaxtextarea.*;
|
||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
|
||||
/**
|
||||
* A simple example showing how to modify the fonts and colors used in an
|
||||
* RSyntaxTextArea. There are two methods to do this - via the Java API, and via
|
||||
* an XML file. The latter method is preferred since it's more modular, and
|
||||
* provides a way for your users to customize RSTA in your application.<p>
|
||||
*
|
||||
* This example uses RSyntaxTextArea 2.0.1.<p>
|
||||
*
|
||||
* Project Home: http://fifesoft.com/rsyntaxtextarea<br>
|
||||
* Downloads: https://sourceforge.net/projects/rsyntaxtextarea
|
||||
*/
|
||||
public class PeerInfoWindow extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private boolean autoScroll = false;
|
||||
private RSyntaxTextArea textArea;
|
||||
private ToolBar toolBar = null;
|
||||
|
||||
/**
|
||||
* ERROR (exceptions) WARN (when something happens that's not supposed to)
|
||||
* INFO (wire output)
|
||||
* DEBUG (test/displaying intermediate values),
|
||||
* TRACE (start/end method)
|
||||
*/
|
||||
public PeerInfoWindow(PeersTableModel.PeerInfo peerInfo) {
|
||||
final PeerInfoWindow thisConsole = this;
|
||||
|
||||
java.net.URL url = ClassLoader.getSystemResource("ethereum-icon.png");
|
||||
Toolkit kit = Toolkit.getDefaultToolkit();
|
||||
Image img = kit.createImage(url);
|
||||
this.setIconImage(img);
|
||||
addCloseAction();
|
||||
|
||||
JPanel cp = new JPanel(new BorderLayout());
|
||||
|
||||
AbstractTokenMakerFactory atmf = (AbstractTokenMakerFactory) TokenMakerFactory.getDefaultInstance();
|
||||
atmf.putMapping("text/console", "org.ethereum.gui.ConsoleTokenMaker");
|
||||
|
||||
textArea = new RSyntaxTextArea(16, 44);
|
||||
textArea.setSyntaxEditingStyle("text/console");
|
||||
// textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_LISP);
|
||||
textArea.setCodeFoldingEnabled(true);
|
||||
textArea.setAntiAliasingEnabled(true);
|
||||
|
||||
RTextScrollPane sp = new RTextScrollPane(textArea);
|
||||
textArea.setText(peerInfo.toString());
|
||||
|
||||
cp.add(sp);
|
||||
|
||||
setContentPane(cp);
|
||||
setTitle("Connection Console");
|
||||
// setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
pack();
|
||||
setLocation(802, 460);
|
||||
|
||||
if (CONFIG.peerDiscovery())
|
||||
UIEthereumManager.ethereum.startPeerDiscovery();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void addCloseAction() {
|
||||
this.addWindowListener(new WindowAdapter() {
|
||||
});
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Start all Swing applications on the EDT.
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
new PeerInfoWindow(null).setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -10,7 +10,10 @@ import javax.swing.table.AbstractTableModel;
|
|||
|
||||
|
||||
import org.ethereum.geo.IpGeoDB;
|
||||
import org.ethereum.net.peerdiscovery.PeerData;
|
||||
|
||||
import org.ethereum.net.eth.StatusMessage;
|
||||
import org.ethereum.net.p2p.HelloMessage;
|
||||
import org.ethereum.net.peerdiscovery.PeerInfo;
|
||||
import org.ethereum.util.Utils;
|
||||
|
||||
import com.maxmind.geoip.Location;
|
||||
|
@ -110,29 +113,37 @@ public class PeersTableModel extends AbstractTableModel {
|
|||
synchronized (peerInfoList) {
|
||||
peerInfoList.clear();
|
||||
|
||||
final Set<PeerData> peers = UIEthereumManager.ethereum.getPeers();
|
||||
final Set<org.ethereum.net.peerdiscovery.PeerInfo> peers = UIEthereumManager.ethereum.getPeers();
|
||||
|
||||
synchronized (peers){
|
||||
|
||||
for (PeerData peer : peers) {
|
||||
for (org.ethereum.net.peerdiscovery.PeerInfo peer : peers) {
|
||||
InetAddress addr = peer.getAddress();
|
||||
Location cr = IpGeoDB.getLocationForIp(addr);
|
||||
peerInfoList.add(new PeerInfo(cr, addr, peer.isOnline(), peer.getLastCheckTime()));
|
||||
peerInfoList.add(new PeerInfo(cr, addr, peer.isOnline(), peer.getLastCheckTime(),
|
||||
peer.getHandshakeHelloMessage(), peer.getStatusMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PeerInfo {
|
||||
public PeerInfo getPeerInfo(int index){
|
||||
return peerInfoList.get(index);
|
||||
}
|
||||
|
||||
|
||||
public class PeerInfo {
|
||||
|
||||
Location location;
|
||||
InetAddress ip;
|
||||
boolean connected;
|
||||
long lastAccessed = 0;
|
||||
|
||||
HelloMessage handshakeHelloMessage;
|
||||
StatusMessage handshakeStatusMessage;
|
||||
|
||||
private PeerInfo(Location location, InetAddress ip,
|
||||
boolean isConnected, long lastAccessed) {
|
||||
boolean isConnected, long lastAccessed, HelloMessage helloMessage, StatusMessage statusMessage) {
|
||||
|
||||
if (location == null)
|
||||
this.location = new Location();
|
||||
|
@ -142,6 +153,8 @@ public class PeersTableModel extends AbstractTableModel {
|
|||
this.ip = ip;
|
||||
this.connected = isConnected;
|
||||
this.lastAccessed = lastAccessed;
|
||||
this.handshakeHelloMessage = helloMessage;
|
||||
this.handshakeStatusMessage = statusMessage;
|
||||
}
|
||||
|
||||
private Location getLocation() {
|
||||
|
@ -159,6 +172,17 @@ public class PeersTableModel extends AbstractTableModel {
|
|||
public long getLastAccessed() {
|
||||
return lastAccessed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PeerInfo{" +
|
||||
"location=" + location.city +
|
||||
", ip=" + ip +
|
||||
", connected=" + connected +
|
||||
", lastAccessed=" + lastAccessed +
|
||||
'}' + "\n -->" + (handshakeHelloMessage == null ?"": handshakeHelloMessage.toString())
|
||||
+ "\n -->" + (handshakeStatusMessage == null?"": handshakeStatusMessage.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package org.ethereum.gui;
|
||||
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.Timer;
|
||||
|
@ -55,6 +59,24 @@ public class PeersTableWindow extends JFrame {
|
|||
table = new JTable();
|
||||
table.setModel(new PeersTableModel());
|
||||
|
||||
table.addMouseListener(new MouseAdapter() {
|
||||
public void mousePressed(MouseEvent me) {
|
||||
JTable table =(JTable) me.getSource();
|
||||
Point p = me.getPoint();
|
||||
int row = table.rowAtPoint(p);
|
||||
PeersTableModel model = (PeersTableModel) table.getModel();
|
||||
if (me.getClickCount() == 2) {
|
||||
final PeersTableModel.PeerInfo peerInfo = model.getPeerInfo(row);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
new PeerInfoWindow(peerInfo).setVisible(true);
|
||||
}
|
||||
});
|
||||
System.out.println(peerInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
table.setFont(new Font("Courier New", Font.PLAIN, 15));
|
||||
table.setForeground(Color.GRAY);
|
||||
table.setTableHeader(null);
|
||||
|
|
Loading…
Reference in New Issue