Skip to content

Conversation

maflcko
Copy link
Member

@maflcko maflcko commented Mar 28, 2022

Those refactors are overlapping with, but otherwise largely unrelated to #24662.

@maflcko maflcko force-pushed the 2203-refactor-addr-relay-time- branch from fa34ccf to fa0e4eb Compare March 28, 2022 15:15
@DrahtBot
Copy link
Contributor

DrahtBot commented Mar 29, 2022

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #25673 (refactor: make member functions const when applicable by aureleoules)
  • #25284 ([WIP] consensus: Remove dependency on net (BIP 155 / ADDRV2_FORMAT) by MarcoFalke)
  • #25221 (Improve CMedianFilter algorithm by antoinedesbois)
  • #23829 (refactor: use braced init for integer literals instead of c style casts by PastaPastaPasta)
  • #21878 (Make all networking code mockable by vasild)
  • #21283 (Implement BIP 370 PSBTv2 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.

Copy link
Contributor

@mzumsande mzumsande left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review ACK fa0e4eb

As far as I can see all refactors are correct, and I agree that it makes sense to use std::chrono. I verified that the log message is unchanged.

@ajtowns
Copy link
Contributor

ajtowns commented Apr 7, 2022

I guess I'm not entirely seeing the point of this? If we're trying to keep AdjustedTime, shouldn't we have a GetChronoAdjustedTime() rather than casting the result of the existing function? If we're trying to get rid of it, shouldn't we just do that, rather than fiddling with whether we treat it as a seconds count or not? If you just want to write constants as "1h" instead of "60*60", could do that via count_seconds(1h)?

EDIT: I suppose you're not really doing much more than that anyway... Would be nice to have a motivation in the PR description I guess; the code changes don't really seem obviously better to me.

@maflcko maflcko force-pushed the 2203-refactor-addr-relay-time- branch from fa0e4eb to fadf5a7 Compare April 7, 2022 07:28
@maflcko
Copy link
Member Author

maflcko commented Apr 7, 2022

I guess I'm not entirely seeing the point of this? If we're trying to keep AdjustedTime, shouldn't we have a GetChronoAdjustedTime() rather than casting the result of the existing function? If we're trying to get rid of it, shouldn't we just do that, rather than fiddling with whether we treat it as a seconds count or not?

I assume that adjusted time will be removed from addrman (see concept acks in the conflicting pull).
Once it is removed, it will be switched to use std::chrono (type safe, human readable, mockable).
This means that any std::chrono::seconds{GetAdjustedTime()} will be changed to GetTime<std::chrono::seconds>() (or a pre-existing variable storing the result). However, CAddress::nTime will not be converted to std::chrono::seconds, because it is a serialized field, which needs to be an exact-width unsigned type, not an implementation defined signed type.

If you just want to write constants as "1h" instead of "60*60", could do that via count_seconds(1h)?

Sure that is possible, but I don't see where it could make sense. count_seconds returns an integral value, so using it instead of 3600.0 still requires double{count_seconds(1h)}. I think CountHoursDouble is nicer, but I am happy to drop the commit.
Using count_seconds in nUpdateInterval could make sense, though I am assuming that nTimePenalty will use std::chrono after commit 89a08ec (from the conflicting pull) as well, so I think switching it now is fine. Happy to drop the commit, though.

Would be nice to have a motivation in the PR description I guess;

I've added some text to each commit to motivate it, no code changes. Can be checked with git range-diff bitcoin-core/master fa0e4eb108 fadf5a7086.

the code changes don't really seem obviously better to me.

There are four commit, and I am happy to drop any or all of them.

@ajtowns
Copy link
Contributor

ajtowns commented Apr 7, 2022

However, CAddress::nTime will not be converted to std::chrono::seconds, because it is a serialized field, which needs to be an exact-width unsigned type, not an implementation defined signed type.

Could have accessors that convert to chrono, or convert from chrono to uint32_t when serializing (and back when deserializing).

[EDIT: can do the conversion when de/serializing as something like:

READWRITECONVERT(obj.chrono_time, uint32_t,
    [](const auto& t) { return static_cast<uint32_t>(count_seconds(t)); },
    [](const uint32_t t) { return std::chrono::seconds{t}; }
);

with READWRITECONVERT defined as:

#define READWRITECONVERT(obj, type, from, to) (::ReadWriteConvert<type>(s, ser_action, obj, from, to))

template<typename X, typename From, typename To, typename Y, typename Stream> void ReadWriteConvert(Stream& s, CSerActionSerialize ser_action, const Y& obj, From from, To)
{
    X dummy{from(obj)};
    ::Serialize(s, dummy);
}

template<typename X, typename From, typename To, typename Y, typename Stream> void ReadWriteConvert(Stream& s, CSerActionUnserialize ser_action, Y& obj, From, To to)
{
    X dummy;
    ::Unserialize(s, dummy);
    obj = to(dummy);
}

]

Copy link
Contributor

@ajtowns ajtowns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK fadf5a7

I think the advantage of using std::chrono is type checking and brevity/simplicity -- being able to say "now + 2h" and have the compiler ensure that everything's using seconds or microseconds or whatever correctly.

So I think it's a problem if we're having to do a lot of manual conversions (via std::chrono::seconds{nTime} and count_seconds(now)), especially doing them in the middle of expressions (eg pinfo->nTime < addr.nTime - count_seconds(update_interval) - nTimePenalty). Most of the type changes here are making the code longer and harder to read, rather than shorter and simpler, for instance...

That's okay while we're in the middle of changing things, I guess; but I think the endgame should be that we're only manually converting to/from microseconds/seconds/hours when we're logging/serializing...

@maflcko maflcko force-pushed the 2203-refactor-addr-relay-time- branch from fadf5a7 to fa62c1b Compare April 7, 2022 11:03
@maflcko
Copy link
Member Author

maflcko commented Apr 7, 2022

Thanks for the review. At this point it seems easier to include the commits in the conflicting pull request.

@maflcko maflcko closed this Apr 7, 2022
@maflcko maflcko deleted the 2203-refactor-addr-relay-time-🌦 branch April 7, 2022 11:35
@maflcko maflcko changed the title refactor: Address relay time refactors refactor: Use type-safe time for address relay Apr 7, 2022
@maflcko maflcko restored the 2203-refactor-addr-relay-time-🌦 branch April 8, 2022 07:42
@maflcko maflcko reopened this Apr 8, 2022
@maflcko
Copy link
Member Author

maflcko commented Apr 8, 2022

Going to reopen this with all refactoring changes split out. Switching adjusted time to system time can then be done with a trivial scripted-diff.

@maflcko maflcko force-pushed the 2203-refactor-addr-relay-time- branch from fa62c1b to fa01898 Compare April 8, 2022 11:25
@jonatack
Copy link
Member

jonatack commented Apr 8, 2022

Skimmed the changes so far, concept ACK.

@maflcko maflcko force-pushed the 2203-refactor-addr-relay-time- branch from fa01898 to fad2021 Compare April 8, 2022 12:09
@ajtowns
Copy link
Contributor

ajtowns commented Apr 9, 2022

Concept ACK, but the "Remove default time arguments" seems to also be switching from adjusted time to GetTime, which seems like a bit more than a refactor for type safety?

Could do: EDIT: (no you can't)

template<class Rep, class Period>
std::chrono::duration<Rep,Period> rand_dur(std::chrono::duration<Rep,Period> max) { ... }

template<class T>
auto rand_seconds(T max) { return rand_dur<std::chrono::seconds>(max); }

@maflcko maflcko changed the title refactor: Use type-safe time for address relay refactor address relay time Apr 9, 2022
/** ... in at least this many days */
static constexpr int64_t ADDRMAN_MIN_FAIL_DAYS{7};
/** ... in at least this duration */
static constexpr auto ADDRMAN_MIN_FAIL{7 * 24h};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps it's a good opportunity to give a better variable name here.
ADDRMAN_FAIL_DUR_UNIT or something

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, happy to do if people agree. Please leave a comment here or upvote glebs comment.

@maflcko
Copy link
Member Author

maflcko commented Jul 19, 2022

Rebased

Copy link
Contributor

@aureleoules aureleoules left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK fad1f55.
I agree that using std::chrono instead of raw ints makes the code easier to read and allows for a better type checking of timestamps.

MacroFake added 6 commits July 26, 2022 11:03
-BEGIN VERIFY SCRIPT-
 ren() { sed -i "s:\<$1\>:$2:g" $(git grep -l "\<$1\>" ./src ./test); }

 ren nLastTry          m_last_try
 ren nLastSuccess      m_last_success
 ren nLastGood         m_last_good
 ren nLastCountAttempt m_last_count_attempt
 ren nSinceLastTry     since_last_try
 ren nTimePenalty      time_penalty
 ren nUpdateInterval   update_interval
 ren fCurrentlyOnline  currently_online
-END VERIFY SCRIPT-
Also, fix includes.

The getter will be used in a future commit.
@maflcko maflcko force-pushed the 2203-refactor-addr-relay-time- branch from fad1f55 to fa64dd6 Compare July 26, 2022 09:06
if (nTime - info.nTime > update_interval)
info.nTime = nTime;
const auto update_interval{20min};
if (time - info.nTime > update_interval) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's unfortunate github highlights time as it's a keyword.

@@ -990,8 +994,9 @@ int AddrManImpl::CheckAddrman() const
int n = entry.first;
const AddrInfo& info = entry.second;
if (info.fInTried) {
if (!info.m_last_success)
if (!TicksSinceEpoch<std::chrono::seconds>(info.m_last_success)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm generally not a big fan of casting 0 to bool :)

@naumenkogs
Copy link
Member

utACK fa64dd6

@fanquake fanquake requested review from mzumsande and dergoegge July 26, 2022 11:57
Copy link
Member

@dergoegge dergoegge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK fa64dd6

{
double fChance = 1.0;
int64_t nSinceLastTry = std::max<int64_t>(nNow - nLastTry, 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit (feel free to ignore): This variable is still being renamed in the scripted diff in the next commit but it no longer exists.

@fanquake fanquake merged commit 9ba7375 into bitcoin:master Jul 27, 2022
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Jul 27, 2022
fa64dd6 refactor: Use type-safe std::chrono for addrman time (MarcoFalke)
fa2ae37 Add type-safe AdjustedTime() getter to timedata (MarcoFalke)
fa5103a Add ChronoFormatter to serialize (MarcoFalke)
fa253d3 util: Add HoursDouble (MarcoFalke)
fa21fc6 scripted-diff: Rename addrman time symbols (MarcoFalke)
fa9284c refactor: Remove not needed std::max (MacroFake)

Pull request description:

  Those refactors are overlapping with, but otherwise largely unrelated to bitcoin#24662.

ACKs for top commit:
  naumenkogs:
    utACK fa64dd6
  dergoegge:
    Code review ACK fa64dd6

Tree-SHA512: a50625e78036e7220a11997e6d9b6c6b317cb38ce02b1835fb41cbee2d8bfb1faf29b29d8990be78d6b5e15e9a9d8dec33bf25fa439b47610ef708950969724b
@maflcko maflcko deleted the 2203-refactor-addr-relay-time-🌦 branch July 29, 2022 14:53
@bitcoin bitcoin locked and limited conversation to collaborators Jul 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants