Peer: Prevent connecting to remote peers if required services are not supported.

This commit is contained in:
Andreas Schildbach 2020-03-04 17:15:07 +01:00
parent c967fda4d6
commit 57f53f038c
2 changed files with 19 additions and 11 deletions

View file

@ -68,6 +68,7 @@ public class Peer extends PeerSocketHandler {
private final NetworkParameters params;
private final AbstractBlockChain blockChain;
private final long requiredServices;
private final Context context;
private final CopyOnWriteArrayList<ListenerRegistration<BlocksDownloadedEventListener>> blocksDownloadedEventListeners
@ -206,7 +207,7 @@ public class Peer extends PeerSocketHandler {
*/
public Peer(NetworkParameters params, VersionMessage ver, PeerAddress remoteAddress,
@Nullable AbstractBlockChain chain) {
this(params, ver, remoteAddress, chain, Integer.MAX_VALUE);
this(params, ver, remoteAddress, chain, 0, Integer.MAX_VALUE);
}
/**
@ -224,12 +225,13 @@ public class Peer extends PeerSocketHandler {
* used to keep track of which peers relayed transactions and offer more descriptive logging.</p>
*/
public Peer(NetworkParameters params, VersionMessage ver, PeerAddress remoteAddress,
@Nullable AbstractBlockChain chain, int downloadTxDependencyDepth) {
@Nullable AbstractBlockChain chain, long requiredServices, int downloadTxDependencyDepth) {
super(params, remoteAddress);
this.params = Preconditions.checkNotNull(params);
this.versionMessage = Preconditions.checkNotNull(ver);
this.vDownloadTxDependencyDepth = chain != null ? downloadTxDependencyDepth : 0;
this.blockChain = chain; // Allowed to be null.
this.requiredServices = requiredServices;
this.vDownloadData = chain != null;
this.getDataFutures = new CopyOnWriteArrayList<>();
this.getAddrFutures = new LinkedList<>();
@ -520,33 +522,39 @@ public class Peer extends PeerSocketHandler {
future.set(m);
}
private void processVersionMessage(VersionMessage m) throws ProtocolException {
private void processVersionMessage(VersionMessage peerVersionMessage) throws ProtocolException {
if (vPeerVersionMessage != null)
throw new ProtocolException("Got two version messages from peer");
vPeerVersionMessage = m;
vPeerVersionMessage = peerVersionMessage;
// Switch to the new protocol version.
log.info(toString());
// bitcoinj is a client mode implementation. That means there's not much point in us talking to other client
// mode nodes because we can't download the data from them we need to find/verify transactions. Some bogus
// implementations claim to have a block chain in their services field but then report a height of zero, filter
// them out here.
if (!vPeerVersionMessage.hasLimitedBlockChain() ||
(!params.allowEmptyPeerChain() && vPeerVersionMessage.bestHeight == 0)) {
if (!peerVersionMessage.hasLimitedBlockChain() ||
(!params.allowEmptyPeerChain() && peerVersionMessage.bestHeight == 0)) {
// Shut down the channel gracefully.
log.info("{}: Peer does not have at least a recent part of the block chain.", this);
close();
return;
}
if ((vPeerVersionMessage.localServices
& VersionMessage.NODE_BITCOIN_CASH) == VersionMessage.NODE_BITCOIN_CASH) {
if ((peerVersionMessage.localServices & requiredServices) != requiredServices) {
log.info("{}: Peer doesn't support these required services: {}", this,
VersionMessage.toStringServices(requiredServices & ~peerVersionMessage.localServices));
// Shut down the channel gracefully.
close();
return;
}
if ((peerVersionMessage.localServices & VersionMessage.NODE_BITCOIN_CASH) == VersionMessage.NODE_BITCOIN_CASH) {
log.info("{}: Peer follows an incompatible block chain.", this);
// Shut down the channel gracefully.
close();
return;
}
if (vPeerVersionMessage.bestHeight < 0)
if (peerVersionMessage.bestHeight < 0)
// In this case, it's a protocol violation.
throw new ProtocolException("Peer reports invalid best height: " + vPeerVersionMessage.bestHeight);
throw new ProtocolException("Peer reports invalid best height: " + peerVersionMessage.bestHeight);
// Now it's our turn ...
// Send an ACK message stating we accept the peers protocol version.
sendMessage(new VersionAck());

View file

@ -1382,7 +1382,7 @@ public class PeerGroup implements TransactionBroadcaster {
/** You can override this to customise the creation of {@link Peer} objects. */
@GuardedBy("lock")
protected Peer createPeer(PeerAddress address, VersionMessage ver) {
return new Peer(params, ver, address, chain, downloadTxDependencyDepth);
return new Peer(params, ver, address, chain, requiredServices, downloadTxDependencyDepth);
}
/**