diff --git a/core/src/main/java/com/google/bitcoin/core/Peer.java b/core/src/main/java/com/google/bitcoin/core/Peer.java index da4a18fa..8725f93a 100644 --- a/core/src/main/java/com/google/bitcoin/core/Peer.java +++ b/core/src/main/java/com/google/bitcoin/core/Peer.java @@ -81,6 +81,8 @@ public class Peer extends PeerSocketHandler { // The version data to announce to the other side of the connections we make: useful for setting our "user agent" // equivalent and other things. private final VersionMessage versionMessage; + // Switch for enabling download of pending transaction dependencies. + private final boolean downloadTxDependencies; // How many block messages the peer has announced to us. Peers only announce blocks that attach to their best chain // so we can use this to calculate the height of the peers chain, by adding it to the initial height in the version // message. This method can go wrong if the peer re-orgs onto a shorter (but harder) chain, however, this is rare. @@ -173,10 +175,30 @@ public class Peer extends PeerSocketHandler { * used to keep track of which peers relayed transactions and offer more descriptive logging.

*/ public Peer(NetworkParameters params, VersionMessage ver, PeerAddress remoteAddress, - @Nullable AbstractBlockChain chain, @Nullable MemoryPool mempool) { + @Nullable AbstractBlockChain chain, @Nullable MemoryPool mempool) { + this(params, ver, remoteAddress, chain, mempool, true); + } + + /** + *

Construct a peer that reads/writes from the given block chain and memory pool. Transactions stored in a memory + * pool will have their confidence levels updated when a peer announces it, to reflect the greater likelyhood that + * the transaction is valid.

+ * + *

Note that this does NOT make a connection to the given remoteAddress, it only creates a handler for a + * connection. If you want to create a one-off connection, create a Peer and pass it to + * {@link com.google.bitcoin.net.NioClientManager#openConnection(java.net.SocketAddress, com.google.bitcoin.net.StreamParser)} + * or + * {@link com.google.bitcoin.net.NioClient#NioClient(java.net.SocketAddress, com.google.bitcoin.net.StreamParser, int)}.

+ * + *

The remoteAddress provided should match the remote address of the peer which is being connected to, and is + * used to keep track of which peers relayed transactions and offer more descriptive logging.

+ */ + public Peer(NetworkParameters params, VersionMessage ver, PeerAddress remoteAddress, + @Nullable AbstractBlockChain chain, @Nullable MemoryPool mempool, boolean downloadTxDependencies) { super(params, remoteAddress); this.params = Preconditions.checkNotNull(params); this.versionMessage = Preconditions.checkNotNull(ver); + this.downloadTxDependencies = downloadTxDependencies; this.blockChain = chain; // Allowed to be null. this.vDownloadData = chain != null; this.getDataFutures = new CopyOnWriteArrayList(); @@ -577,26 +599,27 @@ public class Peer extends PeerSocketHandler { // the chain, in case the sender goes away and the network starts to forget. // TODO: Not all the above things are implemented. - Futures.addCallback(downloadDependencies(fTx), new FutureCallback>() { - public void onSuccess(List dependencies) { - try { - log.info("{}: Dependency download complete!", getAddress()); - wallet.receivePending(fTx, dependencies); - } catch (VerificationException e) { - log.error("{}: Wallet failed to process pending transaction {}", - getAddress(), fTx.getHashAsString()); - log.error("Error was: ", e); + if (downloadTxDependencies) { + Futures.addCallback(downloadDependencies(fTx), new FutureCallback>() { + public void onSuccess(List dependencies) { + try { + log.info("{}: Dependency download complete!", getAddress()); + wallet.receivePending(fTx, dependencies); + } catch (VerificationException e) { + log.error("{}: Wallet failed to process pending transaction {}", getAddress(), + fTx.getHashAsString()); + log.error("Error was: ", e); + // Not much more we can do at this point. + } + } + + public void onFailure(Throwable throwable) { + log.error("Could not download dependencies of tx {}", fTx.getHashAsString()); + log.error("Error was: ", throwable); // Not much more we can do at this point. } - } - - public void onFailure(Throwable throwable) { - log.error("Could not download dependencies of tx {}", fTx.getHashAsString()); - log.error("Error was: ", throwable); - // Not much more we can do at this point. - } - }); - + }); + } } } catch (VerificationException e) { log.error("Wallet failed to verify tx", e); diff --git a/core/src/main/java/com/google/bitcoin/core/PeerGroup.java b/core/src/main/java/com/google/bitcoin/core/PeerGroup.java index 7831f3a4..9384e450 100644 --- a/core/src/main/java/com/google/bitcoin/core/PeerGroup.java +++ b/core/src/main/java/com/google/bitcoin/core/PeerGroup.java @@ -94,6 +94,8 @@ public class PeerGroup extends AbstractExecutionThreadService implements Transac private final CopyOnWriteArraySet peerDiscoverers; // The version message to use for new connections. @GuardedBy("lock") private VersionMessage versionMessage; + // Switch for enabling download of pending transaction dependencies. + @GuardedBy("lock") private boolean downloadTxDependencies; // A class that tracks recent transactions that have been broadcast across the network, counts how many // peers announced them and updates the transaction confidence data. It is passed to each Peer. private final MemoryPool memoryPool; @@ -290,6 +292,7 @@ public class PeerGroup extends AbstractExecutionThreadService implements Transac int height = chain == null ? 0 : chain.getBestChainHeight(); // We never request that the remote node wait for a bloom filter yet, as we have no wallets this.versionMessage = new VersionMessage(params, height, true); + this.downloadTxDependencies = true; memoryPool = new MemoryPool(); @@ -335,6 +338,18 @@ public class PeerGroup extends AbstractExecutionThreadService implements Transac channels.closeConnections(-adjustment); } + /** + * Switch for enabling download of pending transaction dependencies. A change of value only takes effect for newly + * connected peers. + */ + public void setDownloadTxDependencies(boolean downloadTxDependencies) { + lock.lock(); + try { + this.downloadTxDependencies = downloadTxDependencies; + } finally { + lock.unlock(); + } + } private Runnable triggerConnectionsJob = new Runnable() { @Override @@ -895,7 +910,7 @@ public class PeerGroup extends AbstractExecutionThreadService implements Transac ver.bestHeight = chain == null ? 0 : chain.getBestChainHeight(); ver.time = Utils.currentTimeSeconds(); - Peer peer = new Peer(params, ver, address, chain, memoryPool); + Peer peer = new Peer(params, ver, address, chain, memoryPool, downloadTxDependencies); peer.addEventListener(startupListener, Threading.SAME_THREAD); peer.setMinProtocolVersion(vMinRequiredProtocolVersion); pendingPeers.add(peer);