brunoerg
commented at 8:31 pm on February 16, 2023:
contributor
Revives #17167. It allows whitelisting manual connections. Fixes #9923
Since there are some PRs/issues around this topic, I’ll list some motivations/comments for whitelisting outbound connections from them:
Speed-up tx relay/mempool sync for testing purposes (my personal motivation for this) - In #26970, theStack pointed out that we whitelist peers to speed up tx relay for fast mempool synchronization, however, since it applies only for inbound connections and considering the topology node0 <--- node1 <---- node2 <--- ... <-- nodeN, if a tx is submitted from any node other than node0, the mempool synchronization can take quite long.
#29058 (comment) - “Before enabling -v2transport by default (which I’d image may happen after #24748) we could consider a way to force manual connections to be only-v1 or even only-v2 (disabling reconnect-with-v1). A possibility could be through a net permission flag, if #27114 makes it in.”
#17167 (comment) - “This would allow us to use #25355 when making outgoing connections to all nodes, except to whitelisted ones for which we would use our persistent I2P address.”
Force-relay/mempool permissions for a node you intentionally connected to.
DrahtBot
commented at 8:31 pm on February 16, 2023:
contributor
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
Conflicts
Reviewers, this pull request conflicts with the following ones:
#29415 (Broadcast own transactions only via short-lived Tor or I2P connections by vasild)
#28834 (net: attempts to connect to all resolved addresses when connecting to a node by sr-gi)
#28710 (Remove the legacy wallet and BDB dependency by achow101)
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
DrahtBot added the label
P2P
on Feb 16, 2023
brunoerg
commented at 8:31 pm on February 16, 2023:
contributor
DrahtBot added the label
Needs rebase
on Feb 22, 2023
brunoerg force-pushed
on Feb 22, 2023
DrahtBot removed the label
Needs rebase
on Feb 22, 2023
naumenkogs
commented at 12:55 pm on February 23, 2023:
member
Concept ACK
in
src/init.cpp:525
in
5410b13a9coutdated
519@@ -520,9 +520,11 @@ void SetupServerArgs(ArgsManager& argsman)
520 "Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". "
521 "Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
522523- argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers connecting from the given IP address (e.g. 1.2.3.4) or "
524+ argsman.AddArg("-whitelist=<[permissions@]IP address or network>", strprintf("Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or "
525 "CIDR-notated network (e.g. 1.2.3.0/24). Uses the same permissions as "
526- "-whitebind. Can be specified multiple times." , ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
527+ "-whitebind. "
528+ "Additional flags in and out control whether permissions apply to incoming connections and/or outgoing (default: %s). "
stratospher
commented at 9:12 pm on March 10, 2023:
why do we mention outgoing? (isn’t it incoming only)
stratospher
commented at 9:17 pm on March 10, 2023:
contributor
concept ACK. whitelisting outgoing connections is a useful feature to have! went through the code and it looks good.
integration tests in p2p_permissions.py would be nice! (It’d be interesting to see the behaviour when different permissions are set in different connection directions.)
something i had trouble understanding was if we give a trusted peer special permissions, would it matter who initiated the connection?
micro nit: next time you rebase/update, maybe reword the 1st commit message to use NetPermissionFlags::Implicit instead of PF_ISIMPLICIT?
furszy
commented at 8:19 pm on March 13, 2023:
member
Concept ACK
Could also add a test framework option to whitelist peers. So we don’t have to add -whitelist flag everywhere.
brunoerg
commented at 9:13 pm on March 13, 2023:
contributor
Could also add a test framework option to whitelist peers. So we don’t have to add -whitelist flag everywhere.
Sounds good! Gonna implement it!
brunoerg force-pushed
on Mar 14, 2023
brunoerg force-pushed
on Mar 14, 2023
brunoerg
commented at 0:21 am on March 15, 2023:
contributor
force-pushed: Added self.whitelist_peers in test_framework to avoid having to add -whitelist flag everywhere. Also, I changed the 1st commit message as suggested by @stratospher.
DrahtBot added the label
Needs rebase
on Mar 28, 2023
brunoerg force-pushed
on Mar 28, 2023
brunoerg
commented at 5:29 pm on March 28, 2023:
contributor
Rebased
DrahtBot removed the label
Needs rebase
on Mar 28, 2023
glozow
commented at 9:57 am on April 20, 2023:
member
39f6466 could be wrong, but there doesn’t seem to be any need for this to be CConnMan class member instead of a static helper function in the implementation file.
The following error message would be clearer, I think
0 error = _("whitebind may only be used for incoming connections (\"out\" was passed)");
My first thought was if it would make sense to pass output_connection_direction as a std::optional<ConnectionDirection>.
But also, relying on nullptr and overloading this param for the callee to know who the caller is (here and line 77 after) seems needlessly non-robust just to avoid a boolean param. Could either make it very clear
0- if (!output_connection_direction) {
1+ if (output_connection_direction == nullptr) {
2+ // Only NetWhitebindPermissions() should pass a nullptr.
or use an explicit is_whitebind boolean param for this – a bool is extremely cheap – and pass output_connection_direction as a ConnectionDirection, which would make the code simpler and more self-documenting. (Edit: I realize this commit was pulled in from another author, so feel free to ignore this last point.)
0a77e6ab37a9b23bd293 I would suggest placing this new helper with the other standalone ones, i.e. after IsLocal() or higher, not between the CConnman::FindNode() class members (unless there’s a reason that I didn’t see).
520@@ -521,9 +521,11 @@ void SetupServerArgs(ArgsManager& argsman)
521 "Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". "
522 "Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
523524- argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers connecting from the given IP address (e.g. 1.2.3.4) or "
525+ argsman.AddArg("-whitelist=<[permissions@]IP address or network>", strprintf("Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or "
526 "CIDR-notated network (e.g. 1.2.3.0/24). Uses the same permissions as "
527- "-whitebind. Can be specified multiple times." , ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
528+ "-whitebind. "
529+ "Additional flags \"in\" and \"in\" control whether permissions apply to incoming connections and/or outgoing (default: %s). "
0 # Whitelist peers to speed up tx relay / mempool sync. Don't use if testing tx relay or timing.
in
src/init.cpp:437
in
f99912850eoutdated
433@@ -434,7 +434,7 @@ void SetupServerArgs(ArgsManager& argsman)
434 argsman.AddArg("-blocknotify=<cmd>", "Execute command when the best block changes (%s in cmd is replaced by block hash)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
435 #endif
436 argsman.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);
437- argsman.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);
438+ argsman.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Automatic broadcast and rebroadcast of any transactions from peers is disabled, unless the peer has the 'forcerelay' permission. RPC transactions are not affected. (default: %u)", DEFAULT_BLOCKSONLY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
I think it was accidental, sorry. I will revert it.
jonatack
commented at 1:58 pm on May 11, 2023:
member
Approach ACK, modulo comments and #27114 (review) – it might be better for that commit to be a pure refactoring. Thanks for addressing the previous feedback.
brunoerg force-pushed
on May 15, 2023
brunoerg
commented at 5:10 pm on May 15, 2023:
contributor
DrahtBot added the label
CI failed
on May 15, 2023
brunoerg force-pushed
on May 15, 2023
DrahtBot removed the label
CI failed
on May 15, 2023
furszy
commented at 0:32 am on June 22, 2023:
member
The InitializePermissionFlags function is added twice, at two different locations, at the first and second commits, then one of them gets erased at the third one.
Would be good to cleanup the history so it’s only added once.
brunoerg force-pushed
on Jun 22, 2023
brunoerg
commented at 5:11 pm on June 22, 2023:
contributor
The InitializePermissionFlags function is added twice, at two different locations, at the first and second commits, then one of them gets erased at the third one.
Would be good to cleanup the history so it’s only added once.
If the options is used to speedup tx relay / mempool sync, it should be named appropriately. For example self.noban_tx_relay. Also, the option shouldn’t be set for tests that previously didn’t have it set. Otherwise they are testing something else. (noban has other effects than just immediate trickle)
You’re right. I am gonna change it for tests that previously had set it for all nodes.
in
src/init.cpp:536
in
1e09c265a9outdated
533+ argsman.AddArg("-whitelist=<[permissions@]IP address or network>", strprintf("Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or "
534 "CIDR-notated network (e.g. 1.2.3.0/24). Uses the same permissions as "
535- "-whitebind. Can be specified multiple times." , ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
536+ "-whitebind. "
537+ "Additional flags \"in\" and \"out\" control whether permissions apply to incoming connections and/or outgoing (default: %s). "
538+ "Can be specified multiple times.", "incoming only"), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
Also I think it’s a bit unclear where the “additional flags” go, are they part of [permissions@] ?
Yes, see the docs of -whitelist:
0 argsman.AddArg("-whitelist=<[permissions@]IP address or network>", strprintf("Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or "1"CIDR-notated network (e.g. 1.2.3.0/24). Uses the same permissions as "2"-whitebind. "3"Additional flags \"in\" and \"out\" control whether permissions apply to incoming connections and/or outgoing (default: %s). "4"Can be specified multiple times.", "incoming only"), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
56 g_wallet_init_interface.AddWalletOptions(argsman);
We call [permissions@] as permissions flags, so this adds additional ones.
in
test/functional/wallet_import_rescan.py:179
in
1e09c265a9outdated
in
test/functional/test_framework/test_framework.py:501
in
1e09c265a9outdated
495@@ -495,6 +496,10 @@ def get_bin_from_version(version, bin_name, bin_default):
496 extra_confs = [[]] * num_nodes
497 if extra_args is None:
498 extra_args = [[]] * num_nodes
499+ # Whitelist peers to speed up tx relay / mempool sync. Don't use it if testing tx relay or timing.
500+ if self.whitelist_peers:
501+ for i in range(len(extra_args)):
502+ extra_args[i] = extra_args[i] + ["-whitelist=noban,in,out@127.0.0.1"]
I’m not sure this is sufficient functional test coverage. With the exception of the new permissions “in” and “out” which are invalid on master, all tests otherwise pass with this commit (1e09c265a9598df3cc39336e3bcccb993dacf3d8) applied.
I was expecting to see a test that makes an outbound connection to a node that misbehaves and doesn’t get banned.
Or was the motivation more about the tx “trickle”? In that case I can see it being hard to test without waiting for time to pass?
Yea, the motivation here is just to ‘speed up’ some existing tests. But I like the idea of “I was expecting to see a test that makes an outbound connection to a node that misbehaves and doesn’t get banned.” this kind of coverage. I’m gonna add it.
pinheadmz
commented at 8:23 pm on July 26, 2023:
member
concept ACK
Ran all tests locally. Built and reviewed code at each commit. Some questions/comments below. Also I notice this is a fairly old feature request that has been through a few PRs. I wonder if you could address Greg’s comments on this older version
luke-jr changes_requested
luke-jr
commented at 1:15 am on July 27, 2023:
member
brunoerg
commented at 10:10 pm on August 7, 2023:
contributor
Force-pushed:
Renamed whitelist_peers to noban_tx_relay and set up it True for tests that explicity was whitelisting peers with this purpose of speeding up. - #27114 (review)
Added test coverage for an outbound node that misbehaves and doesn’t get banned. - #27114 (review)
Updated -blocksonly documentation.
Changed InitializePermissionFlags to deal with https://github.com/bitcoin/bitcoin/commit/8d8eeb422e64ccd08bce92eed2ee9cbbf55ffd67 -https://github.com/bitcoin/bitcoin/pull/27114#discussion_r1275643872
luke-jr
commented at 10:51 pm on August 7, 2023:
member
brunoerg
commented at 0:01 am on August 8, 2023:
contributor
Thanks, @luke-jr! Force-pushed changing CConnman::ConnectNode to std::optional
in
src/init.cpp:532
in
42ad2ea37doutdated
528@@ -529,9 +529,11 @@ void SetupServerArgs(ArgsManager& argsman)
529 "Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". "
530 "Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
531532- argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers connecting from the given IP address (e.g. 1.2.3.4) or "
533+ argsman.AddArg("-whitelist=<[permissions@]IP address or network>", strprintf("Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or "
I might be misunderstanding something here, but I think this chunk can be moved to net_processing.cppInitializeNode() because:
the CNode will already have its m_permission_flags set in ConnectNode()
m_permission_flags is all that’s needed to set our_services inside InitializeNode()
then you won’t need to use std::optional<std::pair<CNode*, ServiceFlags>> which is, hey, a real banger of a type!
Otherwise I don’t see a reason to compute and then pass around those service flags through all those functions before they are used. (ConnectNode()->OpenNetworkConnection()->InitializeNode())
As a side note, this looks like a lot of work to allow BLOOM for an outgoing peer, which must be a really weird edge case anyway right?
brunoerg
commented at 5:02 pm on September 27, 2023:
m_permission_flags is all that’s needed to set our_services inside InitializeNode()
Are you sure? I think we need to access of nLocalServices for it and we need to do it in CConnman, doesn’t it?
pinheadmz
commented at 7:14 pm on October 16, 2023:
Hi sorry just getting back to this review. Check out my top two commits here:
I’m still running the tests locally and I could be totally missing something, but this was what I was thinking. I don’t think ConnectNode() needs to return a pair with the service flags, as long as we keep your other changes that pass the permission flags along inside the CNode
brunoerg
commented at 12:12 pm on October 18, 2023:
Interesting! I’m going to do some tests before addressing it, but it sounds good and much cleaner.
brunoerg
commented at 6:53 pm on October 18, 2023:
done!
pinheadmz
commented at 6:50 pm on August 8, 2023:
member
code review ACK at d54e7dad7513ab4c587456b56d3a838daa151e4d
built and passed all tests
However as noted below I think the approach can be simplified in regards to local services.
DrahtBot requested review from naumenkogs
on Aug 8, 2023
luke-jr referenced this in commit
82d287e0df
on Aug 16, 2023
luke-jr referenced this in commit
e0d6813ec3
on Aug 16, 2023
luke-jr referenced this in commit
0487c4a755
on Aug 16, 2023
luke-jr referenced this in commit
ee974799fb
on Aug 29, 2023
luke-jr referenced this in commit
a298689861
on Aug 29, 2023
luke-jr referenced this in commit
47a92035cb
on Aug 29, 2023
achow101 requested review from furszy
on Sep 20, 2023
RandyMcMillan
commented at 10:36 pm on September 27, 2023:
contributor
Concept ACK
DrahtBot added the label
Needs rebase
on Oct 3, 2023
brunoerg force-pushed
on Oct 3, 2023
brunoerg
commented at 2:12 pm on October 3, 2023:
contributor
530@@ -531,9 +531,11 @@ void SetupServerArgs(ArgsManager& argsman)
531 "Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". "
532 "Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
533534- argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers connecting from the given IP address (e.g. 1.2.3.4) or "
535+ argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or "
pinheadmz
commented at 2:22 pm on October 19, 2023:
optional nit: I think connecting from is still better than using
brunoerg
commented at 3:46 pm on October 19, 2023:
perhaps only “from”? “connecting from” seems inbound only.
pinheadmz
commented at 4:53 pm on October 19, 2023:
“at” ? I dunno
brunoerg
commented at 8:02 pm on October 20, 2023:
pinheadmz
commented at 2:29 pm on October 19, 2023:
Might be nice for future devs looking at this code to rename the original vWhitelistedRange to vWhitelistedRangeIncoming, unless there’s a reason like is it ever not just for incoming connections?
brunoerg
commented at 8:00 pm on October 20, 2023:
Done
in
src/net_permissions.cpp:27
in
22e64e8ab5outdated
It’s cleaner when/if the default is changed to both.
in
test/functional/test_framework/test_framework.py:99
in
38839bea82outdated
95@@ -96,6 +96,7 @@ def __init__(self) -> None:
96 """Sets test framework defaults. Do not override this method. Instead, override the set_test_params() method"""
97 self.chain: str = 'regtest'
98 self.setup_clean_chain: bool = False
99+ self.noban_tx_relay: bool = False
pinheadmz
commented at 2:50 pm on October 19, 2023:
I really like this clean up commit! Nice feature. I didn’t deeply check all the results from this git grep, but there might still be more to do? Maybe from recent test additions on master?
0--> git grep whitelist *.py | wc -l
155
brunoerg
commented at 6:21 pm on October 20, 2023:
there might still be more to do?
Maybe. I’m checking it again, I only modified the tests that explicity points out that is using it to speedup tx relay. so, there are other tests using it for other purposes.
pinheadmz
commented at 2:53 pm on October 19, 2023:
member
code review ACK at 51618c9c8a87f3a1cd7fcb9b4f7d4da96f182138
I left some more notes below, but recent updates are great. Looking lean and clean
DrahtBot requested review from stratospher
on Oct 19, 2023
DrahtBot requested review from jonatack
on Oct 19, 2023
DrahtBot removed review request from stratospher
on Oct 19, 2023
DrahtBot requested review from stratospher
on Oct 19, 2023
pinheadmz
commented at 2:54 pm on October 19, 2023:
member
oh one more thing! probably should add a release note :-)
DrahtBot removed review request from stratospher
on Oct 19, 2023
DrahtBot requested review from stratospher
on Oct 19, 2023
DrahtBot removed review request from stratospher
on Oct 19, 2023
DrahtBot requested review from stratospher
on Oct 19, 2023
DrahtBot removed review request from stratospher
on Oct 19, 2023
DrahtBot requested review from stratospher
on Oct 19, 2023
DrahtBot removed review request from stratospher
on Oct 19, 2023
DrahtBot requested review from stratospher
on Oct 19, 2023
I don’t think so because it’s expected to not modify nLocalServices. Doesn’t it?
0/**
1 * Services this node offers.
2 *
3 * This data is replicated in each Peer instance we create.
4 *
5 * This data is not marked const, but after being set it should not
6 * change.
7 *
8 * \sa Peer::our_services
9 */10ServiceFlags nLocalServices;
naumenkogs
commented at 8:42 am on January 10, 2024:
What does \sa mean?
stratospher
commented at 5:34 pm on March 6, 2024:
I don’t think so because some tests rely on -whitelist for other purposes.
DrahtBot removed review request from stratospher
on Oct 19, 2023
DrahtBot requested review from stratospher
on Oct 19, 2023
luke-jr referenced this in commit
e11c4d433e
on Oct 19, 2023
luke-jr referenced this in commit
c1bd439b38
on Oct 19, 2023
luke-jr referenced this in commit
7ca26240f1
on Oct 19, 2023
luke-jr referenced this in commit
622ae61e0b
on Oct 19, 2023
brunoerg referenced this in commit
31ea683b24
on Oct 20, 2023
brunoerg force-pushed
on Oct 20, 2023
brunoerg force-pushed
on Oct 20, 2023
brunoerg referenced this in commit
d69747ab65
on Oct 20, 2023
DrahtBot added the label
CI failed
on Oct 20, 2023
brunoerg
commented at 8:04 pm on October 20, 2023:
contributor
Force-pushed:
added release note
renamed vWhitelistedRange to vWhitelistedRangeIncoming
addressed self.noban_tx_relay in more tests
brunoerg
commented at 9:23 pm on October 22, 2023:
contributor
CI failure is unrelated.
pinheadmz approved
pinheadmz
commented at 5:25 pm on October 23, 2023:
member
ACKd69747ab656899d1014483809d22a2c85cb45d78
Built and ran tests locally on macOS/arm. Confirmed changes since last approval were release note, renaming vWhitelistedRangeIncoming and applying the new feature to more tests.
naumenkogs
commented at 11:02 am on October 27, 2023:
622a829ca1473814928ba32f003480b2382701a2
what’s the benefit of having two separate vectors?
brunoerg
commented at 2:46 pm on November 3, 2023:
You can specify different permissions for each connection direction.
naumenkogs
commented at 8:07 am on November 7, 2023:
perhaps two separate lists (or a mapping to bool) could be added when it’s needed, and not now that it’s unused?
brunoerg
commented at 12:40 pm on November 17, 2023:
I don’t think it’s unused because you can specify -whitelist=noban,in@ipaddr -whitelist=mempool,out@sameipaddr.
naumenkogs
commented at 9:06 am on November 24, 2023:
good point.
naumenkogs
commented at 9:07 am on November 24, 2023:
well, actually….you still can track it with a map<addr, bool>, no?
brunoerg
commented at 10:59 pm on November 24, 2023:
I think so, but we would have to iterate the whole vector everytime we want to get specific permissions (only outbound or inbound)?
naumenkogs
commented at 9:05 am on January 10, 2024:
But we don’t do this much anyway?
I think the code could be easily modified for this change, you’d only have to pass addr direction to `AddWhitelistPermissionFlags. I won’t insist though.
in
test/functional/interface_rest.py:55
in
edbc1ae33boutdated
naumenkogs
commented at 11:08 am on October 27, 2023:
edbc1ae33b0a17994331de0660b231e7f00a2bda
I like saving a few LOC, but dropping these comments here and there… Presumably they were helpful for the reader to understand why whitelist. And noban_tx_relay doesn’t immediately mean speeding up.
brunoerg
commented at 2:30 pm on November 3, 2023:
I agree it’s helpful, but I am not sure about having it for all occurances. Perhaps we could put in test_framework, e.g.:
0diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
1index 220e51df38..aeb9a2691c 100755
2--- a/test/functional/test_framework/test_framework.py
3+++ b/test/functional/test_framework/test_framework.py
4@@ -97,6 +97,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
5 """Sets test framework defaults. Do not override this method. Instead, override the set_test_params() method"""
6 self.chain: str = 'regtest'
7 self.setup_clean_chain: bool = False
8+ # whitelist peers to speed up tx relay / mempool sync
9 self.noban_tx_relay: bool = False
10 self.nodes: List[TestNode]
naumenkogs
commented at 8:10 am on November 7, 2023:
This could yield false positives: sometimes we need just this flags for a different reason than speeding up, right? I also don’t think we can reliably expect a test code reader to figure out his answer (“why noban”) is in the test framework.
brunoerg
commented at 12:38 pm on November 17, 2023:
Fair enough, gonna add comments.
DrahtBot requested review from naumenkogs
on Oct 27, 2023
DrahtBot added the label
Needs rebase
on Nov 17, 2023
brunoerg force-pushed
on Nov 17, 2023
brunoerg referenced this in commit
a5c5dde1cc
on Nov 17, 2023
brunoerg
commented at 12:52 pm on November 17, 2023:
contributor
Rebased
DrahtBot removed the label
Needs rebase
on Nov 17, 2023
in
src/init.cpp:445
in
a5c5dde1ccoutdated
441@@ -442,7 +442,7 @@ void SetupServerArgs(ArgsManager& argsman)
442 argsman.AddArg("-blocknotify=<cmd>", "Execute command when the best block changes (%s in cmd is replaced by block hash)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
443 #endif
444 argsman.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);
445- argsman.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);
446+ argsman.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Automatic broadcast and rebroadcast of any transactions from any peer is disabled, unless it has the 'forcerelay' permission. RPC transactions are not affected. (default: %u)", DEFAULT_BLOCKSONLY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
jonatack
commented at 5:37 pm on November 17, 2023:
0 argsman.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Disables automatic broadcast and rebroadcast of transactions, unless the source peer has the 'forcerelay' permission. RPC transactions are not affected. (default: %u)", DEFAULT_BLOCKSONLY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
brunoerg
commented at 10:13 pm on November 27, 2023:
furszy
commented at 11:07 pm on November 27, 2023:
In 1a47109c2cd:
Extra “;” here
brunoerg
commented at 4:40 pm on November 28, 2023:
done
in
src/net_permissions.cpp:30
in
1a47109c2coutdated
26+ if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
27+ AddFlag(flags, NetPermissionFlags::ForceRelay);
28+ }
29+ if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) {
30+ AddFlag(flags, NetPermissionFlags::Relay);
31+ }
furszy
commented at 11:16 pm on November 27, 2023:
In 1a47109c:
nit: could provide “-whitelistforcerelay” and “-whitelistrelay” as two booleans instead of accessing the global ArgsManager.
It would help the path of decreasing the global variables usage and make the function easier to test and use in tests.
jonatack
commented at 11:56 pm on November 27, 2023:
This would also allow dropping #include <common/args.h> in src/net_permissions.cpp.
brunoerg
commented at 2:52 pm on November 28, 2023:
Sgtm
brunoerg
commented at 4:40 pm on November 28, 2023:
done
furszy
commented at 11:32 pm on November 27, 2023:
member
left two small things. Nothing important.
brunoerg referenced this in commit
e0d068bb50
on Nov 28, 2023
brunoerg force-pushed
on Nov 28, 2023
brunoerg
commented at 4:40 pm on November 28, 2023:
contributor
nit, if you have to re-touch and it makes sense to you:
0"Specify multiple permissions separated by commas (default: download,noban,mempool,relay,in). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
535@@ -536,9 +536,11 @@ void SetupServerArgs(ArgsManager& argsman)
536 "Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". "
537 "Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
538539- argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers connecting from the given IP address (e.g. 1.2.3.4) or "
540+ argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or "
541 "CIDR-notated network (e.g. 1.2.3.0/24). Uses the same permissions as "
542- "-whitebind. Can be specified multiple times." , ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
543+ "-whitebind. "
544+ "Additional flags \"in\" and \"out\" control whether permissions apply to incoming connections and/or outgoing (default: incoming only). "
nit, since it was not very clear to me at first sight and I saw another comment related to this (feel free to change it if you agree with the general idea):
0 "Additional flags \"in\" and \"out\" are part of [permissions@] and control whether permissions apply to incoming connections and/or outgoing (default: incoming only - e.g. noban,in,out@1.2.3.4). "
brunoerg
commented at 12:45 pm on December 27, 2023:
(default: incoming only - e.g. noban,in,out@1.2.3.4)
I think it might misconfuse. It seems the example (e.g) refers to the default behaviour.
Yeah, I meant to write how to pass the additional flags in the [permissions@]’s syntax format (the default behaviour should be without the out in it as noban,in@1.2.3.4, perhaps that’s confusing?). Feel free to ignore if doesn’t make sense to you.
pablomartin4btc
commented at 10:37 pm on November 30, 2023:
member
tACKd0e3c62d414d91f34bf9c0991a58139ae9365221
Tested it with bitcoin-qt and I’m wondering if later as a follow-up we could add a feature as a “nice to have” to identify the “whitelisted” peers (and it permissions passed) in the Peers tab on the Node window (we show already the permissions@ on RPCgetpeerinfo but not sure about other details on -whitelist or -whitebind and if we want to provide that info via RPC). There’s already a “related” GUIrequest but more generic to show the options passed on the command line.
As @glozowpointed out perhaps you can link the issue #9923 related with this change as “fixes #”.
DrahtBot requested review from furszy
on Nov 30, 2023
DrahtBot requested review from jonatack
on Nov 30, 2023
DrahtBot requested review from pinheadmz
on Nov 30, 2023
brunoerg
commented at 12:20 pm on December 27, 2023:
contributor
Tested it with bitcoin-qt and I’m wondering if later as a follow-up we could add a feature as a “nice to have” to identify the “whitelisted” peers (and it permissions passed) in the Peers tab on the Node window (we show already the permissions@ on RPC getpeerinfo but not sure about other details on -whitelist or -whitebind and if we want to provide that info via RPC). There’s already a “related” GUI https://github.com/bitcoin-core/gui/issues/649 but more generic to show the options passed on the command line.
Sure, will leave it for a follow-up.
brunoerg force-pushed
on Jan 2, 2024
brunoerg referenced this in commit
0b8147375d
on Jan 2, 2024
brunoerg
commented at 6:35 pm on January 2, 2024:
contributor
in
src/net_permissions.cpp:21
in
0b8147375doutdated
17@@ -18,12 +18,28 @@ const std::vector<std::string> NET_PERMISSIONS_DOC{
18 "addr (responses to GETADDR avoid hitting the cache and contain random records with the most up-to-date info)"
19 };
2021+void NetPermissions::Initialize(NetPermissionFlags& flags, bool whitelist_forcerelay, bool whitelist_relay)
Passing options individually like this is ugly - worse than just passing const ArgsManager& IMO. If you really want to cache it as a bool, maybe make a struct for connection permission options or something to pass instead.
Another possibility is to just cache a single NetPermissionFlags for these.
brunoerg
commented at 10:29 am on January 5, 2024:
I think we can avoid passing them in Initialize by setting them in AddWhitelistPermissionFlags (since it’s from CConnman).
I agree to move it to the CConman::AddWhitelistPermissionFlags (since the obj has both whitelist_forcerelay & whitelist_relay vars already set) and you could have something like CConman:UpdateNetPermissionsFlagswith the logic below.
brunoerg referenced this in commit
eb1ed589fc
on Jan 5, 2024
brunoerg force-pushed
on Jan 5, 2024
brunoerg referenced this in commit
bb4784ee22
on Jan 5, 2024
brunoerg
commented at 5:26 pm on January 5, 2024:
contributor
Force-pushed: Rebased and addressed #27114 (review) and #27114 (review) (I moved the -whitelistrelay and -whitelistforcerelay verification to the AddWhitelistPermissionFlags function.
brunoerg referenced this in commit
a0dafc1297
on Jan 5, 2024
brunoerg force-pushed
on Jan 5, 2024
luke-jr
commented at 6:27 pm on January 5, 2024:
member
Why was it rebased? Just seems to make it harder to review the changes…
maflcko
commented at 7:42 pm on January 5, 2024:
member
Why was it rebased? Just seems to make it harder to review the changes…
git range-diff bitcoin-core/master a b does not care about rebases, see the docs in this repo.
brunoerg referenced this in commit
72013c25ad
on Jan 5, 2024
brunoerg force-pushed
on Jan 5, 2024
brunoerg
commented at 7:43 pm on January 5, 2024:
contributor
Pushed to fix CI.
luke-jr
commented at 7:51 pm on January 5, 2024:
member
git range-diff bitcoin-core/master a b does not care about rebases, see the docs in this repo.
It’s also painful to review. If there’s no benefit to a rebase, better to just avoid it.
brunoerg force-pushed
on Jan 5, 2024
brunoerg referenced this in commit
6175a2ee09
on Jan 5, 2024
pablomartin4btc
commented at 1:58 am on January 7, 2024:
member
concept ack to having a TestFramework-wide setting to whitelist everybody for immediate tx relay. e5593fc9bf48b27227786e7f4145b58c849367a3 could be its own PR, as I don’t think there are any instances where we are specifically making outbound connections and need immediate tx relay.
brunoerg
commented at 8:39 pm on January 17, 2024:
571+ argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or "
572 "CIDR-notated network (e.g. 1.2.3.0/24). Uses the same permissions as "
573- "-whitebind. Can be specified multiple times." , ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
574+ "-whitebind. "
575+ "Additional flags \"in\" and \"out\" control whether permissions apply to incoming connections and/or outgoing (default: incoming only). "
576+ "Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
Why is the approach to add “in” and “out” instead of just having specified permissions apply to both? Are there instances where you want to specify different permissions for the same address depending on the connection direction?
brunoerg
commented at 2:22 pm on January 12, 2024:
Why is the approach to add “in” and “out” instead of just having specified permissions apply to both? Are there instances where you want to specify different permissions for the same address depending on the connection direction?
For the same address especifically, idk. But since we can use -whitelist to give permissions for “all” nodes (e.g. using 0.0.0.0), it could be worth to specify the direction.
glozow requested review from sr-gi
on Jan 12, 2024
glozow requested review from dergoegge
on Jan 12, 2024
glozow requested review from mzumsande
on Jan 12, 2024
dergoegge
commented at 10:33 am on January 12, 2024:
member
I don’t see what this would be useful for, could you elaborate on the motivation?
glozow
commented at 10:54 am on January 12, 2024:
member
+1 Could you update the OP with motivation for this PR? I didn’t see much from the linked PRs
brunoerg
commented at 1:45 pm on January 12, 2024:
contributor
sipa
commented at 2:50 pm on January 12, 2024:
member
It appears to me that whitelisting of outbound connections really only applies to manual ones: if you have reason to specifically trust another peer or otherwise give them elevated privileges, you probably want to also try actually connecting to them.
If so, it seems more natural to me to specify outbound net permissions wherever that manual connection is instructed (so inside -addnode, -connect=, or as argument to the addnode RPC)?
mzumsande
commented at 3:35 pm on January 12, 2024:
contributor
If so, it seems more natural to me to specify outbound net permissions wherever that manual connection is instructed
That would mean adding logic / additional options for it in possibly multiple spots, and having yet another place where net permissions are defined. If that becomes too messy, another option would be to leave it in -whitelist but just not apply it to automatic outbound connections.
brunoerg
commented at 4:39 pm on January 12, 2024:
contributor
That would mean adding logic / additional options for it in possibly multiple spots, and having yet another place where net permissions are defined. If that becomes too messy, another option would be to leave it in -whitelist but just not apply it to automatic outbound connections.
I agree. I think the easiest path would be not applying these permissions for the automatic outbound connections, leaving them for the manual ones.
DrahtBot added the label
CI failed
on Jan 13, 2024
brunoerg referenced this in commit
1d0216ed32
on Jan 17, 2024
brunoerg force-pushed
on Jan 17, 2024
brunoerg renamed this:
p2p: Allow whitelisting outgoing connections
p2p: Allow whitelisting manual connections
on Jan 17, 2024
brunoerg
commented at 8:25 pm on January 17, 2024:
contributor
Thanks for the reviews! Since there is a consensus about being useful only for manual connections, I just changed the approach. The flags won’t be applied for automatic connections, only for manual ones. I updated the title and description.
DrahtBot removed the label
CI failed
on Jan 17, 2024
luke-jr
commented at 4:37 pm on January 26, 2024:
member
Concept NACK to restricting it to only manual connections. This will cause random breakage when automatic peering happens to connect to a manual peer first.
mzumsande
commented at 4:47 pm on January 26, 2024:
contributor
Concept NACK to restricting it to only manual connections. This will cause random breakage when automatic peering happens to connect to a manual peer first.
did you see #28895? We don’t make automatic connections to manually specified peers anymore.
luke-jr
commented at 6:45 pm on January 26, 2024:
member
Hmm, it’s still weird, but I guess it’s not terrible then.
in
src/net.h:1568
in
1d0216ed32outdated
1555+ /**
1556+ * flag for adding 'relay' permission to whitelisted inbound
1557+ * peers with default permissions.
1558+ */
1559+ bool whitelist_relay;
1560+
brunoerg
commented at 12:42 pm on February 8, 2024:
Yes, I’ll fix it.
in
src/net_permissions.cpp:24
in
1d0216ed32outdated
17@@ -18,12 +18,22 @@ const std::vector<std::string> NET_PERMISSIONS_DOC{
18 "addr (responses to GETADDR avoid hitting the cache and contain random records with the most up-to-date info)"
19 };
2021+void NetPermissions::Initialize(NetPermissionFlags& flags)
22+{
23+ if (HasFlag(flags, NetPermissionFlags::Implicit)) {
24+ ClearFlag(flags, NetPermissionFlags::Implicit);
NetPermissions::Initialize will call NetPermissions::ClearFlag, clear the Implicit flag, and call NetPermissions::Initialize again, which will simply return given the flag is not set anymore
brunoerg
commented at 12:50 pm on February 8, 2024:
Where is it calling NetPermissions::Initialize again?
Sorry, my bad, looking at the diff I misinterpreted the definition of initialize that is right bellow NetPermissions::ClearFlag as a call to it. Disregard this commet.
in
src/net.cpp:575
in
1d0216ed32outdated
573+ NetPermissions::AddFlag(flags, subnet.m_flags);
574+ }
575+ }
576+ if (NetPermissions::HasFlag(flags, NetPermissionFlags::Implicit)) {
577+ if (whitelist_forcerelay) NetPermissions::AddFlag(flags, NetPermissionFlags::ForceRelay);
578+ if (whitelist_relay) NetPermissions::AddFlag(flags, NetPermissionFlags::Relay);
Why are we splitting the parsing of NetPermissionFlags::Implicit between here and NetPermissions::Initialize? I find this a bit weird
brunoerg
commented at 1:45 pm on February 8, 2024:
I think that was a result of many changes during the path. In fact, we do not need Initialize anymore. We can concentrate the logic into AddWhitelistPermissionFlags.
Just curious, is there a reason to initialize this if you are overwriting it during Options::Init? (i.e. is this ever being used without initializing?)
Also, if kept, wouldn’t it be better to set it to the default constant defined in net_permission.h?
brunoerg
commented at 1:21 pm on February 8, 2024:
Yes, we can call Init without setting all values in Options (e.g. connman fuzz target). I will change it to use DEFAULT_WHITELISTFORCERELAY and DEFAULT_WHITELISTRELAY.
in
src/net_permissions.cpp:57
in
1d0216ed32outdated
61@@ -52,6 +62,15 @@ bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output,
62 else if (permission == "all") NetPermissions::AddFlag(flags, NetPermissionFlags::All);
63 else if (permission == "relay") NetPermissions::AddFlag(flags, NetPermissionFlags::Relay);
64 else if (permission == "addr") NetPermissions::AddFlag(flags, NetPermissionFlags::Addr);
65+ else if (permission == "in") connection_direction |= ConnectionDirection::In;
66+ else if (permission == "out") {
I guess that depends on what feedback we want to provide the user when an invalid configuration has been set (i.e. silently dropping vs being loud about it).
This is quite similar to other misconfigurations, such as setting the same permission twice, but with the particularity that it actually cannot be applied by itself, so maybe it’s worth returning an error in this case
brunoerg
commented at 9:41 pm on February 8, 2024:
Sounds good, I’ll address it.
stratospher
commented at 4:49 am on February 28, 2024:
47c596b: not entirely convinced that we should throw an error here because empty permissions like ",,@1.2.3.4:32" are allowed (an example). curious to know what other people think.
regardless, a unit test to document this scenario in netbase_tests.cpp would be nice.
brunoerg
commented at 1:19 pm on February 28, 2024:
Since we have the all flag, I do not see how useful would be allowing passing only conn direction.
in
src/net_permissions.cpp:59
in
1d0216ed32outdated
61@@ -52,6 +62,15 @@ bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output,
62 else if (permission == "all") NetPermissions::AddFlag(flags, NetPermissionFlags::All);
63 else if (permission == "relay") NetPermissions::AddFlag(flags, NetPermissionFlags::Relay);
64 else if (permission == "addr") NetPermissions::AddFlag(flags, NetPermissionFlags::Addr);
65+ else if (permission == "in") connection_direction |= ConnectionDirection::In;
66+ else if (permission == "out") {
67+ if (output_connection_direction == nullptr) {
68+ // Only NetWhitebindPermissions() should pass a nullptr.
566@@ -567,9 +567,11 @@ void SetupServerArgs(ArgsManager& argsman)
567 "Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". "
568 "Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
569570- argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers connecting from the given IP address (e.g. 1.2.3.4) or "
571+ argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or "
572 "CIDR-notated network (e.g. 1.2.3.0/24). Uses the same permissions as "
573- "-whitebind. Can be specified multiple times." , ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
574+ "-whitebind. "
575+ "Additional flags \"in\" and \"out\" control whether permissions apply to incoming connections and/or outgoing (default: incoming only). "
pinheadmz
commented at 9:15 pm on February 20, 2024:
nit, I think these should get the m_ prefix. When I was reviewing a7240eb99dc792fdf3a6f5aeb93c40c42a8cdc16 I thought whitelist_relay was a local variable and couldn’t tell where it was defined. Maybe just me though 🤷
in
doc/release-notes-27114.md:2
in
c10f528350outdated
0@@ -0,0 +1,2 @@
1+- Additional flags "in" and "out" have been added to `-whitelist` to control whether
2+ permissions apply to incoming connections and/or manual (default: incoming only).
pinheadmz
commented at 9:47 pm on February 20, 2024:
Kinda funny that in/out maps to in/manual … perhaps "manual" should’ve been the permission flag?
brunoerg
commented at 12:01 pm on February 26, 2024:
I’ll leave it as is for while since it is specified that it applies only for manual connections.
pinheadmz approved
pinheadmz
commented at 9:49 pm on February 20, 2024:
member
ACKc10f528350152ca9248e8c167b67993fc7321ca3
I left comments on a few nits but none are breaking for me. Happy to re-ACK if you update.
Built and ran all functional and unit tests locally on macOS/arm
in
test/functional/mempool_packages.py:31
in
c985eb854coutdated
26@@ -27,10 +27,11 @@
27 class MempoolPackagesTest(BitcoinTestFramework):
28 def set_test_params(self):
29 self.num_nodes = 2
30+ # whitelist peers to speed up tx relay / mempool sync
31+ self.noban_tx_relay = True
stratospher
commented at 11:34 am on March 6, 2024:
c985eb8: isn’t this a behaviour change in the functional test? now, the second node also has noban permission - previously it didn’t. same situation happens in test/functional/p2p_segwit.py.
so maybe keep "-whitelist=noban@127.0.0.1" instead of self.noban_tx_relay = True in both these tests.
(haven’t looked into how having noban permission for second node affects the functional test though.)
I does not affect the behaviour of the tests since those tests does not test any misbehaviour. It is just to speed up tx relay.
stratospher
commented at 5:32 pm on March 6, 2024:
contributor
concept ACK! it’s useful to be able to whitelist and give special permissions to manual peers which are essentially peers you trust.
I’ve gone through all the commits but not leaving a code review/approach ACK since I don’t understand why we’d need different permissions for each connection direction. (related comments - #17167 (comment), #27114 (review), #27114 (review))
DrahtBot requested review from stratospher
on Mar 6, 2024
achow101
commented at 4:50 pm on March 12, 2024:
member
ACK0a533613fb44207053796fd01a9f4b523a3153d4
achow101 merged this
on Mar 12, 2024
achow101 closed this
on Mar 12, 2024
kevkevinpal referenced this in commit
c8589c0879
on Mar 13, 2024
kevkevinpal referenced this in commit
9860a035fd
on Mar 13, 2024
sr-gi referenced this in commit
f8c54c8dee
on Mar 25, 2024
Retropex referenced this in commit
7076169c8c
on Mar 28, 2024
Retropex referenced this in commit
b99db205c4
on Mar 28, 2024
Retropex referenced this in commit
66d5aa3e1d
on Mar 28, 2024
Retropex referenced this in commit
96d715f180
on Mar 28, 2024
Retropex referenced this in commit
8d290f4c57
on Mar 28, 2024
Retropex referenced this in commit
f33cd8869d
on Mar 28, 2024
theStack referenced this in commit
93fae5ae7c
on Apr 6, 2024
fanquake referenced this in commit
f0794cbd40
on Apr 7, 2024
in
src/net_permissions.cpp:77
in
66bc6e2d17outdated
70@@ -61,7 +71,16 @@ bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output,
71 readen++;
72 }
7374+ // By default, whitelist only applies to incoming connections
75+ if (connection_direction == ConnectionDirection::None) {
76+ connection_direction = ConnectionDirection::In;
77+ } else if (flags == NetPermissionFlags::None) {
This is a metadata mirror of the GitHub repository
bitcoin/bitcoin.
This site is not affiliated with GitHub.
Content is generated from a GitHub metadata backup.
generated: 2025-05-19 00:13 UTC
This site is hosted by @0xB10C More mirrored repositories can be found on mirror.b10c.me