From 74d54de1f6ec58c76e3a97df11df592be0a4f616 Mon Sep 17 00:00:00 2001 From: Andreas Schildbach Date: Mon, 21 Nov 2022 15:39:24 +0100 Subject: [PATCH] AddressEventListener: new event produced by Peer if an `addr` or `addrv2` message is received --- .../src/main/java/org/bitcoinj/core/Peer.java | 24 +++++++++++-- .../core/listeners/AddressEventListener.java | 34 +++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/org/bitcoinj/core/listeners/AddressEventListener.java diff --git a/core/src/main/java/org/bitcoinj/core/Peer.java b/core/src/main/java/org/bitcoinj/core/Peer.java index 77d52f9f1..42b275a18 100644 --- a/core/src/main/java/org/bitcoinj/core/Peer.java +++ b/core/src/main/java/org/bitcoinj/core/Peer.java @@ -23,6 +23,7 @@ import com.google.common.base.Throwables; import net.jcip.annotations.GuardedBy; import org.bitcoinj.base.Coin; import org.bitcoinj.base.Sha256Hash; +import org.bitcoinj.core.listeners.AddressEventListener; import org.bitcoinj.core.listeners.BlocksDownloadedEventListener; import org.bitcoinj.core.listeners.ChainDownloadStartedEventListener; import org.bitcoinj.core.listeners.GetDataEventListener; @@ -101,6 +102,8 @@ public class Peer extends PeerSocketHandler { = new CopyOnWriteArrayList<>(); private final CopyOnWriteArrayList> onTransactionEventListeners = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList> addressEventListeners + = new CopyOnWriteArrayList<>(); // 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. @@ -331,6 +334,16 @@ public class Peer extends PeerSocketHandler { preMessageReceivedEventListeners.add(new ListenerRegistration<>(listener, executor)); } + /** Registers a listener that is called when addr or addrv2 messages are received. */ + public void addAddressEventListener(AddressEventListener listener) { + addAddressEventListener(Threading.USER_THREAD, listener); + } + + /** Registers a listener that is called when addr or addrv2 messages are received. */ + public void addAddressEventListener(Executor executor, AddressEventListener listener) { + addressEventListeners.add(new ListenerRegistration<>(listener, executor)); + } + public boolean removeBlocksDownloadedEventListener(BlocksDownloadedEventListener listener) { return ListenerRegistration.removeFromList(listener, blocksDownloadedEventListeners); } @@ -359,6 +372,10 @@ public class Peer extends PeerSocketHandler { return ListenerRegistration.removeFromList(listener, preMessageReceivedEventListeners); } + public boolean removeAddressEventListener(AddressEventListener listener) { + return ListenerRegistration.removeFromList(listener, addressEventListeners); + } + @Override public String toString() { final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this).omitNullValues(); @@ -485,14 +502,17 @@ public class Peer extends PeerSocketHandler { } } - private void processAddressMessage(AddressMessage m) { + private void processAddressMessage(AddressMessage message) { + for (final ListenerRegistration registration : addressEventListeners) { + registration.executor.execute(() -> registration.listener.onAddr(Peer.this, message)); + } CompletableFuture future; synchronized (getAddrFutures) { future = getAddrFutures.poll(); if (future == null) // Not an addr message we are waiting for. return; } - future.complete(m); + future.complete(message); } private void processVersionMessage(VersionMessage peerVersionMessage) throws ProtocolException { diff --git a/core/src/main/java/org/bitcoinj/core/listeners/AddressEventListener.java b/core/src/main/java/org/bitcoinj/core/listeners/AddressEventListener.java new file mode 100644 index 000000000..7aa94094f --- /dev/null +++ b/core/src/main/java/org/bitcoinj/core/listeners/AddressEventListener.java @@ -0,0 +1,34 @@ +/* + * Copyright by the original author or authors. + * + * 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.AddressMessage; +import org.bitcoinj.core.Peer; + +/** + *

Implementors can listen to addresses being received from remote peers.

+ */ +public interface AddressEventListener { + + /** + *

Called when a peer receives an addr or addrv2 message, usually in response to a getaddr message.

+ * + * @param peer the peer that received the addr or addrv2 message + * @param message the addr or addrv2 message that was received + */ + void onAddr(Peer peer, AddressMessage message); +}