mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-11-02 05:27:17 +00:00
Ensure peer.eventListeners is always accessed under the peer lock, and switch to EventListenerInvoker in most places so listeners can remove themselves.
Resolves issue 210.
This commit is contained in:
@@ -188,16 +188,17 @@ public class Peer {
|
|||||||
|
|
||||||
/** Handle incoming Bitcoin messages */
|
/** Handle incoming Bitcoin messages */
|
||||||
@Override
|
@Override
|
||||||
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
|
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
|
||||||
throws Exception {
|
|
||||||
Message m = (Message)e.getMessage();
|
Message m = (Message)e.getMessage();
|
||||||
|
|
||||||
// Allow event listeners to filter the message stream. Listeners are allowed to drop messages by
|
// Allow event listeners to filter the message stream. Listeners are allowed to drop messages by
|
||||||
// returning null.
|
// returning null.
|
||||||
for (PeerEventListener listener : eventListeners) {
|
synchronized (Peer.this) {
|
||||||
synchronized (listener) {
|
for (PeerEventListener listener : eventListeners) {
|
||||||
m = listener.onPreMessageReceived(Peer.this, m);
|
synchronized (listener) {
|
||||||
if (m == null) break;
|
m = listener.onPreMessageReceived(Peer.this, m);
|
||||||
|
if (m == null) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,17 +329,19 @@ public class Peer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processTransaction(Transaction tx) {
|
private synchronized void processTransaction(Transaction tx) {
|
||||||
log.info("Received broadcast tx {}", tx.getHashAsString());
|
log.info("Received broadcast tx {}", tx.getHashAsString());
|
||||||
if (memoryPool != null) {
|
if (memoryPool != null) {
|
||||||
// We may get back a different transaction object.
|
// We may get back a different transaction object.
|
||||||
tx = memoryPool.seen(tx, getAddress());
|
tx = memoryPool.seen(tx, getAddress());
|
||||||
}
|
}
|
||||||
for (PeerEventListener listener : eventListeners) {
|
final Transaction ftx = tx;
|
||||||
synchronized (listener) {
|
EventListenerInvoker.invoke(eventListeners, new EventListenerInvoker<PeerEventListener>() {
|
||||||
listener.onTransaction(this, tx);
|
@Override
|
||||||
|
public void invoke(PeerEventListener listener) {
|
||||||
|
listener.onTransaction(Peer.this, ftx);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processBlock(Block m) throws IOException {
|
private void processBlock(Block m) throws IOException {
|
||||||
@@ -394,7 +397,7 @@ public class Peer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invokeOnBlocksDownloaded(final Block m) {
|
private synchronized void invokeOnBlocksDownloaded(final Block m) {
|
||||||
// It is possible for the peer block height difference to be negative when blocks have been solved and broadcast
|
// It is possible for the peer block height difference to be negative when blocks have been solved and broadcast
|
||||||
// since the time we first connected to the peer. However, it's weird and unexpected to receive a callback
|
// since the time we first connected to the peer. However, it's weird and unexpected to receive a callback
|
||||||
// with negative "blocks left" in this case, so we clamp to zero so the API user doesn't have to think about it.
|
// with negative "blocks left" in this case, so we clamp to zero so the API user doesn't have to think about it.
|
||||||
@@ -705,16 +708,17 @@ public class Peer {
|
|||||||
* Starts an asynchronous download of the block chain. The chain download is deemed to be complete once we've
|
* Starts an asynchronous download of the block chain. The chain download is deemed to be complete once we've
|
||||||
* downloaded the same number of blocks that the peer advertised having in its version handshake message.
|
* downloaded the same number of blocks that the peer advertised having in its version handshake message.
|
||||||
*/
|
*/
|
||||||
public void startBlockChainDownload() throws IOException {
|
public synchronized void startBlockChainDownload() throws IOException {
|
||||||
setDownloadData(true);
|
setDownloadData(true);
|
||||||
// TODO: peer might still have blocks that we don't have, and even have a heavier
|
// TODO: peer might still have blocks that we don't have, and even have a heavier
|
||||||
// chain even if the chain block count is lower.
|
// chain even if the chain block count is lower.
|
||||||
if (getPeerBlockHeightDifference() >= 0) {
|
if (getPeerBlockHeightDifference() >= 0) {
|
||||||
for (PeerEventListener listener : eventListeners) {
|
EventListenerInvoker.invoke(eventListeners, new EventListenerInvoker<PeerEventListener>() {
|
||||||
synchronized (listener) {
|
@Override
|
||||||
listener.onChainDownloadStarted(this, getPeerBlockHeightDifference());
|
public void invoke(PeerEventListener listener) {
|
||||||
|
listener.onChainDownloadStarted(Peer.this, getPeerBlockHeightDifference());
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
// When we just want as many blocks as possible, we can set the target hash to zero.
|
// When we just want as many blocks as possible, we can set the target hash to zero.
|
||||||
blockChainDownload(Sha256Hash.ZERO_HASH);
|
blockChainDownload(Sha256Hash.ZERO_HASH);
|
||||||
|
|||||||
Reference in New Issue
Block a user