diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java index 6a5b1f1b..961e92e8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java @@ -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 excludePeerSet) ; + public PeerInfo findOnlinePeer(Set 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 getPeers(); + public Set getPeers(); public void startPeerDiscovery(); public void stopPeerDiscovery(); diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index 81a9b9c0..9bfc0a78 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -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 excludePeers = new HashSet<>(); + public PeerInfo findOnlinePeer(PeerInfo peer) { + Set excludePeers = new HashSet<>(); excludePeers.add(peer); return findOnlinePeer(excludePeers); } @Override - public PeerData findOnlinePeer() { - Set excludePeers = new HashSet<>(); + public PeerInfo findOnlinePeer() { + Set excludePeers = new HashSet<>(); return findOnlinePeer(excludePeers); } @Override - public PeerData findOnlinePeer(Set excludePeers) { + public PeerInfo findOnlinePeer(Set 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 peers = WorldManager.getInstance().getPeerDiscovery().getPeers(); + final Set 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 getPeers() { + public Set getPeers() { return WorldManager.getInstance().getPeerDiscovery().getPeers(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java index 4fce9018..a1d14671 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java @@ -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(); + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/EthHandler.java index e863b97a..3f1cc2cb 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/EthHandler.java @@ -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 { 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 { * @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 { BLOCK_RETRIEVING, SYNC_DONE; } + + public StatusMessage getHandshakeStatusMessage(){ + return handshakeStatusMessage; + } } \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java index 8efa9778..9dc74e0b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java @@ -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 { 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 { 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 { 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 { } private void sendPeers() { - Set peers = WorldManager.getInstance().getPeerDiscovery().getPeers(); - PeersMessage msg = new PeersMessage(peers); + Set peers = WorldManager.getInstance().getPeerDiscovery().getPeers(); + + Set 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 { 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 { } } + public HelloMessage getHandshakeHelloMessage() { + return handshakeHelloMessage; + } + private void startTimers() { // sample for pinging in background @@ -268,4 +276,6 @@ public class P2pHandler extends SimpleChannelInboundHandler { msgQueue.close(); } + + } \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerData.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/Peer.java similarity index 74% rename from ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerData.java rename to ethereumj-core/src/main/java/org/ethereum/net/p2p/Peer.java index 55443f65..61adb600 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerData.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/Peer.java @@ -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 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 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()); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/p2p/PeersMessage.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/PeersMessage.java index fa2cb1b9..e3c060f3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/p2p/PeersMessage.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/PeersMessage.java @@ -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 peers; + private Set peers; public PeersMessage(byte[] payload) { super(payload); } - public PeersMessage(Set peers) { + public PeersMessage(Set 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 peerList = new ArrayList<>(this.peers); + List 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 getPeers() { + public Set 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() + "]"; diff --git a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerDiscovery.java b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerDiscovery.java index 0b97fd92..c01041c3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerDiscovery.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerDiscovery.java @@ -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 peers = Collections.synchronizedSet(new HashSet()); + private final Set peers = Collections.synchronizedSet(new HashSet()); private PeerMonitorThread monitor; private ThreadFactory threadFactory; @@ -47,10 +48,10 @@ public class PeerDiscovery { monitorThread.start(); // Initialize PeerData - List peerDataList = parsePeerDiscoveryIpList(CONFIG.peerDiscoveryIPList()); + List 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 getPeers() { + public Set 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 newPeers) { + public void addPeers(Set 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 parsePeerDiscoveryIpList(final String peerDiscoveryIpList){ + public List parsePeerDiscoveryIpList(final String peerDiscoveryIpList){ final List ipList = Arrays.asList( peerDiscoveryIpList.split(",") ); - final List peers = new ArrayList<>(); + final List 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(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerInfo.java b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerInfo.java new file mode 100644 index 00000000..a8a48071 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerInfo.java @@ -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 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 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; + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/WorkerThread.java b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/WorkerThread.java index f411cae8..75805b75 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/WorkerThread.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/WorkerThread.java @@ -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(); } } diff --git a/ethereumj-core/src/test/java/org/ethereum/net/PeersMessageTest.java b/ethereumj-core/src/test/java/org/ethereum/net/PeersMessageTest.java index 20b90264..a578184c 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/PeersMessageTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/PeersMessageTest.java @@ -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 it = peersMessage.getPeers().iterator(); it.next(); - PeerData peer = it.next(); + Iterator 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 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 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()); diff --git a/ethereumj-studio/src/main/java/org/ethereum/gui/PeerInfoWindow.java b/ethereumj-studio/src/main/java/org/ethereum/gui/PeerInfoWindow.java new file mode 100644 index 00000000..4edb4d1d --- /dev/null +++ b/ethereumj-studio/src/main/java/org/ethereum/gui/PeerInfoWindow.java @@ -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.

+ * + * This example uses RSyntaxTextArea 2.0.1.

+ * + * Project Home: http://fifesoft.com/rsyntaxtextarea
+ * 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); + } + }); + } +} diff --git a/ethereumj-studio/src/main/java/org/ethereum/gui/PeersTableModel.java b/ethereumj-studio/src/main/java/org/ethereum/gui/PeersTableModel.java index f5f5d592..4c54b00f 100644 --- a/ethereumj-studio/src/main/java/org/ethereum/gui/PeersTableModel.java +++ b/ethereumj-studio/src/main/java/org/ethereum/gui/PeersTableModel.java @@ -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 peers = UIEthereumManager.ethereum.getPeers(); + final Set 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()); + } } } diff --git a/ethereumj-studio/src/main/java/org/ethereum/gui/PeersTableWindow.java b/ethereumj-studio/src/main/java/org/ethereum/gui/PeersTableWindow.java index 2bebf801..f5e7eb6a 100644 --- a/ethereumj-studio/src/main/java/org/ethereum/gui/PeersTableWindow.java +++ b/ethereumj-studio/src/main/java/org/ethereum/gui/PeersTableWindow.java @@ -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);