2017-08-09 02:19:06 +02:00
|
|
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
|
|
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
#ifndef BITCOIN_NET_PROCESSING_H
|
|
|
|
#define BITCOIN_NET_PROCESSING_H
|
|
|
|
|
|
|
|
#include "net.h"
|
|
|
|
#include "validationinterface.h"
|
|
|
|
|
2016-06-20 14:45:34 +02:00
|
|
|
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
|
|
|
|
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
|
|
|
|
/** Expiration time for orphan transactions in seconds */
|
|
|
|
static const int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60;
|
|
|
|
/** Minimum time between orphan transactions expire time checks in seconds */
|
|
|
|
static const int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60;
|
|
|
|
|
2017-08-23 16:21:08 +02:00
|
|
|
/** Headers download timeout expressed in microseconds
|
|
|
|
* Timeout = base + per_header * (expected number of headers) */
|
|
|
|
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE = 15 * 60 * 1000000; // 15 minutes
|
|
|
|
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER = 1000; // 1ms/header
|
|
|
|
|
2017-08-09 02:19:06 +02:00
|
|
|
/** Register with a network node to receive its signals */
|
|
|
|
void RegisterNodeSignals(CNodeSignals& nodeSignals);
|
|
|
|
/** Unregister a network node */
|
|
|
|
void UnregisterNodeSignals(CNodeSignals& nodeSignals);
|
|
|
|
|
|
|
|
class PeerLogicValidation : public CValidationInterface {
|
|
|
|
private:
|
|
|
|
CConnman* connman;
|
|
|
|
|
|
|
|
public:
|
|
|
|
PeerLogicValidation(CConnman* connmanIn);
|
|
|
|
|
2016-11-24 01:19:14 +01:00
|
|
|
virtual void SyncTransaction(const CTransaction& tx, const CBlockIndex* pindex, int nPosInBlock);
|
2017-08-09 02:19:06 +02:00
|
|
|
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload);
|
|
|
|
virtual void BlockChecked(const CBlock& block, const CValidationState& state);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CNodeStateStats {
|
|
|
|
int nMisbehavior;
|
|
|
|
int nSyncHeight;
|
|
|
|
int nCommonHeight;
|
|
|
|
std::vector<int> vHeightInFlight;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Get statistics from node state */
|
|
|
|
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
|
|
|
|
/** Increase a node's misbehavior score. */
|
|
|
|
void Misbehaving(NodeId nodeid, int howmuch);
|
|
|
|
|
|
|
|
/** Process protocol messages received from a given node */
|
2017-08-09 18:06:31 +02:00
|
|
|
bool ProcessMessages(CNode* pfrom, CConnman& connman, std::atomic<bool>& interrupt);
|
2017-08-09 02:19:06 +02:00
|
|
|
/**
|
|
|
|
* Send queued protocol messages to be sent to a give node.
|
|
|
|
*
|
|
|
|
* @param[in] pto The node which we are sending messages to.
|
|
|
|
* @param[in] connman The connection manager for that node.
|
2017-08-09 18:06:31 +02:00
|
|
|
* @param[in] interrupt Interrupt condition for processing threads
|
Backport Bitcoin PR#9441: Net: Massive speedup. Net locks overhaul (#1586)
* net: fix typo causing the wrong receive buffer size
Surprisingly this hasn't been causing me any issues while testing, probably
because it requires lots of large blocks to be flying around.
Send/Recv corks need tests!
* net: make vRecvMsg a list so that we can use splice()
* net: make GetReceiveFloodSize public
This will be needed so that the message processor can cork incoming messages
* net: only disconnect if fDisconnect has been set
These conditions are problematic to check without locking, and we shouldn't be
relying on the refcount to disconnect.
* net: wait until the node is destroyed to delete its recv buffer
when vRecvMsg becomes a private buffer, it won't make sense to allow other
threads to mess with it anymore.
* net: set message deserialization version when it's actually time to deserialize
We'll soon no longer have access to vRecvMsg, and this is more intuitive anyway.
* net: handle message accounting in ReceiveMsgBytes
This allows locking to be pushed down to only where it's needed
Also reuse the current time rather than checking multiple times.
* net: record bytes written before notifying the message processor
* net: Add a simple function for waking the message handler
This may be used publicly in the future
* net: remove useless comments
* net: remove redundant max sendbuffer size check
This is left-over from before there was proper accounting. Hitting 2x the
sendbuffer size should not be possible.
* net: rework the way that the messagehandler sleeps
In order to sleep accurately, the message handler needs to know if _any_ node
has more processing that it should do before the entire thread sleeps.
Rather than returning a value that represents whether ProcessMessages
encountered a message that should trigger a disconnnect, interpret the return
value as whether or not that node has more work to do.
Also, use a global fProcessWake value that can be set by other threads,
which takes precedence (for one cycle) over the messagehandler's decision.
Note that the previous behavior was to only process one message per loop
(except in the case of a bad checksum or invalid header). That was changed in
PR #3180.
The only change here in that regard is that the current node now falls to the
back of the processing queue for the bad checksum/invalid header cases.
* net: add a new message queue for the message processor
This separates the storage of messages from the net and queued messages for
processing, allowing the locks to be split.
* net: add a flag to indicate when a node's process queue is full
Messages are dumped very quickly from the socket handler to the processor, so
it's the depth of the processing queue that's interesting.
The socket handler checks the process queue's size during the brief message
hand-off and pauses if necessary, and the processor possibly unpauses each time
a message is popped off of its queue.
* net: add a flag to indicate when a node's send buffer is full
Similar to the recv flag, but this one indicates whether or not the net's send
buffer is full.
The socket handler checks the send queue when a new message is added and pauses
if necessary, and possibly unpauses after each message is drained from its buffer.
* net: remove cs_vRecvMsg
vRecvMsg is now only touched by the socket handler thread.
The accounting vars (nRecvBytes/nLastRecv/mapRecvBytesPerMsgCmd) are also
only used by the socket handler thread, with the exception of queries from
rpc/gui. These accesses are not threadsafe, but they never were. This needs to
be addressed separately.
Also, update comment describing data flow
2017-08-23 16:20:43 +02:00
|
|
|
* @return True if there is more work to be done
|
2017-08-09 02:19:06 +02:00
|
|
|
*/
|
2017-08-09 18:06:31 +02:00
|
|
|
bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interrupt);
|
2017-08-09 02:19:06 +02:00
|
|
|
|
|
|
|
#endif // BITCOIN_NET_PROCESSING_H
|