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.
Modifier and Type | Field and Description |
---|---|
protected java.util.concurrent.locks.ReentrantLock |
lock |
peerAddress, writeTarget
Constructor and Description |
---|
Peer(NetworkParameters params,
AbstractBlockChain blockChain,
PeerAddress peerAddress,
java.lang.String thisSoftwareName,
java.lang.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)
Construct a peer that reads/writes from the given block chain.
|
Peer(NetworkParameters params,
VersionMessage ver,
PeerAddress remoteAddress,
AbstractBlockChain chain,
int downloadTxDependencyDepth)
Construct a peer that reads/writes from the given block chain.
|
Modifier and Type | Method and Description |
---|---|
void |
addBlocksDownloadedEventListener(BlocksDownloadedEventListener listener)
Registers a listener that is invoked when new blocks are downloaded.
|
void |
addBlocksDownloadedEventListener(java.util.concurrent.Executor executor,
BlocksDownloadedEventListener listener)
Registers a listener that is invoked when new blocks are downloaded.
|
void |
addChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener)
Registers a listener that is invoked when a blockchain downloaded starts.
|
void |
addChainDownloadStartedEventListener(java.util.concurrent.Executor executor,
ChainDownloadStartedEventListener listener)
Registers a listener that is invoked when a blockchain downloaded starts.
|
void |
addConnectedEventListener(java.util.concurrent.Executor executor,
PeerConnectedEventListener listener)
Registers a listener that is invoked when a peer is connected.
|
void |
addConnectedEventListener(PeerConnectedEventListener listener)
Registers a listener that is invoked when a peer is connected.
|
void |
addDisconnectedEventListener(java.util.concurrent.Executor executor,
PeerDisconnectedEventListener listener)
Registers a listener that is invoked when a peer is disconnected.
|
void |
addDisconnectedEventListener(PeerDisconnectedEventListener listener)
Registers a listener that is invoked when a peer is disconnected.
|
void |
addGetDataEventListener(java.util.concurrent.Executor executor,
GetDataEventListener listener)
Registers a listener that is called when messages are received.
|
void |
addGetDataEventListener(GetDataEventListener listener)
Registers a listener that is called when messages are received.
|
void |
addOnTransactionBroadcastListener(java.util.concurrent.Executor executor,
OnTransactionBroadcastListener listener)
Registers a listener that is called when a transaction is broadcast across the network
|
void |
addOnTransactionBroadcastListener(OnTransactionBroadcastListener listener)
Registers a listener that is called when a transaction is broadcast across the network
|
void |
addPreMessageReceivedEventListener(java.util.concurrent.Executor executor,
PreMessageReceivedEventListener listener)
Registers a listener that is called immediately before a message is received
|
void |
addPreMessageReceivedEventListener(PreMessageReceivedEventListener listener)
Registers a listener that is called immediately before a message is received
|
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<java.util.List<Transaction>> |
downloadDependencies(Transaction tx)
Returns a future that wraps a list of all transactions that the given transaction depends on, recursively.
|
protected com.google.common.util.concurrent.ListenableFuture<java.lang.Object> |
downloadDependenciesInternal(int maxDepth,
int depth,
Transaction tx,
java.lang.Object marker,
java.util.List<Transaction> results) |
protected void |
endFilteredBlock(FilteredBlock m) |
com.google.common.util.concurrent.ListenableFuture<AddressMessage> |
getAddr()
Sends a getaddr request to the peer and returns a future that completes with the answer once the peer has replied.
|
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.
|
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.
|
com.google.common.util.concurrent.ListenableFuture<UTXOsMessage> |
getUTXOs(java.util.List<TransactionOutPoint> outPoints)
Sends a query to the remote peer asking for the unspent transaction outputs (UTXOs) for the given outpoints,
with the memory pool included.
|
com.google.common.util.concurrent.ListenableFuture<UTXOsMessage> |
getUTXOs(java.util.List<TransactionOutPoint> outPoints,
boolean includeMempool)
Sends a query to the remote peer asking for the unspent transaction outputs (UTXOs) for the given outpoints.
|
com.google.common.util.concurrent.ListenableFuture<Peer> |
getVersionHandshakeFuture() |
VersionMessage |
getVersionMessage()
Returns version data we announce to our remote peers.
|
boolean |
isDownloadData()
Returns true if this peer will try and download things it is sent in "inv" messages.
|
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.
|
com.google.common.util.concurrent.ListenableFuture<java.lang.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<java.lang.Long> |
ping(long nonce) |
protected void |
processAlert(AlertMessage m) |
protected void |
processBlock(Block m) |
protected void |
processGetData(GetDataMessage getdata) |
protected void |
processHeaders(HeadersMessage m) |
protected void |
processInv(InventoryMessage inv) |
protected void |
processMessage(Message m)
Called every time a message is received from the network
|
protected void |
processNotFoundMessage(NotFoundMessage m) |
protected void |
processPong(Pong m) |
protected void |
processTransaction(Transaction tx) |
protected void |
processUTXOMessage(UTXOsMessage m) |
boolean |
removeBlocksDownloadedEventListener(BlocksDownloadedEventListener listener) |
boolean |
removeChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener) |
boolean |
removeConnectedEventListener(PeerConnectedEventListener listener) |
boolean |
removeDisconnectedEventListener(PeerDisconnectedEventListener listener) |
boolean |
removeGetDataEventListener(GetDataEventListener listener) |
boolean |
removeOnTransactionBroadcastListener(OnTransactionBroadcastListener listener) |
boolean |
removePreMessageReceivedEventListener(PreMessageReceivedEventListener listener) |
void |
removeWallet(Wallet wallet)
Unlinks the given wallet from peer.
|
void |
setBloomFilter(BloomFilter filter)
Sets a Bloom filter on this connection.
|
void |
setBloomFilter(BloomFilter filter,
boolean andQueryMemPool)
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.
|
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.
|
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.
|
boolean |
setMinProtocolVersion(int minProtocolVersion)
The minimum P2P protocol version that is accepted.
|
void |
startBlockChainDownload()
Starts an asynchronous download of the block chain.
|
protected void |
startFilteredBlock(FilteredBlock m) |
protected void |
timeoutOccurred() |
java.lang.String |
toString() |
java.lang.String |
toStringServices(long services) |
close, getAddress, getMaxMessageSize, receiveBytes, sendMessage, setWriteTarget
resetTimeout, setSocketTimeout, setTimeoutEnabled
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(SocketAddress, StreamConnection)
or
NioClient.NioClient(SocketAddress, StreamConnection, 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)
Construct a peer that reads/writes from the given block chain. Transactions stored in a TxConfidenceTable
will have their confidence levels updated when a peer announces it, to reflect the greater likelihood 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(SocketAddress, StreamConnection)
or
NioClient.NioClient(SocketAddress, StreamConnection, 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, int downloadTxDependencyDepth)
Construct a peer that reads/writes from the given block chain. Transactions stored in a TxConfidenceTable
will have their confidence levels updated when a peer announces it, to reflect the greater likelihood 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(SocketAddress, StreamConnection)
or
NioClient.NioClient(SocketAddress, StreamConnection, 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, AbstractBlockChain blockChain, PeerAddress peerAddress, java.lang.String thisSoftwareName, java.lang.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(SocketAddress, StreamConnection)
or
NioClient.NioClient(SocketAddress, StreamConnection, 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 void addBlocksDownloadedEventListener(BlocksDownloadedEventListener listener)
public void addBlocksDownloadedEventListener(java.util.concurrent.Executor executor, BlocksDownloadedEventListener listener)
public void addChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener)
public void addChainDownloadStartedEventListener(java.util.concurrent.Executor executor, ChainDownloadStartedEventListener listener)
public void addConnectedEventListener(PeerConnectedEventListener listener)
public void addConnectedEventListener(java.util.concurrent.Executor executor, PeerConnectedEventListener listener)
public void addDisconnectedEventListener(PeerDisconnectedEventListener listener)
public void addDisconnectedEventListener(java.util.concurrent.Executor executor, PeerDisconnectedEventListener listener)
public void addGetDataEventListener(GetDataEventListener listener)
public void addGetDataEventListener(java.util.concurrent.Executor executor, GetDataEventListener listener)
public void addOnTransactionBroadcastListener(OnTransactionBroadcastListener listener)
public void addOnTransactionBroadcastListener(java.util.concurrent.Executor executor, OnTransactionBroadcastListener listener)
public void addPreMessageReceivedEventListener(PreMessageReceivedEventListener listener)
public void addPreMessageReceivedEventListener(java.util.concurrent.Executor executor, PreMessageReceivedEventListener listener)
public boolean removeBlocksDownloadedEventListener(BlocksDownloadedEventListener listener)
public boolean removeChainDownloadStartedEventListener(ChainDownloadStartedEventListener listener)
public boolean removeConnectedEventListener(PeerConnectedEventListener listener)
public boolean removeDisconnectedEventListener(PeerDisconnectedEventListener listener)
public boolean removeGetDataEventListener(GetDataEventListener listener)
public boolean removeOnTransactionBroadcastListener(OnTransactionBroadcastListener listener)
public boolean removePreMessageReceivedEventListener(PreMessageReceivedEventListener listener)
public java.lang.String toString()
toString
in class java.lang.Object
public java.lang.String toStringServices(long services)
protected void timeoutOccurred()
timeoutOccurred
in class PeerSocketHandler
public void connectionClosed()
StreamConnection
public void connectionOpened()
StreamConnection
public com.google.common.util.concurrent.ListenableFuture<Peer> getConnectionOpenFuture()
public com.google.common.util.concurrent.ListenableFuture<Peer> getVersionHandshakeFuture()
protected void processMessage(Message m) throws java.lang.Exception
PeerSocketHandler
processMessage
in class PeerSocketHandler
java.lang.Exception
protected void processUTXOMessage(UTXOsMessage m)
protected void startFilteredBlock(FilteredBlock m)
protected void processNotFoundMessage(NotFoundMessage m)
protected void processAlert(AlertMessage m)
protected void processHeaders(HeadersMessage m) throws ProtocolException
ProtocolException
protected void processGetData(GetDataMessage getdata)
protected void processTransaction(Transaction tx) throws VerificationException
VerificationException
public com.google.common.util.concurrent.ListenableFuture<java.util.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.
protected com.google.common.util.concurrent.ListenableFuture<java.lang.Object> downloadDependenciesInternal(int maxDepth, int depth, Transaction tx, java.lang.Object marker, java.util.List<Transaction> results)
protected void processBlock(Block m)
protected void endFilteredBlock(FilteredBlock m)
protected void processInv(InventoryMessage inv)
public com.google.common.util.concurrent.ListenableFuture<Block> getBlock(Sha256Hash blockHash)
public com.google.common.util.concurrent.ListenableFuture<Transaction> getPeerMempoolTransaction(Sha256Hash hash)
public com.google.common.util.concurrent.ListenableFuture<AddressMessage> getAddr()
public void setDownloadParameters(long secondsSinceEpoch, boolean useFilteredBlocks)
secondsSinceEpoch
- Time in seconds since the epoch or 0 to reset to always downloading block bodies.public void addWallet(Wallet wallet)
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.public void removeWallet(Wallet wallet)
addWallet(Wallet)
.public void startBlockChainDownload()
public com.google.common.util.concurrent.ListenableFuture<java.lang.Long> ping() throws ProtocolException
getLastPingTime()
is
updated.ProtocolException
- if the peer version is too low to support measurable pings.protected com.google.common.util.concurrent.ListenableFuture<java.lang.Long> ping(long nonce) throws ProtocolException
ProtocolException
public long getLastPingTime()
ping()
has never
been called or we did not hear back the "pong" message yet, returns Long.MAX_VALUE
.public long getPingTime()
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.protected void processPong(Pong m)
public int getPeerBlockHeightDifference()
public boolean isDownloadData()
public void setDownloadData(boolean downloadData)
public VersionMessage getPeerVersionMessage()
public VersionMessage getVersionMessage()
public long getBestHeight()
public boolean setMinProtocolVersion(int minProtocolVersion)
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.
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.
public BloomFilter getBloomFilter()
BloomFilter
set by setBloomFilter(BloomFilter)
. Bloom filters tell
the remote node what transactions to send us, in a compact manner.public com.google.common.util.concurrent.ListenableFuture<UTXOsMessage> getUTXOs(java.util.List<TransactionOutPoint> outPoints)
ProtocolException
- if this peer doesn't support the protocol.public com.google.common.util.concurrent.ListenableFuture<UTXOsMessage> getUTXOs(java.util.List<TransactionOutPoint> outPoints, boolean includeMempool)
includeMempool
- If true (the default) the results take into account the contents of the memory pool too.ProtocolException
- if this peer doesn't support the protocol.public boolean isDownloadTxDependencies()
public void setDownloadTxDependencies(boolean enable)
public void setDownloadTxDependencies(int depth)