LCOV - code coverage report
Current view: top level - src/test - denialofservice_tests.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 291 292 99.7 %
Date: 2021-06-29 14:35:33 Functions: 12 12 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 29 30 96.7 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2011-2020 The Bitcoin Core developers
#       2                 :            : // Distributed under the MIT software license, see the accompanying
#       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       4                 :            : 
#       5                 :            : // Unit tests for denial-of-service detection/prevention code
#       6                 :            : 
#       7                 :            : #include <arith_uint256.h>
#       8                 :            : #include <banman.h>
#       9                 :            : #include <chainparams.h>
#      10                 :            : #include <net.h>
#      11                 :            : #include <net_processing.h>
#      12                 :            : #include <pubkey.h>
#      13                 :            : #include <script/sign.h>
#      14                 :            : #include <script/signingprovider.h>
#      15                 :            : #include <script/standard.h>
#      16                 :            : #include <serialize.h>
#      17                 :            : #include <txorphanage.h>
#      18                 :            : #include <util/string.h>
#      19                 :            : #include <util/system.h>
#      20                 :            : #include <util/time.h>
#      21                 :            : #include <validation.h>
#      22                 :            : 
#      23                 :            : #include <test/util/setup_common.h>
#      24                 :            : 
#      25                 :            : #include <array>
#      26                 :            : #include <stdint.h>
#      27                 :            : 
#      28                 :            : #include <boost/test/unit_test.hpp>
#      29                 :            : 
#      30                 :            : struct CConnmanTest : public CConnman {
#      31                 :            :     using CConnman::CConnman;
#      32                 :            :     void AddNode(CNode& node)
#      33                 :         24 :     {
#      34                 :         24 :         LOCK(cs_vNodes);
#      35                 :         24 :         vNodes.push_back(&node);
#      36                 :         24 :     }
#      37                 :            :     void ClearNodes()
#      38                 :          4 :     {
#      39                 :          4 :         LOCK(cs_vNodes);
#      40         [ +  + ]:         24 :         for (CNode* node : vNodes) {
#      41                 :         24 :             delete node;
#      42                 :         24 :         }
#      43                 :          4 :         vNodes.clear();
#      44                 :          4 :     }
#      45                 :            : };
#      46                 :            : 
#      47                 :            : static CService ip(uint32_t i)
#      48                 :         28 : {
#      49                 :         28 :     struct in_addr s;
#      50                 :         28 :     s.s_addr = i;
#      51                 :         28 :     return CService(CNetAddr(s), Params().GetDefaultPort());
#      52                 :         28 : }
#      53                 :            : 
#      54                 :            : static NodeId id = 0;
#      55                 :            : 
#      56                 :            : void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds);
#      57                 :            : 
#      58                 :            : BOOST_FIXTURE_TEST_SUITE(denialofservice_tests, TestingSetup)
#      59                 :            : 
#      60                 :            : // Test eviction of an outbound peer whose chain never advances
#      61                 :            : // Mock a node connection, and use mocktime to simulate a peer
#      62                 :            : // which never sends any headers messages.  PeerLogic should
#      63                 :            : // decide to evict that outbound peer, after the appropriate timeouts.
#      64                 :            : // Note that we protect 4 outbound nodes from being subject to
#      65                 :            : // this logic; this test takes advantage of that protection only
#      66                 :            : // being applied to nodes which send headers with sufficient
#      67                 :            : // work.
#      68                 :            : BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
#      69                 :          2 : {
#      70                 :          2 :     const CChainParams& chainparams = Params();
#      71                 :          2 :     auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
#      72                 :          2 :     auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr,
#      73                 :          2 :                                        *m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
#      74                 :            : 
#      75                 :            :     // Mock an outbound peer
#      76                 :          2 :     CAddress addr1(ip(0xa0b0c001), NODE_NONE);
#      77                 :          2 :     CNode dummyNode1(id++, ServiceFlags(NODE_NETWORK | NODE_WITNESS), INVALID_SOCKET, addr1, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress(), /* pszDest */ "", ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false);
#      78                 :          2 :     dummyNode1.SetCommonVersion(PROTOCOL_VERSION);
#      79                 :            : 
#      80                 :          2 :     peerLogic->InitializeNode(&dummyNode1);
#      81                 :          2 :     dummyNode1.fSuccessfullyConnected = true;
#      82                 :            : 
#      83                 :            :     // This test requires that we have a chain with non-zero work.
#      84                 :          2 :     {
#      85                 :          2 :         LOCK(cs_main);
#      86                 :          2 :         BOOST_CHECK(::ChainActive().Tip() != nullptr);
#      87                 :          2 :         BOOST_CHECK(::ChainActive().Tip()->nChainWork > 0);
#      88                 :          2 :     }
#      89                 :            : 
#      90                 :            :     // Test starts here
#      91                 :          2 :     {
#      92                 :          2 :         LOCK(dummyNode1.cs_sendProcessing);
#      93                 :          2 :         BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); // should result in getheaders
#      94                 :          2 :     }
#      95                 :          2 :     {
#      96                 :          2 :         LOCK(dummyNode1.cs_vSend);
#      97                 :          2 :         BOOST_CHECK(dummyNode1.vSendMsg.size() > 0);
#      98                 :          2 :         dummyNode1.vSendMsg.clear();
#      99                 :          2 :     }
#     100                 :            : 
#     101                 :          2 :     int64_t nStartTime = GetTime();
#     102                 :            :     // Wait 21 minutes
#     103                 :          2 :     SetMockTime(nStartTime+21*60);
#     104                 :          2 :     {
#     105                 :          2 :         LOCK(dummyNode1.cs_sendProcessing);
#     106                 :          2 :         BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); // should result in getheaders
#     107                 :          2 :     }
#     108                 :          2 :     {
#     109                 :          2 :         LOCK(dummyNode1.cs_vSend);
#     110                 :          2 :         BOOST_CHECK(dummyNode1.vSendMsg.size() > 0);
#     111                 :          2 :     }
#     112                 :            :     // Wait 3 more minutes
#     113                 :          2 :     SetMockTime(nStartTime+24*60);
#     114                 :          2 :     {
#     115                 :          2 :         LOCK(dummyNode1.cs_sendProcessing);
#     116                 :          2 :         BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); // should result in disconnect
#     117                 :          2 :     }
#     118                 :          2 :     BOOST_CHECK(dummyNode1.fDisconnect == true);
#     119                 :            : 
#     120                 :          2 :     peerLogic->FinalizeNode(dummyNode1);
#     121                 :          2 : }
#     122                 :            : 
#     123                 :            : static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerManager &peerLogic, CConnmanTest* connman)
#     124                 :         18 : {
#     125                 :         18 :     CAddress addr(ip(g_insecure_rand_ctx.randbits(32)), NODE_NONE);
#     126                 :         18 :     vNodes.emplace_back(new CNode(id++, ServiceFlags(NODE_NETWORK | NODE_WITNESS), INVALID_SOCKET, addr, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress(), /* pszDest */ "", ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false));
#     127                 :         18 :     CNode &node = *vNodes.back();
#     128                 :         18 :     node.SetCommonVersion(PROTOCOL_VERSION);
#     129                 :            : 
#     130                 :         18 :     peerLogic.InitializeNode(&node);
#     131                 :         18 :     node.fSuccessfullyConnected = true;
#     132                 :            : 
#     133                 :         18 :     connman->AddNode(node);
#     134                 :         18 : }
#     135                 :            : 
#     136                 :            : BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
#     137                 :          2 : {
#     138                 :          2 :     const CChainParams& chainparams = Params();
#     139                 :          2 :     auto connman = std::make_unique<CConnmanTest>(0x1337, 0x1337, *m_node.addrman);
#     140                 :          2 :     auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr,
#     141                 :          2 :                                        *m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
#     142                 :            : 
#     143                 :          2 :     constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
#     144                 :          2 :     CConnman::Options options;
#     145                 :          2 :     options.nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
#     146                 :          2 :     options.m_max_outbound_full_relay = max_outbound_full_relay;
#     147                 :          2 :     options.nMaxFeeler = MAX_FEELER_CONNECTIONS;
#     148                 :            : 
#     149                 :          2 :     connman->Init(options);
#     150                 :          2 :     std::vector<CNode *> vNodes;
#     151                 :            : 
#     152                 :            :     // Mock some outbound peers
#     153         [ +  + ]:         18 :     for (int i=0; i<max_outbound_full_relay; ++i) {
#     154                 :         16 :         AddRandomOutboundPeer(vNodes, *peerLogic, connman.get());
#     155                 :         16 :     }
#     156                 :            : 
#     157                 :          2 :     peerLogic->CheckForStaleTipAndEvictPeers();
#     158                 :            : 
#     159                 :            :     // No nodes should be marked for disconnection while we have no extra peers
#     160         [ +  + ]:         16 :     for (const CNode *node : vNodes) {
#     161                 :         16 :         BOOST_CHECK(node->fDisconnect == false);
#     162                 :         16 :     }
#     163                 :            : 
#     164                 :          2 :     SetMockTime(GetTime() + 3 * chainparams.GetConsensus().nPowTargetSpacing + 1);
#     165                 :            : 
#     166                 :            :     // Now tip should definitely be stale, and we should look for an extra
#     167                 :            :     // outbound peer
#     168                 :          2 :     peerLogic->CheckForStaleTipAndEvictPeers();
#     169                 :          2 :     BOOST_CHECK(connman->GetTryNewOutboundPeer());
#     170                 :            : 
#     171                 :            :     // Still no peers should be marked for disconnection
#     172         [ +  + ]:         16 :     for (const CNode *node : vNodes) {
#     173                 :         16 :         BOOST_CHECK(node->fDisconnect == false);
#     174                 :         16 :     }
#     175                 :            : 
#     176                 :            :     // If we add one more peer, something should get marked for eviction
#     177                 :            :     // on the next check (since we're mocking the time to be in the future, the
#     178                 :            :     // required time connected check should be satisfied).
#     179                 :          2 :     AddRandomOutboundPeer(vNodes, *peerLogic, connman.get());
#     180                 :            : 
#     181                 :          2 :     peerLogic->CheckForStaleTipAndEvictPeers();
#     182         [ +  + ]:         18 :     for (int i = 0; i < max_outbound_full_relay; ++i) {
#     183                 :         16 :         BOOST_CHECK(vNodes[i]->fDisconnect == false);
#     184                 :         16 :     }
#     185                 :            :     // Last added node should get marked for eviction
#     186                 :          2 :     BOOST_CHECK(vNodes.back()->fDisconnect == true);
#     187                 :            : 
#     188                 :          2 :     vNodes.back()->fDisconnect = false;
#     189                 :            : 
#     190                 :            :     // Update the last announced block time for the last
#     191                 :            :     // peer, and check that the next newest node gets evicted.
#     192                 :          2 :     UpdateLastBlockAnnounceTime(vNodes.back()->GetId(), GetTime());
#     193                 :            : 
#     194                 :          2 :     peerLogic->CheckForStaleTipAndEvictPeers();
#     195         [ +  + ]:         16 :     for (int i = 0; i < max_outbound_full_relay - 1; ++i) {
#     196                 :         14 :         BOOST_CHECK(vNodes[i]->fDisconnect == false);
#     197                 :         14 :     }
#     198                 :          2 :     BOOST_CHECK(vNodes[max_outbound_full_relay-1]->fDisconnect == true);
#     199                 :          2 :     BOOST_CHECK(vNodes.back()->fDisconnect == false);
#     200                 :            : 
#     201         [ +  + ]:         18 :     for (const CNode *node : vNodes) {
#     202                 :         18 :         peerLogic->FinalizeNode(*node);
#     203                 :         18 :     }
#     204                 :            : 
#     205                 :          2 :     connman->ClearNodes();
#     206                 :          2 : }
#     207                 :            : 
#     208                 :            : BOOST_AUTO_TEST_CASE(peer_discouragement)
#     209                 :          2 : {
#     210                 :          2 :     const CChainParams& chainparams = Params();
#     211                 :          2 :     auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
#     212                 :          2 :     auto connman = std::make_unique<CConnmanTest>(0x1337, 0x1337, *m_node.addrman);
#     213                 :          2 :     auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(),
#     214                 :          2 :                                        *m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
#     215                 :            : 
#     216                 :          2 :     CNetAddr tor_netaddr;
#     217                 :          2 :     BOOST_REQUIRE(
#     218                 :          2 :         tor_netaddr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
#     219                 :          2 :     const CService tor_service{tor_netaddr, Params().GetDefaultPort()};
#     220                 :            : 
#     221                 :          2 :     const std::array<CAddress, 3> addr{CAddress{ip(0xa0b0c001), NODE_NONE},
#     222                 :          2 :                                        CAddress{ip(0xa0b0c002), NODE_NONE},
#     223                 :          2 :                                        CAddress{tor_service, NODE_NONE}};
#     224                 :            : 
#     225                 :          2 :     const CNetAddr other_addr{ip(0xa0b0ff01)}; // Not any of addr[].
#     226                 :            : 
#     227                 :          2 :     std::array<CNode*, 3> nodes;
#     228                 :            : 
#     229                 :          2 :     banman->ClearBanned();
#     230                 :          2 :     nodes[0] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[0], /* nKeyedNetGroupIn */ 0,
#     231                 :          2 :                          /* nLocalHostNonceIn */ 0, CAddress(), /* pszDest */ "",
#     232                 :          2 :                          ConnectionType::INBOUND, /* inbound_onion */ false};
#     233                 :          2 :     nodes[0]->SetCommonVersion(PROTOCOL_VERSION);
#     234                 :          2 :     peerLogic->InitializeNode(nodes[0]);
#     235                 :          2 :     nodes[0]->fSuccessfullyConnected = true;
#     236                 :          2 :     connman->AddNode(*nodes[0]);
#     237                 :          2 :     peerLogic->Misbehaving(nodes[0]->GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ ""); // Should be discouraged
#     238                 :          2 :     {
#     239                 :          2 :         LOCK(nodes[0]->cs_sendProcessing);
#     240                 :          2 :         BOOST_CHECK(peerLogic->SendMessages(nodes[0]));
#     241                 :          2 :     }
#     242                 :          2 :     BOOST_CHECK(banman->IsDiscouraged(addr[0]));
#     243                 :          2 :     BOOST_CHECK(nodes[0]->fDisconnect);
#     244                 :          2 :     BOOST_CHECK(!banman->IsDiscouraged(other_addr)); // Different address, not discouraged
#     245                 :            : 
#     246                 :          2 :     nodes[1] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[1], /* nKeyedNetGroupIn */ 1,
#     247                 :          2 :                          /* nLocalHostNonceIn */ 1, CAddress(), /* pszDest */ "",
#     248                 :          2 :                          ConnectionType::INBOUND, /* inbound_onion */ false};
#     249                 :          2 :     nodes[1]->SetCommonVersion(PROTOCOL_VERSION);
#     250                 :          2 :     peerLogic->InitializeNode(nodes[1]);
#     251                 :          2 :     nodes[1]->fSuccessfullyConnected = true;
#     252                 :          2 :     connman->AddNode(*nodes[1]);
#     253                 :          2 :     peerLogic->Misbehaving(nodes[1]->GetId(), DISCOURAGEMENT_THRESHOLD - 1, /* message */ "");
#     254                 :          2 :     {
#     255                 :          2 :         LOCK(nodes[1]->cs_sendProcessing);
#     256                 :          2 :         BOOST_CHECK(peerLogic->SendMessages(nodes[1]));
#     257                 :          2 :     }
#     258                 :            :     // [0] is still discouraged/disconnected.
#     259                 :          2 :     BOOST_CHECK(banman->IsDiscouraged(addr[0]));
#     260                 :          2 :     BOOST_CHECK(nodes[0]->fDisconnect);
#     261                 :            :     // [1] is not discouraged/disconnected yet.
#     262                 :          2 :     BOOST_CHECK(!banman->IsDiscouraged(addr[1]));
#     263                 :          2 :     BOOST_CHECK(!nodes[1]->fDisconnect);
#     264                 :          2 :     peerLogic->Misbehaving(nodes[1]->GetId(), 1, /* message */ ""); // [1] reaches discouragement threshold
#     265                 :          2 :     {
#     266                 :          2 :         LOCK(nodes[1]->cs_sendProcessing);
#     267                 :          2 :         BOOST_CHECK(peerLogic->SendMessages(nodes[1]));
#     268                 :          2 :     }
#     269                 :            :     // Expect both [0] and [1] to be discouraged/disconnected now.
#     270                 :          2 :     BOOST_CHECK(banman->IsDiscouraged(addr[0]));
#     271                 :          2 :     BOOST_CHECK(nodes[0]->fDisconnect);
#     272                 :          2 :     BOOST_CHECK(banman->IsDiscouraged(addr[1]));
#     273                 :          2 :     BOOST_CHECK(nodes[1]->fDisconnect);
#     274                 :            : 
#     275                 :            :     // Make sure non-IP peers are discouraged and disconnected properly.
#     276                 :            : 
#     277                 :          2 :     nodes[2] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[2], /* nKeyedNetGroupIn */ 1,
#     278                 :          2 :                          /* nLocalHostNonceIn */ 1, CAddress(), /* pszDest */ "",
#     279                 :          2 :                          ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false};
#     280                 :          2 :     nodes[2]->SetCommonVersion(PROTOCOL_VERSION);
#     281                 :          2 :     peerLogic->InitializeNode(nodes[2]);
#     282                 :          2 :     nodes[2]->fSuccessfullyConnected = true;
#     283                 :          2 :     connman->AddNode(*nodes[2]);
#     284                 :          2 :     peerLogic->Misbehaving(nodes[2]->GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ "");
#     285                 :          2 :     {
#     286                 :          2 :         LOCK(nodes[2]->cs_sendProcessing);
#     287                 :          2 :         BOOST_CHECK(peerLogic->SendMessages(nodes[2]));
#     288                 :          2 :     }
#     289                 :          2 :     BOOST_CHECK(banman->IsDiscouraged(addr[0]));
#     290                 :          2 :     BOOST_CHECK(banman->IsDiscouraged(addr[1]));
#     291                 :          2 :     BOOST_CHECK(banman->IsDiscouraged(addr[2]));
#     292                 :          2 :     BOOST_CHECK(nodes[0]->fDisconnect);
#     293                 :          2 :     BOOST_CHECK(nodes[1]->fDisconnect);
#     294                 :          2 :     BOOST_CHECK(nodes[2]->fDisconnect);
#     295                 :            : 
#     296         [ +  + ]:          6 :     for (CNode* node : nodes) {
#     297                 :          6 :         peerLogic->FinalizeNode(*node);
#     298                 :          6 :     }
#     299                 :          2 :     connman->ClearNodes();
#     300                 :          2 : }
#     301                 :            : 
#     302                 :            : BOOST_AUTO_TEST_CASE(DoS_bantime)
#     303                 :          2 : {
#     304                 :          2 :     const CChainParams& chainparams = Params();
#     305                 :          2 :     auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
#     306                 :          2 :     auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
#     307                 :          2 :     auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(),
#     308                 :          2 :                                        *m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
#     309                 :            : 
#     310                 :          2 :     banman->ClearBanned();
#     311                 :          2 :     int64_t nStartTime = GetTime();
#     312                 :          2 :     SetMockTime(nStartTime); // Overrides future calls to GetTime()
#     313                 :            : 
#     314                 :          2 :     CAddress addr(ip(0xa0b0c001), NODE_NONE);
#     315                 :          2 :     CNode dummyNode(id++, NODE_NETWORK, INVALID_SOCKET, addr, /* nKeyedNetGroupIn */ 4, /* nLocalHostNonceIn */ 4, CAddress(), /* pszDest */ "", ConnectionType::INBOUND, /* inbound_onion */ false);
#     316                 :          2 :     dummyNode.SetCommonVersion(PROTOCOL_VERSION);
#     317                 :          2 :     peerLogic->InitializeNode(&dummyNode);
#     318                 :          2 :     dummyNode.fSuccessfullyConnected = true;
#     319                 :            : 
#     320                 :          2 :     peerLogic->Misbehaving(dummyNode.GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ "");
#     321                 :          2 :     {
#     322                 :          2 :         LOCK(dummyNode.cs_sendProcessing);
#     323                 :          2 :         BOOST_CHECK(peerLogic->SendMessages(&dummyNode));
#     324                 :          2 :     }
#     325                 :          2 :     BOOST_CHECK(banman->IsDiscouraged(addr));
#     326                 :            : 
#     327                 :          2 :     peerLogic->FinalizeNode(dummyNode);
#     328                 :          2 : }
#     329                 :            : 
#     330                 :            : class TxOrphanageTest : public TxOrphanage
#     331                 :            : {
#     332                 :            : public:
#     333                 :            :     inline size_t CountOrphans() const EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
#     334                 :         18 :     {
#     335                 :         18 :         return m_orphans.size();
#     336                 :         18 :     }
#     337                 :            : 
#     338                 :            :     CTransactionRef RandomOrphan() EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
#     339                 :        120 :     {
#     340                 :        120 :         std::map<uint256, OrphanTx>::iterator it;
#     341                 :        120 :         it = m_orphans.lower_bound(InsecureRand256());
#     342         [ -  + ]:        120 :         if (it == m_orphans.end())
#     343                 :          0 :             it = m_orphans.begin();
#     344                 :        120 :         return it->second.tx;
#     345                 :        120 :     }
#     346                 :            : };
#     347                 :            : 
#     348                 :            : static void MakeNewKeyWithFastRandomContext(CKey& key)
#     349                 :          2 : {
#     350                 :          2 :     std::vector<unsigned char> keydata;
#     351                 :          2 :     keydata = g_insecure_rand_ctx.randbytes(32);
#     352                 :          2 :     key.Set(keydata.data(), keydata.data() + keydata.size(), /*fCompressedIn*/ true);
#     353                 :          2 :     assert(key.IsValid());
#     354                 :          2 : }
#     355                 :            : 
#     356                 :            : BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
#     357                 :          2 : {
#     358                 :            :     // This test had non-deterministic coverage due to
#     359                 :            :     // randomly selected seeds.
#     360                 :            :     // This seed is chosen so that all branches of the function
#     361                 :            :     // ecdsa_signature_parse_der_lax are executed during this test.
#     362                 :            :     // Specifically branches that run only when an ECDSA
#     363                 :            :     // signature's R and S values have leading zeros.
#     364                 :          2 :     g_insecure_rand_ctx = FastRandomContext(ArithToUint256(arith_uint256(33)));
#     365                 :            : 
#     366                 :          2 :     TxOrphanageTest orphanage;
#     367                 :          2 :     CKey key;
#     368                 :          2 :     MakeNewKeyWithFastRandomContext(key);
#     369                 :          2 :     FillableSigningProvider keystore;
#     370                 :          2 :     BOOST_CHECK(keystore.AddKey(key));
#     371                 :            : 
#     372                 :          2 :     LOCK(g_cs_orphans);
#     373                 :            : 
#     374                 :            :     // 50 orphan transactions:
#     375         [ +  + ]:        102 :     for (int i = 0; i < 50; i++)
#     376                 :        100 :     {
#     377                 :        100 :         CMutableTransaction tx;
#     378                 :        100 :         tx.vin.resize(1);
#     379                 :        100 :         tx.vin[0].prevout.n = 0;
#     380                 :        100 :         tx.vin[0].prevout.hash = InsecureRand256();
#     381                 :        100 :         tx.vin[0].scriptSig << OP_1;
#     382                 :        100 :         tx.vout.resize(1);
#     383                 :        100 :         tx.vout[0].nValue = 1*CENT;
#     384                 :        100 :         tx.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
#     385                 :            : 
#     386                 :        100 :         orphanage.AddTx(MakeTransactionRef(tx), i);
#     387                 :        100 :     }
#     388                 :            : 
#     389                 :            :     // ... and 50 that depend on other orphans:
#     390         [ +  + ]:        102 :     for (int i = 0; i < 50; i++)
#     391                 :        100 :     {
#     392                 :        100 :         CTransactionRef txPrev = orphanage.RandomOrphan();
#     393                 :            : 
#     394                 :        100 :         CMutableTransaction tx;
#     395                 :        100 :         tx.vin.resize(1);
#     396                 :        100 :         tx.vin[0].prevout.n = 0;
#     397                 :        100 :         tx.vin[0].prevout.hash = txPrev->GetHash();
#     398                 :        100 :         tx.vout.resize(1);
#     399                 :        100 :         tx.vout[0].nValue = 1*CENT;
#     400                 :        100 :         tx.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
#     401                 :        100 :         BOOST_CHECK(SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL));
#     402                 :            : 
#     403                 :        100 :         orphanage.AddTx(MakeTransactionRef(tx), i);
#     404                 :        100 :     }
#     405                 :            : 
#     406                 :            :     // This really-big orphan should be ignored:
#     407         [ +  + ]:         22 :     for (int i = 0; i < 10; i++)
#     408                 :         20 :     {
#     409                 :         20 :         CTransactionRef txPrev = orphanage.RandomOrphan();
#     410                 :            : 
#     411                 :         20 :         CMutableTransaction tx;
#     412                 :         20 :         tx.vout.resize(1);
#     413                 :         20 :         tx.vout[0].nValue = 1*CENT;
#     414                 :         20 :         tx.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
#     415                 :         20 :         tx.vin.resize(2777);
#     416         [ +  + ]:      55560 :         for (unsigned int j = 0; j < tx.vin.size(); j++)
#     417                 :      55540 :         {
#     418                 :      55540 :             tx.vin[j].prevout.n = j;
#     419                 :      55540 :             tx.vin[j].prevout.hash = txPrev->GetHash();
#     420                 :      55540 :         }
#     421                 :         20 :         BOOST_CHECK(SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL));
#     422                 :            :         // Re-use same signature for other inputs
#     423                 :            :         // (they don't have to be valid for this test)
#     424         [ +  + ]:      55540 :         for (unsigned int j = 1; j < tx.vin.size(); j++)
#     425                 :      55520 :             tx.vin[j].scriptSig = tx.vin[0].scriptSig;
#     426                 :            : 
#     427                 :         20 :         BOOST_CHECK(!orphanage.AddTx(MakeTransactionRef(tx), i));
#     428                 :         20 :     }
#     429                 :            : 
#     430                 :            :     // Test EraseOrphansFor:
#     431         [ +  + ]:          8 :     for (NodeId i = 0; i < 3; i++)
#     432                 :          6 :     {
#     433                 :          6 :         size_t sizeBefore = orphanage.CountOrphans();
#     434                 :          6 :         orphanage.EraseForPeer(i);
#     435                 :          6 :         BOOST_CHECK(orphanage.CountOrphans() < sizeBefore);
#     436                 :          6 :     }
#     437                 :            : 
#     438                 :            :     // Test LimitOrphanTxSize() function:
#     439                 :          2 :     orphanage.LimitOrphans(40);
#     440                 :          2 :     BOOST_CHECK(orphanage.CountOrphans() <= 40);
#     441                 :          2 :     orphanage.LimitOrphans(10);
#     442                 :          2 :     BOOST_CHECK(orphanage.CountOrphans() <= 10);
#     443                 :          2 :     orphanage.LimitOrphans(0);
#     444                 :          2 :     BOOST_CHECK(orphanage.CountOrphans() == 0);
#     445                 :          2 : }
#     446                 :            : 
#     447                 :            : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.14