mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-01-30 23:02:15 +00:00
Add a minimum version to Peer and use it to exclude peers so old they don't support pong messages.
This commit is contained in:
parent
f488c29c12
commit
5ce607f1ae
@ -89,7 +89,8 @@ public class Peer {
|
||||
// It is important to avoid a nasty edge case where we can end up with parallel chain downloads proceeding
|
||||
// simultaneously if we were to receive a newly solved block whilst parts of the chain are streaming to us.
|
||||
private HashSet<Sha256Hash> pendingBlockDownloads = new HashSet<Sha256Hash>();
|
||||
|
||||
// The lowest version number we're willing to accept. Lower than this will result in an immediate disconnect.
|
||||
private int minProtocolVersion = Pong.MIN_PROTOCOL_VERSION;
|
||||
// When an API user explicitly requests a block or transaction from a peer, the InventoryItem is put here
|
||||
// whilst waiting for the response. Synchronized on itself. Is not used for downloads Peer generates itself.
|
||||
private static class GetDataRequest {
|
||||
@ -279,6 +280,11 @@ public class Peer {
|
||||
listener.onPeerConnected(Peer.this);
|
||||
}
|
||||
});
|
||||
if (peerVersionMessage.clientVersion < minProtocolVersion) {
|
||||
log.warn("Connected to a peer speaking protocol version {} but need {}, closing",
|
||||
peerVersionMessage.clientVersion, minProtocolVersion);
|
||||
e.getChannel().close();
|
||||
}
|
||||
} else if (m instanceof VersionAck) {
|
||||
synchronized (Peer.this) {
|
||||
if (peerVersionMessage == null) {
|
||||
@ -295,7 +301,6 @@ public class Peer {
|
||||
} else if (m instanceof Pong) {
|
||||
processPong((Pong)m);
|
||||
} else {
|
||||
// TODO: Handle the other messages we can receive.
|
||||
log.warn("Received unhandled message: {}", m);
|
||||
}
|
||||
}
|
||||
@ -1203,4 +1208,21 @@ public class Peer {
|
||||
public synchronized long getBestHeight() {
|
||||
return peerVersionMessage.bestHeight + blocksAnnounced;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum P2P protocol version that is accepted. If the peer speaks a protocol version lower than this, it
|
||||
* will be disconnected.
|
||||
* @return if not-null then this is the future for the Peer disconnection event.
|
||||
*/
|
||||
public ChannelFuture setMinProtocolVersion(int minProtocolVersion) {
|
||||
synchronized (this) {
|
||||
this.minProtocolVersion = minProtocolVersion;
|
||||
}
|
||||
if (getVersionMessage().clientVersion < minProtocolVersion) {
|
||||
log.warn("{}: Disconnecting due to new min protocol version {}", this, minProtocolVersion);
|
||||
return Channels.close(channel);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -630,8 +630,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
t2.setLockTime(999999);
|
||||
// Add a fake input to t3 that goes nowhere.
|
||||
Sha256Hash t3 = Sha256Hash.create("abc".getBytes(Charset.forName("UTF-8")));
|
||||
t2.addInput(new TransactionInput(unitTestParams, t2, new byte[]{}, new TransactionOutPoint(unitTestParams, 0,
|
||||
t3)));
|
||||
t2.addInput(new TransactionInput(unitTestParams, t2, new byte[]{}, new TransactionOutPoint(unitTestParams, 0, t3)));
|
||||
t2.addOutput(Utils.toNanoCoins(1, 0), new ECKey());
|
||||
Transaction t1 = new Transaction(unitTestParams);
|
||||
t1.addInput(t2.getOutput(0));
|
||||
@ -664,6 +663,33 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
assertNull(vtx[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disconnectOldVersions1() throws Exception {
|
||||
expect(channel.close()).andReturn(null);
|
||||
control.replay();
|
||||
// Set up the connection with an old version.
|
||||
handler.connectRequested(ctx, new UpstreamChannelStateEvent(channel, ChannelState.CONNECTED, socketAddress));
|
||||
VersionMessage peerVersion = new VersionMessage(unitTestParams, OTHER_PEER_CHAIN_HEIGHT);
|
||||
peerVersion.clientVersion = 500;
|
||||
DownstreamMessageEvent versionEvent =
|
||||
new DownstreamMessageEvent(channel, Channels.future(channel), peerVersion, null);
|
||||
handler.messageReceived(ctx, versionEvent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disconnectOldVersions2() throws Exception {
|
||||
expect(channel.close()).andReturn(null);
|
||||
control.replay();
|
||||
// Set up the connection with an old version.
|
||||
handler.connectRequested(ctx, new UpstreamChannelStateEvent(channel, ChannelState.CONNECTED, socketAddress));
|
||||
VersionMessage peerVersion = new VersionMessage(unitTestParams, OTHER_PEER_CHAIN_HEIGHT);
|
||||
peerVersion.clientVersion = 70000;
|
||||
DownstreamMessageEvent versionEvent =
|
||||
new DownstreamMessageEvent(channel, Channels.future(channel), peerVersion, null);
|
||||
handler.messageReceived(ctx, versionEvent);
|
||||
peer.setMinProtocolVersion(500);
|
||||
}
|
||||
|
||||
// TODO: Use generics here to avoid unnecessary casting.
|
||||
private Message outbound() {
|
||||
List<DownstreamMessageEvent> messages = event.getValues();
|
||||
|
Loading…
Reference in New Issue
Block a user