mirror of https://github.com/hyperledger/besu
Move connect decision into protocol layer (#4759)
Move the decision making for connecting or not connecting to peers into the eth layer. Future changes will take advantage if this to improve peering. Signed-off-by: Stefan <stefan.pingel@consensys.net> --------- Signed-off-by: Stefan <stefan.pingel@consensys.net> Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com> Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>pull/5344/head
parent
067a263374
commit
534a369574
@ -0,0 +1,32 @@ |
||||
/* |
||||
* Copyright contributors to Hyperledger Besu |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.eth; |
||||
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.DefaultPeer; |
||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; |
||||
import org.hyperledger.besu.ethereum.p2p.peers.Peer; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
|
||||
public class EthPeerTestUtil { |
||||
|
||||
public static EnodeURLImpl.Builder enodeBuilder() { |
||||
return EnodeURLImpl.builder().ipAddress("127.0.0.1").useDefaultPorts().nodeId(Peer.randomId()); |
||||
} |
||||
|
||||
public static Peer createPeer(final Bytes nodeId) { |
||||
return DefaultPeer.fromEnodeURL(enodeBuilder().nodeId(nodeId).build()); |
||||
} |
||||
} |
@ -1,254 +0,0 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.p2p.rlpx.connections; |
||||
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.Peer; |
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; |
||||
|
||||
import java.util.Objects; |
||||
import java.util.concurrent.CompletableFuture; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
|
||||
public abstract class RlpxConnection { |
||||
|
||||
private final long initiatedAt; |
||||
protected final CompletableFuture<PeerConnection> future; |
||||
|
||||
private RlpxConnection(final CompletableFuture<PeerConnection> future) { |
||||
this.future = future; |
||||
this.initiatedAt = System.currentTimeMillis(); |
||||
} |
||||
|
||||
public static RlpxConnection inboundConnection(final PeerConnection peerConnection) { |
||||
return new RemotelyInitiatedRlpxConnection(peerConnection); |
||||
} |
||||
|
||||
public static RlpxConnection outboundConnection( |
||||
final Peer peer, final CompletableFuture<PeerConnection> future) { |
||||
return new LocallyInitiatedRlpxConnection(peer, future); |
||||
} |
||||
|
||||
public abstract Peer getPeer(); |
||||
|
||||
public abstract void disconnect(DisconnectReason reason); |
||||
|
||||
public Bytes getId() { |
||||
return getPeer().getId(); |
||||
} |
||||
|
||||
public abstract PeerConnection getPeerConnection() throws ConnectionNotEstablishedException; |
||||
|
||||
public CompletableFuture<PeerConnection> getFuture() { |
||||
return future; |
||||
} |
||||
|
||||
public abstract boolean isActive(); |
||||
|
||||
public abstract boolean isPending(); |
||||
|
||||
public abstract boolean isFailedOrDisconnected(); |
||||
|
||||
public abstract boolean initiatedRemotely(); |
||||
|
||||
public void subscribeConnectionEstablished( |
||||
final RlpxConnectCallback successCallback, final RlpxConnectFailedCallback failedCallback) { |
||||
future.whenComplete( |
||||
(conn, err) -> { |
||||
if (err != null) { |
||||
failedCallback.onFailure(this); |
||||
} else { |
||||
successCallback.onConnect(this); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public boolean initiatedLocally() { |
||||
return !initiatedRemotely(); |
||||
} |
||||
|
||||
public long getInitiatedAt() { |
||||
return initiatedAt; |
||||
} |
||||
|
||||
private static class RemotelyInitiatedRlpxConnection extends RlpxConnection { |
||||
|
||||
private final PeerConnection peerConnection; |
||||
|
||||
private RemotelyInitiatedRlpxConnection(final PeerConnection peerConnection) { |
||||
super(CompletableFuture.completedFuture(peerConnection)); |
||||
this.peerConnection = peerConnection; |
||||
} |
||||
|
||||
@Override |
||||
public Peer getPeer() { |
||||
return peerConnection.getPeer(); |
||||
} |
||||
|
||||
@Override |
||||
public void disconnect(final DisconnectReason reason) { |
||||
peerConnection.disconnect(reason); |
||||
} |
||||
|
||||
@Override |
||||
public PeerConnection getPeerConnection() { |
||||
return peerConnection; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isActive() { |
||||
return !peerConnection.isDisconnected(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isPending() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isFailedOrDisconnected() { |
||||
return peerConnection.isDisconnected(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean initiatedRemotely() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(final Object o) { |
||||
if (o == this) { |
||||
return true; |
||||
} |
||||
if (!(o instanceof RemotelyInitiatedRlpxConnection)) { |
||||
return false; |
||||
} |
||||
final RemotelyInitiatedRlpxConnection that = (RemotelyInitiatedRlpxConnection) o; |
||||
return Objects.equals(peerConnection, that.peerConnection); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return Objects.hash(peerConnection); |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return "RemotelyInitiatedRlpxConnection initiatedAt:" |
||||
+ getInitiatedAt() |
||||
+ " to " |
||||
+ peerConnection.getPeer().getId() |
||||
+ " disconnected? " |
||||
+ isFailedOrDisconnected(); |
||||
} |
||||
} |
||||
|
||||
private static class LocallyInitiatedRlpxConnection extends RlpxConnection { |
||||
|
||||
private final Peer peer; |
||||
|
||||
private LocallyInitiatedRlpxConnection( |
||||
final Peer peer, final CompletableFuture<PeerConnection> future) { |
||||
super(future); |
||||
this.peer = peer; |
||||
} |
||||
|
||||
@Override |
||||
public Peer getPeer() { |
||||
return peer; |
||||
} |
||||
|
||||
@Override |
||||
public void disconnect(final DisconnectReason reason) { |
||||
future.thenAccept((conn) -> conn.disconnect(reason)); |
||||
} |
||||
|
||||
@Override |
||||
public PeerConnection getPeerConnection() throws ConnectionNotEstablishedException { |
||||
if (!future.isDone() || future.isCompletedExceptionally()) { |
||||
throw new ConnectionNotEstablishedException( |
||||
"Cannot access PeerConnection before connection is fully established."); |
||||
} |
||||
return future.getNow(null); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isActive() { |
||||
return future.isDone() |
||||
&& !future.isCompletedExceptionally() |
||||
&& !getPeerConnection().isDisconnected(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isPending() { |
||||
return !future.isDone(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isFailedOrDisconnected() { |
||||
return future.isCompletedExceptionally() |
||||
|| (future.isDone() && getPeerConnection().isDisconnected()); |
||||
} |
||||
|
||||
@Override |
||||
public boolean initiatedRemotely() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(final Object o) { |
||||
if (o == this) { |
||||
return true; |
||||
} |
||||
if (!(o instanceof LocallyInitiatedRlpxConnection)) { |
||||
return false; |
||||
} |
||||
final LocallyInitiatedRlpxConnection that = (LocallyInitiatedRlpxConnection) o; |
||||
return Objects.equals(peer, that.peer) && Objects.equals(future, that.future); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return Objects.hash(peer, future); |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return "LocallyInitiatedRlpxConnection initiatedAt:" |
||||
+ getInitiatedAt() |
||||
+ " to " |
||||
+ getPeer().getId() |
||||
+ " disconnected? " |
||||
+ isFailedOrDisconnected(); |
||||
} |
||||
} |
||||
|
||||
public static class ConnectionNotEstablishedException extends IllegalStateException { |
||||
|
||||
public ConnectionNotEstablishedException(final String message) { |
||||
super(message); |
||||
} |
||||
} |
||||
|
||||
@FunctionalInterface |
||||
public interface RlpxConnectCallback { |
||||
void onConnect(RlpxConnection connection); |
||||
} |
||||
|
||||
@FunctionalInterface |
||||
public interface RlpxConnectFailedCallback { |
||||
void onFailure(RlpxConnection connection); |
||||
} |
||||
} |
@ -0,0 +1,23 @@ |
||||
/* |
||||
* Copyright contributors to Hyperledger Besu |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.p2p.rlpx.wire; |
||||
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.Peer; |
||||
|
||||
@FunctionalInterface |
||||
public interface ShouldConnectCallback { |
||||
|
||||
boolean shouldConnect(final Peer peer, final boolean incoming); |
||||
} |
@ -1,66 +0,0 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.p2p.config; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
public class RlpxConfigurationTest { |
||||
|
||||
@Test |
||||
public void getMaxRemotelyInitiatedConnections_remoteLimitsDisabled() { |
||||
final RlpxConfiguration config = |
||||
RlpxConfiguration.create() |
||||
.setFractionRemoteWireConnectionsAllowed(.5f) |
||||
.setLimitRemoteWireConnectionsEnabled(false) |
||||
.setPeerUpperBound(20); |
||||
|
||||
assertThat(config.getMaxRemotelyInitiatedConnections()).isEqualTo(20); |
||||
} |
||||
|
||||
@Test |
||||
public void getMaxRemotelyInitiatedConnections_remoteLimitsEnabled() { |
||||
final RlpxConfiguration config = |
||||
RlpxConfiguration.create() |
||||
.setFractionRemoteWireConnectionsAllowed(.5f) |
||||
.setLimitRemoteWireConnectionsEnabled(true) |
||||
.setPeerUpperBound(20); |
||||
|
||||
assertThat(config.getMaxRemotelyInitiatedConnections()).isEqualTo(10); |
||||
} |
||||
|
||||
@Test |
||||
public void getMaxRemotelyInitiatedConnections_remoteLimitsEnabledWithNonIntegerRatio() { |
||||
final RlpxConfiguration config = |
||||
RlpxConfiguration.create() |
||||
.setFractionRemoteWireConnectionsAllowed(.5f) |
||||
.setLimitRemoteWireConnectionsEnabled(true) |
||||
.setPeerUpperBound(25); |
||||
|
||||
assertThat(config.getMaxRemotelyInitiatedConnections()).isEqualTo(12); |
||||
} |
||||
|
||||
@Test |
||||
public void getMaxRemotelyInitiatedConnections_remoteLimitsEnabledRoundsToZero() { |
||||
final RlpxConfiguration config = |
||||
RlpxConfiguration.create() |
||||
.setFractionRemoteWireConnectionsAllowed(.5f) |
||||
.setLimitRemoteWireConnectionsEnabled(true) |
||||
.setPeerUpperBound(1); |
||||
|
||||
assertThat(config.getMaxRemotelyInitiatedConnections()).isEqualTo(0); |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,269 +0,0 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.p2p.rlpx.connections; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
import static org.hyperledger.besu.ethereum.p2p.peers.PeerTestHelper.createPeer; |
||||
import static org.mockito.Mockito.spy; |
||||
import static org.mockito.Mockito.verify; |
||||
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.Peer; |
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.RlpxConnection.ConnectionNotEstablishedException; |
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; |
||||
|
||||
import java.util.concurrent.CompletableFuture; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
public class RlpxConnectionTest { |
||||
|
||||
@Test |
||||
public void getPeer_pendingOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
|
||||
assertThat(conn.getPeer()).isEqualTo(peer); |
||||
} |
||||
|
||||
@Test |
||||
public void getPeer_establishedOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
future.complete(peerConnection(peer)); |
||||
|
||||
assertThat(conn.getPeer()).isEqualTo(peer); |
||||
} |
||||
|
||||
@Test |
||||
public void getPeer_inboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
final RlpxConnection conn = RlpxConnection.inboundConnection(peerConnection); |
||||
|
||||
assertThat(conn.getPeer()).isEqualTo(peer); |
||||
} |
||||
|
||||
@Test |
||||
public void disconnect_pendingOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
|
||||
final DisconnectReason reason = DisconnectReason.REQUESTED; |
||||
conn.disconnect(reason); |
||||
assertThat(conn.isFailedOrDisconnected()).isFalse(); |
||||
|
||||
// Resolve future
|
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
future.complete(peerConnection); |
||||
|
||||
// Check disconnect was issued
|
||||
verify(peerConnection).disconnect(reason); |
||||
assertThat(conn.isFailedOrDisconnected()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
public void disconnect_activeOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
future.complete(peerConnection); |
||||
|
||||
final DisconnectReason reason = DisconnectReason.REQUESTED; |
||||
conn.disconnect(reason); |
||||
|
||||
// Check disconnect was issued
|
||||
assertThat(conn.isFailedOrDisconnected()).isTrue(); |
||||
verify(peerConnection).disconnect(reason); |
||||
} |
||||
|
||||
@Test |
||||
public void disconnect_failedOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
future.completeExceptionally(new IllegalStateException("whoops")); |
||||
|
||||
assertThat(conn.isFailedOrDisconnected()).isTrue(); |
||||
final DisconnectReason reason = DisconnectReason.REQUESTED; |
||||
conn.disconnect(reason); |
||||
assertThat(conn.isFailedOrDisconnected()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
public void disconnect_inboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
final RlpxConnection conn = RlpxConnection.inboundConnection(peerConnection); |
||||
|
||||
assertThat(conn.isFailedOrDisconnected()).isFalse(); |
||||
final DisconnectReason reason = DisconnectReason.REQUESTED; |
||||
conn.disconnect(reason); |
||||
|
||||
// Check disconnect was issued
|
||||
assertThat(conn.isFailedOrDisconnected()).isTrue(); |
||||
verify(peerConnection).disconnect(reason); |
||||
} |
||||
|
||||
@Test |
||||
public void getPeerConnection_pendingOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
|
||||
assertThatThrownBy(conn::getPeerConnection) |
||||
.isInstanceOf(ConnectionNotEstablishedException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void getPeerConnection_activeOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
future.complete(peerConnection); |
||||
|
||||
assertThat(conn.getPeerConnection()).isEqualTo(peerConnection); |
||||
} |
||||
|
||||
@Test |
||||
public void getPeerConnection_failedOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
future.completeExceptionally(new IllegalStateException("whoops")); |
||||
|
||||
assertThatThrownBy(conn::getPeerConnection) |
||||
.isInstanceOf(ConnectionNotEstablishedException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void getPeerConnection_disconnectedOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
future.complete(peerConnection); |
||||
conn.disconnect(DisconnectReason.REQUESTED); |
||||
|
||||
assertThat(conn.getPeerConnection()).isEqualTo(peerConnection); |
||||
} |
||||
|
||||
@Test |
||||
public void getPeerConnection_activeInboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
final RlpxConnection conn = RlpxConnection.inboundConnection(peerConnection); |
||||
|
||||
assertThat(conn.getPeerConnection()).isEqualTo(peerConnection); |
||||
} |
||||
|
||||
@Test |
||||
public void getPeerConnection_disconnectedInboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
final RlpxConnection conn = RlpxConnection.inboundConnection(peerConnection); |
||||
conn.disconnect(DisconnectReason.REQUESTED); |
||||
|
||||
assertThat(conn.getPeerConnection()).isEqualTo(peerConnection); |
||||
} |
||||
|
||||
@Test |
||||
public void checkState_pendingOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
|
||||
assertThat(conn.initiatedRemotely()).isFalse(); |
||||
assertThat(conn.isActive()).isFalse(); |
||||
assertThat(conn.isPending()).isTrue(); |
||||
assertThat(conn.isFailedOrDisconnected()).isFalse(); |
||||
} |
||||
|
||||
@Test |
||||
public void checkState_activeOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
future.complete(peerConnection); |
||||
|
||||
assertThat(conn.initiatedRemotely()).isFalse(); |
||||
assertThat(conn.isActive()).isTrue(); |
||||
assertThat(conn.isPending()).isFalse(); |
||||
assertThat(conn.isFailedOrDisconnected()).isFalse(); |
||||
} |
||||
|
||||
@Test |
||||
public void checkState_failedOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
future.completeExceptionally(new IllegalStateException("whoops")); |
||||
|
||||
assertThat(conn.initiatedRemotely()).isFalse(); |
||||
assertThat(conn.isActive()).isFalse(); |
||||
assertThat(conn.isPending()).isFalse(); |
||||
assertThat(conn.isFailedOrDisconnected()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
public void checkState_disconnectedOutboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final CompletableFuture<PeerConnection> future = new CompletableFuture<>(); |
||||
final RlpxConnection conn = RlpxConnection.outboundConnection(peer, future); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
future.complete(peerConnection); |
||||
conn.disconnect(DisconnectReason.UNKNOWN); |
||||
|
||||
assertThat(conn.initiatedRemotely()).isFalse(); |
||||
assertThat(conn.isActive()).isFalse(); |
||||
assertThat(conn.isPending()).isFalse(); |
||||
assertThat(conn.isFailedOrDisconnected()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
public void checkState_activeInboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
final RlpxConnection conn = RlpxConnection.inboundConnection(peerConnection); |
||||
|
||||
assertThat(conn.initiatedRemotely()).isTrue(); |
||||
assertThat(conn.isActive()).isTrue(); |
||||
assertThat(conn.isPending()).isFalse(); |
||||
assertThat(conn.isFailedOrDisconnected()).isFalse(); |
||||
} |
||||
|
||||
@Test |
||||
public void checkState_disconnectedInboundConnection() { |
||||
final Peer peer = createPeer(); |
||||
final PeerConnection peerConnection = peerConnection(peer); |
||||
final RlpxConnection conn = RlpxConnection.inboundConnection(peerConnection); |
||||
conn.disconnect(DisconnectReason.UNKNOWN); |
||||
|
||||
assertThat(conn.initiatedRemotely()).isTrue(); |
||||
assertThat(conn.isActive()).isFalse(); |
||||
assertThat(conn.isPending()).isFalse(); |
||||
assertThat(conn.isFailedOrDisconnected()).isTrue(); |
||||
} |
||||
|
||||
private PeerConnection peerConnection(final Peer peer) { |
||||
return spy(MockPeerConnection.create(peer)); |
||||
} |
||||
} |
Loading…
Reference in new issue