Auto merge of #4996 - str4d:2074-net-blocksonly, r=str4d

Add -blocksonly option

Cherry-picked from the following upstream PRs:

- bitcoin/bitcoin#6993
- bitcoin/bitcoin#7046
- bitcoin/bitcoin#6780
  - The third commit (we backported the rest in #2390).
- bitcoin/bitcoin#7126
- bitcoin/bitcoin#7439
- bitcoin/bitcoin#15990
  - Only the `-blocksonly` documentation changes.
- bitcoin/bitcoin#16555
- bitcoin/bitcoin#18391
  - Only the `-blocksonly` documentation changes.

Part of #2074.
This commit is contained in:
Homu 2021-03-31 11:27:22 +00:00
commit ba4eb241e7
7 changed files with 73 additions and 6 deletions

View File

@ -36,3 +36,20 @@ blocks and transactions to fewer nodes.
Reducing the maximum connected nodes to a minimum could be desirable if traffic
limits are tiny. Keep in mind that bitcoin's trustless model works best if you are
connected to a handful of nodes.
## 4. Turn off transaction relay (`-blocksonly`)
Forwarding transactions to peers increases the P2P traffic. To only sync blocks
with other peers, you can disable transaction relay.
Be reminded of the effects of this setting.
- Fee estimation will no longer work.
- It sets the flag "-walletbroadcast" to be "0", only if it is currently unset.
Doing so disables the automatic broadcasting of transactions from wallet. Not
relaying other's transactions could hurt your privacy if used while a wallet
is loaded or if you use the node to broadcast transactions.
- If a peer is whitelisted and "-whitelistforcerelay" is set to "1" (which will
also set "whitelistrelay" to "1"), we will still receive and relay their transactions.
- It makes block propagation slower because compact block relay can only be
used when transaction relay is enabled.

View File

@ -331,6 +331,8 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS));
strUsage += HelpMessageOpt("-alertnotify=<cmd>", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)"));
strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
if (showDebug)
strUsage += HelpMessageOpt("-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));
strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), DEFAULT_CHECKBLOCKS));
strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), DEFAULT_CHECKLEVEL));
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME));
@ -398,6 +400,8 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
" " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway"));
strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted inbound peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY));
strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted inbound peers even they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY));
strUsage += HelpMessageOpt("-maxuploadtarget=<n>", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET));
#ifdef ENABLE_WALLET
@ -809,6 +813,22 @@ void InitParameterInteraction()
if (SoftSetBoolArg("-rescan", true))
LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
}
// disable walletbroadcast and whitelistrelay in blocksonly mode
if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
if (SoftSetBoolArg("-whitelistrelay", false))
LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__);
#ifdef ENABLE_WALLET
if (SoftSetBoolArg("-walletbroadcast", false))
LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
#endif
}
// Forcing relay from whitelisted hosts implies we will accept relays from them in the first place.
if (GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
if (SoftSetBoolArg("-whitelistrelay", true))
LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__);
}
}
void InitLogging()
@ -922,6 +942,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// ********************************************************* Step 2: parameter interactions
const CChainParams& chainparams = Params();
// also see: InitParameterInteraction()
// Set this early so that experimental features are correctly enabled/disabled
auto err = InitExperimentalMode();
if (err) {
@ -938,7 +960,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
#endif
}
// Make sure enough file descriptors are available
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);

View File

@ -5947,6 +5947,12 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
return error("message inv size() = %u", vInv.size());
}
bool fBlocksOnly = GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY);
// Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistrelay is true
if (pfrom->fWhitelisted && GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))
fBlocksOnly = false;
LOCK(cs_main);
std::vector<CInv> vToFetch;
@ -5984,8 +5990,12 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
}
LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
}
} else {
if (!fAlreadyHave && !IsInitialBlockDownload(chainparams.GetConsensus()))
}
else
{
if (fBlocksOnly)
LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id);
else if (!fAlreadyHave && !IsInitialBlockDownload(chainparams.GetConsensus()))
pfrom->AskFor(inv);
}
@ -6112,6 +6122,14 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
else if (strCommand == "tx" && !IsInitialBlockDownload(chainparams.GetConsensus()))
{
// Stop processing the transaction early if
// We are in blocks only mode and peer is either not whitelisted or whitelistrelay is off
if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)))
{
LogPrint("net", "transaction sent in violation of protocol peer=%d\n", pfrom->id);
return true;
}
vector<uint256> vWorkQueue;
vector<uint256> vEraseQueue;
CTransaction tx;
@ -6210,7 +6228,7 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
assert(recentRejects);
recentRejects->insert(tx.GetHash());
if (pfrom->fWhitelisted) {
if (pfrom->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
// Always relay transactions received from whitelisted peers, even
// if they were already in the mempool or rejected from it due
// to policy, allowing the node to function as a gateway for

View File

@ -60,6 +60,10 @@ struct CNodeStateStats;
static const bool DEFAULT_ALERTS = true;
/** Maximum reorg length we will accept before we shut down and alert the user. */
static const unsigned int MAX_REORG_LENGTH = COINBASE_MATURITY - 1;
/** Default for DEFAULT_WHITELISTRELAY. */
static const bool DEFAULT_WHITELISTRELAY = true;
/** Default for DEFAULT_WHITELISTFORCERELAY. */
static const bool DEFAULT_WHITELISTFORCERELAY = true;
/** Default for -minrelaytxfee, minimum relay fee for transactions */
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 100;
//! -maxtxfee default

View File

@ -468,7 +468,7 @@ void CNode::PushVersion()
else
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id);
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, strSubVersion, nBestHeight, true);
nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY));
}
@ -640,6 +640,7 @@ void CNode::copyStats(CNodeStats &stats)
{
stats.nodeid = this->GetId();
stats.nServices = nServices;
stats.fRelayTxes = fRelayTxes;
stats.nLastSend = nLastSend;
stats.nLastRecv = nLastRecv;
stats.nTimeConnected = nTimeConnected;

View File

@ -63,6 +63,8 @@ static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
/** The default for -maxuploadtarget. 0 = Unlimited */
static const uint64_t DEFAULT_MAX_UPLOAD_TARGET = 0;
/** Default for blocks only*/
static const bool DEFAULT_BLOCKSONLY = false;
/**
* The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks).
* This was three days for upgrades up to and including Blossom, and is 1.5 days from Heartwood onward.
@ -189,6 +191,7 @@ class CNodeStats
public:
NodeId nodeid;
uint64_t nServices;
bool fRelayTxes;
int64_t nLastSend;
int64_t nLastRecv;
int64_t nTimeConnected;
@ -292,7 +295,7 @@ public:
// We use fRelayTxes for two purposes -
// a) it allows us to not relay tx invs before receiving the peer's version message
// b) the peer may tell us in its version message that we should not relay tx invs
// until it has initialized its bloom filter.
// unless it loads a bloom filter.
bool fRelayTxes;
bool fSentAddr;
CSemaphoreGrant grantOutbound;

View File

@ -87,6 +87,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
" \"addr\":\"host:port\", (string) The IP address and port of the peer\n"
" \"addrlocal\":\"ip:port\", (string) local address\n"
" \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n"
" \"relaytxes\":true|false, (boolean) Whether peer has asked us to relay transactions to it\n"
" \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
" \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
" \"bytessent\": n, (numeric) The total bytes sent\n"
@ -130,6 +131,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
if (!(stats.addrLocal.empty()))
obj.pushKV("addrlocal", stats.addrLocal);
obj.pushKV("services", strprintf("%016x", stats.nServices));
obj.pushKV("relaytxes", stats.fRelayTxes);
obj.pushKV("lastsend", stats.nLastSend);
obj.pushKV("lastrecv", stats.nLastRecv);
obj.pushKV("bytessent", stats.nSendBytes);