Skip to content

Commit ca05588

Browse files
author
MarcoFalke
committed
Merge #19474: doc: Use precise permission flags where possible
fab5586 doc: Use precise permission flags where possible (MarcoFalke) Pull request description: Instead of mentioning the all-encompassing `-whitelist*` settings, change the docs to mention the exact permission flag that will influence the behaviour. This is needed because in the future, the too-broad `-whitelist*` settings (they either include *all* permission flags or apply to *all* peers) might be deprecated to require the permission flags to be enumerated. Alternatively, in the future there could be an RPC to set the net permission flags on an existing connection, in which case the `-whitelist*` terminology is of no help. ACKs for top commit: jnewbery: reACK fab5586 fjahr: Code review ACK fab5586 jonatack: ACK fab5586 Tree-SHA512: c7dea3e577d90103bb2b0ffab7b7c8640b388932a3a880f69e2b70747fc9213dc1f437085671fd54c902ec2a578458b8a2fae6dbe076642fb88efbf9fa9e679c
2 parents 505b4ed + fab5586 commit ca05588

10 files changed

+37
-45
lines changed

doc/reduce-traffic.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Be reminded of the effects of this setting.
5050
Doing so disables the automatic broadcasting of transactions from wallet. Not
5151
relaying other's transactions could hurt your privacy if used while a wallet
5252
is loaded or if you use the node to broadcast transactions.
53-
- If a peer is whitelisted and "-whitelistforcerelay" is set to "1" (which will
54-
also set "whitelistrelay" to "1"), we will still receive and relay their transactions.
53+
- If a peer has the forcerelay permission, we will still receive and relay
54+
their transactions.
5555
- It makes block propagation slower because compact block relay can only be
5656
used when transaction relay is enabled.

share/examples/bitcoin.conf

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
# Bind to given address and always listen on it. Use [host]:port notation for IPv6
2121
#bind=<addr>
2222

23-
# Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6
24-
#whitebind=<addr>
23+
# Bind to given address and add permission flags to peers connecting to it. Use [host]:port notation for IPv6
24+
#whitebind=perm@<addr>
2525

2626
##############################################################
2727
## Quick Primer on addnode vs connect ##

src/init.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ void SetupServerArgs(NodeContext& node)
396396
gArgs.AddArg("-blocknotify=<cmd>", "Execute command when the best block changes (%s in cmd is replaced by block hash)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
397397
#endif
398398
gArgs.AddArg("-blockreconstructionextratxn=<n>", strprintf("Extra transactions to keep in memory for compact block reconstructions (default: %u)", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
399-
gArgs.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Automatic broadcast and rebroadcast of any transactions from inbound peers is disabled, unless '-whitelistforcerelay' is '1', in which case whitelisted peers' transactions will be relayed. RPC transactions are not affected. (default: %u)", DEFAULT_BLOCKSONLY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
399+
gArgs.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Automatic broadcast and rebroadcast of any transactions from inbound peers is disabled, unless the peer has the 'forcerelay' permission. RPC transactions are not affected. (default: %u)", DEFAULT_BLOCKSONLY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
400400
gArgs.AddArg("-conf=<file>", strprintf("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
401401
gArgs.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
402402
gArgs.AddArg("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);

src/net_processing.cpp

+15-14
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static constexpr std::chrono::hours AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL{24};
117117
/** Average delay between peer address broadcasts */
118118
static constexpr std::chrono::seconds AVG_ADDRESS_BROADCAST_INTERVAL{30};
119119
/** Average delay between trickled inventory transmissions in seconds.
120-
* Blocks and whitelisted receivers bypass this, outbound peers get half this delay. */
120+
* Blocks and peers with noban permission bypass this, outbound peers get half this delay. */
121121
static const unsigned int INVENTORY_BROADCAST_INTERVAL = 5;
122122
/** Maximum number of inventory items to send per transmission.
123123
* Limits the impact of low-fee transaction floods. */
@@ -249,7 +249,7 @@ struct CNodeState {
249249
bool fCurrentlyConnected;
250250
//! Accumulated misbehaviour score for this peer.
251251
int nMisbehavior;
252-
//! Whether this peer should be disconnected and marked as discouraged (unless whitelisted with noban).
252+
//! Whether this peer should be disconnected and marked as discouraged (unless it has the noban permission).
253253
bool m_should_discourage;
254254
//! String name of this peer (debugging/logging purposes).
255255
const std::string name;
@@ -1895,8 +1895,8 @@ static void ProcessHeadersMessage(CNode& pfrom, CConnman* connman, ChainstateMan
18951895
// headers to fetch from this peer.
18961896
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
18971897
// This peer has too little work on their headers chain to help
1898-
// us sync -- disconnect if using an outbound slot (unless
1899-
// whitelisted or addnode).
1898+
// us sync -- disconnect if it is an outbound disconnection
1899+
// candidate.
19001900
// Note: We compare their tip to nMinimumChainWork (rather than
19011901
// ::ChainActive().Tip()) because we won't start block download
19021902
// until we have a headers chain that has at least
@@ -2531,9 +2531,10 @@ void ProcessMessage(
25312531
// block-relay-only peer
25322532
bool fBlocksOnly = !g_relay_txes || (pfrom.m_tx_relay == nullptr);
25332533

2534-
// Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistrelay is true
2535-
if (pfrom.HasPermission(PF_RELAY))
2534+
// Allow peers with relay permission to send data other than blocks in blocks only mode
2535+
if (pfrom.HasPermission(PF_RELAY)) {
25362536
fBlocksOnly = false;
2537+
}
25372538

25382539
LOCK(cs_main);
25392540

@@ -2887,14 +2888,14 @@ void ProcessMessage(
28872888
}
28882889

28892890
if (pfrom.HasPermission(PF_FORCERELAY)) {
2890-
// Always relay transactions received from whitelisted peers, even
2891+
// Always relay transactions received from peers with forcerelay permission, even
28912892
// if they were already in the mempool,
28922893
// allowing the node to function as a gateway for
28932894
// nodes hidden behind it.
28942895
if (!mempool.exists(tx.GetHash())) {
2895-
LogPrintf("Not relaying non-mempool transaction %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom.GetId());
2896+
LogPrintf("Not relaying non-mempool transaction %s from forcerelay peer=%d\n", tx.GetHash().ToString(), pfrom.GetId());
28962897
} else {
2897-
LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom.GetId());
2898+
LogPrintf("Force relaying tx %s from peer=%d\n", tx.GetHash().ToString(), pfrom.GetId());
28982899
RelayTransaction(tx.GetHash(), *connman);
28992900
}
29002901
}
@@ -3044,7 +3045,7 @@ void ProcessMessage(
30443045
PartiallyDownloadedBlock& partialBlock = *(*queuedBlockIt)->partialBlock;
30453046
ReadStatus status = partialBlock.InitData(cmpctblock, vExtraTxnForCompact);
30463047
if (status == READ_STATUS_INVALID) {
3047-
MarkBlockAsReceived(pindex->GetBlockHash()); // Reset in-flight state in case of whitelist
3048+
MarkBlockAsReceived(pindex->GetBlockHash()); // Reset in-flight state in case Misbehaving does not result in a disconnect
30483049
Misbehaving(pfrom.GetId(), 100, strprintf("Peer %d sent us invalid compact block\n", pfrom.GetId()));
30493050
return;
30503051
} else if (status == READ_STATUS_FAILED) {
@@ -3177,7 +3178,7 @@ void ProcessMessage(
31773178
PartiallyDownloadedBlock& partialBlock = *it->second.second->partialBlock;
31783179
ReadStatus status = partialBlock.FillBlock(*pblock, resp.txn);
31793180
if (status == READ_STATUS_INVALID) {
3180-
MarkBlockAsReceived(resp.blockhash); // Reset in-flight state in case of whitelist
3181+
MarkBlockAsReceived(resp.blockhash); // Reset in-flight state in case Misbehaving does not result in a disconnect
31813182
Misbehaving(pfrom.GetId(), 100, strprintf("Peer %d sent us invalid compact block/non-matching block transactions\n", pfrom.GetId()));
31823183
return;
31833184
} else if (status == READ_STATUS_FAILED) {
@@ -4258,9 +4259,9 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
42584259
// Check for headers sync timeouts
42594260
if (state.fSyncStarted && state.nHeadersSyncTimeout < std::numeric_limits<int64_t>::max()) {
42604261
// Detect whether this is a stalling initial-headers-sync peer
4261-
if (pindexBestHeader->GetBlockTime() <= GetAdjustedTime() - 24*60*60) {
4262+
if (pindexBestHeader->GetBlockTime() <= GetAdjustedTime() - 24 * 60 * 60) {
42624263
if (nNow > state.nHeadersSyncTimeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
4263-
// Disconnect a (non-whitelisted) peer if it is our only sync peer,
4264+
// Disconnect a peer (without the noban permission) if it is our only sync peer,
42644265
// and we have others we could be using instead.
42654266
// Note: If all our peers are inbound, then we won't
42664267
// disconnect our sync peer for stalling; we have bigger
@@ -4270,7 +4271,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
42704271
pto->fDisconnect = true;
42714272
return true;
42724273
} else {
4273-
LogPrintf("Timeout downloading headers from whitelisted peer=%d, not disconnecting\n", pto->GetId());
4274+
LogPrintf("Timeout downloading headers from noban peer=%d, not disconnecting\n", pto->GetId());
42744275
// Reset the headers sync state so that we have a
42754276
// chance to try downloading from a different peer.
42764277
// Note: this will also result in at least one more

src/rpc/blockchain.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -798,10 +798,8 @@ static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
798798

799799
if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) {
800800
// Block not found on disk. This could be because we have the block
801-
// header in our index but don't have the block (for example if a
802-
// non-whitelisted node sends us an unrequested long chain of valid
803-
// blocks, we add the headers to our index, but don't accept the
804-
// block).
801+
// header in our index but not yet have the block or did not accept the
802+
// block.
805803
throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
806804
}
807805

src/test/netbase_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ BOOST_AUTO_TEST_CASE(netpermissions_test)
383383
BOOST_CHECK(!NetWhitebindPermissions::TryParse("bloom,forcerelay,[email protected]:32", whitebindPermissions, error));
384384
BOOST_CHECK(error.original.find("Invalid P2P permission") != std::string::npos);
385385

386-
// Check whitelist error
386+
// Check netmask error
387387
BOOST_CHECK(!NetWhitelistPermissions::TryParse("bloom,forcerelay,[email protected]:32", whitelistPermissions, error));
388388
BOOST_CHECK(error.original.find("Invalid netmask specified in -whitelist") != std::string::npos);
389389

src/validation.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ class ChainstateManager
845845
* validationinterface callback.
846846
*
847847
* @param[in] pblock The block we want to process.
848-
* @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
848+
* @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources.
849849
* @param[out] fNewBlock A boolean which is set to indicate if the block was first received via this call
850850
* @returns If the block was processed, independently of block validity
851851
*/

test/functional/p2p_blocksonly.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ def run_test(self):
5757
self.nodes[0].p2p.wait_for_tx(txid)
5858
assert_equal(self.nodes[0].getmempoolinfo()['size'], 1)
5959

60-
self.log.info('Check that txs from whitelisted peers are not rejected and relayed to others')
61-
self.log.info("Restarting node 0 with whitelist permission and blocksonly")
60+
self.log.info('Check that txs from forcerelay peers are not rejected and relayed to others')
61+
self.log.info("Restarting node 0 with forcerelay permission and blocksonly")
6262
self.restart_node(0, ["-persistmempool=0", "-whitelist=127.0.0.1", "-whitelistforcerelay", "-blocksonly"])
63-
assert_equal(self.nodes[0].getrawmempool(),[])
63+
assert_equal(self.nodes[0].getrawmempool(), [])
6464
first_peer = self.nodes[0].add_p2p_connection(P2PInterface())
6565
second_peer = self.nodes[0].add_p2p_connection(P2PInterface())
6666
peer_1_info = self.nodes[0].getpeerinfo()[0]
@@ -72,14 +72,15 @@ def run_test(self):
7272
assert_equal(self.nodes[0].testmempoolaccept([sigtx])[0]['allowed'], True)
7373
txid = self.nodes[0].testmempoolaccept([sigtx])[0]['txid']
7474

75-
self.log.info('Check that the tx from whitelisted first_peer is relayed to others (ie.second_peer)')
75+
self.log.info('Check that the tx from forcerelay first_peer is relayed to others (ie.second_peer)')
7676
with self.nodes[0].assert_debug_log(["received getdata"]):
7777
first_peer.send_message(msg_tx(FromHex(CTransaction(), sigtx)))
78-
self.log.info('Check that the whitelisted peer is still connected after sending the transaction')
78+
self.log.info('Check that the forcerelay peer is still connected after sending the transaction')
7979
assert_equal(first_peer.is_connected, True)
8080
second_peer.wait_for_tx(txid)
8181
assert_equal(self.nodes[0].getmempoolinfo()['size'], 1)
82-
self.log.info("Whitelisted peer's transaction is accepted and relayed")
82+
self.log.info("Forcerelay peer's transaction is accepted and relayed")
83+
8384

8485
if __name__ == '__main__':
8586
P2PBlocksOnly().main()

test/functional/p2p_permissions.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ def check_tx_relay(self):
108108
block_op_true = self.nodes[0].getblock(self.nodes[0].generatetoaddress(100, ADDRESS_BCRT1_P2WSH_OP_TRUE)[0])
109109
self.sync_all()
110110

111-
self.log.debug("Create a connection from a whitelisted wallet that rebroadcasts raw txs")
111+
self.log.debug("Create a connection from a forcerelay peer that rebroadcasts raw txs")
112112
# A python mininode is needed to send the raw transaction directly. If a full node was used, it could only
113-
# rebroadcast via the inv-getdata mechanism. However, even for whitelisted connections, a full node would
113+
# rebroadcast via the inv-getdata mechanism. However, even for forcerelay connections, a full node would
114114
# currently not request a txid that is already in the mempool.
115115
self.restart_node(1, extra_args=["[email protected]"])
116116
p2p_rebroadcast_wallet = self.nodes[1].add_p2p_connection(P2PDataStore())
@@ -135,7 +135,7 @@ def check_tx_relay(self):
135135

136136
self.log.debug("Check that node[1] will send the tx to node[0] even though it is already in the mempool")
137137
connect_nodes(self.nodes[1], 0)
138-
with self.nodes[1].assert_debug_log(["Force relaying tx {} from whitelisted peer=0".format(txid)]):
138+
with self.nodes[1].assert_debug_log(["Force relaying tx {} from peer=0".format(txid)]):
139139
p2p_rebroadcast_wallet.send_txs_and_test([tx], self.nodes[1])
140140
wait_until(lambda: txid in self.nodes[0].getrawmempool())
141141

@@ -146,7 +146,7 @@ def check_tx_relay(self):
146146
[tx],
147147
self.nodes[1],
148148
success=False,
149-
reject_reason='Not relaying non-mempool transaction {} from whitelisted peer=0'.format(txid),
149+
reject_reason='Not relaying non-mempool transaction {} from forcerelay peer=0'.format(txid),
150150
)
151151

152152
def checkpermission(self, args, expectedPermissions, whitelisted):

test/functional/p2p_unrequested_blocks.py

+2-10
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test processing of unrequested blocks.
66
7-
Setup: two nodes, node0+node1, not connected to each other. Node1 will have
7+
Setup: two nodes, node0 + node1, not connected to each other. Node1 will have
88
nMinimumChainWork set to 0x10, so it won't process low-work unrequested blocks.
99
1010
We have one P2PInterface connection to node0 called test_node, and one to node1
@@ -71,18 +71,10 @@ def set_test_params(self):
7171
self.extra_args = [[], ["-minimumchainwork=0x10"]]
7272

7373
def setup_network(self):
74-
# Node0 will be used to test behavior of processing unrequested blocks
75-
# from peers which are not whitelisted, while Node1 will be used for
76-
# the whitelisted case.
77-
# Node2 will be used for non-whitelisted peers to test the interaction
78-
# with nMinimumChainWork.
7974
self.setup_nodes()
8075

8176
def run_test(self):
82-
# Setup the p2p connections
83-
# test_node connects to node0 (not whitelisted)
8477
test_node = self.nodes[0].add_p2p_connection(P2PInterface())
85-
# min_work_node connects to node1 (whitelisted)
8678
min_work_node = self.nodes[1].add_p2p_connection(P2PInterface())
8779

8880
# 1. Have nodes mine a block (leave IBD)
@@ -226,7 +218,7 @@ def run_test(self):
226218
self.nodes[0].getblock(all_blocks[286].hash)
227219
assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash)
228220
assert_raises_rpc_error(-1, "Block not found on disk", self.nodes[0].getblock, all_blocks[287].hash)
229-
self.log.info("Successfully reorged to longer chain from non-whitelisted peer")
221+
self.log.info("Successfully reorged to longer chain")
230222

231223
# 8. Create a chain which is invalid at a height longer than the
232224
# current chain, but which has more blocks on top of that

0 commit comments

Comments
 (0)