mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-15 11:45:51 +00:00
Peer: Both halves of the version handshake need to be complete before the protocol can continue.
This commit is contained in:
parent
b2d7b95450
commit
709e6f7562
@ -153,11 +153,13 @@ public class Peer extends PeerSocketHandler {
|
|||||||
private static final int PING_MOVING_AVERAGE_WINDOW = 20;
|
private static final int PING_MOVING_AVERAGE_WINDOW = 20;
|
||||||
|
|
||||||
private volatile VersionMessage vPeerVersionMessage;
|
private volatile VersionMessage vPeerVersionMessage;
|
||||||
private boolean isAcked;
|
|
||||||
|
|
||||||
// A settable future which completes (with this) when the connection is open
|
// A settable future which completes (with this) when the connection is open
|
||||||
private final SettableFuture<Peer> connectionOpenFuture = SettableFuture.create();
|
private final SettableFuture<Peer> connectionOpenFuture = SettableFuture.create();
|
||||||
private final SettableFuture<Peer> versionHandshakeFuture = SettableFuture.create();
|
private final SettableFuture<Peer> outgoingVersionHandshakeFuture = SettableFuture.create();
|
||||||
|
private final SettableFuture<Peer> incomingVersionHandshakeFuture = SettableFuture.create();
|
||||||
|
private final ListenableFuture<List<Peer>> versionHandshakeFuture = Futures
|
||||||
|
.allAsList(outgoingVersionHandshakeFuture, incomingVersionHandshakeFuture);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Construct a peer that reads/writes from the given block chain.</p>
|
* <p>Construct a peer that reads/writes from the given block chain.</p>
|
||||||
@ -219,11 +221,17 @@ public class Peer extends PeerSocketHandler {
|
|||||||
this.getDataFutures = new CopyOnWriteArrayList<GetDataRequest>();
|
this.getDataFutures = new CopyOnWriteArrayList<GetDataRequest>();
|
||||||
this.getAddrFutures = new LinkedList<SettableFuture<AddressMessage>>();
|
this.getAddrFutures = new LinkedList<SettableFuture<AddressMessage>>();
|
||||||
this.fastCatchupTimeSecs = params.getGenesisBlock().getTimeSeconds();
|
this.fastCatchupTimeSecs = params.getGenesisBlock().getTimeSeconds();
|
||||||
this.isAcked = false;
|
|
||||||
this.pendingPings = new CopyOnWriteArrayList<PendingPing>();
|
this.pendingPings = new CopyOnWriteArrayList<PendingPing>();
|
||||||
this.vMinProtocolVersion = params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.PONG);
|
this.vMinProtocolVersion = params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.PONG);
|
||||||
this.wallets = new CopyOnWriteArrayList<Wallet>();
|
this.wallets = new CopyOnWriteArrayList<Wallet>();
|
||||||
this.context = Context.get();
|
this.context = Context.get();
|
||||||
|
|
||||||
|
this.versionHandshakeFuture.addListener(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
versionHandshakeComplete();
|
||||||
|
}
|
||||||
|
}, Threading.SAME_THREAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -426,7 +434,7 @@ public class Peer extends PeerSocketHandler {
|
|||||||
return connectionOpenFuture;
|
return connectionOpenFuture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenableFuture<Peer> getVersionHandshakeFuture() {
|
public ListenableFuture<List<Peer>> getVersionHandshakeFuture() {
|
||||||
return versionHandshakeFuture;
|
return versionHandshakeFuture;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,9 +535,6 @@ public class Peer extends PeerSocketHandler {
|
|||||||
vPeerVersionMessage.localServices,
|
vPeerVersionMessage.localServices,
|
||||||
String.format(Locale.US, "%tF %tT", peerTime, peerTime),
|
String.format(Locale.US, "%tF %tT", peerTime, peerTime),
|
||||||
vPeerVersionMessage.bestHeight);
|
vPeerVersionMessage.bestHeight);
|
||||||
// Now it's our turn ...
|
|
||||||
// Send an ACK message stating we accept the peers protocol version.
|
|
||||||
sendMessage(new VersionAck());
|
|
||||||
// bitcoinj is a client mode implementation. That means there's not much point in us talking to other client
|
// 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
|
// 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
|
// implementations claim to have a block chain in their services field but then report a height of zero, filter
|
||||||
@ -544,18 +549,27 @@ public class Peer extends PeerSocketHandler {
|
|||||||
if (vPeerVersionMessage.bestHeight < 0)
|
if (vPeerVersionMessage.bestHeight < 0)
|
||||||
// In this case, it's a protocol violation.
|
// 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: " + vPeerVersionMessage.bestHeight);
|
||||||
versionHandshakeFuture.set(this);
|
// Now it's our turn ...
|
||||||
|
// Send an ACK message stating we accept the peers protocol version.
|
||||||
|
sendMessage(new VersionAck());
|
||||||
|
log.debug("{}: Incoming version handshake complete.", this);
|
||||||
|
incomingVersionHandshakeFuture.set(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processVersionAck(VersionAck m) throws ProtocolException {
|
private void processVersionAck(VersionAck m) throws ProtocolException {
|
||||||
if (vPeerVersionMessage == null) {
|
if (vPeerVersionMessage == null) {
|
||||||
throw new ProtocolException("got a version ack before version");
|
throw new ProtocolException("got a version ack before version");
|
||||||
}
|
}
|
||||||
if (isAcked) {
|
if (outgoingVersionHandshakeFuture.isDone()) {
|
||||||
throw new ProtocolException("got more than one version ack");
|
throw new ProtocolException("got more than one version ack");
|
||||||
}
|
}
|
||||||
isAcked = true;
|
log.debug("{}: Outgoing version handshake complete.", this);
|
||||||
this.setTimeoutEnabled(false);
|
outgoingVersionHandshakeFuture.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void versionHandshakeComplete() {
|
||||||
|
log.debug("{}: Handshake complete.", this);
|
||||||
|
setTimeoutEnabled(false);
|
||||||
for (final ListenerRegistration<PeerConnectedEventListener> registration : connectedEventListeners) {
|
for (final ListenerRegistration<PeerConnectedEventListener> registration : connectedEventListeners) {
|
||||||
registration.executor.execute(new Runnable() {
|
registration.executor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user