Next step in #19398. Moves additional members from CNode and CNodeState into Peer.
Also renames CNodeStateStats to PeerStats, since most of the stats are now taken from the Peer object.
Concept ACK
Concept ACK.
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--174a7506f384e20aa4161008e828411d-->
Reviewers, this pull request conflicts with the following ones:
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.
Concept ACK
Fixed a bug (subver may not be present in the getpeerinfo results while the peer connection is being torn down, so needs to be marked as optional) and rebased on master.
I'm going to mark this as a draft since it conflicts with and overlaps with #24543, which has been open for longer.
Rebased on master and tidied up the nonce handling code. This is now ready for review.
205 | @@ -204,6 +206,15 @@ struct Peer { 206 | /** Same id as the CNode object for this peer */ 207 | const NodeId m_id{0}; 208 | 209 | + /** Protects subversion data member */ 210 | + RecursiveMutex m_subver_mutex;
Thanks. Fixed!
Most of the stats in CNodeStateStats are now taken from the Peer object.
Rename the struct to PeerStats.
-BEGIN VERIFY SCRIPT-
ren() { sed -i "s:\<$1\>:$2:g" $(git grep -l "\<$1\>" ./src ./test); }
ren CNodeStateStats PeerStats
ren GetNodeStateStats GetPeerStats
ren nodeStateStats m_peer_stats
ren statestats peer_stats
ren fNodeStateStatsAvailable m_peer_stats_available
ren fStateStats peer_stats_available
-END VERIFY SCRIPT-
Also rename to m_clean_subversion.
Since the subversion is now contained in the Peer object, it may not be
available in `getpeerinfo` while the peer connection is being torn down.
Update the rpc help text to mark the field optional and update the tests
to tolerate the field being absent.
Also rename to m_preferred_download
Rebased
1337 | @@ -1311,6 +1338,10 @@ void PeerManagerImpl::ReattemptInitialBroadcast(CScheduler& scheduler) 1338 | void PeerManagerImpl::FinalizeNode(const CNode& node) 1339 | { 1340 | NodeId nodeid = node.GetId(); 1341 | + { 1342 | + LOCK(m_version_nonces_mutex); 1343 | + m_version_nonces.erase(nodeid); 1344 | + }
WITH_LOCK(m_version_nonces_mutex, m_version_nonces.erase(nodeid));
Done. Thanks!
2934 | @@ -2910,6 +2935,11 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, 2935 | // they may wish to request compact blocks from us 2936 | m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, /*high_bandwidth=*/false, /*version=*/CMPCTBLOCKS_VERSION)); 2937 | } 2938 | + { 2939 | + LOCK(m_version_nonces_mutex); 2940 | + m_version_nonces.erase(pfrom.GetId()); 2941 | + }
WITH_LOCK(m_version_nonces_mutex, m_version_nonces.erase(pfrom.GetId());
Done
Code-review ACK f6bf0d1787673e83e0aefd4ef6678655aef0e299
Nice idea to use a std::map for the sent nonce values and only store them as long as necessary (that is, until the connection is fully established). Left two refactoring nits where one-liners could be used instead, feel free to ignore.
Handle version nonces entirely within net_processing.
re-ACK 7df3d82395ab87a5f9f85af1988d568c07cfb945
209 | @@ -210,6 +210,9 @@ struct Peer { 210 | * This cleaned string can safely be logged or displayed. */ 211 | std::string m_clean_subversion GUARDED_BY(m_subver_mutex){}; 212 | 213 | + /** Whether we consider this a preferred download peer. */ 214 | + bool m_preferred_download{false};
fPreferredDownload used to be protected by cs_main. Can you explain why the lock is not needed anymore, considering that the socket thread and the p2p thread will both read this value?
656 | @@ -656,7 +657,7 @@ class PeerManagerImpl final : public PeerManager 657 | int m_outbound_peers_with_protect_from_disconnect GUARDED_BY(cs_main) = 0; 658 | 659 | /** Number of preferable block download peers. */ 660 | - int m_num_preferred_download_peers GUARDED_BY(cs_main){0}; 661 | + std::atomic<int> m_num_preferred_download_peers{0};
can you explain why atomic is sufficient, given that the value is assumed to be changed atomically with fPreferredDownload, and is used in calculations with that assumption:
m_num_preferred_download_peers - state.fPreferredDownload >= 1
concept ACK 4680a64075758f3a08a69dc2bf9243631628900d 🚡
<details><summary>Show signature</summary>
Signature:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
concept ACK 4680a64075758f3a08a69dc2bf9243631628900d 🚡
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUhd+gv+IJsGtuUaa3dRjoJRyLWYPP5KF8uARYx7CkD9oxwEaVycVUCrTvQevQFE
pT6AV7iljFwqfboaliFxveFaoJlZY314jNUtjlpADZS20FQrKvQN74ZEt8/WYWOy
aZ2KOaTd7+kxJOIAcIIPFuFPCZM/PYjuuEwO1POYtvUGCIQySCV15uoHALhklxmE
x8BcZ6PBycjLyCtZ9J6se6yB+PNoIoWZlELVEe5sX8cpWrloQVSfx89k9tRf7oMF
LrentpcIo3Iu/k2LTUw8yjeQGuq9c5OrSw0GxLo2J1vrB5LyKVSpca2VP29GOdnv
QgBBNIT2UQLCsWuHm/wQVdSqkDCxPAfXzLRFmXSbFCLQWuKpG4MxXSUXpKbzGD6i
W5E9Kbm24KR/TnkayAVOIIcJTMBuTvw2f3Mu0durb4dBaOo9ZMEAPOI4vvyE/Ohq
x1Zx+0Ecn5+CFuVQfFeXrBKTsREFn9YHomksVCdoBkaPPdzlEVOyQOWk2tHi1zhd
RSZPVvfl
=uVaU
-----END PGP SIGNATURE-----
</details>
Closing this since it needs a bit of work and I don't have time to maintain it. In terms of priority, I think there's more immediate benefit in moving the services fields from CNode to Peer (the last 6 commits in https://github.com/bitcoin/bitcoin/compare/master...jnewbery:2020-06-cs-main-split), since that allows PeerManagerImpl to be unit tested through the public p2p interfaces.