mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2024-11-19 09:50:32 +01:00
Change NetworkConnection API to separate connect method.
This allows the Peer to close the connection earlier when connect() takes a long time. Resolves issue 161.
This commit is contained in:
parent
92398d2c47
commit
9474eaa0d4
@ -31,6 +31,15 @@ import java.io.IOException;
|
||||
* Construction is blocking whilst the protocol version is negotiated.
|
||||
*/
|
||||
public interface NetworkConnection {
|
||||
/**
|
||||
* Connect to the remote peer.
|
||||
*
|
||||
* @param peerAddress the address of the remote peer
|
||||
* @param connectTimeoutMsec timeout in milliseconds
|
||||
*/
|
||||
public void connect(PeerAddress peerAddress, int connectTimeoutMsec)
|
||||
throws IOException, ProtocolException;
|
||||
|
||||
/**
|
||||
* Sends a "ping" message to the remote node. The protocol doesn't presently use this feature much.
|
||||
*
|
||||
|
@ -154,7 +154,8 @@ public class Peer {
|
||||
*/
|
||||
public synchronized void connect() throws PeerException {
|
||||
try {
|
||||
conn = new TCPNetworkConnection(address, params, CONNECT_TIMEOUT_MSEC, false, versionMessage);
|
||||
conn = new TCPNetworkConnection(params, false, versionMessage);
|
||||
conn.connect(address, CONNECT_TIMEOUT_MSEC);
|
||||
} catch (IOException ex) {
|
||||
throw new PeerException(ex);
|
||||
} catch (ProtocolException ex) {
|
||||
|
@ -40,16 +40,18 @@ public class TCPNetworkConnection implements NetworkConnection {
|
||||
private static final Logger log = LoggerFactory.getLogger(TCPNetworkConnection.class);
|
||||
|
||||
private final Socket socket;
|
||||
private final OutputStream out;
|
||||
private final InputStream in;
|
||||
private OutputStream out;
|
||||
private InputStream in;
|
||||
// The IP address to which we are connecting.
|
||||
private final InetAddress remoteIp;
|
||||
private InetAddress remoteIp;
|
||||
private final NetworkParameters params;
|
||||
private final VersionMessage versionMessage;
|
||||
private VersionMessage versionMessage;
|
||||
|
||||
// Given to the BitcoinSerializer to de-duplicate messages.
|
||||
private static final LinkedHashMap<Sha256Hash, Integer> dedupeList = BitcoinSerializer.createDedupeList();
|
||||
private BitcoinSerializer serializer = null;
|
||||
|
||||
private VersionMessage myVersionMessage;
|
||||
private static final Date checksummingProtocolChangeDate = new Date(1329696000000L);
|
||||
|
||||
/**
|
||||
@ -65,30 +67,35 @@ public class TCPNetworkConnection implements NetworkConnection {
|
||||
* @throws IOException if there is a network related failure.
|
||||
* @throws ProtocolException if the version negotiation failed.
|
||||
*/
|
||||
public TCPNetworkConnection(PeerAddress peerAddress, NetworkParameters params,
|
||||
int connectTimeoutMsec, boolean dedupe, VersionMessage ver)
|
||||
public TCPNetworkConnection(NetworkParameters params, boolean dedupe, VersionMessage ver)
|
||||
throws IOException, ProtocolException {
|
||||
this.params = params;
|
||||
this.remoteIp = peerAddress.getAddr();
|
||||
this.myVersionMessage = ver;
|
||||
|
||||
int port = (peerAddress.getPort() > 0) ? peerAddress.getPort() : params.port;
|
||||
socket = new Socket();
|
||||
|
||||
// So pre-Feb 2012, update checkumming property after version is read.
|
||||
this.serializer = new BitcoinSerializer(this.params, false, dedupe ? dedupeList : null);
|
||||
this.serializer.setUseChecksumming(Utils.now().after(checksummingProtocolChangeDate));
|
||||
}
|
||||
|
||||
public void connect(PeerAddress peerAddress, int connectTimeoutMsec)
|
||||
throws IOException, ProtocolException {
|
||||
remoteIp = peerAddress.getAddr();
|
||||
int port = (peerAddress.getPort() > 0) ? peerAddress.getPort() : this.params.port;
|
||||
|
||||
InetSocketAddress address = new InetSocketAddress(remoteIp, port);
|
||||
socket = new Socket();
|
||||
|
||||
socket.connect(address, connectTimeoutMsec);
|
||||
|
||||
out = socket.getOutputStream();
|
||||
in = socket.getInputStream();
|
||||
|
||||
// The version message does not use checksumming, until Feb 2012 when it magically does.
|
||||
// So pre-Feb 2012, update checkumming property after version is read.
|
||||
this.serializer = new BitcoinSerializer(params, false, dedupe ? dedupeList : null);
|
||||
this.serializer.setUseChecksumming(Utils.now().after(checksummingProtocolChangeDate));
|
||||
|
||||
// Announce ourselves. This has to come first to connect to clients beyond v0.30.20.2 which wait to hear
|
||||
// from us until they send their version message back.
|
||||
log.info("Announcing ourselves as: {}", ver.subVer);
|
||||
writeMessage(ver);
|
||||
log.info("Announcing ourselves as: {}", myVersionMessage.subVer);
|
||||
writeMessage(myVersionMessage);
|
||||
// When connecting, the remote peer sends us a version message with various bits of
|
||||
// useful data in it. We need to know the peer protocol version before we can talk to it.
|
||||
Message m = readMessage();
|
||||
@ -140,15 +147,15 @@ public class TCPNetworkConnection implements NetworkConnection {
|
||||
* @throws IOException if there is a network related failure.
|
||||
* @throws ProtocolException if the version negotiation failed.
|
||||
*/
|
||||
public TCPNetworkConnection(PeerAddress peerAddress, NetworkParameters params,
|
||||
int bestHeight, int connectTimeoutMsec, boolean dedupe)
|
||||
public TCPNetworkConnection(NetworkParameters params,
|
||||
int bestHeight, boolean dedupe)
|
||||
throws IOException, ProtocolException {
|
||||
this(peerAddress, params, connectTimeoutMsec, dedupe, new VersionMessage(params, bestHeight));
|
||||
this(params, dedupe, new VersionMessage(params, bestHeight));
|
||||
}
|
||||
|
||||
public TCPNetworkConnection(InetAddress inetAddress, NetworkParameters params, int bestHeight, int connectTimeout)
|
||||
public TCPNetworkConnection(NetworkParameters params, int bestHeight)
|
||||
throws IOException, ProtocolException {
|
||||
this(new PeerAddress(inetAddress), params, bestHeight, connectTimeout, true);
|
||||
this(params, bestHeight, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,13 +37,13 @@ public class MockNetworkConnection implements NetworkConnection {
|
||||
private PeerAddress peerAddress;
|
||||
|
||||
public MockNetworkConnection() {
|
||||
}
|
||||
|
||||
|
||||
public void connect(PeerAddress peerAddress, int connectTimeoutMsec) {
|
||||
inboundMessageQ = new ArrayBlockingQueue<Object>(10);
|
||||
outboundMessageQ = new ArrayBlockingQueue<Message>(10);
|
||||
try {
|
||||
peerAddress = new PeerAddress(InetAddress.getLocalHost(), fakePort++);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e); // Cannot happen.
|
||||
}
|
||||
this.peerAddress = peerAddress;
|
||||
}
|
||||
|
||||
public void ping() throws IOException {
|
||||
|
@ -21,6 +21,8 @@ import com.google.bitcoin.utils.BriefLogFormatter;
|
||||
import org.easymock.IMocksControl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import static org.easymock.EasyMock.createStrictControl;
|
||||
|
||||
@ -35,6 +37,7 @@ public class TestWithNetworkConnections {
|
||||
protected Wallet wallet;
|
||||
protected ECKey key;
|
||||
protected Address address;
|
||||
private static int fakePort;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
BriefLogFormatter.init();
|
||||
@ -52,7 +55,13 @@ public class TestWithNetworkConnections {
|
||||
}
|
||||
|
||||
protected MockNetworkConnection createMockNetworkConnection() {
|
||||
return new MockNetworkConnection();
|
||||
MockNetworkConnection conn = new MockNetworkConnection();
|
||||
try {
|
||||
conn.connect(new PeerAddress(InetAddress.getLocalHost(), fakePort++), 0);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e); // Cannot happen
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
protected void runPeer(Peer peer, MockNetworkConnection connection) throws IOException, PeerException {
|
||||
@ -65,7 +74,7 @@ public class TestWithNetworkConnections {
|
||||
}
|
||||
}
|
||||
|
||||
protected void runPeerAsync(final Peer peer, MockNetworkConnection connection) throws IOException, PeerException {
|
||||
protected void runPeerAsync(final Peer peer, MockNetworkConnection connection) {
|
||||
new Thread("Test Peer Thread") {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -18,6 +18,7 @@ package com.google.bitcoin.examples;
|
||||
|
||||
import com.google.bitcoin.core.NetworkConnection;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.PeerAddress;
|
||||
import com.google.bitcoin.core.TCPNetworkConnection;
|
||||
import com.google.bitcoin.discovery.DnsDiscovery;
|
||||
import com.google.bitcoin.discovery.IrcDiscovery;
|
||||
@ -94,8 +95,9 @@ public class PrintPeers {
|
||||
pool.submit(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
NetworkConnection conn = new TCPNetworkConnection(addr,
|
||||
NetworkParameters.prodNet(), 0, 1000);
|
||||
NetworkConnection conn =
|
||||
new TCPNetworkConnection(NetworkParameters.prodNet(), 0);
|
||||
conn.connect(new PeerAddress(addr), 1000);
|
||||
synchronized (lock) {
|
||||
long nodeHeight = conn.getVersionMessage().bestHeight;
|
||||
long diff = bestHeight[0] - nodeHeight;
|
||||
|
Loading…
Reference in New Issue
Block a user