mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-11-01 21:17:13 +00:00
Split peer event listeners into single method interfaces
This commit is contained in:
committed by
Andreas Schildbach
parent
76c16b41e5
commit
3d3dd6f721
@@ -76,9 +76,18 @@ public class Peer extends PeerSocketHandler {
|
||||
this.callOnDisconnect = callOnDisconnect;
|
||||
}
|
||||
}
|
||||
private final CopyOnWriteArrayList<PeerConnectionListenerRegistration> connectionEventListeners;
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<PeerDataEventListener>> dataEventListeners;
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<OnTransactionBroadcastListener>> onTransactionEventListeners;
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<BlocksDownloadedEventListener>> blocksDownloadedEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<BlocksDownloadedEventListener>>();
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<ChainDownloadStartedEventListener>> chainDownloadStartedEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<ChainDownloadStartedEventListener>>();
|
||||
private final CopyOnWriteArrayList<PeerConnectionListenerRegistration> connectionEventListeners
|
||||
= new CopyOnWriteArrayList<PeerConnectionListenerRegistration>();
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<GetDataEventListener>> getDataEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<GetDataEventListener>>();
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<PreMessageReceivedEventListener>> preMessageReceivedEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<PreMessageReceivedEventListener>>();
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<OnTransactionBroadcastListener>> onTransactionEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<OnTransactionBroadcastListener>>();
|
||||
// Whether to try and download blocks and transactions from this peer. Set to false by PeerGroup if not the
|
||||
// primary peer. This is to avoid redundant work and concurrency problems with downloading the same chain
|
||||
// in parallel.
|
||||
@@ -220,9 +229,6 @@ public class Peer extends PeerSocketHandler {
|
||||
this.blockChain = chain; // Allowed to be null.
|
||||
this.vDownloadData = chain != null;
|
||||
this.getDataFutures = new CopyOnWriteArrayList<GetDataRequest>();
|
||||
this.connectionEventListeners = new CopyOnWriteArrayList<PeerConnectionListenerRegistration>();
|
||||
this.dataEventListeners = new CopyOnWriteArrayList<ListenerRegistration<PeerDataEventListener>>();
|
||||
this.onTransactionEventListeners = new CopyOnWriteArrayList<ListenerRegistration<OnTransactionBroadcastListener>>();
|
||||
this.getAddrFutures = new LinkedList<SettableFuture<AddressMessage>>();
|
||||
this.fastCatchupTimeSecs = params.getGenesisBlock().getTimeSeconds();
|
||||
this.isAcked = false;
|
||||
@@ -254,23 +260,54 @@ public class Peer extends PeerSocketHandler {
|
||||
/** Deprecated: use the more specific event handler methods instead */
|
||||
@Deprecated @SuppressWarnings("deprecation")
|
||||
public void addEventListener(AbstractPeerEventListener listener) {
|
||||
addEventListener(listener, Threading.USER_THREAD);
|
||||
addBlocksDownloadedEventListener(Threading.USER_THREAD, listener);
|
||||
addChainDownloadStartedEventListener(Threading.USER_THREAD, listener);
|
||||
addConnectionEventListener(Threading.USER_THREAD, listener);
|
||||
addGetDataEventListener(Threading.USER_THREAD, listener);
|
||||
addOnTransactionBroadcastListener(Threading.USER_THREAD, listener);
|
||||
addPreMessageReceivedEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/** Deprecated: use the more specific event handler methods instead */
|
||||
@Deprecated
|
||||
public void addEventListener(AbstractPeerEventListener listener, Executor executor) {
|
||||
addBlocksDownloadedEventListener(executor, listener);
|
||||
addChainDownloadStartedEventListener(executor, listener);
|
||||
addConnectionEventListener(executor, listener);
|
||||
addDataEventListener(executor, listener);
|
||||
addGetDataEventListener(executor, listener);
|
||||
addOnTransactionBroadcastListener(executor, listener);
|
||||
addPreMessageReceivedEventListener(executor, listener);
|
||||
}
|
||||
|
||||
/** Deprecated: use the more specific event handler methods instead */
|
||||
@Deprecated
|
||||
public void removeEventListener(AbstractPeerEventListener listener) {
|
||||
removeBlocksDownloadedEventListener(listener);
|
||||
removeChainDownloadStartedEventListener(listener);
|
||||
removeConnectionEventListener(listener);
|
||||
removeDataEventListener(listener);
|
||||
removeGetDataEventListener(listener);
|
||||
removeOnTransactionBroadcastListener(listener);
|
||||
removePreMessageReceivedEventListener(listener);
|
||||
}
|
||||
|
||||
/** Registers a listener that is invoked when new blocks are downloaded. */
|
||||
public void addBlocksDownloadedEventListener(BlocksDownloadedEventListener listener) {
|
||||
addBlocksDownloadedEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/** Registers a listener that is invoked when new blocks are downloaded. */
|
||||
public void addBlocksDownloadedEventListener(Executor executor, BlocksDownloadedEventListener listener) {
|
||||
blocksDownloadedEventListeners.add(new ListenerRegistration(listener, executor));
|
||||
}
|
||||
|
||||
/** Registers a listener that is invoked when a blockchain downloaded starts. */
|
||||
public void addChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener) {
|
||||
addChainDownloadStartedEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/** Registers a listener that is invoked when a blockchain downloaded starts. */
|
||||
public void addChainDownloadStartedEventListener(Executor executor, ChainDownloadStartedEventListener listener) {
|
||||
chainDownloadStartedEventListeners.add(new ListenerRegistration(listener, executor));
|
||||
}
|
||||
|
||||
/** Registers a listener that is invoked when a peer is connected or disconnected. */
|
||||
@@ -284,13 +321,13 @@ public class Peer extends PeerSocketHandler {
|
||||
}
|
||||
|
||||
/** Registers a listener that is called when messages are received. */
|
||||
public void addDataEventListener(PeerDataEventListener listener) {
|
||||
addDataEventListener(Threading.USER_THREAD, listener);
|
||||
public void addGetDataEventListener(GetDataEventListener listener) {
|
||||
addGetDataEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/** Registers a listener that is called when messages are received. */
|
||||
public void addDataEventListener(Executor executor, PeerDataEventListener listener) {
|
||||
dataEventListeners.add(new ListenerRegistration<PeerDataEventListener>(listener, executor));
|
||||
public void addGetDataEventListener(Executor executor, GetDataEventListener listener) {
|
||||
getDataEventListeners.add(new ListenerRegistration<GetDataEventListener>(listener, executor));
|
||||
}
|
||||
|
||||
/** Registers a listener that is called when a transaction is broadcast across the network */
|
||||
@@ -303,23 +340,45 @@ public class Peer extends PeerSocketHandler {
|
||||
onTransactionEventListeners.add(new ListenerRegistration<OnTransactionBroadcastListener>(listener, executor));
|
||||
}
|
||||
|
||||
/** Registers a listener that is called immediately before a message is received */
|
||||
public void addPreMessageReceivedEventListener(PreMessageReceivedEventListener listener) {
|
||||
addPreMessageReceivedEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/** Registers a listener that is called immediately before a message is received */
|
||||
public void addPreMessageReceivedEventListener(Executor executor, PreMessageReceivedEventListener listener) {
|
||||
preMessageReceivedEventListeners.add(new ListenerRegistration<PreMessageReceivedEventListener>(listener, executor));
|
||||
}
|
||||
|
||||
// Package-local version for PeerGroup
|
||||
void addConnectionEventListenerWithoutOnDisconnect(Executor executor, PeerConnectionEventListener listener) {
|
||||
connectionEventListeners.add(new PeerConnectionListenerRegistration(listener, executor, false));
|
||||
}
|
||||
|
||||
public boolean removeBlocksDownloadedEventListener(BlocksDownloadedEventListener listener) {
|
||||
return ListenerRegistration.removeFromList(listener, blocksDownloadedEventListeners);
|
||||
}
|
||||
|
||||
public boolean removeChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener) {
|
||||
return ListenerRegistration.removeFromList(listener, chainDownloadStartedEventListeners);
|
||||
}
|
||||
|
||||
public boolean removeConnectionEventListener(PeerConnectionEventListener listener) {
|
||||
return ListenerRegistration.removeFromList(listener, connectionEventListeners);
|
||||
}
|
||||
|
||||
public boolean removeDataEventListener(PeerDataEventListener listener) {
|
||||
return ListenerRegistration.removeFromList(listener, dataEventListeners);
|
||||
public boolean removeGetDataEventListener(GetDataEventListener listener) {
|
||||
return ListenerRegistration.removeFromList(listener, getDataEventListeners);
|
||||
}
|
||||
|
||||
public boolean removeOnTransactionBroadcastListener(OnTransactionBroadcastListener listener) {
|
||||
return ListenerRegistration.removeFromList(listener, onTransactionEventListeners);
|
||||
}
|
||||
|
||||
public boolean removePreMessageReceivedEventListener(PreMessageReceivedEventListener listener) {
|
||||
return ListenerRegistration.removeFromList(listener, preMessageReceivedEventListeners);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
PeerAddress addr = getAddress();
|
||||
@@ -376,7 +435,7 @@ public class Peer extends PeerSocketHandler {
|
||||
protected void processMessage(Message m) throws Exception {
|
||||
// Allow event listeners to filter the message stream. Listeners are allowed to drop messages by
|
||||
// returning null.
|
||||
for (ListenerRegistration<PeerDataEventListener> registration : dataEventListeners) {
|
||||
for (ListenerRegistration<PreMessageReceivedEventListener> registration : preMessageReceivedEventListeners) {
|
||||
// Skip any listeners that are supposed to run in another thread as we don't want to block waiting
|
||||
// for it, which might cause circular deadlock.
|
||||
if (registration.executor == Threading.SAME_THREAD) {
|
||||
@@ -642,13 +701,13 @@ public class Peer extends PeerSocketHandler {
|
||||
protected void processGetData(GetDataMessage getdata) {
|
||||
log.info("{}: Received getdata message: {}", getAddress(), getdata.toString());
|
||||
ArrayList<Message> items = new ArrayList<Message>();
|
||||
for (ListenerRegistration<PeerDataEventListener> registration : dataEventListeners) {
|
||||
for (ListenerRegistration<GetDataEventListener> registration : getDataEventListeners) {
|
||||
if (registration.executor != Threading.SAME_THREAD) continue;
|
||||
List<Message> listenerItems = registration.listener.getData(this, getdata);
|
||||
if (listenerItems == null) continue;
|
||||
items.addAll(listenerItems);
|
||||
}
|
||||
if (items.size() == 0) {
|
||||
if (items.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
log.info("{}: Sending {} items gathered from listeners to peer", getAddress(), items.size());
|
||||
@@ -1055,7 +1114,7 @@ public class Peer extends PeerSocketHandler {
|
||||
// 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.
|
||||
final int blocksLeft = Math.max(0, (int) vPeerVersionMessage.bestHeight - checkNotNull(blockChain).getBestChainHeight());
|
||||
for (final ListenerRegistration<PeerDataEventListener> registration : dataEventListeners) {
|
||||
for (final ListenerRegistration<BlocksDownloadedEventListener> registration : blocksDownloadedEventListeners) {
|
||||
registration.executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -1388,7 +1447,7 @@ public class Peer extends PeerSocketHandler {
|
||||
// chain even if the chain block count is lower.
|
||||
final int blocksLeft = getPeerBlockHeightDifference();
|
||||
if (blocksLeft >= 0) {
|
||||
for (final ListenerRegistration<PeerDataEventListener> registration : dataEventListeners) {
|
||||
for (final ListenerRegistration<ChainDownloadStartedEventListener> registration : chainDownloadStartedEventListeners) {
|
||||
registration.executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
@@ -116,11 +116,20 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
@GuardedBy("lock") private Peer downloadPeer;
|
||||
// Callback for events related to chain download.
|
||||
@Nullable @GuardedBy("lock") private PeerDataEventListener downloadListener;
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<BlocksDownloadedEventListener>> peersBlocksDownloadedEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<BlocksDownloadedEventListener>>();
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<ChainDownloadStartedEventListener>> peersChainDownloadStartedEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<ChainDownloadStartedEventListener>>();
|
||||
/** Callbacks for events related to peer connection/disconnection */
|
||||
protected final CopyOnWriteArrayList<ListenerRegistration<PeerConnectionEventListener>> peerConnectionEventListeners;
|
||||
protected final CopyOnWriteArrayList<ListenerRegistration<PeerConnectionEventListener>> peerConnectionEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<PeerConnectionEventListener>>();
|
||||
/** Callbacks for events related to peer data being received */
|
||||
protected final CopyOnWriteArrayList<ListenerRegistration<PeerDataEventListener>> peerDataEventListeners;
|
||||
protected final CopyOnWriteArrayList<ListenerRegistration<OnTransactionBroadcastListener>> onTransactionBroadastEventListeners;
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<GetDataEventListener>> peerGetDataEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<GetDataEventListener>>();
|
||||
private final CopyOnWriteArrayList<ListenerRegistration<PreMessageReceivedEventListener>> peersPreMessageReceivedEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<PreMessageReceivedEventListener>>();
|
||||
protected final CopyOnWriteArrayList<ListenerRegistration<OnTransactionBroadcastListener>> peersTransactionBroadastEventListeners
|
||||
= new CopyOnWriteArrayList<ListenerRegistration<OnTransactionBroadcastListener>>();
|
||||
// Peer discovery sources, will be polled occasionally if there aren't enough inactives.
|
||||
private final CopyOnWriteArraySet<PeerDiscovery> peerDiscoverers;
|
||||
// The version message to use for new connections.
|
||||
@@ -146,25 +155,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
|
||||
// This event listener is added to every peer. It's here so when we announce transactions via an "inv", every
|
||||
// peer can fetch them.
|
||||
private final AbstractPeerDataEventListener peerListener = new AbstractPeerDataEventListener() {
|
||||
@Override
|
||||
public List<Message> getData(Peer peer, GetDataMessage m) {
|
||||
return handleGetData(m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlocksDownloaded(Peer peer, Block block, @Nullable FilteredBlock filteredBlock, int blocksLeft) {
|
||||
if (chain == null) return;
|
||||
final double rate = chain.getFalsePositiveRate();
|
||||
final double target = bloomFilterMerger.getBloomFilterFPRate() * MAX_FP_RATE_INCREASE;
|
||||
if (rate > target) {
|
||||
// TODO: Avoid hitting this path if the remote peer didn't acknowledge applying a new filter yet.
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Force update Bloom filter due to high false positive rate ({} vs {})", rate, target);
|
||||
recalculateFastCatchupAndFilter(FilterRecalculateMode.FORCE_SEND_FOR_REFRESH);
|
||||
}
|
||||
}
|
||||
};
|
||||
private final PeerListener peerListener = new PeerListener();
|
||||
|
||||
private int minBroadcastConnections = 0;
|
||||
private final ScriptsChangeEventListener walletScriptEventListener = new ScriptsChangeEventListener() {
|
||||
@@ -226,6 +217,30 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
// in broadcastTransaction.
|
||||
private final Set<TransactionBroadcast> runningBroadcasts;
|
||||
|
||||
private class PeerListener implements GetDataEventListener, BlocksDownloadedEventListener {
|
||||
|
||||
public PeerListener() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Message> getData(Peer peer, GetDataMessage m) {
|
||||
return handleGetData(m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlocksDownloaded(Peer peer, Block block, @Nullable FilteredBlock filteredBlock, int blocksLeft) {
|
||||
if (chain == null) return;
|
||||
final double rate = chain.getFalsePositiveRate();
|
||||
final double target = bloomFilterMerger.getBloomFilterFPRate() * MAX_FP_RATE_INCREASE;
|
||||
if (rate > target) {
|
||||
// TODO: Avoid hitting this path if the remote peer didn't acknowledge applying a new filter yet.
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Force update Bloom filter due to high false positive rate ({} vs {})", rate, target);
|
||||
recalculateFastCatchupAndFilter(FilterRecalculateMode.FORCE_SEND_FOR_REFRESH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PeerStartupListener extends AbstractPeerConnectionEventListener {
|
||||
@Override
|
||||
public void onPeerConnected(Peer peer, int peerCount) {
|
||||
@@ -324,7 +339,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
* <p>The user does not need any additional software for this: it's all pure Java. As of April 2014 <b>this mode
|
||||
* is experimental</b>.</p>
|
||||
*
|
||||
* @params doDiscovery if true, DNS or HTTP peer discovery will be performed via Tor: this is almost always what you want.
|
||||
* @param doDiscovery if true, DNS or HTTP peer discovery will be performed via Tor: this is almost always what you want.
|
||||
* @throws java.util.concurrent.TimeoutException if Tor fails to start within 20 seconds.
|
||||
*/
|
||||
public static PeerGroup newWithTor(Context context, @Nullable AbstractBlockChain chain, TorClient torClient, boolean doDiscovery) throws TimeoutException {
|
||||
@@ -411,9 +426,6 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
pendingPeers = new CopyOnWriteArrayList<Peer>();
|
||||
channels = connectionManager;
|
||||
peerDiscoverers = new CopyOnWriteArraySet<PeerDiscovery>();
|
||||
peerConnectionEventListeners = new CopyOnWriteArrayList<ListenerRegistration<PeerConnectionEventListener>>();
|
||||
peerDataEventListeners = new CopyOnWriteArrayList<ListenerRegistration<PeerDataEventListener>>();
|
||||
onTransactionBroadastEventListeners = new CopyOnWriteArrayList<ListenerRegistration<OnTransactionBroadcastListener>>();
|
||||
runningBroadcasts = Collections.synchronizedSet(new HashSet<TransactionBroadcast>());
|
||||
bloomFilterMerger = new FilterMerger(DEFAULT_BLOOM_FILTER_FP_RATE);
|
||||
vMinRequiredProtocolVersion = params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.BLOOM_FILTER);
|
||||
@@ -687,15 +699,74 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
setUserAgent(name, version, null);
|
||||
}
|
||||
|
||||
/** Use the more specific listener methods instead */
|
||||
@Deprecated @SuppressWarnings("deprecation")
|
||||
public void addEventListener(AbstractPeerEventListener listener, Executor executor) {
|
||||
addBlocksDownloadedEventListener(Threading.USER_THREAD, listener);
|
||||
addChainDownloadStartedEventListener(Threading.USER_THREAD, listener);
|
||||
addConnectionEventListener(Threading.USER_THREAD, listener);
|
||||
addGetDataEventListener(Threading.USER_THREAD, listener);
|
||||
addOnTransactionBroadcastListener(Threading.USER_THREAD, listener);
|
||||
addPreMessageReceivedEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/** Use the more specific listener methods instead */
|
||||
@Deprecated @SuppressWarnings("deprecation")
|
||||
public void addEventListener(AbstractPeerEventListener listener) {
|
||||
addBlocksDownloadedEventListener(executor, listener);
|
||||
addChainDownloadStartedEventListener(executor, listener);
|
||||
addConnectionEventListener(executor, listener);
|
||||
addGetDataEventListener(executor, listener);
|
||||
addOnTransactionBroadcastListener(executor, listener);
|
||||
addPreMessageReceivedEventListener(executor, listener);
|
||||
}
|
||||
|
||||
/** See {@link Peer#addBlocksDownloadedEventListener(BlocksDownloadedEventListener)} */
|
||||
public void addBlocksDownloadedEventListener(BlocksDownloadedEventListener listener) {
|
||||
addBlocksDownloadedEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Adds a listener that will be notified on the given executor when
|
||||
* blocks are downloaded by the download peer.</p>
|
||||
* @see Peer#addBlocksDownloadedEventListener(Executor, BlocksDownloadedEventListener)
|
||||
*/
|
||||
public void addBlocksDownloadedEventListener(Executor executor, BlocksDownloadedEventListener listener) {
|
||||
peersBlocksDownloadedEventListeners.add(new ListenerRegistration<BlocksDownloadedEventListener>(checkNotNull(listener), executor));
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.addBlocksDownloadedEventListener(executor, listener);
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.addBlocksDownloadedEventListener(executor, listener);
|
||||
}
|
||||
|
||||
/** See {@link Peer#addBlocksDownloadedEventListener(BlocksDownloadedEventListener)} */
|
||||
public void addChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener) {
|
||||
addChainDownloadStartedEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Adds a listener that will be notified on the given executor when
|
||||
* chain download starts.</p>
|
||||
*/
|
||||
public void addChainDownloadStartedEventListener(Executor executor, ChainDownloadStartedEventListener listener) {
|
||||
peersChainDownloadStartedEventListeners.add(new ListenerRegistration<ChainDownloadStartedEventListener>(checkNotNull(listener), executor));
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.addChainDownloadStartedEventListener(executor, listener);
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.addChainDownloadStartedEventListener(executor, listener);
|
||||
}
|
||||
|
||||
/** See {@link Peer#addConnectionEventListener(PeerConnectionEventListener)} */
|
||||
public void addConnectionEventListener(PeerConnectionEventListener listener) {
|
||||
addConnectionEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Adds a listener that will be notified on the given executor when:</p>
|
||||
* <ol>
|
||||
* <li>New peers are discovered.</li>
|
||||
* <li>New peers are connected to.</li>
|
||||
* <li>Peers are disconnected from.</li>
|
||||
* <li>A message is received by the download peer (there is always one peer which is elected as a peer which
|
||||
* will be used to retrieve data).
|
||||
* <li>Blocks are downloaded by the download peer.</li>
|
||||
* </li>
|
||||
* </ol>
|
||||
*/
|
||||
@@ -703,22 +774,22 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
peerConnectionEventListeners.add(new ListenerRegistration<PeerConnectionEventListener>(checkNotNull(listener), executor));
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.addConnectionEventListener(executor, listener);
|
||||
for (Peer peer: getPendingPeers())
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.addConnectionEventListener(executor, listener);
|
||||
}
|
||||
|
||||
/** See {@link Peer#addDataEventListener(Executor, PeerDataEventListener)} */
|
||||
public void addDataEventListener(final Executor executor, final PeerDataEventListener listener) {
|
||||
peerDataEventListeners.add(new ListenerRegistration<PeerDataEventListener>(checkNotNull(listener), executor));
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.addDataEventListener(executor, listener);
|
||||
for (Peer peer: getPendingPeers())
|
||||
peer.addDataEventListener(executor, listener);
|
||||
/** See {@link Peer#addGetDataEventListener(GetDataEventListener)} */
|
||||
public void addGetDataEventListener(GetDataEventListener listener) {
|
||||
addGetDataEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/** See {@link Peer#addDataEventListener(PeerDataEventListener)} */
|
||||
public void addDataEventListener(PeerDataEventListener listener) {
|
||||
addDataEventListener(Threading.USER_THREAD, listener);
|
||||
/** See {@link Peer#addGetDataEventListener(Executor, GetDataEventListener)} */
|
||||
public void addGetDataEventListener(final Executor executor, final GetDataEventListener listener) {
|
||||
peerGetDataEventListeners.add(new ListenerRegistration<GetDataEventListener>(checkNotNull(listener), executor));
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.addGetDataEventListener(executor, listener);
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.addGetDataEventListener(executor, listener);
|
||||
}
|
||||
|
||||
/** See {@link Peer#addOnTransactionBroadcastListener(OnTransactionBroadcastListener)} */
|
||||
@@ -728,16 +799,54 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
|
||||
/** See {@link Peer#addOnTransactionBroadcastListener(OnTransactionBroadcastListener)} */
|
||||
public void addOnTransactionBroadcastListener(Executor executor, OnTransactionBroadcastListener listener) {
|
||||
onTransactionBroadastEventListeners.add(new ListenerRegistration<OnTransactionBroadcastListener>(checkNotNull(listener), executor));
|
||||
peersTransactionBroadastEventListeners.add(new ListenerRegistration<OnTransactionBroadcastListener>(checkNotNull(listener), executor));
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.addOnTransactionBroadcastListener(executor, listener);
|
||||
for (Peer peer: getPendingPeers())
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.addOnTransactionBroadcastListener(executor, listener);
|
||||
}
|
||||
|
||||
/** See {@link Peer#addConnectionEventListener(PeerConnectionEventListener)} */
|
||||
public void addConnectionEventListener(PeerConnectionEventListener listener) {
|
||||
addConnectionEventListener(Threading.USER_THREAD, listener);
|
||||
/** See {@link Peer#addPreMessageReceivedEventListener(PreMessageReceivedEventListener)} */
|
||||
public void addPreMessageReceivedEventListener(PreMessageReceivedEventListener listener) {
|
||||
addPreMessageReceivedEventListener(Threading.USER_THREAD, listener);
|
||||
}
|
||||
|
||||
/** See {@link Peer#addPreMessageReceivedEventListener(Executor, PreMessageReceivedEventListener)} */
|
||||
public void addPreMessageReceivedEventListener(Executor executor, PreMessageReceivedEventListener listener) {
|
||||
peersPreMessageReceivedEventListeners.add(new ListenerRegistration<PreMessageReceivedEventListener>(checkNotNull(listener), executor));
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.addPreMessageReceivedEventListener(executor, listener);
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.addPreMessageReceivedEventListener(executor, listener);
|
||||
}
|
||||
|
||||
/** Use the more specific listener methods instead */
|
||||
@Deprecated @SuppressWarnings("deprecation")
|
||||
public void removeEventListener(AbstractPeerEventListener listener) {
|
||||
removeBlocksDownloadedEventListener(listener);
|
||||
removeChainDownloadStartedEventListener(listener);
|
||||
removeConnectionEventListener(listener);
|
||||
removeGetDataEventListener(listener);
|
||||
removeOnTransactionBroadcastListener(listener);
|
||||
removePreMessageReceivedEventListener(listener);
|
||||
}
|
||||
|
||||
public boolean removeBlocksDownloadedEventListener(BlocksDownloadedEventListener listener) {
|
||||
boolean result = ListenerRegistration.removeFromList(listener, peersBlocksDownloadedEventListeners);
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.removeBlocksDownloadedEventListener(listener);
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.removeBlocksDownloadedEventListener(listener);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean removeChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener) {
|
||||
boolean result = ListenerRegistration.removeFromList(listener, peersChainDownloadStartedEventListeners);
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.removeChainDownloadStartedEventListener(listener);
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.removeChainDownloadStartedEventListener(listener);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** The given event listener will no longer be called with events. */
|
||||
@@ -751,18 +860,18 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
}
|
||||
|
||||
/** The given event listener will no longer be called with events. */
|
||||
public boolean removeDataEventListener(PeerDataEventListener listener) {
|
||||
boolean result = ListenerRegistration.removeFromList(listener, peerDataEventListeners);
|
||||
public boolean removeGetDataEventListener(GetDataEventListener listener) {
|
||||
boolean result = ListenerRegistration.removeFromList(listener, peerGetDataEventListeners);
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.removeDataEventListener(listener);
|
||||
peer.removeGetDataEventListener(listener);
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.removeDataEventListener(listener);
|
||||
peer.removeGetDataEventListener(listener);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** The given event listener will no longer be called with events. */
|
||||
public boolean removeOnTransactionBroadcastListener(OnTransactionBroadcastListener listener) {
|
||||
boolean result = ListenerRegistration.removeFromList(listener, onTransactionBroadastEventListeners);
|
||||
boolean result = ListenerRegistration.removeFromList(listener, peersTransactionBroadastEventListeners);
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.removeOnTransactionBroadcastListener(listener);
|
||||
for (Peer peer : getPendingPeers())
|
||||
@@ -770,26 +879,13 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Use the more specific listener methods instead */
|
||||
@Deprecated @SuppressWarnings("deprecation")
|
||||
public void addEventListener(AbstractPeerEventListener listener, Executor executor) {
|
||||
addConnectionEventListener(executor, listener);
|
||||
addDataEventListener(executor, listener);
|
||||
addOnTransactionBroadcastListener(executor, listener);
|
||||
}
|
||||
|
||||
/** Use the more specific listener methods instead */
|
||||
@Deprecated @SuppressWarnings("deprecation")
|
||||
public void addEventListener(AbstractPeerEventListener listener) {
|
||||
addEventListener(listener, Threading.USER_THREAD);
|
||||
}
|
||||
|
||||
/** Use the more specific listener methods instead */
|
||||
@Deprecated @SuppressWarnings("deprecation")
|
||||
public void removeEventListener(AbstractPeerEventListener listener) {
|
||||
removeConnectionEventListener(listener);
|
||||
removeDataEventListener(listener);
|
||||
removeOnTransactionBroadcastListener(listener);
|
||||
public boolean removePreMessageReceivedEventListener(PreMessageReceivedEventListener listener) {
|
||||
boolean result = ListenerRegistration.removeFromList(listener, peersPreMessageReceivedEventListeners);
|
||||
for (Peer peer : getConnectedPeers())
|
||||
peer.removePreMessageReceivedEventListener(listener);
|
||||
for (Peer peer : getPendingPeers())
|
||||
peer.removePreMessageReceivedEventListener(listener);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1273,7 +1369,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
|
||||
/**
|
||||
* Returns the number of currently connected peers. To be informed when this count changes, register a
|
||||
* {@link PeerEventListener} and use the onPeerConnected/onPeerDisconnected methods.
|
||||
* {@link org.bitcoinj.core.listeners.PeerConnectionEventListener} and use the onPeerConnected/onPeerDisconnected methods.
|
||||
*/
|
||||
public int numConnectedPeers() {
|
||||
return peers.size();
|
||||
@@ -1383,10 +1479,20 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
public void startBlockChainDownload(PeerDataEventListener listener) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (downloadPeer != null && this.downloadListener != null)
|
||||
downloadPeer.removeDataEventListener(this.downloadListener);
|
||||
if (downloadPeer != null && listener != null)
|
||||
downloadPeer.addDataEventListener(listener);
|
||||
if (downloadPeer != null) {
|
||||
if (this.downloadListener != null) {
|
||||
downloadPeer.removeBlocksDownloadedEventListener(this.downloadListener);
|
||||
downloadPeer.removeChainDownloadStartedEventListener(this.downloadListener);
|
||||
downloadPeer.removeGetDataEventListener(this.downloadListener);
|
||||
downloadPeer.removePreMessageReceivedEventListener(this.downloadListener);
|
||||
}
|
||||
if (listener != null) {
|
||||
downloadPeer.addBlocksDownloadedEventListener(listener);
|
||||
downloadPeer.addChainDownloadStartedEventListener(listener);
|
||||
downloadPeer.addGetDataEventListener(listener);
|
||||
downloadPeer.addPreMessageReceivedEventListener(listener);
|
||||
}
|
||||
}
|
||||
this.downloadListener = listener;
|
||||
// TODO: be more nuanced about which peer to download from. We can also try
|
||||
// downloading from multiple peers and handle the case when a new peer comes along
|
||||
@@ -1444,14 +1550,22 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
}
|
||||
}
|
||||
// Make sure the peer knows how to upload transactions that are requested from us.
|
||||
peer.addDataEventListener(Threading.SAME_THREAD, peerListener);
|
||||
peer.addBlocksDownloadedEventListener(Threading.SAME_THREAD, peerListener);
|
||||
peer.addGetDataEventListener(Threading.SAME_THREAD, peerListener);
|
||||
|
||||
// And set up event listeners for clients. This will allow them to find out about new transactions and blocks.
|
||||
for (ListenerRegistration<BlocksDownloadedEventListener> registration : peersBlocksDownloadedEventListeners)
|
||||
peer.addBlocksDownloadedEventListener(registration.executor, registration.listener);
|
||||
for (ListenerRegistration<ChainDownloadStartedEventListener> registration : peersChainDownloadStartedEventListeners)
|
||||
peer.addChainDownloadStartedEventListener(registration.executor, registration.listener);
|
||||
for (ListenerRegistration<PeerConnectionEventListener> registration : peerConnectionEventListeners)
|
||||
peer.addConnectionEventListenerWithoutOnDisconnect(registration.executor, registration.listener);
|
||||
for (ListenerRegistration<PeerDataEventListener> registration : peerDataEventListeners)
|
||||
peer.addDataEventListener(registration.executor, registration.listener);
|
||||
for (ListenerRegistration<OnTransactionBroadcastListener> registration : onTransactionBroadastEventListeners)
|
||||
for (ListenerRegistration<GetDataEventListener> registration : peerGetDataEventListeners)
|
||||
peer.addGetDataEventListener(registration.executor, registration.listener);
|
||||
for (ListenerRegistration<OnTransactionBroadcastListener> registration : peersTransactionBroadastEventListeners)
|
||||
peer.addOnTransactionBroadcastListener(registration.executor, registration.listener);
|
||||
for (ListenerRegistration<PreMessageReceivedEventListener> registration : peersPreMessageReceivedEventListeners)
|
||||
peer.addPreMessageReceivedEventListener(registration.executor, registration.listener);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
@@ -1505,15 +1619,23 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
return;
|
||||
if (downloadPeer != null) {
|
||||
log.info("Unsetting download peer: {}", downloadPeer);
|
||||
if (downloadListener != null)
|
||||
downloadPeer.removeDataEventListener(downloadListener);
|
||||
if (downloadListener != null) {
|
||||
downloadPeer.removeBlocksDownloadedEventListener(downloadListener);
|
||||
downloadPeer.removeChainDownloadStartedEventListener(downloadListener);
|
||||
downloadPeer.removeGetDataEventListener(downloadListener);
|
||||
downloadPeer.removePreMessageReceivedEventListener(downloadListener);
|
||||
}
|
||||
downloadPeer.setDownloadData(false);
|
||||
}
|
||||
downloadPeer = peer;
|
||||
if (downloadPeer != null) {
|
||||
log.info("Setting download peer: {}", downloadPeer);
|
||||
if (downloadListener != null)
|
||||
peer.addDataEventListener(Threading.SAME_THREAD, downloadListener);
|
||||
if (downloadListener != null) {
|
||||
peer.addBlocksDownloadedEventListener(Threading.SAME_THREAD, downloadListener);
|
||||
peer.addChainDownloadStartedEventListener(Threading.SAME_THREAD, downloadListener);
|
||||
peer.addGetDataEventListener(Threading.SAME_THREAD, downloadListener);
|
||||
peer.addPreMessageReceivedEventListener(Threading.SAME_THREAD, downloadListener);
|
||||
}
|
||||
downloadPeer.setDownloadData(true);
|
||||
if (chain != null)
|
||||
downloadPeer.setDownloadParameters(fastCatchupTimeSecs, bloomFilterMerger.getLastFilter() != null);
|
||||
@@ -1611,15 +1733,23 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
peer.removeDataEventListener(peerListener);
|
||||
peer.removeBlocksDownloadedEventListener(peerListener);
|
||||
peer.removeGetDataEventListener(peerListener);
|
||||
for (Wallet wallet : wallets) {
|
||||
peer.removeWallet(wallet);
|
||||
}
|
||||
|
||||
final int fNumConnectedPeers = numConnectedPeers;
|
||||
for (ListenerRegistration<PeerDataEventListener> registration : peerDataEventListeners)
|
||||
peer.removeDataEventListener(registration.listener);
|
||||
for (ListenerRegistration<OnTransactionBroadcastListener> registration : onTransactionBroadastEventListeners)
|
||||
|
||||
for (ListenerRegistration<BlocksDownloadedEventListener> registration: peersBlocksDownloadedEventListeners)
|
||||
peer.removeBlocksDownloadedEventListener(registration.listener);
|
||||
for (ListenerRegistration<ChainDownloadStartedEventListener> registration: peersChainDownloadStartedEventListeners)
|
||||
peer.removeChainDownloadStartedEventListener(registration.listener);
|
||||
for (ListenerRegistration<GetDataEventListener> registration: peerGetDataEventListeners)
|
||||
peer.removeGetDataEventListener(registration.listener);
|
||||
for (ListenerRegistration<PreMessageReceivedEventListener> registration: peersPreMessageReceivedEventListeners)
|
||||
peer.removePreMessageReceivedEventListener(registration.listener);
|
||||
for (ListenerRegistration<OnTransactionBroadcastListener> registration : peersTransactionBroadastEventListeners)
|
||||
peer.removeOnTransactionBroadcastListener(registration.listener);
|
||||
for (final ListenerRegistration<PeerConnectionEventListener> registration : peerConnectionEventListeners) {
|
||||
registration.executor.execute(new Runnable() {
|
||||
@@ -1656,7 +1786,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
}
|
||||
}
|
||||
|
||||
private class ChainDownloadSpeedCalculator extends AbstractPeerDataEventListener implements Runnable {
|
||||
private class ChainDownloadSpeedCalculator implements BlocksDownloadedEventListener, Runnable {
|
||||
private int blocksInLastSecond, txnsInLastSecond, origTxnsInLastSecond;
|
||||
private long bytesInLastSecond;
|
||||
|
||||
@@ -1783,7 +1913,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
chainDownloadSpeedCalculator = new ChainDownloadSpeedCalculator();
|
||||
executor.scheduleAtFixedRate(chainDownloadSpeedCalculator, 1, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
peer.addDataEventListener(Threading.SAME_THREAD, chainDownloadSpeedCalculator);
|
||||
peer.addBlocksDownloadedEventListener(Threading.SAME_THREAD, chainDownloadSpeedCalculator);
|
||||
|
||||
// startBlockChainDownload will setDownloadData(true) on itself automatically.
|
||||
peer.startBlockChainDownload();
|
||||
|
||||
@@ -19,8 +19,6 @@ package org.bitcoinj.core;
|
||||
import com.google.common.annotations.*;
|
||||
import com.google.common.base.*;
|
||||
import com.google.common.util.concurrent.*;
|
||||
import org.bitcoinj.core.listeners.AbstractPeerDataEventListener;
|
||||
import org.bitcoinj.core.listeners.PeerDataEventListener;
|
||||
import org.bitcoinj.utils.*;
|
||||
import org.slf4j.*;
|
||||
|
||||
@@ -29,6 +27,7 @@ import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import org.bitcoinj.core.listeners.PreMessageReceivedEventListener;
|
||||
|
||||
/**
|
||||
* Represents a single transaction broadcast that we are performing. A broadcast occurs after a new transaction is created
|
||||
@@ -88,7 +87,7 @@ public class TransactionBroadcast {
|
||||
this.minConnections = minConnections;
|
||||
}
|
||||
|
||||
private PeerDataEventListener rejectionListener = new AbstractPeerDataEventListener() {
|
||||
private PreMessageReceivedEventListener rejectionListener = new PreMessageReceivedEventListener() {
|
||||
@Override
|
||||
public Message onPreMessageReceived(Peer peer, Message m) {
|
||||
if (m instanceof RejectMessage) {
|
||||
@@ -100,7 +99,7 @@ public class TransactionBroadcast {
|
||||
if (size > threshold) {
|
||||
log.warn("Threshold for considering broadcast rejected has been reached ({}/{})", size, threshold);
|
||||
future.setException(new RejectedTransactionException(tx, rejectMessage));
|
||||
peerGroup.removeDataEventListener(this);
|
||||
peerGroup.removePreMessageReceivedEventListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,7 +108,7 @@ public class TransactionBroadcast {
|
||||
};
|
||||
|
||||
public ListenableFuture<Transaction> broadcast() {
|
||||
peerGroup.addDataEventListener(Threading.SAME_THREAD, rejectionListener);
|
||||
peerGroup.addPreMessageReceivedEventListener(Threading.SAME_THREAD, rejectionListener);
|
||||
log.info("Waiting for {} peers required for broadcast, we have {} ...", minConnections, peerGroup.getConnectedPeers().size());
|
||||
peerGroup.waitForPeers(minConnections).addListener(new EnoughAvailablePeers(), Threading.SAME_THREAD);
|
||||
return future;
|
||||
@@ -161,7 +160,7 @@ public class TransactionBroadcast {
|
||||
// So we just have to assume we're done, at that point. This happens when we're not given
|
||||
// any peer discovery source and the user just calls connectTo() once.
|
||||
if (minConnections == 1) {
|
||||
peerGroup.removeDataEventListener(rejectionListener);
|
||||
peerGroup.removePreMessageReceivedEventListener(rejectionListener);
|
||||
future.set(tx);
|
||||
}
|
||||
}
|
||||
@@ -197,7 +196,7 @@ public class TransactionBroadcast {
|
||||
// We're done! It's important that the PeerGroup lock is not held (by this thread) at this
|
||||
// point to avoid triggering inversions when the Future completes.
|
||||
log.info("broadcastTransaction: {} complete", tx.getHash());
|
||||
peerGroup.removeDataEventListener(rejectionListener);
|
||||
peerGroup.removePreMessageReceivedEventListener(rejectionListener);
|
||||
conf.removeEventListener(this);
|
||||
future.set(tx); // RE-ENTRANCY POINT
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.bitcoinj.core.listeners;
|
||||
|
||||
import org.bitcoinj.core.*;
|
||||
|
||||
import javax.annotation.*;
|
||||
|
||||
/**
|
||||
* <p>Implementors can listen to events like blocks being downloaded/transactions being broadcast/connect/disconnects,
|
||||
* they can pre-filter messages before they are procesesed by a {@link Peer} or {@link PeerGroup}, and they can
|
||||
* provide transactions to remote peers when they ask for them.</p>
|
||||
*/
|
||||
public interface BlocksDownloadedEventListener {
|
||||
|
||||
// TODO: Fix the Block/FilteredBlock type hierarchy so we can avoid the stupid typeless API here.
|
||||
/**
|
||||
* <p>Called on a Peer thread when a block is received.</p>
|
||||
*
|
||||
* <p>The block may be a Block object that contains transactions, a Block object that is only a header when
|
||||
* fast catchup is being used. If set, filteredBlock can be used to retrieve the list of associated transactions.</p>
|
||||
*
|
||||
* @param peer the peer receiving the block
|
||||
* @param block the downloaded block
|
||||
* @param filteredBlock if non-null, the object that wraps the block header passed as the block param.
|
||||
* @param blocksLeft the number of blocks left to download
|
||||
*/
|
||||
void onBlocksDownloaded(Peer peer, Block block, @Nullable FilteredBlock filteredBlock, int blocksLeft);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.bitcoinj.core.listeners;
|
||||
|
||||
import org.bitcoinj.core.*;
|
||||
|
||||
/**
|
||||
* <p>Implementors can listen to events like blocks being downloaded/transactions being broadcast/connect/disconnects,
|
||||
* they can pre-filter messages before they are procesesed by a {@link Peer} or {@link PeerGroup}, and they can
|
||||
* provide transactions to remote peers when they ask for them.</p>
|
||||
*/
|
||||
public interface ChainDownloadStartedEventListener {
|
||||
|
||||
/**
|
||||
* Called when a download is started with the initial number of blocks to be downloaded.
|
||||
*
|
||||
* @param peer the peer receiving the block
|
||||
* @param blocksLeft the number of blocks left to download
|
||||
*/
|
||||
void onChainDownloadStarted(Peer peer, int blocksLeft);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.bitcoinj.core.listeners;
|
||||
|
||||
import org.bitcoinj.core.*;
|
||||
|
||||
import javax.annotation.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>Implementors can listen to events like blocks being downloaded/transactions being broadcast/connect/disconnects,
|
||||
* they can pre-filter messages before they are procesesed by a {@link Peer} or {@link PeerGroup}, and they can
|
||||
* provide transactions to remote peers when they ask for them.</p>
|
||||
*/
|
||||
public interface GetDataEventListener {
|
||||
|
||||
/**
|
||||
* <p>Called when a peer receives a getdata message, usually in response to an "inv" being broadcast. Return as many
|
||||
* items as possible which appear in the {@link GetDataMessage}, or null if you're not interested in responding.</p>
|
||||
*
|
||||
* <p>Note that this will never be called if registered with any executor other than
|
||||
* {@link org.bitcoinj.utils.Threading#SAME_THREAD}</p>
|
||||
*/
|
||||
@Nullable
|
||||
List<Message> getData(Peer peer, GetDataMessage m);
|
||||
}
|
||||
@@ -25,8 +25,8 @@ public interface NewBestBlockListener {
|
||||
/**
|
||||
* Called when a new block on the best chain is seen, after relevant
|
||||
* transactions are extracted and sent to us via either
|
||||
* {@link ReceiveFromBlockListener#receiveFromBlock(Transaction, StoredBlock, org.bitcoinj.core.BlockChain.NewBlockType, int)}
|
||||
* or {@link TransactionIsInBlockListener#notifyTransactionIsInBlock(Sha256Hash, StoredBlock, org.bitcoinj.core.BlockChain.NewBlockType, int)}.
|
||||
* {@link TransactionReceivedInBlockListener#receiveFromBlock(org.bitcoinj.core.Transaction, org.bitcoinj.core.StoredBlock, org.bitcoinj.core.BlockChain.NewBlockType, int relativityOffset)}
|
||||
* or {@link TransactionReceivedInBlockListener#notifyTransactionIsInBlock(org.bitcoinj.core.Sha256Hash, org.bitcoinj.core.StoredBlock, org.bitcoinj.core.BlockChain.NewBlockType, int)}.
|
||||
* If this block is causing a re-organise to a new chain, this method is NOT
|
||||
* called even though the block may be the new best block: your reorganize
|
||||
* implementation is expected to do whatever would normally be done do for a
|
||||
|
||||
@@ -18,56 +18,11 @@ package org.bitcoinj.core.listeners;
|
||||
|
||||
import org.bitcoinj.core.*;
|
||||
|
||||
import javax.annotation.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>Implementors can listen to events like blocks being downloaded/transactions being broadcast/connect/disconnects,
|
||||
* they can pre-filter messages before they are processed by a {@link Peer} or {@link PeerGroup}, and they can
|
||||
* provide transactions to remote peers when they ask for them.</p>
|
||||
*/
|
||||
public interface PeerDataEventListener {
|
||||
|
||||
// TODO: Fix the Block/FilteredBlock type hierarchy so we can avoid the stupid typeless API here.
|
||||
/**
|
||||
* <p>Called on a Peer thread when a block is received.</p>
|
||||
*
|
||||
* <p>The block may be a Block object that contains transactions, a Block object that is only a header when
|
||||
* fast catchup is being used. If set, filteredBlock can be used to retrieve the list of associated transactions.</p>
|
||||
*
|
||||
* @param peer the peer receiving the block
|
||||
* @param block the downloaded block
|
||||
* @param filteredBlock if non-null, the object that wraps the block header passed as the block param.
|
||||
* @param blocksLeft the number of blocks left to download
|
||||
*/
|
||||
void onBlocksDownloaded(Peer peer, Block block, @Nullable FilteredBlock filteredBlock, int blocksLeft);
|
||||
|
||||
/**
|
||||
* Called when a download is started with the initial number of blocks to be downloaded.
|
||||
*
|
||||
* @param peer the peer receiving the block
|
||||
* @param blocksLeft the number of blocks left to download
|
||||
*/
|
||||
void onChainDownloadStarted(Peer peer, int blocksLeft);
|
||||
|
||||
/**
|
||||
* <p>Called when a message is received by a peer, before the message is processed. The returned message is
|
||||
* processed instead. Returning null will cause the message to be ignored by the Peer returning the same message
|
||||
* object allows you to see the messages received but not change them. The result from one event listeners
|
||||
* callback is passed as "m" to the next, forming a chain.</p>
|
||||
*
|
||||
* <p>Note that this will never be called if registered with any executor other than
|
||||
* {@link org.bitcoinj.utils.Threading#SAME_THREAD}</p>
|
||||
*/
|
||||
Message onPreMessageReceived(Peer peer, Message m);
|
||||
|
||||
/**
|
||||
* <p>Called when a peer receives a getdata message, usually in response to an "inv" being broadcast. Return as many
|
||||
* items as possible which appear in the {@link GetDataMessage}, or null if you're not interested in responding.</p>
|
||||
*
|
||||
* <p>Note that this will never be called if registered with any executor other than
|
||||
* {@link org.bitcoinj.utils.Threading#SAME_THREAD}</p>
|
||||
*/
|
||||
@Nullable
|
||||
List<Message> getData(Peer peer, GetDataMessage m);
|
||||
public interface PeerDataEventListener extends BlocksDownloadedEventListener, ChainDownloadStartedEventListener,
|
||||
GetDataEventListener, PreMessageReceivedEventListener {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.bitcoinj.core.listeners;
|
||||
|
||||
import org.bitcoinj.core.*;
|
||||
|
||||
/**
|
||||
* <p>Implementors can listen to events like blocks being downloaded/transactions being broadcast/connect/disconnects,
|
||||
* they can pre-filter messages before they are procesesed by a {@link Peer} or {@link PeerGroup}, and they can
|
||||
* provide transactions to remote peers when they ask for them.</p>
|
||||
*/
|
||||
public interface PreMessageReceivedEventListener {
|
||||
|
||||
/**
|
||||
* <p>Called when a message is received by a peer, before the message is processed. The returned message is
|
||||
* processed instead. Returning null will cause the message to be ignored by the Peer returning the same message
|
||||
* object allows you to see the messages received but not change them. The result from one event listeners
|
||||
* callback is passed as "m" to the next, forming a chain.</p>
|
||||
*
|
||||
* <p>Note that this will never be called if registered with any executor other than
|
||||
* {@link org.bitcoinj.utils.Threading#SAME_THREAD}</p>
|
||||
*/
|
||||
Message onPreMessageReceived(Peer peer, Message m);
|
||||
}
|
||||
@@ -25,7 +25,8 @@ import org.bitcoinj.core.VerificationException;
|
||||
public interface ReorganizeListener {
|
||||
|
||||
/**
|
||||
* Called by the {@link BlockChain} when the best chain (representing total work done) has changed. In this case,
|
||||
* Called by the {@link org.bitcoinj.core.BlockChain} when the best chain
|
||||
* (representing total work done) has changed. In this case,
|
||||
* we need to go through our transactions and find out if any have become invalid. It's possible for our balance
|
||||
* to go down in this case: money we thought we had can suddenly vanish if the rest of the network agrees it
|
||||
* should be so.<p>
|
||||
|
||||
@@ -20,11 +20,9 @@ package org.bitcoinj.kits;
|
||||
import com.google.common.collect.*;
|
||||
import com.google.common.util.concurrent.*;
|
||||
import com.subgraph.orchid.*;
|
||||
import org.bitcoinj.core.listeners.DownloadProgressTracker;
|
||||
import org.bitcoinj.core.listeners.PeerDataEventListener;
|
||||
import org.bitcoinj.core.listeners.*;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.net.discovery.*;
|
||||
import org.bitcoinj.params.*;
|
||||
import org.bitcoinj.protocols.channels.*;
|
||||
import org.bitcoinj.store.*;
|
||||
import org.bitcoinj.wallet.*;
|
||||
@@ -76,7 +74,7 @@ public class WalletAppKit extends AbstractIdleService {
|
||||
|
||||
protected boolean useAutoSave = true;
|
||||
protected PeerAddress[] peerAddresses;
|
||||
protected PeerDataEventListener downloadListener;
|
||||
protected DownloadProgressTracker downloadListener;
|
||||
protected boolean autoStop = true;
|
||||
protected InputStream checkpoints;
|
||||
protected boolean blockingStartup = true;
|
||||
@@ -135,7 +133,7 @@ public class WalletAppKit extends AbstractIdleService {
|
||||
* {@link org.bitcoinj.core.DownloadProgressTracker} is a good choice. This has no effect unless setBlockingStartup(false) has been called
|
||||
* too, due to some missing implementation code.
|
||||
*/
|
||||
public WalletAppKit setDownloadListener(PeerDataEventListener listener) {
|
||||
public WalletAppKit setDownloadListener(DownloadProgressTracker listener) {
|
||||
this.downloadListener = listener;
|
||||
return this;
|
||||
}
|
||||
@@ -341,7 +339,7 @@ public class WalletAppKit extends AbstractIdleService {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Object result) {
|
||||
completeExtensionInitiations(vPeerGroup);
|
||||
final PeerDataEventListener l = downloadListener == null ? new DownloadProgressTracker() : downloadListener;
|
||||
final DownloadProgressTracker l = downloadListener == null ? new DownloadProgressTracker() : downloadListener;
|
||||
vPeerGroup.startBlockChainDownload(l);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class BitcoindComparisonTool {
|
||||
final Set<Sha256Hash> blocksPendingSend = Collections.synchronizedSet(new HashSet<Sha256Hash>());
|
||||
final AtomicInteger unexpectedInvs = new AtomicInteger(0);
|
||||
final SettableFuture<Void> connectedFuture = SettableFuture.create();
|
||||
final AbstractPeerEventListener listener = new AbstractPeerEventListener() {
|
||||
final PeerConnectionEventListener listener = new PeerConnectionEventListener() {
|
||||
@Override
|
||||
public void onPeerConnected(Peer peer, int peerCount) {
|
||||
if (!peer.getPeerVersionMessage().subVer.contains("Satoshi")) {
|
||||
@@ -114,6 +114,13 @@ public class BitcoindComparisonTool {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPeersDiscovered(Set<PeerAddress> peerAddresses) {
|
||||
// Ignore
|
||||
}
|
||||
};
|
||||
|
||||
final PreMessageReceivedEventListener preMessageReceivedListener = new PreMessageReceivedEventListener() {
|
||||
@Override
|
||||
public Message onPreMessageReceived(Peer peer, Message m) {
|
||||
if (m instanceof HeadersMessage) {
|
||||
@@ -196,7 +203,7 @@ public class BitcoindComparisonTool {
|
||||
}
|
||||
};
|
||||
bitcoind.addConnectionEventListener(Threading.SAME_THREAD, listener);
|
||||
bitcoind.addDataEventListener(Threading.SAME_THREAD, listener);
|
||||
bitcoind.addPreMessageReceivedEventListener(Threading.SAME_THREAD, preMessageReceivedListener);
|
||||
|
||||
|
||||
bitcoindChainHead = params.getGenesisBlock().getHash();
|
||||
|
||||
@@ -47,7 +47,8 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
||||
|
||||
private BlockingQueue<Peer> connectedPeers;
|
||||
private BlockingQueue<Peer> disconnectedPeers;
|
||||
private AbstractPeerEventListener listener;
|
||||
private PeerConnectionEventListener listener;
|
||||
private PreMessageReceivedEventListener preMessageReceivedListener;
|
||||
private Map<Peer, AtomicInteger> peerToMessageCount;
|
||||
|
||||
@Parameterized.Parameters
|
||||
@@ -67,7 +68,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
||||
peerToMessageCount = new HashMap<Peer, AtomicInteger>();
|
||||
connectedPeers = new LinkedBlockingQueue<Peer>();
|
||||
disconnectedPeers = new LinkedBlockingQueue<Peer>();
|
||||
listener = new AbstractPeerEventListener() {
|
||||
listener = new PeerConnectionEventListener() {
|
||||
@Override
|
||||
public void onPeerConnected(Peer peer, int peerCount) {
|
||||
connectedPeers.add(peer);
|
||||
@@ -78,6 +79,13 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
||||
disconnectedPeers.add(peer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPeersDiscovered(Set<PeerAddress> peerAddresses) {
|
||||
// Ignore
|
||||
}
|
||||
};
|
||||
|
||||
preMessageReceivedListener = new PreMessageReceivedEventListener() {
|
||||
@Override
|
||||
public Message onPreMessageReceived(Peer peer, Message m) {
|
||||
AtomicInteger messageCount = peerToMessageCount.get(peer);
|
||||
@@ -102,7 +110,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
||||
public void listener() throws Exception {
|
||||
peerGroup.start();
|
||||
peerGroup.addConnectionEventListener(listener);
|
||||
peerGroup.addDataEventListener(listener);
|
||||
peerGroup.addPreMessageReceivedEventListener(preMessageReceivedListener);
|
||||
|
||||
// Create a couple of peers.
|
||||
InboundMessageQueuer p1 = connectPeer(1);
|
||||
@@ -124,8 +132,8 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
||||
|
||||
assertTrue(peerGroup.removeConnectionEventListener(listener));
|
||||
assertFalse(peerGroup.removeConnectionEventListener(listener));
|
||||
assertTrue(peerGroup.removeDataEventListener(listener));
|
||||
assertFalse(peerGroup.removeDataEventListener(listener));
|
||||
assertTrue(peerGroup.removePreMessageReceivedEventListener(preMessageReceivedListener));
|
||||
assertFalse(peerGroup.removePreMessageReceivedEventListener(preMessageReceivedListener));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -532,7 +540,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
||||
new InetSocketAddress("localhost", 2002)
|
||||
);
|
||||
peerGroup.addConnectionEventListener(listener);
|
||||
peerGroup.addDataEventListener(listener);
|
||||
peerGroup.addPreMessageReceivedEventListener(preMessageReceivedListener);
|
||||
peerGroup.addPeerDiscovery(new PeerDiscovery() {
|
||||
@Override
|
||||
public InetSocketAddress[] getPeers(long services, long unused, TimeUnit unused2) throws PeerDiscoveryException {
|
||||
|
||||
@@ -315,7 +315,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
connect();
|
||||
// Round-trip a ping so that we never see the response verack if we attach too quick
|
||||
pingAndWait(writeTarget);
|
||||
peer.addDataEventListener(Threading.SAME_THREAD, new AbstractPeerDataEventListener() {
|
||||
peer.addPreMessageReceivedEventListener(Threading.SAME_THREAD, new PreMessageReceivedEventListener() {
|
||||
@Override
|
||||
public synchronized Message onPreMessageReceived(Peer p, Message m) {
|
||||
if (p != peer)
|
||||
@@ -331,7 +331,8 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
fail.set(true);
|
||||
return m;
|
||||
}
|
||||
|
||||
});
|
||||
peer.addBlocksDownloadedEventListener(Threading.SAME_THREAD, new BlocksDownloadedEventListener() {
|
||||
@Override
|
||||
public synchronized void onBlocksDownloaded(Peer p, Block block, @Nullable FilteredBlock filteredBlock, int blocksLeft) {
|
||||
int newValue = newBlockMessagesReceived.incrementAndGet();
|
||||
@@ -369,7 +370,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
|
||||
connect();
|
||||
fail.set(true);
|
||||
peer.addDataEventListener(Threading.SAME_THREAD, new AbstractPeerDataEventListener() {
|
||||
peer.addChainDownloadStartedEventListener(Threading.SAME_THREAD, new ChainDownloadStartedEventListener() {
|
||||
@Override
|
||||
public void onChainDownloadStarted(Peer p, int blocksLeft) {
|
||||
if (p == peer && blocksLeft == 108)
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
package org.bitcoinj.testing;
|
||||
|
||||
import org.bitcoinj.core.listeners.AbstractPeerConnectionEventListener;
|
||||
import org.bitcoinj.core.listeners.AbstractPeerDataEventListener;
|
||||
import org.bitcoinj.core.listeners.PeerDataEventListener;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.net.*;
|
||||
import org.bitcoinj.params.UnitTestParams;
|
||||
@@ -41,6 +39,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import org.bitcoinj.core.listeners.PreMessageReceivedEventListener;
|
||||
|
||||
/**
|
||||
* Utility class that makes it easy to work with mock NetworkConnections.
|
||||
@@ -208,7 +207,7 @@ public class TestWithNetworkConnections {
|
||||
private void inboundPongAndWait(final InboundMessageQueuer p, final long nonce) throws Exception {
|
||||
// Receive a ping (that the Peer doesn't see) and wait for it to get through the socket
|
||||
final SettableFuture<Void> pongReceivedFuture = SettableFuture.create();
|
||||
PeerDataEventListener listener = new AbstractPeerDataEventListener() {
|
||||
PreMessageReceivedEventListener listener = new PreMessageReceivedEventListener() {
|
||||
@Override
|
||||
public Message onPreMessageReceived(Peer p, Message m) {
|
||||
if (m instanceof Pong && ((Pong) m).getNonce() == nonce) {
|
||||
@@ -218,10 +217,10 @@ public class TestWithNetworkConnections {
|
||||
return m;
|
||||
}
|
||||
};
|
||||
p.peer.addDataEventListener(Threading.SAME_THREAD, listener);
|
||||
p.peer.addPreMessageReceivedEventListener(Threading.SAME_THREAD, listener);
|
||||
inbound(p, new Pong(nonce));
|
||||
pongReceivedFuture.get();
|
||||
p.peer.removeDataEventListener(listener);
|
||||
p.peer.removePreMessageReceivedEventListener(listener);
|
||||
}
|
||||
|
||||
protected void pingAndWait(final InboundMessageQueuer p) throws Exception {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
package org.bitcoinj.examples;
|
||||
|
||||
import org.bitcoinj.core.listeners.AbstractPeerEventListener;
|
||||
import org.bitcoinj.core.listeners.PreMessageReceivedEventListener;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.kits.WalletAppKit;
|
||||
import org.bitcoinj.params.RegTestParams;
|
||||
@@ -46,8 +46,8 @@ public class DoubleSpend {
|
||||
Transaction tx1 = kit.wallet().createSend(Address.fromBase58(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), CENT);
|
||||
Transaction tx2 = kit.wallet().createSend(Address.fromBase58(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), CENT.add(SATOSHI.multiply(10)));
|
||||
final Peer peer = kit.peerGroup().getConnectedPeers().get(0);
|
||||
peer.addDataEventListener(Threading.SAME_THREAD,
|
||||
new AbstractPeerEventListener() {
|
||||
peer.addPreMessageReceivedEventListener(Threading.SAME_THREAD,
|
||||
new PreMessageReceivedEventListener() {
|
||||
@Override
|
||||
public Message onPreMessageReceived(Peer peer, Message m) {
|
||||
System.err.println("Got a message!" + m.getClass().getSimpleName() + ": " + m);
|
||||
|
||||
@@ -48,8 +48,12 @@ import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpec;
|
||||
import joptsimple.util.DateConverter;
|
||||
|
||||
import org.bitcoinj.core.listeners.AbstractPeerDataEventListener;
|
||||
import org.bitcoinj.core.listeners.BlocksDownloadedEventListener;
|
||||
import org.bitcoinj.core.listeners.DownloadProgressTracker;
|
||||
import org.bitcoinj.core.listeners.WalletChangeEventListener;
|
||||
import org.bitcoinj.core.listeners.WalletCoinsReceivedEventListener;
|
||||
import org.bitcoinj.core.listeners.WalletCoinsSentEventListener;
|
||||
import org.bitcoinj.core.listeners.WalletReorganizeEventListener;
|
||||
import org.bitcoinj.wallet.MarriedKeyChain;
|
||||
import org.bitcoinj.wallet.Protos;
|
||||
import org.slf4j.Logger;
|
||||
@@ -77,10 +81,6 @@ import java.util.logging.LogManager;
|
||||
|
||||
import static org.bitcoinj.core.Coin.parseCoin;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import org.bitcoinj.core.listeners.WalletChangeEventListener;
|
||||
import org.bitcoinj.core.listeners.WalletCoinsReceivedEventListener;
|
||||
import org.bitcoinj.core.listeners.WalletCoinsSentEventListener;
|
||||
import org.bitcoinj.core.listeners.WalletReorganizeEventListener;
|
||||
|
||||
/**
|
||||
* A command line tool for manipulating wallets and working with Bitcoin.
|
||||
@@ -1131,7 +1131,7 @@ public class WalletTool {
|
||||
break;
|
||||
|
||||
case BLOCK:
|
||||
peers.addDataEventListener(new AbstractPeerDataEventListener() {
|
||||
peers.addBlocksDownloadedEventListener(new BlocksDownloadedEventListener() {
|
||||
@Override
|
||||
public void onBlocksDownloaded(Peer peer, Block block, @Nullable FilteredBlock filteredBlock, int blocksLeft) {
|
||||
// Check if we already ran. This can happen if a block being received triggers download of more
|
||||
|
||||
Reference in New Issue
Block a user