Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1501}1502tester.ReceiveKey();1503tester.SendGarbageTerm();1504for (unsigned v = 0; v < num_ignore_version; ++v) {1505size_t ver_ign_data_len = m_rng.randbool() ? 0 : m_rng.randrange(1000);1506auto ver_ign_data = m_rng.randbytes<uint8_t>(ver_ign_data_len);1507tester.SendVersion(ver_ign_data, true);1508}1509tester.SendVersion(ver_data, false);1510ret = tester.Interact();1511BOOST_REQUIRE(ret);1512BOOST_REQUIRE(ret->empty());1513tester.ReceiveGarbage();1514tester.ReceiveVersion();1515tester.CompareSessionIDs();1516for (unsigned d = 0; d < num_decoys_1; ++d) {1517auto decoy_data = m_rng.randbytes<uint8_t>(m_rng.randrange(1000));1518tester.SendPacket(/*content=*/decoy_data, /*aad=*/{}, /*ignore=*/true);1519}1520auto msg_data_1 = m_rng.randbytes<uint8_t>(m_rng.randrange(4000000));1521tester.SendMessage(uint8_t(28), msg_data_1);1522for (unsigned d = 0; d < num_decoys_2; ++d) {1523auto decoy_data = m_rng.randbytes<uint8_t>(m_rng.randrange(1000));1524tester.SendPacket(/*content=*/decoy_data, /*aad=*/{}, /*ignore=*/true);1525}1526auto msg_data_2 = m_rng.randbytes<uint8_t>(m_rng.randrange(1000));1527tester.SendMessage(uint8_t(13), msg_data_2); // headers short id1528// Send invalidly-encoded message1529tester.SendMessage(std::string("blocktxn\x00\x00\x00a", CMessageHeader::MESSAGE_TYPE_SIZE), {});1530tester.SendMessage("foobar", {}); // test receiving unknown message type1531tester.AddMessage("barfoo", {}); // test sending unknown message type1532ret = tester.Interact();1533BOOST_REQUIRE(ret);1534BOOST_REQUIRE(ret->size() == 4);1535BOOST_REQUIRE((*ret)[0]);1536BOOST_CHECK((*ret)[0]->m_type == "addrv2");1537BOOST_CHECK(std::ranges::equal((*ret)[0]->m_recv, MakeByteSpan(msg_data_1)));1538BOOST_REQUIRE((*ret)[1]);1539BOOST_CHECK((*ret)[1]->m_type == "headers");1540BOOST_CHECK(std::ranges::equal((*ret)[1]->m_recv, MakeByteSpan(msg_data_2)));1541BOOST_CHECK(!(*ret)[2]);1542BOOST_REQUIRE((*ret)[3]);1543BOOST_CHECK((*ret)[3]->m_type == "foobar");1544BOOST_CHECK((*ret)[3]->m_recv.empty());1545tester.ReceiveMessage("barfoo", {});1546}1548// Too long garbage (initiator).1549{1550V2TransportTester tester(m_rng, true);1551auto ret = tester.Interact();1552BOOST_REQUIRE(ret);1553BOOST_REQUIRE(ret->empty());1554tester.SendKey();1555tester.SendGarbage(V2Transport::MAX_GARBAGE_LEN + 1);1556tester.ReceiveKey();1557tester.SendGarbageTerm();1558ret = tester.Interact();1559BOOST_CHECK(!ret);1560}1562// Too long garbage (responder).1563{1564V2TransportTester tester(m_rng, false);1565tester.SendKey();1566tester.SendGarbage(V2Transport::MAX_GARBAGE_LEN + 1);1567auto ret = tester.Interact();1568BOOST_REQUIRE(ret);1569BOOST_REQUIRE(ret->empty());1570tester.ReceiveKey();1571tester.SendGarbageTerm();1572ret = tester.Interact();1573BOOST_CHECK(!ret);1574}1576// Send garbage that includes the first 15 garbage terminator bytes somewhere.1577{1578V2TransportTester tester(m_rng, true);1579auto ret = tester.Interact();1580BOOST_REQUIRE(ret);1581BOOST_REQUIRE(ret->empty());1582tester.SendKey();1583tester.ReceiveKey();1584/** The number of random garbage bytes before the included first 15 bytes of terminator. */1585size_t len_before = m_rng.randrange(V2Transport::MAX_GARBAGE_LEN - 16 + 1);1586/** The number of random garbage bytes after it. */1587size_t len_after = m_rng.randrange(V2Transport::MAX_GARBAGE_LEN - 16 - len_before + 1);1588// Construct len_before + 16 + len_after random bytes.1589auto garbage = m_rng.randbytes<uint8_t>(len_before + 16 + len_after);1590// Replace the designed 16 bytes in the middle with the to-be-sent garbage terminator.1591auto garb_term = MakeUCharSpan(tester.GetCipher().GetSendGarbageTerminator());1592std::copy(garb_term.begin(), garb_term.begin() + 16, garbage.begin() + len_before);1593// Introduce a bit error in the last byte of that copied garbage terminator, making only1594// the first 15 of them match.1595garbage[len_before + 15] ^= (uint8_t(1) << m_rng.randrange(8));1596tester.SendGarbage(garbage);1597tester.SendGarbageTerm();1598tester.SendVersion();1599ret = tester.Interact();1600BOOST_REQUIRE(ret);1601BOOST_REQUIRE(ret->empty());1602tester.ReceiveGarbage();1603tester.ReceiveVersion();1604tester.CompareSessionIDs();1605auto msg_data_1 = m_rng.randbytes<uint8_t>(4000000); // test that receiving 4M payload works1606auto msg_data_2 = m_rng.randbytes<uint8_t>(4000000); // test that sending 4M payload works1607tester.SendMessage(uint8_t(m_rng.randrange(256 - BIP324_SHORTIDS_IMPLEMENTED) + BIP324_SHORTIDS_IMPLEMENTED), {}); // unknown short id1608tester.SendMessage(uint8_t(2), msg_data_1); // "block" short id1609tester.AddMessage("blocktxn", msg_data_2); // schedule blocktxn to be sent to us1610ret = tester.Interact();1611BOOST_REQUIRE(ret);1612BOOST_REQUIRE(ret->size() == 2);1613BOOST_CHECK(!(*ret)[0]);1614BOOST_REQUIRE((*ret)[1]);1615BOOST_CHECK((*ret)[1]->m_type == "block");1616BOOST_CHECK(std::ranges::equal((*ret)[1]->m_recv, MakeByteSpan(msg_data_1)));1617tester.ReceiveMessage(uint8_t(3), msg_data_2); // "blocktxn" short id1618}1620// Send correct network's V1 header1621{1622V2TransportTester tester(m_rng, false);1623tester.SendV1Version(Params().MessageStart());1624auto ret = tester.Interact();1625BOOST_CHECK(ret);1626}1628// Send wrong network's V1 header1629{1630V2TransportTester tester(m_rng, false);1631tester.SendV1Version(CChainParams::Main()->MessageStart());1632auto ret = tester.Interact();1633BOOST_CHECK(!ret);1634}1635}1637BOOST_AUTO_TEST_CASE(private_broadcast_version_does_not_update_addrman_services)1638{1639LOCK(NetEventsInterface::g_msgproc_mutex);1641const CNetAddr source{LookupHost("2.3.4.5", /*fAllowLookup=*/false).value()};1642const CAddress addr{Lookup("1.2.3.4", 8333, /*fAllowLookup=*/false).value(), NODE_NONE};1643BOOST_REQUIRE(m_node.addrman->Add({addr}, source));1644CNode node{/*id=*/0,1645/*sock=*/nullptr,1646/*addrIn=*/addr,1647/*nKeyedNetGroupIn=*/0,1648/*nLocalHostNonceIn=*/0,1649/*addrBindIn=*/CService{},1650/*addrNameIn=*/"",1651/*conn_type_in=*/ConnectionType::PRIVATE_BROADCAST,1652/*inbound_onion=*/false,1653/*network_key=*/0};1655auto& connman = static_cast<ConnmanTestMsg&>(*m_node.connman);1656connman.Handshake(node,1657/*successfully_connected=*/false,1658/*remote_services=*/NODE_NETWORK,1659/*local_services=*/NODE_NONE,1660/*version=*/PROTOCOL_VERSION,1661/*relay_txs=*/true);1663BOOST_CHECK_EQUAL(m_node.addrman->Select().first.nServices, NODE_NONE);1664m_node.peerman->FinalizeNode(node);1665}1667BOOST_AUTO_TEST_CASE(addlocal_onlynet_externalip)1668{1669// Test that `-externalip` addresses bypass `-onlynet`, but score alone does1670// not.1672CAddress addr_onion;1673BOOST_REQUIRE(addr_onion.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));1674BOOST_REQUIRE(addr_onion.IsValid());1675BOOST_REQUIRE(addr_onion.IsTor());1677const auto reachable_nets_at_start{g_reachable_nets.All()};1678const bool discover_orig{fDiscover};1680// Simulate using -onlynet=ipv4 -externalip=<onion>1681g_reachable_nets.RemoveAll();1682g_reachable_nets.Add(NET_IPV4);1683fDiscover = false;1685// Now AddLocal with a non-manual score should fail for an unreachable network.1686BOOST_CHECK(!AddLocal(addr_onion, LOCAL_BIND));1687BOOST_CHECK(!IsLocal(addr_onion));1689BOOST_CHECK(!AddLocal(addr_onion, LOCAL_MANUAL));1690BOOST_CHECK(!IsLocal(addr_onion));1692// Whereas AddLocal for -externalip should succeed.1693BOOST_CHECK(AddLocal(addr_onion, LOCAL_MANUAL, /*add_even_if_unreachable=*/true));1694BOOST_CHECK(IsLocal(addr_onion));1696// Normal AddLocal on a reachable network still works.1697const CNetAddr addr_ipv4{LookupHost("1.2.3.4", false).value()};1698BOOST_CHECK(AddLocal(addr_ipv4, LOCAL_MANUAL));1699BOOST_CHECK(IsLocal(CService{addr_ipv4, GetListenPort()}));1701RemoveLocal(CService{addr_ipv4, GetListenPort()});1702RemoveLocal(addr_onion);1703g_reachable_nets.RemoveAll();1704for (const auto& net : reachable_nets_at_start) {1705g_reachable_nets.Add(net);1706}1707fDiscover = discover_orig;1708}1710BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.