|
|
|
@ -34,13 +34,10 @@ import org.slf4j.LoggerFactory; |
|
|
|
|
public class PeerReputation implements Comparable<PeerReputation> { |
|
|
|
|
static final long USELESS_RESPONSE_WINDOW_IN_MILLIS = |
|
|
|
|
TimeUnit.MILLISECONDS.convert(1, TimeUnit.MINUTES); |
|
|
|
|
static final int DEFAULT_MAX_SCORE = 200; |
|
|
|
|
// how much above the initial score you need to be to not get disconnected for timeouts/useless
|
|
|
|
|
// responses
|
|
|
|
|
private final int hasBeenUsefulThreshold; |
|
|
|
|
static final int DEFAULT_MAX_SCORE = 150; |
|
|
|
|
static final int DEFAULT_INITIAL_SCORE = 100; |
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(PeerReputation.class); |
|
|
|
|
private static final int TIMEOUT_THRESHOLD = 5; |
|
|
|
|
private static final int TIMEOUT_THRESHOLD = 3; |
|
|
|
|
private static final int USELESS_RESPONSE_THRESHOLD = 5; |
|
|
|
|
|
|
|
|
|
private final ConcurrentMap<Integer, AtomicInteger> timeoutCountByRequestType = |
|
|
|
@ -48,7 +45,8 @@ public class PeerReputation implements Comparable<PeerReputation> { |
|
|
|
|
private final Queue<Long> uselessResponseTimes = new ConcurrentLinkedQueue<>(); |
|
|
|
|
|
|
|
|
|
private static final int SMALL_ADJUSTMENT = 1; |
|
|
|
|
private static final int LARGE_ADJUSTMENT = 5; |
|
|
|
|
private static final int LARGE_ADJUSTMENT = 10; |
|
|
|
|
|
|
|
|
|
private int score; |
|
|
|
|
|
|
|
|
|
private final int maxScore; |
|
|
|
@ -61,37 +59,22 @@ public class PeerReputation implements Comparable<PeerReputation> { |
|
|
|
|
checkArgument( |
|
|
|
|
initialScore <= maxScore, "Initial score must be less than or equal to max score"); |
|
|
|
|
this.maxScore = maxScore; |
|
|
|
|
this.hasBeenUsefulThreshold = Math.min(maxScore, initialScore + 10); |
|
|
|
|
this.score = initialScore; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public Optional<DisconnectReason> recordRequestTimeout(final int requestCode) { |
|
|
|
|
final int newTimeoutCount = getOrCreateTimeoutCount(requestCode).incrementAndGet(); |
|
|
|
|
if (newTimeoutCount >= TIMEOUT_THRESHOLD) { |
|
|
|
|
score -= LARGE_ADJUSTMENT; |
|
|
|
|
// don't trigger disconnect if this peer has a sufficiently high reputation score
|
|
|
|
|
if (peerHasNotBeenUseful()) { |
|
|
|
|
LOG.debug( |
|
|
|
|
"Disconnection triggered by {} repeated timeouts for requestCode {}, peer score {}", |
|
|
|
|
newTimeoutCount, |
|
|
|
|
requestCode, |
|
|
|
|
score); |
|
|
|
|
return Optional.of(DisconnectReason.TIMEOUT); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LOG.trace( |
|
|
|
|
"Not triggering disconnect for {} repeated timeouts for requestCode {} because peer has high score {}", |
|
|
|
|
LOG.debug( |
|
|
|
|
"Disconnection triggered by {} repeated timeouts for requestCode {}", |
|
|
|
|
newTimeoutCount, |
|
|
|
|
requestCode, |
|
|
|
|
score); |
|
|
|
|
requestCode); |
|
|
|
|
score -= LARGE_ADJUSTMENT; |
|
|
|
|
return Optional.of(DisconnectReason.TIMEOUT); |
|
|
|
|
} else { |
|
|
|
|
score -= SMALL_ADJUSTMENT; |
|
|
|
|
return Optional.empty(); |
|
|
|
|
} |
|
|
|
|
return Optional.empty(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private boolean peerHasNotBeenUseful() { |
|
|
|
|
return score < hasBeenUsefulThreshold; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void resetTimeoutCount(final int requestCode) { |
|
|
|
@ -113,19 +96,12 @@ public class PeerReputation implements Comparable<PeerReputation> { |
|
|
|
|
} |
|
|
|
|
if (uselessResponseTimes.size() >= USELESS_RESPONSE_THRESHOLD) { |
|
|
|
|
score -= LARGE_ADJUSTMENT; |
|
|
|
|
// don't trigger disconnect if this peer has a sufficiently high reputation score
|
|
|
|
|
if (peerHasNotBeenUseful()) { |
|
|
|
|
LOG.debug( |
|
|
|
|
"Disconnection triggered by exceeding useless response threshold, score {}", score); |
|
|
|
|
return Optional.of(DisconnectReason.USELESS_PEER); |
|
|
|
|
} |
|
|
|
|
LOG.trace( |
|
|
|
|
"Not triggering disconnect for exceeding useless response threshold because peer has high score {}", |
|
|
|
|
score); |
|
|
|
|
LOG.debug("Disconnection triggered by exceeding useless response threshold"); |
|
|
|
|
return Optional.of(DisconnectReason.USELESS_PEER); |
|
|
|
|
} else { |
|
|
|
|
score -= SMALL_ADJUSTMENT; |
|
|
|
|
return Optional.empty(); |
|
|
|
|
} |
|
|
|
|
return Optional.empty(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void recordUsefulResponse() { |
|
|
|
|