Following review of new changes merged today, move a use of statestats in getpeerinfo to within the section guarded by if (fStateStats), e.g. PeerManagerImpl::GetNodeStateStats true, and pass an in-param by reference to const.
p2p, rpc: address relay fixups #22616
pull jonatack wants to merge 1 commits into bitcoin:master from jonatack:addr_relay_fixups changing 2 files +4 −4-
jonatack commented at 11:17 AM on August 3, 2021: member
-
p2p, rpc: address relay fixups 5e33f762d4
-
MarcoFalke commented at 11:20 AM on August 3, 2021: member
Could use
std::optionalto avoid this stuff in the future? - DrahtBot added the label P2P on Aug 3, 2021
- DrahtBot added the label RPC/REST/ZMQ on Aug 3, 2021
-
jonatack commented at 4:07 PM on August 3, 2021: member
Could use
std::optionalto avoid this stuff in the future?Sure, will have a look. Might be better as a separate refactoring patch?
-
amitiuttarwar commented at 4:57 PM on August 3, 2021: contributor
good catch on the
statestatsconditional @jonatack! thanks for fixing :) ACK 5e33f762d4RE:
Could use std::optional to avoid this stuff in the future?
Sure, will have a look
good idea @MarcoFalke! FYI @jonatack I'm also going to take a look. having compiler catch this error seems like a good move because clearly I missed it 😛
-
jonatack commented at 6:58 PM on August 3, 2021: member
@amitiuttarwar sgtm, go for it, happy to review!
-
amitiuttarwar commented at 8:27 PM on August 3, 2021: contributor
took a look, unfortunately I don't think having
GetNodeStateStatsreturn anstd::optional<CNodeStateStats>increases the compiler guarantee. we still have to manually check for presence.<details><summary>example of accessing fields of a std::nullopt </summary>
struct NewStruct { int a; int b; }; std::optional<NewStruct> GetNodeStateStats() { return std::nullopt; } int main() { std::optional<NewStruct> fStateStats = GetNodeStateStats(); std::cout << fStateStats->a << std::endl; std::cout << fStateStats->b << std::endl; return 0; }... compiles fine =\
</details>
-
DrahtBot commented at 8:29 PM on August 3, 2021: member
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--174a7506f384e20aa4161008e828411d-->
Conflicts
Reviewers, this pull request conflicts with the following ones:
- #22604 (p2p, rpc, test: address rate-limiting follow-ups by jonatack)
- #21515 (Erlay: bandwidth-efficient transaction relay protocol by naumenkogs)
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.
-
jonatack commented at 9:19 PM on August 3, 2021: member
yes...did https://github.com/jonatack/bitcoin/commit/397c33c399685b2ca4fe98de6e975f29f2f3d040 as a warmup, it builds and tests pass, and it seems to be a bit nicer as an interface but doesn't yet do what we're looking for, was thinking to then convert some of the
CNodeStateStatsstruct members to std::optional and then maybe use them withvalue_oror something. -
MarcoFalke commented at 6:17 AM on August 4, 2021: member
Can you explain why this is something we don't want? Surely compilers are happy to compile UB, but that doesn't mean it won't be caught.
Previously (returning a pair of
bool+ some typeT), the only way to catch it is with code review (and maybe tests).Returning a
std::optional<T>instead will allow any of the following to catch it:- code review (it is easier because there is a
*or->without corresponding check) - compiler warning
- valgrind [1]
- static analysis
- tests (maybe also with valgrind)
- something I missed?
[1]: For example:
#include <optional> struct NewStruct { int a; int b; }; std::optional<NewStruct> GetNodeStateStats() { return std::nullopt; } int main() { return GetNodeStateStats()->a; }==991573== Memcheck, a memory error detector ==991573== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==991573== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==991573== Command: ./exe ==991573== ==991573== Syscall param exit_group(status) contains uninitialised byte(s) ==991573== at 0x4CB2021: _Exit (in /usr/lib64/libc-2.33.so) ==991573== by 0x4C24C01: __run_exit_handlers (in /usr/lib64/libc-2.33.so) ==991573== by 0x4C24C9F: exit (in /usr/lib64/libc-2.33.so) ==991573== by 0x4C0CB7B: (below main) (in /usr/lib64/libc-2.33.so) - code review (it is easier because there is a
-
MarcoFalke commented at 6:24 AM on August 4, 2021: member
Note that on master it is impossible for valgrind to catch this because the memory is always filled:
struct CNodeStateStats { int nSyncHeight = -1; int nCommonHeight = -1; int m_starting_height = -1; std::chrono::microseconds m_ping_wait; std::vector<int> vHeightInFlight; uint64_t m_addr_processed = 0; uint64_t m_addr_rate_limited = 0; bool m_addr_relay_enabled{false}; };If it wasn't filled, valgrind detecting it would depend on whether
{}is used to initialize or not. I.eNewStruct ret{}; GetNodeStateStats(ret);vs
NewStruct ret; GetNodeStateStats(ret); -
jonatack commented at 6:44 AM on August 4, 2021: member
For my part, I wasn't sure if the direction started with in https://github.com/jonatack/bitcoin/commit/397c33c399685b2ca4fe98de6e975f29f2f3d040 was what you had in mind, versus for instance also or starting with making the struct member(s) std::optional themselves, or something else.
It seems to be a separate refactoring from this small fix-up, but good to clarify the direction.
-
jnewbery commented at 10:36 AM on August 4, 2021: member
I think one way to improve this would be to combine
CNodeStatsandCNodeStateStatsinto a single struct, and change the individual fields that are populated by net_processing to bestd::optional<>s. The rpc code could then populate the univalue object as follows:// ... obj.pushKV("inbound", stats.fInbound); obj.pushKV("bip152_hb_to", stats.m_bip152_highbandwidth_to); obj.pushKV("bip152_hb_from", stats.m_bip152_highbandwidth_from); if (stats->m_starting_height) obj.pushKV("startingheight", stats->m_starting_height.value()); if (stats->nSyncHeight) obj.pushKV("synced_headers", stats->nSyncHeight.value()); // etc ...That requires quite a bit of moving code around, since both net and net_processing would have to include the header that defines the combined stats struct. I made a start on that work, but it's very out of date: https://github.com/jnewbery/bitcoin/tree/2021-01-stats
-
jnewbery commented at 10:37 AM on August 4, 2021: member
ACK 5e33f762d44557a1e3f0ff3c280d8a3ab98e3867
-
DrahtBot commented at 3:42 PM on August 4, 2021: member
<!--cf906140f33d8803c4a75a2196329ecb-->
🐙 This pull request conflicts with the target branch and needs rebase.
<sub>Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft".</sub>
- DrahtBot added the label Needs rebase on Aug 4, 2021
- MarcoFalke merged this on Aug 4, 2021
- MarcoFalke closed this on Aug 4, 2021
- jonatack deleted the branch on Aug 4, 2021
- sidhujag referenced this in commit a36a7528fb on Aug 4, 2021
- DrahtBot locked this on Aug 16, 2022