Class Peer

All Implemented Interfaces:
StreamConnection, TimeoutHandler

public class Peer extends PeerSocketHandler

A Peer handles the high level communication with a Bitcoin node, extending a PeerSocketHandler which handles low-level message (de)serialization.

Note that timeouts are handled by the implemented TimeoutHandler and timeout is automatically disabled (using TimeoutHandler.setTimeoutEnabled(boolean)) once the version handshake completes.

  • Field Details

  • Constructor Details

  • Method Details

    • addBlocksDownloadedEventListener

      public void addBlocksDownloadedEventListener(BlocksDownloadedEventListener listener)
      Registers a listener that is invoked when new blocks are downloaded.
    • addBlocksDownloadedEventListener

      public void addBlocksDownloadedEventListener(Executor executor, BlocksDownloadedEventListener listener)
      Registers a listener that is invoked when new blocks are downloaded.
    • addChainDownloadStartedEventListener

      public void addChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener)
      Registers a listener that is invoked when a blockchain downloaded starts.
    • addChainDownloadStartedEventListener

      public void addChainDownloadStartedEventListener(Executor executor, ChainDownloadStartedEventListener listener)
      Registers a listener that is invoked when a blockchain downloaded starts.
    • addConnectedEventListener

      public void addConnectedEventListener(PeerConnectedEventListener listener)
      Registers a listener that is invoked when a peer is connected.
    • addConnectedEventListener

      public void addConnectedEventListener(Executor executor, PeerConnectedEventListener listener)
      Registers a listener that is invoked when a peer is connected.
    • addDisconnectedEventListener

      public void addDisconnectedEventListener(PeerDisconnectedEventListener listener)
      Registers a listener that is invoked when a peer is disconnected.
    • addDisconnectedEventListener

      public void addDisconnectedEventListener(Executor executor, PeerDisconnectedEventListener listener)
      Registers a listener that is invoked when a peer is disconnected.
    • addGetDataEventListener

      public void addGetDataEventListener(GetDataEventListener listener)
      Registers a listener that is called when messages are received.
    • addGetDataEventListener

      public void addGetDataEventListener(Executor executor, GetDataEventListener listener)
      Registers a listener that is called when messages are received.
    • addOnTransactionBroadcastListener

      public void addOnTransactionBroadcastListener(OnTransactionBroadcastListener listener)
      Registers a listener that is called when a transaction is broadcast across the network
    • addOnTransactionBroadcastListener

      public void addOnTransactionBroadcastListener(Executor executor, OnTransactionBroadcastListener listener)
      Registers a listener that is called when a transaction is broadcast across the network
    • addPreMessageReceivedEventListener

      public void addPreMessageReceivedEventListener(PreMessageReceivedEventListener listener)
      Registers a listener that is called immediately before a message is received
    • addPreMessageReceivedEventListener

      public void addPreMessageReceivedEventListener(Executor executor, PreMessageReceivedEventListener listener)
      Registers a listener that is called immediately before a message is received
    • addAddressEventListener

      public void addAddressEventListener(AddressEventListener listener)
      Registers a listener that is called when addr or addrv2 messages are received.
    • addAddressEventListener

      public void addAddressEventListener(Executor executor, AddressEventListener listener)
      Registers a listener that is called when addr or addrv2 messages are received.
    • removeBlocksDownloadedEventListener

      public boolean removeBlocksDownloadedEventListener(BlocksDownloadedEventListener listener)
    • removeChainDownloadStartedEventListener

      public boolean removeChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener)
    • removeConnectedEventListener

      public boolean removeConnectedEventListener(PeerConnectedEventListener listener)
    • removeDisconnectedEventListener

      public boolean removeDisconnectedEventListener(PeerDisconnectedEventListener listener)
    • removeGetDataEventListener

      public boolean removeGetDataEventListener(GetDataEventListener listener)
    • removeOnTransactionBroadcastListener

      public boolean removeOnTransactionBroadcastListener(OnTransactionBroadcastListener listener)
    • removePreMessageReceivedEventListener

      public boolean removePreMessageReceivedEventListener(PreMessageReceivedEventListener listener)
    • removeAddressEventListener

      public boolean removeAddressEventListener(AddressEventListener listener)
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • timeoutOccurred

      protected void timeoutOccurred()
      Overrides:
      timeoutOccurred in class PeerSocketHandler
    • connectionClosed

      public void connectionClosed()
      Description copied from interface: StreamConnection
      Called when the connection socket is closed
    • connectionOpened

      public void connectionOpened()
      Description copied from interface: StreamConnection
      Called when the connection socket is first opened
    • getConnectionOpenFuture

      public ListenableCompletableFuture<Peer> getConnectionOpenFuture()
      Provides a ListenableCompletableFuture that can be used to wait for the socket to connect. A socket connection does not mean that protocol handshake has occurred.
    • getVersionHandshakeFuture

      public ListenableCompletableFuture<Peer> getVersionHandshakeFuture()
    • processMessage

      protected void processMessage(Message m) throws Exception
      Description copied from class: PeerSocketHandler
      Called every time a message is received from the network
      Specified by:
      processMessage in class PeerSocketHandler
      Throws:
      Exception
    • startFilteredBlock

      protected void startFilteredBlock(FilteredBlock m)
    • processNotFoundMessage

      protected void processNotFoundMessage(NotFoundMessage m)
    • processHeaders

      protected void processHeaders(HeadersMessage m) throws ProtocolException
      Throws:
      ProtocolException
    • processGetData

      protected void processGetData(GetDataMessage getdata)
    • processTransaction

      protected void processTransaction(Transaction tx) throws VerificationException
      Throws:
      VerificationException
    • downloadDependencies

      public ListenableCompletableFuture<List<Transaction>> downloadDependencies(Transaction tx)

      Returns a future that wraps a list of all transactions that the given transaction depends on, recursively. Only transactions in peers memory pools are included; the recursion stops at transactions that are in the current best chain. So it doesn't make much sense to provide a tx that was already in the best chain and a precondition checks this.

      For example, if tx has 2 inputs that connect to transactions A and B, and transaction B is unconfirmed and has one input connecting to transaction C that is unconfirmed, and transaction C connects to transaction D that is in the chain, then this method will return either {B, C} or {C, B}. No ordering is guaranteed.

      This method is useful for apps that want to learn about how long an unconfirmed transaction might take to confirm, by checking for unexpectedly time locked transactions, unusually deep dependency trees or fee-paying transactions that depend on unconfirmed free transactions.

      Note that dependencies downloaded this way will not trigger the onTransaction method of event listeners.

      Parameters:
      tx - The transaction
      Returns:
      A Future for a list of dependent transactions
    • downloadDependenciesInternal

      protected CompletableFuture<List<Transaction>> downloadDependenciesInternal(Transaction rootTx, int maxDepth, int depth)
      Internal, recursive dependency downloader
      Parameters:
      rootTx - The root transaction
      maxDepth - maximum recursion depth
      depth - current recursion depth (starts at 0)
      Returns:
      A Future for a list of dependent transactions
    • processBlock

      protected void processBlock(Block m)
    • endFilteredBlock

      protected void endFilteredBlock(FilteredBlock m)
    • processInv

      protected void processInv(InventoryMessage inv)
    • getBlock

      public ListenableCompletableFuture<Block> getBlock(Sha256Hash blockHash)
      Asks the connected peer for the block of the given hash, and returns a future representing the answer. If you want the block right away and don't mind waiting for it, just call .get() on the result. Your thread will block until the peer answers.
    • getPeerMempoolTransaction

      public ListenableCompletableFuture<Transaction> getPeerMempoolTransaction(Sha256Hash hash)
      Asks the connected peer for the given transaction from its memory pool. Transactions in the chain cannot be retrieved this way because peers don't have a transaction ID to transaction-pos-on-disk index, and besides, in future many peers will delete old transaction data they don't need.
    • getAddr

      Sends a getaddr request to the peer and returns a future that completes with the answer once the peer has replied.
    • setFastDownloadParameters

      public void setFastDownloadParameters(boolean useFilteredBlocks, Instant fastCatchupTime)
      When downloading the block chain, the bodies will be skipped for blocks created before the given date. Any transactions relevant to the wallet will therefore not be found, but if you know your wallet has no such transactions it doesn't matter and can save a lot of bandwidth and processing time. Note that the times of blocks isn't known until their headers are available and they are requested in chunks, so some headers may be downloaded twice using this scheme, but this optimization can still be a large win for newly created wallets.
      Parameters:
      useFilteredBlocks - whether to request filtered blocks if the protocol version allows for them
      fastCatchupTime - time before which block bodies are skipped
    • setDownloadParameters

      public void setDownloadParameters(boolean useFilteredBlocks)
      Always download full blocks.
      Parameters:
      useFilteredBlocks - whether to request filtered blocks if the protocol version allows for them
    • setDownloadParameters

      @Deprecated public void setDownloadParameters(long fastCatchupTimeSecs, boolean useFilteredBlocks)
    • addWallet

      public void addWallet(Wallet wallet)
      Links the given wallet to this peer. If you have multiple peers, you should use a PeerGroup to manage them and use the PeerGroup.addWallet(Wallet) method instead of registering the wallet with each peer independently, otherwise the wallet will receive duplicate notifications.
    • removeWallet

      public void removeWallet(Wallet wallet)
      Unlinks the given wallet from peer. See addWallet(Wallet).
    • startBlockChainDownload

      public void startBlockChainDownload()
      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.
    • sendPing

      public CompletableFuture<Duration> sendPing()
      Sends the peer a ping message and returns a future that will be completed when the pong is received back. The future provides a Duration which contains the time elapsed between the ping and the pong. Once the pong is received the value returned by lastPingInterval() is updated. The future completes exceptionally with a ProtocolException if the peer version is too low to support measurable pings.
      Returns:
      A future for the duration representing elapsed time
    • sendPing

      protected CompletableFuture<Duration> sendPing(long nonce)
    • ping

      Deprecated.
    • lastPingInterval

      public Optional<Duration> lastPingInterval()
      Returns the elapsed time of the last ping/pong cycle. If sendPing() has never been called or we did not hear back the "pong" message yet, returns empty.
      Returns:
      last ping, or empty
    • getLastPingTime

      @Deprecated public long getLastPingTime()
      Deprecated.
    • pingInterval

      public Optional<Duration> pingInterval()
      Returns a moving average of the last N ping/pong cycles. If sendPing() has never been called or we did not hear back the "pong" message yet, returns empty. The moving average window is PING_MOVING_AVERAGE_WINDOW buckets.
      Returns:
      moving average, or empty
    • getPingTime

      @Deprecated public long getPingTime()
      Deprecated.
    • processPong

      protected void processPong(Pong m)
    • getPeerBlockHeightDifference

      public int getPeerBlockHeightDifference()
      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.
    • isDownloadData

      public boolean isDownloadData()
      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.
    • setDownloadData

      public void setDownloadData(boolean downloadData)
      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. Changing this value from false to true may trigger a request to the remote peer for the contents of its memory pool, if Bloom filtering is active.
    • getPeerVersionMessage

      public VersionMessage getPeerVersionMessage()
      Returns version data announced by the remote peer.
    • getFeeFilter

      public Coin getFeeFilter()
      Returns the fee filter announced by the remote peer, interpreted as satoshis per kB.
    • getVersionMessage

      public VersionMessage getVersionMessage()
      Returns version data we announce to our remote peers.
    • getBestHeight

      public long getBestHeight()
      Returns:
      the height of the best chain as claimed by peer: sum of its ver announcement and blocks announced since.
    • setMinProtocolVersion

      public boolean setMinProtocolVersion(int minProtocolVersion)
      The minimum P2P protocol version that is accepted. If the peer speaks a protocol version lower than this, it will be disconnected.
      Returns:
      true if the peer was disconnected as a result
    • setBloomFilter

      public void setBloomFilter(BloomFilter filter)

      Sets a Bloom filter on this connection. This will cause the given BloomFilter object to be sent to the remote peer and if either a memory pool has been set using the constructor or the vDownloadData property is true, a MemoryPoolMessage is sent as well to trigger downloading of any pending transactions that may be relevant.

      The Peer does not automatically request filters from any wallets added using addWallet(Wallet). This is to allow callers to avoid redundantly recalculating the same filter repeatedly when using multiple peers and multiple wallets together.

      Therefore, you should not use this method if your app uses a PeerGroup. It is called for you.

      If the remote peer doesn't support Bloom filtering, then this call is ignored. Once set you presently cannot unset a filter, though the underlying p2p protocol does support it.

    • setBloomFilter

      public void setBloomFilter(BloomFilter filter, boolean andQueryMemPool)

      Sets a Bloom filter on this connection. This will cause the given BloomFilter object to be sent to the remote peer and if requested, a MemoryPoolMessage is sent as well to trigger downloading of any pending transactions that may be relevant.

      The Peer does not automatically request filters from any wallets added using addWallet(Wallet). This is to allow callers to avoid redundantly recalculating the same filter repeatedly when using multiple peers and multiple wallets together.

      Therefore, you should not use this method if your app uses a PeerGroup. It is called for you.

      If the remote peer doesn't support Bloom filtering, then this call is ignored. Once set you presently cannot unset a filter, though the underlying p2p protocol does support it.

    • getBloomFilter

      public BloomFilter getBloomFilter()
      Returns the last BloomFilter set by setBloomFilter(BloomFilter). Bloom filters tell the remote node what transactions to send us, in a compact manner.
    • isDownloadTxDependencies

      public boolean isDownloadTxDependencies()
      Returns true if this peer will use getdata/notfound messages to walk backwards through transaction dependencies before handing the transaction off to the wallet. The wallet can do risk analysis on pending/recent transactions to try and discover if a pending tx might be at risk of double spending.
    • setDownloadTxDependencies

      public void setDownloadTxDependencies(boolean enable)
      Sets if this peer will use getdata/notfound messages to walk backwards through transaction dependencies before handing the transaction off to the wallet. The wallet can do risk analysis on pending/recent transactions to try and discover if a pending tx might be at risk of double spending.
    • setDownloadTxDependencies

      public void setDownloadTxDependencies(int depth)
      Sets if this peer will use getdata/notfound messages to walk backwards through transaction dependencies before handing the transaction off to the wallet. The wallet can do risk analysis on pending/recent transactions to try and discover if a pending tx might be at risk of double spending.