diff --git a/core/src/main/java/org/bitcoinj/core/PeerGroup.java b/core/src/main/java/org/bitcoinj/core/PeerGroup.java index 12ee3f091..d8f2bc9e5 100644 --- a/core/src/main/java/org/bitcoinj/core/PeerGroup.java +++ b/core/src/main/java/org/bitcoinj/core/PeerGroup.java @@ -355,9 +355,9 @@ public class PeerGroup implements TransactionBroadcaster { private final FilterMerger bloomFilterMerger; /** The default timeout between when a connection attempt begins and version message exchange completes */ - public static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 5000; - private volatile int vConnectTimeoutMillis = DEFAULT_CONNECT_TIMEOUT_MILLIS; - + public static final Duration DEFAULT_CONNECT_TIMEOUT = Duration.ofSeconds(5); + private volatile Duration vConnectTimeout = DEFAULT_CONNECT_TIMEOUT; + /** Whether bloom filter support is enabled when using a non FullPrunedBlockchain*/ private volatile boolean vBloomFilteringEnabled = true; @@ -617,7 +617,7 @@ public class PeerGroup implements TransactionBroadcaster { executor.schedule(this, delay.toMillis(), TimeUnit.MILLISECONDS); return; } - connectTo(addrToTry, false, vConnectTimeoutMillis); + connectTo(addrToTry, false, vConnectTimeout); } finally { lock.unlock(); } @@ -1128,7 +1128,7 @@ public class PeerGroup implements TransactionBroadcaster { // Do a fast blocking connect to see if anything is listening. try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), params.getPort()), - vConnectTimeoutMillis); + Math.toIntExact(vConnectTimeout.toMillis())); localhostCheckState = LocalhostCheckState.FOUND; return true; } catch (IOException e) { @@ -1454,7 +1454,7 @@ public class PeerGroup implements TransactionBroadcaster { try { PeerAddress peerAddress = new PeerAddress(params, address); backoffMap.put(peerAddress, new ExponentialBackoff(peerBackoffParams)); - return connectTo(peerAddress, true, vConnectTimeoutMillis); + return connectTo(peerAddress, true, vConnectTimeout); } finally { lock.unlock(); } @@ -1469,7 +1469,7 @@ public class PeerGroup implements TransactionBroadcaster { try { final PeerAddress localhost = PeerAddress.localhost(params); backoffMap.put(localhost, new ExponentialBackoff(peerBackoffParams)); - return connectTo(localhost, true, vConnectTimeoutMillis); + return connectTo(localhost, true, vConnectTimeout); } finally { lock.unlock(); } @@ -1481,10 +1481,11 @@ public class PeerGroup implements TransactionBroadcaster { * @param address Remote network address * @param incrementMaxConnections Whether to consider this connection an attempt to fill our quota, or something * explicitly requested. + * @param connectTimeout timeout for establishing the connection to peers * @return Peer or null. */ @Nullable @GuardedBy("lock") - protected Peer connectTo(PeerAddress address, boolean incrementMaxConnections, int connectTimeoutMillis) { + protected Peer connectTo(PeerAddress address, boolean incrementMaxConnections, Duration connectTimeout) { checkState(lock.isHeldByCurrentThread()); VersionMessage ver = getVersionMessage().duplicate(); ver.bestHeight = chain == null ? 0 : chain.getBestChainHeight(); @@ -1510,7 +1511,7 @@ public class PeerGroup implements TransactionBroadcaster { handlePeerDeath(peer, cause); return null; } - peer.setSocketTimeout(connectTimeoutMillis); + peer.setSocketTimeout(connectTimeout); // When the channel has connected and version negotiated successfully, handleNewPeer will end up being called on // a worker thread. if (incrementMaxConnections) { @@ -1530,9 +1531,16 @@ public class PeerGroup implements TransactionBroadcaster { /** * Sets the timeout between when a connection attempt to a peer begins and when the version message exchange * completes. This does not apply to currently pending peers. + * @param connectTimeout timeout for estiablishing the connection to peers */ + public void setConnectTimeout(Duration connectTimeout) { + this.vConnectTimeout = connectTimeout; + } + + /** @deprecated use {@link #setConnectTimeout(Duration)} */ + @Deprecated public void setConnectTimeoutMillis(int connectTimeoutMillis) { - this.vConnectTimeoutMillis = connectTimeoutMillis; + setConnectTimeout(Duration.ofMillis(connectTimeoutMillis)); } /** diff --git a/core/src/main/java/org/bitcoinj/core/PeerSocketHandler.java b/core/src/main/java/org/bitcoinj/core/PeerSocketHandler.java index 98d91eb98..5b0a333a3 100644 --- a/core/src/main/java/org/bitcoinj/core/PeerSocketHandler.java +++ b/core/src/main/java/org/bitcoinj/core/PeerSocketHandler.java @@ -36,6 +36,7 @@ import java.nio.Buffer; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.channels.NotYetConnectedException; +import java.time.Duration; import java.util.concurrent.locks.Lock; import static com.google.common.base.Preconditions.checkArgument; @@ -82,8 +83,8 @@ public abstract class PeerSocketHandler implements TimeoutHandler, StreamConnect } @Override - public void setSocketTimeout(int timeoutMillis) { - timeoutTask.setSocketTimeout(timeoutMillis); + public void setSocketTimeout(Duration timeout) { + timeoutTask.setSocketTimeout(timeout); } /** diff --git a/core/src/main/java/org/bitcoinj/net/AbstractTimeoutHandler.java b/core/src/main/java/org/bitcoinj/net/AbstractTimeoutHandler.java index 568ac2083..f6fe59840 100644 --- a/core/src/main/java/org/bitcoinj/net/AbstractTimeoutHandler.java +++ b/core/src/main/java/org/bitcoinj/net/AbstractTimeoutHandler.java @@ -16,6 +16,8 @@ package org.bitcoinj.net; +import java.time.Duration; + /** * A base class which provides basic support for socket timeouts. It is used instead of integrating timeouts into the * NIO select thread both for simplicity and to keep code shared between NIO and blocking sockets as much as possible. @@ -34,7 +36,7 @@ public abstract class AbstractTimeoutHandler implements TimeoutHandler { *
Enables or disables the timeout entirely. This may be useful if you want to store the timeout value but wish * to temporarily disable/enable timeouts.
* - *The default is for timeoutEnabled to be true but timeoutMillis to be set to 0 (ie disabled).
+ *The default is for timeoutEnabled to be true but timeout to be set to {@link Duration#ZERO} (ie disabled).
* *This call will reset the current progress towards the timeout.
*/ @@ -44,18 +46,18 @@ public abstract class AbstractTimeoutHandler implements TimeoutHandler { } /** - *Sets the receive timeout to the given number of milliseconds, automatically killing the connection if no + *
Sets the receive timeout, automatically killing the connection if no * messages are received for this long
* - *A timeout of 0 is interpreted as no timeout.
+ *A timeout of 0{@link Duration#ZERO} is interpreted as no timeout.
* - *The default is for timeoutEnabled to be true but timeoutMillis to be set to 0 (ie disabled).
+ *The default is for timeoutEnabled to be true but timeout to be set to {@link Duration#ZERO} (ie disabled).
* *This call will reset the current progress towards the timeout.
*/ @Override - public synchronized final void setSocketTimeout(int timeoutMillis) { - timeoutTask.setSocketTimeout(timeoutMillis); + public synchronized final void setSocketTimeout(Duration timeout) { + timeoutTask.setSocketTimeout(timeout); } /** diff --git a/core/src/main/java/org/bitcoinj/net/BlockingClient.java b/core/src/main/java/org/bitcoinj/net/BlockingClient.java index 65e40fa56..d6ccfdd51 100644 --- a/core/src/main/java/org/bitcoinj/net/BlockingClient.java +++ b/core/src/main/java/org/bitcoinj/net/BlockingClient.java @@ -30,6 +30,7 @@ import java.net.Socket; import java.net.SocketAddress; import java.nio.Buffer; import java.nio.ByteBuffer; +import java.time.Duration; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -58,14 +59,13 @@ public class BlockingClient implements MessageWriteTarget { * open, but will call either the {@link StreamConnection#connectionOpened()} or * {@link StreamConnection#connectionClosed()} callback on the created network event processing thread. * - * @param connectTimeoutMillis The connect timeout set on the connection (in milliseconds). 0 is interpreted as no - * timeout. + * @param connectTimeout The connect timeout set on the connection. ZERO is interpreted as no timeout. * @param socketFactory An object that creates {@link Socket} objects on demand, which may be customised to control * how this client connects to the internet. If not sure, use SocketFactory.getDefault() * @param clientSet A set which this object will add itself to after initialization, and then remove itself from */ public BlockingClient(final SocketAddress serverAddress, final StreamConnection connection, - final int connectTimeoutMillis, final SocketFactory socketFactory, + final Duration connectTimeout, final SocketFactory socketFactory, @Nullable final SetEnables or disables the timeout entirely. This may be useful if you want to store the timeout value but wish * to temporarily disable/enable timeouts.
* - *The default is for timeoutEnabled to be true but timeoutMillis to be set to 0 (ie disabled).
+ *The default is for timeoutEnabled to be true but timeout to be set to {@link Duration#ZERO} (ie disabled).
* *This call will reset the current progress towards the timeout.
*/ @@ -51,18 +52,18 @@ public class SocketTimeoutTask implements TimeoutHandler { } /** - *Sets the receive timeout to the given number of milliseconds, automatically killing the connection if no + *
Sets the receive timeout, automatically killing the connection if no * messages are received for this long
* - *A timeout of 0 is interpreted as no timeout.
+ *A timeout of {@link Duration#ZERO} is interpreted as no timeout.
* - *The default is for timeoutEnabled to be true but timeoutMillis to be set to 0 (ie disabled).
+ *The default is for timeoutEnabled to be true but timeout to be set to {@link Duration#ZERO} (ie disabled).
* *This call will reset the current progress towards the timeout.
*/ @Override - public synchronized final void setSocketTimeout(int timeoutMillis) { - this.timeoutMillis = timeoutMillis; + public synchronized final void setSocketTimeout(Duration timeout) { + this.timeout = timeout; resetTimeout(); } @@ -74,11 +75,11 @@ public class SocketTimeoutTask implements TimeoutHandler { synchronized void resetTimeout() { if (timeoutTask != null) timeoutTask.cancel(); - if (timeoutMillis == 0 || !timeoutEnabled) + if (timeout.isZero() || !timeoutEnabled) return; // TimerTasks are not reusable, so we create a new one each time timeoutTask = timerTask(actualTask); - timeoutTimer.schedule(timeoutTask, timeoutMillis); + timeoutTimer.schedule(timeoutTask, timeout.toMillis()); } // Create TimerTask from Runnable diff --git a/core/src/main/java/org/bitcoinj/net/TimeoutHandler.java b/core/src/main/java/org/bitcoinj/net/TimeoutHandler.java index 7360d298a..455cf5a32 100644 --- a/core/src/main/java/org/bitcoinj/net/TimeoutHandler.java +++ b/core/src/main/java/org/bitcoinj/net/TimeoutHandler.java @@ -16,6 +16,8 @@ package org.bitcoinj.net; +import java.time.Duration; + /** * Provides basic support for socket timeouts. It is used instead of integrating timeouts into the * NIO select thread both for simplicity and to keep code shared between NIO and blocking sockets as much as possible. @@ -25,21 +27,21 @@ public interface TimeoutHandler { *Enables or disables the timeout entirely. This may be useful if you want to store the timeout value but wish * to temporarily disable/enable timeouts.
* - *The default is for timeoutEnabled to be true but timeoutMillis to be set to 0 (ie disabled).
+ *The default is for timeoutEnabled to be true but timeout to be set to 0 (ie disabled).
* *This call will reset the current progress towards the timeout.
*/ void setTimeoutEnabled(boolean timeoutEnabled); /** - *Sets the receive timeout to the given number of milliseconds, automatically killing the connection if no + *
Sets the receive timeout, automatically killing the connection if no * messages are received for this long
* - *A timeout of 0 is interpreted as no timeout.
+ *A timeout of {@link Duration#ZERO} is interpreted as no timeout.
* - *The default is for timeoutEnabled to be true but timeoutMillis to be set to 0 (ie disabled).
+ *The default is for timeoutEnabled to be true but timeout to be set to {@link Duration#ZERO} (ie disabled).
* *This call will reset the current progress towards the timeout.
*/ - void setSocketTimeout(int timeoutMillis); + void setSocketTimeout(Duration timeout); } diff --git a/core/src/test/java/org/bitcoinj/core/BitcoindComparisonTool.java b/core/src/test/java/org/bitcoinj/core/BitcoindComparisonTool.java index d57fcc04e..3f48bc8cb 100644 --- a/core/src/test/java/org/bitcoinj/core/BitcoindComparisonTool.java +++ b/core/src/test/java/org/bitcoinj/core/BitcoindComparisonTool.java @@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.time.Duration; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -207,7 +208,7 @@ public class BitcoindComparisonTool { bitcoindChainHead = PARAMS.getGenesisBlock().getHash(); // bitcoind MUST be on localhost or we will get banned as a DoSer - new NioClient(new InetSocketAddress(InetAddress.getLoopbackAddress(), args.length > 2 ? Integer.parseInt(args[2]) : PARAMS.getPort()), bitcoind, 1000); + new NioClient(new InetSocketAddress(InetAddress.getLoopbackAddress(), args.length > 2 ? Integer.parseInt(args[2]) : PARAMS.getPort()), bitcoind, Duration.ofSeconds(1)); connectedFuture.get(); diff --git a/integration-test/src/test/java/org/bitcoinj/core/PeerGroupTest.java b/integration-test/src/test/java/org/bitcoinj/core/PeerGroupTest.java index c28068444..cc93a78ec 100644 --- a/integration-test/src/test/java/org/bitcoinj/core/PeerGroupTest.java +++ b/integration-test/src/test/java/org/bitcoinj/core/PeerGroupTest.java @@ -525,9 +525,9 @@ public class PeerGroupTest extends TestWithPeerGroup { @Test public void peerTimeoutTest() throws Exception { - final int timeout = 100; + final Duration timeout = Duration.ofMillis(100); peerGroup.start(); - peerGroup.setConnectTimeoutMillis(timeout); + peerGroup.setConnectTimeout(timeout); final CompletableFuture