mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-03-11 01:36:57 +01:00
Peer: Prevent connecting to remote peers if required services are not supported.
This commit is contained in:
parent
c967fda4d6
commit
57f53f038c
2 changed files with 19 additions and 11 deletions
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue