3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-14 11:15:51 +00:00

Fix more inconsistent synchronization bugs.

This commit is contained in:
Mike Hearn 2012-12-11 00:01:50 +01:00
parent 93fd045488
commit 372a23fbfe

View File

@ -152,7 +152,7 @@ public class Peer {
} }
@Override @Override
public String toString() { public synchronized String toString() {
if (address == null) { if (address == null) {
// User-provided NetworkConnection object. // User-provided NetworkConnection object.
return "Peer()"; return "Peer()";
@ -178,7 +178,9 @@ public class Peer {
@Override @Override
public void connectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { public void connectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
synchronized (Peer.this) {
address = new PeerAddress((InetSocketAddress)e.getValue()); address = new PeerAddress((InetSocketAddress)e.getValue());
}
channel = e.getChannel(); channel = e.getChannel();
super.connectRequested(ctx, e); super.connectRequested(ctx, e);
} }
@ -186,7 +188,10 @@ public class Peer {
/** Catch any exceptions, logging them and then closing the channel. */ /** Catch any exceptions, logging them and then closing the channel. */
@Override @Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
String s = address == null ? "?" : address.toString(); String s;
synchronized (Peer.this) {
s = address == null ? "?" : address.toString();
}
if (e.getCause() instanceof ConnectException || e.getCause() instanceof IOException) { if (e.getCause() instanceof ConnectException || e.getCause() instanceof IOException) {
// Short message for network errors // Short message for network errors
log.info(s + " - " + e.getCause().getMessage()); log.info(s + " - " + e.getCause().getMessage());
@ -263,7 +268,7 @@ public class Peer {
} }
} }
private void processAlert(AlertMessage m) { private synchronized void processAlert(AlertMessage m) {
try { try {
if (m.isSignatureValid()) { if (m.isSignatureValid()) {
log.info("Received alert from peer {}: {}", toString(), m.getStatusBar()); log.info("Received alert from peer {}: {}", toString(), m.getStatusBar());
@ -283,7 +288,7 @@ public class Peer {
return handler; return handler;
} }
private void processHeaders(HeadersMessage m) throws IOException, ProtocolException { private synchronized void processHeaders(HeadersMessage m) throws IOException, ProtocolException {
// Runs in network loop thread for this peer. // Runs in network loop thread for this peer.
// //
// This method can run if a peer just randomly sends us a "headers" message (should never happen), or more // This method can run if a peer just randomly sends us a "headers" message (should never happen), or more
@ -360,7 +365,7 @@ public class Peer {
}); });
} }
private void processBlock(Block m) throws IOException { private synchronized void processBlock(Block m) throws IOException {
log.debug("{}: Received broadcast block {}", address, m.getHashAsString()); log.debug("{}: Received broadcast block {}", address, m.getHashAsString());
try { try {
// Was this block requested by getBlock()? // Was this block requested by getBlock()?
@ -428,7 +433,7 @@ public class Peer {
}); });
} }
private void processInv(InventoryMessage inv) throws IOException { private synchronized void processInv(InventoryMessage inv) throws IOException {
// This should be called in the network loop thread for this peer. // This should be called in the network loop thread for this peer.
List<InventoryItem> items = inv.getItems(); List<InventoryItem> items = inv.getItems();
@ -560,7 +565,7 @@ public class Peer {
* *
* @param secondsSinceEpoch Time in seconds since the epoch or 0 to reset to always downloading block bodies. * @param secondsSinceEpoch Time in seconds since the epoch or 0 to reset to always downloading block bodies.
*/ */
public void setFastCatchupTime(long secondsSinceEpoch) { public synchronized void setFastCatchupTime(long secondsSinceEpoch) {
Preconditions.checkNotNull(blockChain); Preconditions.checkNotNull(blockChain);
if (secondsSinceEpoch == 0) { if (secondsSinceEpoch == 0) {
fastCatchupTimeSecs = params.genesisBlock.getTimeSeconds(); fastCatchupTimeSecs = params.genesisBlock.getTimeSeconds();
@ -653,7 +658,7 @@ public class Peer {
// multiple threads simultaneously. // multiple threads simultaneously.
private Sha256Hash lastGetBlocksBegin, lastGetBlocksEnd; private Sha256Hash lastGetBlocksBegin, lastGetBlocksEnd;
private void blockChainDownload(Sha256Hash toHash) throws IOException { private synchronized void blockChainDownload(Sha256Hash toHash) throws IOException {
// This may run in ANY thread. // This may run in ANY thread.
// The block chain download process is a bit complicated. Basically, we start with one or more blocks in a // The block chain download process is a bit complicated. Basically, we start with one or more blocks in a
@ -804,7 +809,7 @@ public class Peer {
* updated. * updated.
* @throws ProtocolException if the peer version is too low to support measurable pings. * @throws ProtocolException if the peer version is too low to support measurable pings.
*/ */
public ListenableFuture<Long> ping() throws IOException, ProtocolException { public synchronized ListenableFuture<Long> ping() throws IOException, ProtocolException {
int peerVersion = getPeerVersionMessage().clientVersion; int peerVersion = getPeerVersionMessage().clientVersion;
if (peerVersion < Pong.MIN_PROTOCOL_VERSION) if (peerVersion < Pong.MIN_PROTOCOL_VERSION)
throw new ProtocolException("Peer version is too low for measurable pings: " + peerVersion); throw new ProtocolException("Peer version is too low for measurable pings: " + peerVersion);
@ -837,7 +842,7 @@ public class Peer {
return (long)((double) sum / lastPingTimes.length); return (long)((double) sum / lastPingTimes.length);
} }
private void processPong(Pong m) { private synchronized void processPong(Pong m) {
ListIterator<PendingPing> it = pendingPings.listIterator(); ListIterator<PendingPing> it = pendingPings.listIterator();
PendingPing ping = null; PendingPing ping = null;
while (it.hasNext()) { while (it.hasNext()) {
@ -856,7 +861,7 @@ public class Peer {
* Returns the difference between our best chain height and the peers, which can either be positive if we are * Returns the difference between our best chain height and the peers, which can either be positive if we are
* behind the peer, or negative if the peer is ahead of us. * behind the peer, or negative if the peer is ahead of us.
*/ */
public int getPeerBlockHeightDifference() { public synchronized int getPeerBlockHeightDifference() {
// Chain will overflow signed int blocks in ~41,000 years. // Chain will overflow signed int blocks in ~41,000 years.
int chainHeight = (int) getBestHeight(); int chainHeight = (int) getBestHeight();
// chainHeight should not be zero/negative because we shouldn't have given the user a Peer that is to another // chainHeight should not be zero/negative because we shouldn't have given the user a Peer that is to another
@ -870,7 +875,7 @@ public class Peer {
* Returns true if this peer will try and download things it is sent in "inv" messages. Normally you only need * Returns true if this peer will try and download things it is sent in "inv" messages. Normally you only need
* one peer to be downloading data. Defaults to true. * one peer to be downloading data. Defaults to true.
*/ */
public boolean getDownloadData() { public synchronized boolean getDownloadData() {
return downloadData; return downloadData;
} }
@ -878,35 +883,35 @@ public class Peer {
* If set to false, the peer won't try and fetch blocks and transactions it hears about. Normally, only one * If set to false, the peer won't try and fetch blocks and transactions it hears about. Normally, only one
* peer should download missing blocks. Defaults to true. * peer should download missing blocks. Defaults to true.
*/ */
public void setDownloadData(boolean downloadData) { public synchronized void setDownloadData(boolean downloadData) {
this.downloadData = downloadData; this.downloadData = downloadData;
} }
/** /**
* @return the IP address and port of peer. * @return the IP address and port of peer.
*/ */
public PeerAddress getAddress() { public synchronized PeerAddress getAddress() {
return address; return address;
} }
/** /**
* @return various version numbers claimed by peer. * @return various version numbers claimed by peer.
*/ */
public VersionMessage getPeerVersionMessage() { public synchronized VersionMessage getPeerVersionMessage() {
return peerVersionMessage; return peerVersionMessage;
} }
/** /**
* @return various version numbers we claim. * @return various version numbers we claim.
*/ */
public VersionMessage getVersionMessage() { public synchronized VersionMessage getVersionMessage() {
return versionMessage; return versionMessage;
} }
/** /**
* @return the height of the best chain as claimed by peer: sum of its ver announcement and blocks announced since. * @return the height of the best chain as claimed by peer: sum of its ver announcement and blocks announced since.
*/ */
public long getBestHeight() { public synchronized long getBestHeight() {
return peerVersionMessage.bestHeight + blocksAnnounced; return peerVersionMessage.bestHeight + blocksAnnounced;
} }
} }