Add 2 outbound block-relay-only connections
Transaction relay is primarily optimized for balancing redundancy/robustness with bandwidth minimization -- as a result transaction relay leaks information that adversaries can use to infer the network topology. Network topology is better kept private for (at least) two reasons: (a) Knowledge of the network graph can make it easier to find the source IP of a given transaction. (b) Knowledge of the network graph could be used to split a target node or nodes from the honest network (eg by knowing which peers to attack in order to achieve a network split). We can eliminate the risks of (b) by separating block relay from transaction relay; inferring network connectivity from the relay of blocks/block headers is much more expensive for an adversary. After this commit, bitcoind will make 2 additional outbound connections that are only used for block relay. (In the future, we might consider rotating our transaction-relay peers to help limit the effects of (a).)
This commit is contained in:
parent
b83f51a4bb
commit
3a5e885306
5 changed files with 75 additions and 40 deletions
|
@ -1753,7 +1753,8 @@ bool AppInitMain(InitInterfaces& interfaces)
|
|||
CConnman::Options connOptions;
|
||||
connOptions.nLocalServices = nLocalServices;
|
||||
connOptions.nMaxConnections = nMaxConnections;
|
||||
connOptions.nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, connOptions.nMaxConnections);
|
||||
connOptions.m_max_outbound_full_relay = std::min(MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, connOptions.nMaxConnections);
|
||||
connOptions.m_max_outbound_block_relay = std::min(MAX_BLOCKS_ONLY_CONNECTIONS, connOptions.nMaxConnections-connOptions.m_max_outbound_full_relay);
|
||||
connOptions.nMaxAddnode = MAX_ADDNODE_CONNECTIONS;
|
||||
connOptions.nMaxFeeler = 1;
|
||||
connOptions.nBestHeight = chain_active_height;
|
||||
|
|
40
src/net.cpp
40
src/net.cpp
|
@ -352,7 +352,7 @@ static CAddress GetBindAddress(SOCKET sock)
|
|||
return addr_bind;
|
||||
}
|
||||
|
||||
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection)
|
||||
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection, bool block_relay_only)
|
||||
{
|
||||
if (pszDest == nullptr) {
|
||||
if (IsLocal(addrConnect))
|
||||
|
@ -442,7 +442,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||
NodeId id = GetNewNodeId();
|
||||
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
|
||||
CAddress addr_bind = GetBindAddress(hSocket);
|
||||
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", false);
|
||||
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", false, block_relay_only);
|
||||
pnode->AddRef();
|
||||
|
||||
return pnode;
|
||||
|
@ -905,7 +905,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
|
|||
SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
|
||||
CAddress addr;
|
||||
int nInbound = 0;
|
||||
int nMaxInbound = nMaxConnections - (nMaxOutbound + nMaxFeeler);
|
||||
int nMaxInbound = nMaxConnections - m_max_outbound;
|
||||
|
||||
if (hSocket != INVALID_SOCKET) {
|
||||
if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) {
|
||||
|
@ -1666,7 +1666,7 @@ int CConnman::GetExtraOutboundCount()
|
|||
}
|
||||
}
|
||||
}
|
||||
return std::max(nOutbound - nMaxOutbound, 0);
|
||||
return std::max(nOutbound - m_max_outbound_full_relay - m_max_outbound_block_relay, 0);
|
||||
}
|
||||
|
||||
void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
||||
|
@ -1726,7 +1726,8 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||
CAddress addrConnect;
|
||||
|
||||
// Only connect out to one peer per network group (/16 for IPv4).
|
||||
int nOutbound = 0;
|
||||
int nOutboundFullRelay = 0;
|
||||
int nOutboundBlockRelay = 0;
|
||||
std::set<std::vector<unsigned char> > setConnected;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
|
@ -1738,7 +1739,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||
// also have the added issue that they're attacker controlled and could be used
|
||||
// to prevent us from connecting to particular hosts if we used them here.
|
||||
setConnected.insert(pnode->addr.GetGroup());
|
||||
nOutbound++;
|
||||
if (pnode->m_tx_relay == nullptr) {
|
||||
nOutboundBlockRelay++;
|
||||
} else if (!pnode->fFeeler) {
|
||||
nOutboundFullRelay++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1757,7 +1762,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||
//
|
||||
bool fFeeler = false;
|
||||
|
||||
if (nOutbound >= nMaxOutbound && !GetTryNewOutboundPeer()) {
|
||||
if (nOutboundFullRelay >= m_max_outbound_full_relay && nOutboundBlockRelay >= m_max_outbound_block_relay && !GetTryNewOutboundPeer()) {
|
||||
int64_t nTime = GetTimeMicros(); // The current time right now (in microseconds).
|
||||
if (nTime > nNextFeeler) {
|
||||
nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL);
|
||||
|
@ -1831,7 +1836,14 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||
LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
|
||||
}
|
||||
|
||||
OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, false, fFeeler);
|
||||
// Open this connection as block-relay-only if we're already at our
|
||||
// full-relay capacity, but not yet at our block-relay peer limit.
|
||||
// (It should not be possible for fFeeler to be set if we're not
|
||||
// also at our block-relay peer limit, but check against that as
|
||||
// well for sanity.)
|
||||
bool block_relay_only = nOutboundBlockRelay < m_max_outbound_block_relay && !fFeeler && nOutboundFullRelay >= m_max_outbound_full_relay;
|
||||
|
||||
OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, false, fFeeler, false, block_relay_only);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1918,7 +1930,7 @@ void CConnman::ThreadOpenAddedConnections()
|
|||
}
|
||||
|
||||
// if successful, this moves the passed grant to the constructed node
|
||||
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool manual_connection)
|
||||
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool manual_connection, bool block_relay_only)
|
||||
{
|
||||
//
|
||||
// Initiate outbound network connection
|
||||
|
@ -1937,7 +1949,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
|
|||
} else if (FindNode(std::string(pszDest)))
|
||||
return;
|
||||
|
||||
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, manual_connection);
|
||||
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, manual_connection, block_relay_only);
|
||||
|
||||
if (!pnode)
|
||||
return;
|
||||
|
@ -2240,7 +2252,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
|
|||
|
||||
if (semOutbound == nullptr) {
|
||||
// initialize semaphore
|
||||
semOutbound = MakeUnique<CSemaphore>(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
|
||||
semOutbound = MakeUnique<CSemaphore>(std::min(m_max_outbound, nMaxConnections));
|
||||
}
|
||||
if (semAddnode == nullptr) {
|
||||
// initialize semaphore
|
||||
|
@ -2318,7 +2330,7 @@ void CConnman::Interrupt()
|
|||
InterruptSocks5(true);
|
||||
|
||||
if (semOutbound) {
|
||||
for (int i=0; i<(nMaxOutbound + nMaxFeeler); i++) {
|
||||
for (int i=0; i<m_max_outbound; i++) {
|
||||
semOutbound->post();
|
||||
}
|
||||
}
|
||||
|
@ -2628,7 +2640,7 @@ int CConnman::GetBestHeight() const
|
|||
|
||||
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
|
||||
|
||||
CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, bool fInboundIn)
|
||||
CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, bool fInboundIn, bool block_relay_only)
|
||||
: nTimeConnected(GetSystemTimeInSeconds()),
|
||||
addr(addrIn),
|
||||
addrBind(addrBindIn),
|
||||
|
@ -2643,7 +2655,9 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
|
|||
hSocket = hSocketIn;
|
||||
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
|
||||
hashContinue = uint256();
|
||||
if (!block_relay_only) {
|
||||
m_tx_relay = MakeUnique<TxRelay>();
|
||||
}
|
||||
|
||||
for (const std::string &msg : getAllNetMessageTypes())
|
||||
mapRecvBytesPerMsgCmd[msg] = 0;
|
||||
|
|
33
src/net.h
33
src/net.h
|
@ -56,10 +56,12 @@ static const unsigned int MAX_ADDR_TO_SEND = 1000;
|
|||
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 4 * 1000 * 1000;
|
||||
/** Maximum length of the user agent string in `version` message */
|
||||
static const unsigned int MAX_SUBVERSION_LENGTH = 256;
|
||||
/** Maximum number of automatic outgoing nodes */
|
||||
static const int MAX_OUTBOUND_CONNECTIONS = 8;
|
||||
/** Maximum number of automatic outgoing nodes over which we'll relay everything (blocks, tx, addrs, etc) */
|
||||
static const int MAX_OUTBOUND_FULL_RELAY_CONNECTIONS = 8;
|
||||
/** Maximum number of addnode outgoing nodes */
|
||||
static const int MAX_ADDNODE_CONNECTIONS = 8;
|
||||
/** Maximum number of block-relay-only outgoing connections */
|
||||
static const int MAX_BLOCKS_ONLY_CONNECTIONS = 2;
|
||||
/** -listen default */
|
||||
static const bool DEFAULT_LISTEN = true;
|
||||
/** -upnp default */
|
||||
|
@ -126,7 +128,8 @@ public:
|
|||
{
|
||||
ServiceFlags nLocalServices = NODE_NONE;
|
||||
int nMaxConnections = 0;
|
||||
int nMaxOutbound = 0;
|
||||
int m_max_outbound_full_relay = 0;
|
||||
int m_max_outbound_block_relay = 0;
|
||||
int nMaxAddnode = 0;
|
||||
int nMaxFeeler = 0;
|
||||
int nBestHeight = 0;
|
||||
|
@ -150,10 +153,12 @@ public:
|
|||
void Init(const Options& connOptions) {
|
||||
nLocalServices = connOptions.nLocalServices;
|
||||
nMaxConnections = connOptions.nMaxConnections;
|
||||
nMaxOutbound = std::min(connOptions.nMaxOutbound, connOptions.nMaxConnections);
|
||||
m_max_outbound_full_relay = std::min(connOptions.m_max_outbound_full_relay, connOptions.nMaxConnections);
|
||||
m_max_outbound_block_relay = connOptions.m_max_outbound_block_relay;
|
||||
m_use_addrman_outgoing = connOptions.m_use_addrman_outgoing;
|
||||
nMaxAddnode = connOptions.nMaxAddnode;
|
||||
nMaxFeeler = connOptions.nMaxFeeler;
|
||||
m_max_outbound = m_max_outbound_full_relay + m_max_outbound_block_relay + nMaxFeeler;
|
||||
nBestHeight = connOptions.nBestHeight;
|
||||
clientInterface = connOptions.uiInterface;
|
||||
m_banman = connOptions.m_banman;
|
||||
|
@ -192,7 +197,7 @@ public:
|
|||
bool GetNetworkActive() const { return fNetworkActive; };
|
||||
bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
|
||||
void SetNetworkActive(bool active);
|
||||
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, bool fOneShot = false, bool fFeeler = false, bool manual_connection = false);
|
||||
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, bool fOneShot = false, bool fFeeler = false, bool manual_connection = false, bool block_relay_only = false);
|
||||
bool CheckIncomingNonce(uint64_t nonce);
|
||||
|
||||
bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func);
|
||||
|
@ -248,7 +253,7 @@ public:
|
|||
void AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
|
||||
std::vector<CAddress> GetAddresses();
|
||||
|
||||
// This allows temporarily exceeding nMaxOutbound, with the goal of finding
|
||||
// This allows temporarily exceeding m_max_outbound_full_relay, with the goal of finding
|
||||
// a peer that is better than all our current peers.
|
||||
void SetTryNewOutboundPeer(bool flag);
|
||||
bool GetTryNewOutboundPeer();
|
||||
|
@ -350,7 +355,7 @@ private:
|
|||
CNode* FindNode(const CService& addr);
|
||||
|
||||
bool AttemptToEvictConnection();
|
||||
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection);
|
||||
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection, bool block_relay_only);
|
||||
void AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const;
|
||||
|
||||
void DeleteNode(CNode* pnode);
|
||||
|
@ -409,9 +414,17 @@ private:
|
|||
std::unique_ptr<CSemaphore> semOutbound;
|
||||
std::unique_ptr<CSemaphore> semAddnode;
|
||||
int nMaxConnections;
|
||||
int nMaxOutbound;
|
||||
|
||||
// How many full-relay (tx, block, addr) outbound peers we want
|
||||
int m_max_outbound_full_relay;
|
||||
|
||||
// How many block-relay only outbound peers we want
|
||||
// We do not relay tx or addr messages with these peers
|
||||
int m_max_outbound_block_relay;
|
||||
|
||||
int nMaxAddnode;
|
||||
int nMaxFeeler;
|
||||
int m_max_outbound;
|
||||
bool m_use_addrman_outgoing;
|
||||
std::atomic<int> nBestHeight;
|
||||
CClientUIInterface* clientInterface;
|
||||
|
@ -437,7 +450,7 @@ private:
|
|||
std::thread threadMessageHandler;
|
||||
|
||||
/** flag for deciding to connect to an extra outbound peer,
|
||||
* in excess of nMaxOutbound
|
||||
* in excess of m_max_outbound_full_relay
|
||||
* This takes the place of a feeler connection */
|
||||
std::atomic_bool m_try_another_outbound_peer;
|
||||
|
||||
|
@ -756,7 +769,7 @@ public:
|
|||
|
||||
std::set<uint256> orphan_work_set;
|
||||
|
||||
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn = "", bool fInboundIn = false);
|
||||
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn = "", bool fInboundIn = false, bool block_relay_only = false);
|
||||
~CNode();
|
||||
CNode(const CNode&) = delete;
|
||||
CNode& operator=(const CNode&) = delete;
|
||||
|
|
|
@ -262,7 +262,7 @@ struct CNodeState {
|
|||
bool fSupportsDesiredCmpctVersion;
|
||||
|
||||
/** State used to enforce CHAIN_SYNC_TIMEOUT
|
||||
* Only in effect for outbound, non-manual connections, with
|
||||
* Only in effect for outbound, non-manual, full-relay connections, with
|
||||
* m_protect == false
|
||||
* Algorithm: if a peer's best known block has less work than our tip,
|
||||
* set a timeout CHAIN_SYNC_TIMEOUT seconds in the future:
|
||||
|
@ -425,7 +425,7 @@ static void PushNodeVersion(CNode *pnode, CConnman* connman, int64_t nTime)
|
|||
CAddress addrMe = CAddress(CService(), nLocalNodeServices);
|
||||
|
||||
connman->PushMessage(pnode, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERSION, PROTOCOL_VERSION, (uint64_t)nLocalNodeServices, nTime, addrYou, addrMe,
|
||||
nonce, strSubVersion, nNodeStartingHeight, ::g_relay_txes));
|
||||
nonce, strSubVersion, nNodeStartingHeight, ::g_relay_txes && pnode->m_tx_relay != nullptr));
|
||||
|
||||
if (fLogIPs) {
|
||||
LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.ToString(), addrYou.ToString(), nodeid);
|
||||
|
@ -757,7 +757,7 @@ void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds)
|
|||
}
|
||||
|
||||
// Returns true for outbound peers, excluding manual connections, feelers, and
|
||||
// one-shots
|
||||
// one-shots.
|
||||
static bool IsOutboundDisconnectionCandidate(const CNode *node)
|
||||
{
|
||||
return !(node->fInbound || node->m_manual_connection || node->fFeeler || node->fOneShot);
|
||||
|
@ -1772,9 +1772,11 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
|
|||
}
|
||||
}
|
||||
|
||||
if (!pfrom->fDisconnect && IsOutboundDisconnectionCandidate(pfrom) && nodestate->pindexBestKnownBlock != nullptr) {
|
||||
// If this is an outbound peer, check to see if we should protect
|
||||
if (!pfrom->fDisconnect && IsOutboundDisconnectionCandidate(pfrom) && nodestate->pindexBestKnownBlock != nullptr && pfrom->m_tx_relay != nullptr) {
|
||||
// If this is an outbound full-relay peer, check to see if we should protect
|
||||
// it from the bad/lagging chain logic.
|
||||
// Note that block-relay-only peers are already implicitly protected, so we
|
||||
// only consider setting m_protect for the full-relay peers.
|
||||
if (g_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= ::ChainActive().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) {
|
||||
LogPrint(BCLog::NET, "Protecting outbound peer=%d from eviction\n", pfrom->GetId());
|
||||
nodestate->m_chain_sync.m_protect = true;
|
||||
|
@ -2088,9 +2090,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||
// Mark this node as currently connected, so we update its timestamp later.
|
||||
LOCK(cs_main);
|
||||
State(pfrom->GetId())->fCurrentlyConnected = true;
|
||||
LogPrintf("New outbound peer connected: version: %d, blocks=%d, peer=%d%s\n",
|
||||
pfrom->nVersion.load(), pfrom->nStartingHeight, pfrom->GetId(),
|
||||
(fLogIPs ? strprintf(", peeraddr=%s", pfrom->addr.ToString()) : ""));
|
||||
LogPrintf("New outbound peer connected: version: %d, blocks=%d, peer=%d%s (%s)\n",
|
||||
pfrom->nVersion.load(), pfrom->nStartingHeight,
|
||||
pfrom->GetId(), (fLogIPs ? strprintf(", peeraddr=%s", pfrom->addr.ToString()) : ""),
|
||||
pfrom->m_tx_relay == nullptr ? "block-relay" : "full-relay");
|
||||
}
|
||||
|
||||
if (pfrom->nVersion >= SENDHEADERS_VERSION) {
|
||||
|
@ -2214,7 +2217,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||
return false;
|
||||
}
|
||||
|
||||
bool fBlocksOnly = !g_relay_txes;
|
||||
// We won't accept tx inv's if we're in blocks-only mode, or this is a
|
||||
// block-relay-only peer
|
||||
bool fBlocksOnly = !g_relay_txes || (pfrom->m_tx_relay == nullptr);
|
||||
|
||||
// Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistrelay is true
|
||||
if (pfrom->HasPermission(PF_RELAY))
|
||||
|
@ -3453,6 +3458,8 @@ void PeerLogicValidation::EvictExtraOutboundPeers(int64_t time_in_seconds)
|
|||
if (state == nullptr) return; // shouldn't be possible, but just in case
|
||||
// Don't evict our protected peers
|
||||
if (state->m_chain_sync.m_protect) return;
|
||||
// Don't evict our block-relay-only peers.
|
||||
if (pnode->m_tx_relay == nullptr) return;
|
||||
if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->GetId() > worst_peer)) {
|
||||
worst_peer = pnode->GetId();
|
||||
oldest_block_announcement = state->m_last_block_announcement;
|
||||
|
|
|
@ -151,17 +151,17 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
|
|||
auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), nullptr, scheduler, false);
|
||||
|
||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||
constexpr int nMaxOutbound = 8;
|
||||
constexpr int max_outbound_full_relay = 8;
|
||||
CConnman::Options options;
|
||||
options.nMaxConnections = 125;
|
||||
options.nMaxOutbound = nMaxOutbound;
|
||||
options.m_max_outbound_full_relay = max_outbound_full_relay;
|
||||
options.nMaxFeeler = 1;
|
||||
|
||||
connman->Init(options);
|
||||
std::vector<CNode *> vNodes;
|
||||
|
||||
// Mock some outbound peers
|
||||
for (int i=0; i<nMaxOutbound; ++i) {
|
||||
for (int i=0; i<max_outbound_full_relay; ++i) {
|
||||
AddRandomOutboundPeer(vNodes, *peerLogic, connman.get());
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
|
|||
AddRandomOutboundPeer(vNodes, *peerLogic, connman.get());
|
||||
|
||||
peerLogic->CheckForStaleTipAndEvictPeers(consensusParams);
|
||||
for (int i=0; i<nMaxOutbound; ++i) {
|
||||
for (int i=0; i<max_outbound_full_relay; ++i) {
|
||||
BOOST_CHECK(vNodes[i]->fDisconnect == false);
|
||||
}
|
||||
// Last added node should get marked for eviction
|
||||
|
@ -203,10 +203,10 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
|
|||
UpdateLastBlockAnnounceTime(vNodes.back()->GetId(), GetTime());
|
||||
|
||||
peerLogic->CheckForStaleTipAndEvictPeers(consensusParams);
|
||||
for (int i=0; i<nMaxOutbound-1; ++i) {
|
||||
for (int i=0; i<max_outbound_full_relay-1; ++i) {
|
||||
BOOST_CHECK(vNodes[i]->fDisconnect == false);
|
||||
}
|
||||
BOOST_CHECK(vNodes[nMaxOutbound-1]->fDisconnect == true);
|
||||
BOOST_CHECK(vNodes[max_outbound_full_relay-1]->fDisconnect == true);
|
||||
BOOST_CHECK(vNodes.back()->fDisconnect == false);
|
||||
|
||||
bool dummy;
|
||||
|
|
Loading…
Reference in a new issue