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.
501BOOST_CHECK(addr.IsValid());502BOOST_CHECK(addr.IsTor());503BOOST_CHECK(!addr.IsAddrV1Compatible());504BOOST_CHECK_EQUAL(addr.ToStringAddr(),505"pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion");506BOOST_REQUIRE(s.empty());508// Invalid TORv3, with bogus length.509s << "04" // network type (TORv3)510"00" // address length511"00"_hex; // address512BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,513HasReason("BIP155 TORv3 address with length 0 (should be 32)"));514BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.515s.clear();517// Valid I2P.518s << "05" // network type (I2P)519"20" // address length520"a2894dabaec08c0051a481a6dac88b64" // address521"f98232ae42d4b6fd2fa81952dfe36a87"_hex;522s >> ser_params(addr);523BOOST_CHECK(addr.IsValid());524BOOST_CHECK(addr.IsI2P());525BOOST_CHECK(!addr.IsAddrV1Compatible());526BOOST_CHECK_EQUAL(addr.ToStringAddr(),527"ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p");528BOOST_REQUIRE(s.empty());530// Invalid I2P, with bogus length.531s << "05" // network type (I2P)532"03" // address length533"00"_hex; // address534BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,535HasReason("BIP155 I2P address with length 3 (should be 32)"));536BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.537s.clear();539// Valid CJDNS.540s << "06" // network type (CJDNS)541"10" // address length542"fc000001000200030004000500060007"_hex; // address543s >> ser_params(addr);544BOOST_CHECK(addr.IsValid());545BOOST_CHECK(addr.IsCJDNS());546BOOST_CHECK(!addr.IsAddrV1Compatible());547BOOST_CHECK_EQUAL(addr.ToStringAddr(), "fc00:1:2:3:4:5:6:7");548BOOST_REQUIRE(s.empty());550// Invalid CJDNS, wrong prefix.551s << "06" // network type (CJDNS)552"10" // address length553"aa000001000200030004000500060007"_hex; // address554s >> ser_params(addr);555BOOST_CHECK(addr.IsCJDNS());556BOOST_CHECK(!addr.IsValid());557BOOST_REQUIRE(s.empty());559// Invalid CJDNS, with bogus length.560s << "06" // network type (CJDNS)561"01" // address length562"00"_hex; // address563BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,564HasReason("BIP155 CJDNS address with length 1 (should be 16)"));565BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.566s.clear();568// Unknown, with extreme length.569s << "aa" // network type (unknown)570"fe00000002" // address length (CompactSize's MAX_SIZE)571"01020304050607"_hex; // address572BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,573HasReason("Address too long: 33554432 > 512"));574BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.575s.clear();577// Unknown, with reasonable length.578s << "aa" // network type (unknown)579"04" // address length580"01020304"_hex; // address581s >> ser_params(addr);582BOOST_CHECK(!addr.IsValid());583BOOST_REQUIRE(s.empty());585// Unknown, with zero length.586s << "aa" // network type (unknown)587"00" // address length588""_hex; // address589s >> ser_params(addr);590BOOST_CHECK(!addr.IsValid());591BOOST_REQUIRE(s.empty());592}594// prior to PR #14728, this test triggers an undefined behavior595BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)596{597// set up local addresses; all that's necessary to reproduce the bug is598// that a normal IPv4 address is among the entries, but if this address is599// !IsRoutable the undefined behavior is easier to trigger deterministically600in_addr raw_addr;601raw_addr.s_addr = htonl(0x7f000001);602const CNetAddr mapLocalHost_entry = CNetAddr(raw_addr);603{604LOCK(g_maplocalhost_mutex);605LocalServiceInfo lsi;606lsi.nScore = 23;607lsi.nPort = 42;608mapLocalHost[mapLocalHost_entry] = lsi;609}611// create a peer with an IPv4 address612in_addr ipv4AddrPeer;613ipv4AddrPeer.s_addr = 0xa0b0c001;614CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK);615std::unique_ptr<CNode> pnode = std::make_unique<CNode>(/*id=*/0,616/*sock=*/nullptr,617addr,618/*nKeyedNetGroupIn=*/0,619/*nLocalHostNonceIn=*/0,620CAddress{},621/*pszDest=*/std::string{},622ConnectionType::OUTBOUND_FULL_RELAY,623/*inbound_onion=*/false,624/*network_key=*/0);625pnode->fSuccessfullyConnected.store(true);627// the peer claims to be reaching us via IPv6628in6_addr ipv6AddrLocal;629memset(ipv6AddrLocal.s6_addr, 0, 16);630ipv6AddrLocal.s6_addr[0] = 0xcc;631CAddress addrLocal = CAddress(CService(ipv6AddrLocal, 7777), NODE_NETWORK);632pnode->SetAddrLocal(addrLocal);634// before patch, this causes undefined behavior detectable with clang's -fsanitize=memory635GetLocalAddrForPeer(*pnode);637// suppress no-checks-run warning; if this test fails, it's by triggering a sanitizer638BOOST_CHECK(1);640// Cleanup, so that we don't confuse other tests.641{642LOCK(g_maplocalhost_mutex);643mapLocalHost.erase(mapLocalHost_entry);644}645}647BOOST_AUTO_TEST_CASE(get_local_addr_for_peer_port)648{649// Test that GetLocalAddrForPeer() properly selects the address to self-advertise:650//651// 1. GetLocalAddrForPeer() calls GetLocalAddress() which returns an address that is652// not routable.653// 2. GetLocalAddrForPeer() overrides the address with whatever the peer has told us654// he sees us as.655// 2.1. For inbound connections we must override both the address and the port.656// 2.2. For outbound connections we must override only the address.658// Pretend that we bound to this port.659const uint16_t bind_port = 20001;660m_node.args->ForceSetArg("-bind", strprintf("3.4.5.6:%u", bind_port));662// Our address:port as seen from the peer, completely different from the above.663in_addr peer_us_addr;664peer_us_addr.s_addr = htonl(0x02030405);665const CService peer_us{peer_us_addr, 20002};667// Create a peer with a routable IPv4 address (outbound).668in_addr peer_out_in_addr;669peer_out_in_addr.s_addr = htonl(0x01020304);670CNode peer_out{/*id=*/0,671/*sock=*/nullptr,672/*addrIn=*/CAddress{CService{peer_out_in_addr, 8333}, NODE_NETWORK},673/*nKeyedNetGroupIn=*/0,674/*nLocalHostNonceIn=*/0,675/*addrBindIn=*/CService{},676/*addrNameIn=*/std::string{},677/*conn_type_in=*/ConnectionType::OUTBOUND_FULL_RELAY,678/*inbound_onion=*/false,679/*network_key=*/0};680peer_out.fSuccessfullyConnected = true;681peer_out.SetAddrLocal(peer_us);683// Without the fix peer_us:8333 is chosen instead of the proper peer_us:bind_port.684auto chosen_local_addr = GetLocalAddrForPeer(peer_out);685BOOST_REQUIRE(chosen_local_addr);686const CService expected{peer_us_addr, bind_port};687BOOST_CHECK(*chosen_local_addr == expected);689// Create a peer with a routable IPv4 address (inbound).690in_addr peer_in_in_addr;691peer_in_in_addr.s_addr = htonl(0x05060708);692CNode peer_in{/*id=*/0,693/*sock=*/nullptr,694/*addrIn=*/CAddress{CService{peer_in_in_addr, 8333}, NODE_NETWORK},695/*nKeyedNetGroupIn=*/0,696/*nLocalHostNonceIn=*/0,697/*addrBindIn=*/CService{},698/*addrNameIn=*/std::string{},699/*conn_type_in=*/ConnectionType::INBOUND,700/*inbound_onion=*/false,701/*network_key=*/1};702peer_in.fSuccessfullyConnected = true;703peer_in.SetAddrLocal(peer_us);705// Without the fix peer_us:8333 is chosen instead of the proper peer_us:peer_us.GetPort().706chosen_local_addr = GetLocalAddrForPeer(peer_in);707BOOST_REQUIRE(chosen_local_addr);708BOOST_CHECK(*chosen_local_addr == peer_us);710m_node.args->ForceSetArg("-bind", "");711}713BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network)714{715BOOST_CHECK(g_reachable_nets.Contains(NET_IPV4));716BOOST_CHECK(g_reachable_nets.Contains(NET_IPV6));717BOOST_CHECK(g_reachable_nets.Contains(NET_ONION));718BOOST_CHECK(g_reachable_nets.Contains(NET_I2P));719BOOST_CHECK(g_reachable_nets.Contains(NET_CJDNS));721g_reachable_nets.Remove(NET_IPV4);722g_reachable_nets.Remove(NET_IPV6);723g_reachable_nets.Remove(NET_ONION);724g_reachable_nets.Remove(NET_I2P);725g_reachable_nets.Remove(NET_CJDNS);727BOOST_CHECK(!g_reachable_nets.Contains(NET_IPV4));728BOOST_CHECK(!g_reachable_nets.Contains(NET_IPV6));729BOOST_CHECK(!g_reachable_nets.Contains(NET_ONION));730BOOST_CHECK(!g_reachable_nets.Contains(NET_I2P));731BOOST_CHECK(!g_reachable_nets.Contains(NET_CJDNS));733g_reachable_nets.Add(NET_IPV4);734g_reachable_nets.Add(NET_IPV6);735g_reachable_nets.Add(NET_ONION);736g_reachable_nets.Add(NET_I2P);737g_reachable_nets.Add(NET_CJDNS);739BOOST_CHECK(g_reachable_nets.Contains(NET_IPV4));740BOOST_CHECK(g_reachable_nets.Contains(NET_IPV6));741BOOST_CHECK(g_reachable_nets.Contains(NET_ONION));742BOOST_CHECK(g_reachable_nets.Contains(NET_I2P));743BOOST_CHECK(g_reachable_nets.Contains(NET_CJDNS));744}746BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal)747{748// Should be reachable by default.749BOOST_CHECK(g_reachable_nets.Contains(NET_UNROUTABLE));750BOOST_CHECK(g_reachable_nets.Contains(NET_INTERNAL));
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.