It doesn't really make sense to continue when the deserialized addrman isn't consistent in the addrman test.
For example, if nLastSuccess is negative, it would later result in integer overflows. Thus, this patch fixes #22931.
This speeds up compilation of the whole program because the included
header file is smaller.
Can be reviewed with --color-moved=dimmed-zebra --color-moved-ws=ignore-all-space
concept ACK
Concept ACK.
I'd understand if it's beyond the scope of this PR, but I think that a second ForceCheckAddrman() at the end of the addrman fuzz target (which isn't caught but can actually lead to crashes) would be really helpful - probably better than activating consistency_check_ratio during fuzzing which could make the fuzzer slow if called in too many steps.
<!--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.
a second ForceCheckAddrman() at the end of the addrman fuzz target
Good idea. Wanted to do it in a follow-up, but it is just a one-line fix, so I added the commit here.
400 | - if (err) { 401 | - LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err); 402 | - assert(false); 403 | - } 404 | - } 405 | + //! Consistency check, taking into account m_consistency_check_ratio.
//! Consistency check, taking into account m_consistency_check_ratio. Will abort(2) if an inconsistency is detected.
405 | + //! Consistency check, taking into account m_consistency_check_ratio. 406 | + void Check() const EXCLUSIVE_LOCKS_REQUIRED(cs); 407 | 408 | - //! Perform consistency check. Returns an error code or zero. 409 | - int Check_() const EXCLUSIVE_LOCKS_REQUIRED(cs); 410 | + //! Perform consistency check, regardless of m_consistency_check_ratio. Returns an error code or zero.
//! Perform consistency check, regardless of `m_consistency_check_ratio`.
//! [@returns](/bitcoin-bitcoin/contributor/returns/) an error code or zero.
240 | @@ -238,6 +241,9 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman) 241 | ds.SetVersion(ser_version); 242 | try { 243 | ds >> *addr_man_ptr; 244 | + if (0 != WITH_LOCK(addr_man_ptr->cs, return addr_man_ptr->ForceCheckAddrman())) { 245 | + throw std::ios_base::failure{"Reset addrman after consistency check failed"}; 246 | + }
What about moving this unconditional check inside, at the end of CAddrMan::Unserialize()? We never want to continue if this check fails after unserialize and it is not too expensive to check once per unserialize.
Right now we have the conditional Check() at the end of Unserialize().
This is what #22734 is doing. Happy to close this fuzz-only pull and rebase the other.
Up to you (and other reviewers). I "voted" for the other PR :)