com.google.bitcoin.core
Class Peer

java.lang.Object
  extended by com.google.bitcoin.net.AbstractTimeoutHandler
      extended by com.google.bitcoin.core.PeerSocketHandler
          extended by com.google.bitcoin.core.Peer
All Implemented Interfaces:
StreamParser

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 extended AbstractTimeoutHandler and timeout is automatically disabled (using AbstractTimeoutHandler.setTimeoutEnabled(boolean)) once the version handshake completes.


Field Summary
protected  ReentrantLock lock
           
 
Fields inherited from class com.google.bitcoin.core.PeerSocketHandler
peerAddress
 
Constructor Summary
Peer(NetworkParameters params, AbstractBlockChain blockChain, PeerAddress peerAddress, String thisSoftwareName, String thisSoftwareVersion)
          Construct a peer that reads/writes from the given chain.
Peer(NetworkParameters params, VersionMessage ver, AbstractBlockChain chain, PeerAddress remoteAddress)
          Construct a peer that reads/writes from the given block chain.
Peer(NetworkParameters params, VersionMessage ver, PeerAddress remoteAddress, AbstractBlockChain chain, MemoryPool mempool)
          Construct a peer that reads/writes from the given block chain and memory pool.
 
Method Summary
 void addEventListener(PeerEventListener listener)
          Registers the given object as an event listener that will be invoked on the user thread.
 void addEventListener(PeerEventListener listener, Executor executor)
          Registers the given object as an event listener that will be invoked by the given executor.
 void addWallet(Wallet wallet)
          Links the given wallet to this peer.
 void connectionClosed()
          Called when the connection socket is closed
 void connectionOpened()
          Called when the connection socket is first opened
 com.google.common.util.concurrent.ListenableFuture<List<Transaction>> downloadDependencies(Transaction tx)
          Returns a future that wraps a list of all transactions that the given transaction depends on, recursively.
 long getBestHeight()
           
 com.google.common.util.concurrent.ListenableFuture<Block> getBlock(Sha256Hash blockHash)
          Asks the connected peer for the block of the given hash, and returns a future representing the answer.
 BloomFilter getBloomFilter()
          Returns the last BloomFilter set by setBloomFilter(BloomFilter).
 com.google.common.util.concurrent.ListenableFuture<Peer> getConnectionOpenFuture()
          Provides a ListenableFuture that can be used to wait for the socket to connect.
 boolean getDownloadData()
          Returns true if this peer will try and download things it is sent in "inv" messages.
 long getLastPingTime()
          Returns the elapsed time of the last ping/pong cycle.
 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.
 com.google.common.util.concurrent.ListenableFuture<Transaction> getPeerMempoolTransaction(Sha256Hash hash)
          Asks the connected peer for the given transaction from its memory pool.
 VersionMessage getPeerVersionMessage()
          Returns version data announced by the remote peer.
 long getPingTime()
          Returns a moving average of the last N ping/pong cycles.
 VersionMessage getVersionMessage()
          Returns version data we announce to our remote peers.
 com.google.common.util.concurrent.ListenableFuture<Long> ping()
          Sends the peer a ping message and returns a future that will be invoked when the pong is received back.
protected  com.google.common.util.concurrent.ListenableFuture<Long> ping(long nonce)
           
protected  void processMessage(Message m)
          Called every time a message is received from the network
 boolean removeEventListener(PeerEventListener listener)
           
 void removeWallet(Wallet wallet)
          Unlinks the given wallet from peer.
 void setBloomFilter(BloomFilter filter)
          Sets a Bloom filter on this connection.
 void setDownloadData(boolean downloadData)
          If set to false, the peer won't try and fetch blocks and transactions it hears about.
 void setDownloadParameters(long secondsSinceEpoch, boolean useFilteredBlocks)
          When downloading the block chain, the bodies will be skipped for blocks created before the given date.
 boolean setMinProtocolVersion(int minProtocolVersion)
          The minimum P2P protocol version that is accepted.
 void startBlockChainDownload()
          Starts an asynchronous download of the block chain.
 String toString()
           
 
Methods inherited from class com.google.bitcoin.core.PeerSocketHandler
close, getAddress, getMaxMessageSize, receiveBytes, sendMessage, setWriteTarget, timeoutOccurred
 
Methods inherited from class com.google.bitcoin.net.AbstractTimeoutHandler
resetTimeout, setSocketTimeout, setTimeoutEnabled
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

lock

protected final ReentrantLock lock
Constructor Detail

Peer

public Peer(NetworkParameters params,
            VersionMessage ver,
            @Nullable
            AbstractBlockChain chain,
            PeerAddress remoteAddress)

Construct a peer that reads/writes from the given block chain.

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 NioClientManager.openConnection(java.net.SocketAddress, com.google.bitcoin.net.StreamParser) or 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.


Peer

public Peer(NetworkParameters params,
            VersionMessage ver,
            PeerAddress remoteAddress,
            @Nullable
            AbstractBlockChain chain,
            @Nullable
            MemoryPool mempool)

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 NioClientManager.openConnection(java.net.SocketAddress, com.google.bitcoin.net.StreamParser) or 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.


Peer

public Peer(NetworkParameters params,
            AbstractBlockChain blockChain,
            PeerAddress peerAddress,
            String thisSoftwareName,
            String thisSoftwareVersion)

Construct a peer that reads/writes from the given chain. Automatically creates a VersionMessage for you from the given software name/version strings, which should be something like "MySimpleTool", "1.0" and which will tell the remote node to relay transaction inv messages before it has received a filter.

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 NioClientManager.openConnection(java.net.SocketAddress, com.google.bitcoin.net.StreamParser) or 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.

Method Detail

addEventListener

public void addEventListener(PeerEventListener listener)
Registers the given object as an event listener that will be invoked on the user thread. Note that listeners added this way will not receive PeerEventListener.getData(Peer, GetDataMessage) or PeerEventListener.onPreMessageReceived(Peer, Message) calls because those require that the listener be added using Threading.SAME_THREAD, which requires the other addListener form.


addEventListener

public void addEventListener(PeerEventListener listener,
                             Executor executor)
Registers the given object as an event listener that will be invoked by the given executor. Note that listeners added using any other executor than Threading.SAME_THREAD will not receive PeerEventListener.getData(Peer, GetDataMessage) or PeerEventListener.onPreMessageReceived(Peer, Message) calls because this class is not willing to cross threads in order to get the results of those hook methods.


removeEventListener

public boolean removeEventListener(PeerEventListener listener)

toString

public String toString()
Overrides:
toString in class Object

connectionClosed

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


connectionOpened

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


getConnectionOpenFuture

public com.google.common.util.concurrent.ListenableFuture<Peer> getConnectionOpenFuture()
Provides a ListenableFuture that can be used to wait for the socket to connect. A socket connection does not mean that protocol handshake has occurred.


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

downloadDependencies

public com.google.common.util.concurrent.ListenableFuture<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.


getBlock

public com.google.common.util.concurrent.ListenableFuture<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 com.google.common.util.concurrent.ListenableFuture<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.


setDownloadParameters

public void setDownloadParameters(long secondsSinceEpoch,
                                  boolean useFilteredBlocks)
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:
secondsSinceEpoch - Time in seconds since the epoch or 0 to reset to always downloading block bodies.

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.


ping

public com.google.common.util.concurrent.ListenableFuture<Long> ping()
                                                              throws ProtocolException
Sends the peer a ping message and returns a future that will be invoked when the pong is received back. The future provides a number which is the number of milliseconds elapsed between the ping and the pong. Once the pong is received the value returned by getLastPingTime() is updated.

Throws:
ProtocolException - if the peer version is too low to support measurable pings.

ping

protected com.google.common.util.concurrent.ListenableFuture<Long> ping(long nonce)
                                                                 throws ProtocolException
Throws:
ProtocolException

getLastPingTime

public long getLastPingTime()
Returns the elapsed time of the last ping/pong cycle. If ping() has never been called or we did not hear back the "pong" message yet, returns Long.MAX_VALUE.


getPingTime

public long getPingTime()
Returns a moving average of the last N ping/pong cycles. If ping() has never been called or we did not hear back the "pong" message yet, returns Long.MAX_VALUE. The moving average window is 5 buckets.


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.


getDownloadData

public boolean getDownloadData()
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.


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.


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.



Copyright © 2014. All rights reserved.