Useful response improves reputation (#4130)

* useful response improves reputation

Signed-off-by: Stefan <stefan.pingel@consensys.net>
pull/4136/head
Stefan Pingel 2 years ago committed by GitHub
parent 0ca45f34b9
commit b7877befdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java
  2. 7
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java
  3. 8
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/PeerReputation.java
  4. 6
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/AbstractPeerRequestTask.java
  5. 8
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthPeerTest.java
  6. 6
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/PeerReputationTest.java

@ -215,6 +215,10 @@ public class EthPeer implements Comparable<EthPeer> {
reputation.recordUselessResponse(System.currentTimeMillis()).ifPresent(this::disconnect); reputation.recordUselessResponse(System.currentTimeMillis()).ifPresent(this::disconnect);
} }
public void recordUsefulResponse() {
reputation.recordUsefulResposne();
}
public void disconnect(final DisconnectReason reason) { public void disconnect(final DisconnectReason reason) {
connection.disconnect(reason); connection.disconnect(reason);
} }

@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.eth.manager;
import org.hyperledger.besu.ethereum.eth.manager.EthPeer.DisconnectCallback; import org.hyperledger.besu.ethereum.eth.manager.EthPeer.DisconnectCallback;
import org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator; import org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator;
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.PeerInfo;
import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.metrics.BesuMetricCategory;
import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider; import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
@ -115,6 +116,12 @@ public class EthPeers {
disconnectCallbacks.forEach(callback -> callback.onDisconnect(peer)); disconnectCallbacks.forEach(callback -> callback.onDisconnect(peer));
peer.handleDisconnect(); peer.handleDisconnect();
abortPendingRequestsAssignedToDisconnectedPeers(); abortPendingRequestsAssignedToDisconnectedPeers();
final PeerInfo peerInfo = peer.getConnection().getPeerInfo();
LOG.debug(
"Disconnected EthPeer {}, client ID: {}, {}",
peerInfo.getNodeId(),
peerInfo.getClientId(),
peer.getReputation());
} }
reattemptPendingPeerRequests(); reattemptPendingPeerRequests();
} }

@ -44,7 +44,7 @@ public class PeerReputation implements Comparable<PeerReputation> {
private static final int SMALL_ADJUSTMENT = 1; private static final int SMALL_ADJUSTMENT = 1;
private static final int LARGE_ADJUSTMENT = 10; private static final int LARGE_ADJUSTMENT = 10;
private int score = DEFAULT_SCORE; private long score = DEFAULT_SCORE;
public Optional<DisconnectReason> recordRequestTimeout(final int requestCode) { public Optional<DisconnectReason> recordRequestTimeout(final int requestCode) {
final int newTimeoutCount = getOrCreateTimeoutCount(requestCode).incrementAndGet(); final int newTimeoutCount = getOrCreateTimeoutCount(requestCode).incrementAndGet();
@ -85,6 +85,10 @@ public class PeerReputation implements Comparable<PeerReputation> {
} }
} }
public void recordUsefulResposne() {
score += SMALL_ADJUSTMENT;
}
private boolean shouldRemove(final Long timestamp, final long currentTimestamp) { private boolean shouldRemove(final Long timestamp, final long currentTimestamp) {
return timestamp != null && timestamp + USELESS_RESPONSE_WINDOW_IN_MILLIS < currentTimestamp; return timestamp != null && timestamp + USELESS_RESPONSE_WINDOW_IN_MILLIS < currentTimestamp;
} }
@ -96,6 +100,6 @@ public class PeerReputation implements Comparable<PeerReputation> {
@Override @Override
public int compareTo(final @Nonnull PeerReputation otherReputation) { public int compareTo(final @Nonnull PeerReputation otherReputation) {
return Integer.compare(this.score, otherReputation.score); return Long.compare(this.score, otherReputation.score);
} }
} }

@ -105,7 +105,11 @@ public abstract class AbstractPeerRequestTask<R> extends AbstractPeerTask<R> {
} }
try { try {
final Optional<R> result = processResponse(streamClosed, message, peer); final Optional<R> result = processResponse(streamClosed, message, peer);
result.ifPresent(promise::complete); result.ifPresent(
r -> {
promise.complete(r);
peer.recordUsefulResponse();
});
} catch (final RLPException e) { } catch (final RLPException e) {
// Peer sent us malformed data - disconnect // Peer sent us malformed data - disconnect
LOG.debug("Disconnecting with BREACH_OF_PROTOCOL due to malformed message: {}", peer, e); LOG.debug("Disconnecting with BREACH_OF_PROTOCOL due to malformed message: {}", peer, e);

@ -362,6 +362,14 @@ public class EthPeerTest {
assertThat(peer2.compareTo(peer1)).isEqualTo(-1); assertThat(peer2.compareTo(peer1)).isEqualTo(-1);
} }
@Test
public void recordUsefullResponse() {
final EthPeer peer = createPeer();
final EthPeer peer2 = createPeer();
peer.recordUsefulResponse();
assertThat(peer.getReputation().compareTo(peer2.getReputation())).isGreaterThan(0);
}
private void messageStream( private void messageStream(
final ResponseStreamSupplier getStream, final ResponseStreamSupplier getStream,
final MessageData targetMessage, final MessageData targetMessage,

@ -80,4 +80,10 @@ public class PeerReputationTest {
1001 + PeerReputation.USELESS_RESPONSE_WINDOW_IN_MILLIS + 1)) 1001 + PeerReputation.USELESS_RESPONSE_WINDOW_IN_MILLIS + 1))
.isEmpty(); .isEmpty();
} }
@Test
public void shouldIncreaseScore() {
reputation.recordUsefulResposne();
assertThat(reputation.compareTo(new PeerReputation())).isGreaterThan(0);
}
} }

Loading…
Cancel
Save