Skip to content

Commit eea30f5

Browse files
dathonohmluke-jr
authored andcommitted
net: preferentially peer with nodes enforcing RDTS; ask DNS seed for x8000009; adapt tests
Squash of: - b662a23198 Define a service bit for BIP148 - 0db5282edd Add questionmark to end of BIP148 service bit string, and add to bitcoin-cli - b5a77cda16 Preferentially peer with nodes enforcing RDTS; rename BIP148 references to ReducedData; adapt tests - 85289a3ac3 net: ask DNS seed for x8000009 (original: ea8c1ee) Define a service bit for BIP148 Github-Pull: bitcoin#10532 Rebased-From: cd74a23fcf9588199e196ab31bc64972400c2027 Add questionmark to end of BIP148 service bit string, and add to bitcoin-cli Preferentially peer with nodes enforcing RDTS; rename BIP148 references to ReducedData; adapt tests Combines: preferential peering (367b344), BIP148->ReducedData rename (85a78b8), service bit test fixes (f98fe90, ebe821e, 5efab4a, 4b757d8, f648a21). net: ask DNS seed for x8000009 Co-Authored-By: Luke Dashjr <luke-jr+git@utopios.org> Co-Authored-By: 3c853b6299 <3c853b6299@pm.me> Co-Authored-By: Léo Haf <leohaf@orangepill.ovh> Github-Pull: #238 Rebased-From: 983555f
1 parent 736d10d commit eea30f5

17 files changed

Lines changed: 60 additions & 42 deletions

src/init.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ namespace { // Variables internal to initialization process only
936936

937937
int nMaxConnections;
938938
int available_fds;
939-
ServiceFlags g_local_services = ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
939+
ServiceFlags g_local_services = ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_REDUCED_DATA);
940940
int64_t peer_connect_timeout;
941941
std::set<BlockFilterType> g_enabled_filter_types;
942942

src/kernel/chainparams.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ class CMainParams : public CChainParams {
155155
// release ASAP to avoid it where possible.
156156
vSeeds.emplace_back("seed.bitcoin.sipa.be."); // Pieter Wuille, only supports x1, x5, x9, and xd
157157
vSeeds.emplace_back("dnsseed.bluematt.me."); // Matt Corallo, only supports x9
158-
vSeeds.emplace_back("dnsseed.bitcoin.dashjr-list-of-p2p-nodes.us."); // Luke Dashjr
159-
vSeeds.emplace_back("seed.bitcoin.haf.ovh."); // Léo Haf
158+
vSeeds.emplace_back("dnsseed.bitcoin.dashjr-list-of-p2p-nodes.us."); // Luke Dashjr, support BIP110 seeding (x8000009)
159+
vSeeds.emplace_back("seed.bitcoin.haf.ovh."); // Léo Haf, support BIP110 seeding (x8000009)
160160
vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch."); // Jonas Schnelli, only supports x1, x5, x9, and xd
161161
vSeeds.emplace_back("seed.btc.petertodd.net."); // Peter Todd, only supports x1, x5, x9, and xd
162162
vSeeds.emplace_back("seed.bitcoin.sprovoost.nl."); // Sjors Provoost

src/net_processing.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,13 +1655,14 @@ bool PeerManagerImpl::HasAllDesirableServiceFlags(ServiceFlags services) const
16551655

16561656
ServiceFlags PeerManagerImpl::GetDesirableServiceFlags(ServiceFlags services) const
16571657
{
1658+
// We want to preferentially peer with other nodes that enforce UASF-ReducedData, in case of a chain split
16581659
if (services & NODE_NETWORK_LIMITED) {
16591660
// Limited peers are desirable when we are close to the tip.
16601661
if (ApproximateBestBlockDepth() < NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS) {
1661-
return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
1662+
return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_REDUCED_DATA);
16621663
}
16631664
}
1664-
return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
1665+
return ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA);
16651666
}
16661667

16671668
PeerRef PeerManagerImpl::GetPeerRef(NodeId id) const

src/protocol.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ std::vector<std::string> serviceFlagsToStr(uint64_t flags);
363363
* should be updated appropriately to filter for nodes with
364364
* desired service flags (compatible with our new flags).
365365
*/
366-
constexpr ServiceFlags SeedsServiceFlags() { return ServiceFlags(NODE_NETWORK | NODE_WITNESS); }
366+
constexpr ServiceFlags SeedsServiceFlags() { return ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA); }
367367

368368
/**
369369
* Checks if a peer with the given service flags may be capable of having a

src/rpc/net.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ static RPCHelpMan addpeeraddress()
10551055

10561056
if (net_addr.has_value()) {
10571057
CService service{net_addr.value(), port};
1058-
CAddress address{MaybeFlipIPv6toCJDNS(service), ServiceFlags{NODE_NETWORK | NODE_WITNESS}};
1058+
CAddress address{MaybeFlipIPv6toCJDNS(service), ServiceFlags{NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA}};
10591059
address.nTime = Now<NodeSeconds>();
10601060
// The source address is set equal to the address. This is equivalent to the peer
10611061
// announcing itself.

src/test/denialofservice_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
6868
connman.Handshake(
6969
/*node=*/dummyNode1,
7070
/*successfully_connected=*/true,
71-
/*remote_services=*/ServiceFlags(NODE_NETWORK | NODE_WITNESS),
72-
/*local_services=*/ServiceFlags(NODE_NETWORK | NODE_WITNESS),
71+
/*remote_services=*/ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA),
72+
/*local_services=*/ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA),
7373
/*version=*/PROTOCOL_VERSION,
7474
/*relay_txs=*/true);
7575

src/test/net_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -865,15 +865,15 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message)
865865
/*inbound_onion=*/false,
866866
/*network_key=*/2};
867867

868-
const uint64_t services{NODE_NETWORK | NODE_WITNESS};
868+
const uint64_t services{NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA};
869869
const int64_t time{0};
870870

871871
// Force ChainstateManager::IsInitialBlockDownload() to return false.
872872
// Otherwise PushAddress() isn't called by PeerManager::ProcessMessage().
873873
auto& chainman = static_cast<TestChainstateManager&>(*m_node.chainman);
874874
chainman.JumpOutOfIbd();
875875

876-
m_node.peerman->InitializeNode(peer, NODE_NETWORK);
876+
m_node.peerman->InitializeNode(peer, ServiceFlags(NODE_NETWORK | NODE_REDUCED_DATA));
877877

878878
std::atomic<bool> interrupt_dummy{false};
879879
std::chrono::microseconds time_received_dummy{0};

src/test/peerman_tests.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE(connections_desirable_service_flags)
3636

3737
// Check we start connecting to full nodes
3838
ServiceFlags peer_flags{NODE_WITNESS | NODE_NETWORK_LIMITED};
39-
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
39+
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA));
4040

4141
// Make peerman aware of the initial best block and verify we accept limited peers when we start close to the tip time.
4242
auto tip = WITH_LOCK(::cs_main, return m_node.chainman->ActiveChain().Tip());
@@ -45,15 +45,15 @@ BOOST_AUTO_TEST_CASE(connections_desirable_service_flags)
4545
peerman->SetBestBlock(tip_block_height, std::chrono::seconds{tip_block_time});
4646

4747
SetMockTime(tip_block_time + 1); // Set node time to tip time
48-
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
48+
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_REDUCED_DATA));
4949

5050
// Check we don't disallow limited peers connections when we are behind but still recoverable (below the connection safety window)
5151
SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS - 1)});
52-
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
52+
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_REDUCED_DATA));
5353

5454
// Check we disallow limited peers connections when we are further than the limited peers safety window
5555
SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * 2});
56-
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
56+
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA));
5757

5858
// By now, we tested that the connections desirable services flags change based on the node's time proximity to the tip.
5959
// Now, perform the same tests for when the node receives a block.
@@ -62,15 +62,15 @@ BOOST_AUTO_TEST_CASE(connections_desirable_service_flags)
6262
// First, verify a block in the past doesn't enable limited peers connections
6363
// At this point, our time is (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1) * 10 minutes ahead the tip's time.
6464
mineBlock(m_node, /*block_time=*/std::chrono::seconds{tip_block_time + 1});
65-
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
65+
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA));
6666

6767
// Verify a block close to the tip enables limited peers connections
6868
mineBlock(m_node, /*block_time=*/GetTime<std::chrono::seconds>());
69-
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS));
69+
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_REDUCED_DATA));
7070

7171
// Lastly, verify the stale tip checks can disallow limited peers connections after not receiving blocks for a prolonged period.
7272
SetMockTime(GetTime<std::chrono::seconds>() + std::chrono::seconds{consensus.nPowTargetSpacing * NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1});
73-
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS));
73+
BOOST_CHECK(peerman->GetDesirableServiceFlags(peer_flags) == ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_REDUCED_DATA));
7474
}
7575

7676
BOOST_AUTO_TEST_SUITE_END()

test/functional/feature_anchors.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from test_framework.p2p import P2PInterface, P2P_SERVICES
1010
from test_framework.socks5 import Socks5Configuration, Socks5Server
11-
from test_framework.messages import CAddress, hash256
11+
from test_framework.messages import CAddress, hash256, ser_compact_size
1212
from test_framework.test_framework import BitcoinTestFramework
1313
from test_framework.util import check_node_connections, assert_equal, p2p_port
1414

@@ -113,7 +113,7 @@ def run_test(self):
113113
caddr.ip, port_str = ONION_ADDR.split(":")
114114
caddr.port = int(port_str)
115115
# TorV3 addrv2 serialization:
116-
# time(4) | services(1) | networkID(1) | address length(1) | address(32)
116+
# time(4) | services(CompactSize) | networkID(1) | address length(CompactSize) | address(32)
117117
expected_pubkey = caddr.serialize_v2()[7:39].hex()
118118

119119
# position of services byte of first addr in anchors.dat
@@ -122,7 +122,7 @@ def run_test(self):
122122
data = bytes()
123123
with open(node_anchors_path, "rb") as file_handler:
124124
data = file_handler.read()
125-
assert_equal(data[services_index], 0x00) # services == NONE
125+
assert_equal(data[services_index], 0x00) # services == NONE (CompactSize encoded as 1 byte)
126126
anchors2 = data.hex()
127127
assert expected_pubkey in anchors2
128128

@@ -131,7 +131,9 @@ def run_test(self):
131131
# This is necessary because on restart we will not attempt an anchor connection
132132
# to a host without our required services, even if its address is in the anchors.dat file
133133
new_data = bytearray(data)[:-32]
134-
new_data[services_index] = P2P_SERVICES
134+
# Replace the 1-byte services field (0x00) with the CompactSize-encoded P2P_SERVICES (5 bytes for 0x08000009)
135+
services_bytes = ser_compact_size(P2P_SERVICES)
136+
new_data = new_data[:services_index] + services_bytes + new_data[services_index+1:]
135137
new_data_hash = hash256(new_data)
136138
file_handler.write(new_data + new_data_hash)
137139

test/functional/interface_bitcoin_cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def test_netinfo(self):
9494
self.log.info("Test -netinfo local services are moved to header if details are requested")
9595
det = self.nodes[0].cli('-netinfo', '1').send_cli().splitlines()
9696
self.log.debug(f"Test -netinfo 1 header output: {det[0]}")
97-
assert re.match(rf"^{re.escape(self.config['environment']['CLIENT_NAME'])} client.+services nwl2?$", det[0])
97+
assert re.match(rf"^{re.escape(self.config['environment']['CLIENT_NAME'])} client.+services nwl2?4$", det[0])
9898
assert not any(line.startswith("Local services:") for line in det)
9999

100100
def run_test(self):

0 commit comments

Comments
 (0)