Skip to content

Conversation

maflcko
Copy link
Member

@maflcko maflcko commented Mar 24, 2022

This changes addrman to use system time for address relay instead of the network adjusted time.

This is an improvement, because network time has multiple issues:

  • It is non-monotonic, even if the system time is monotonic.
  • It may be wrong, even if the system time is correct.
  • It may be wrong, if the system time is wrong. For example, when the node has limited number of connections (4), or the system time is wrong by too much (more than +-70 minutes), or the system time only got wrong after timedata collected more than half of the entries while the time was correct, ...)

This may slightly degrade addr relay for nodes where timedata successfully adjusted the time. Addr relay can already deal with minor offsets of up to 10 minutes. Offsets larger than this should still allow addr relay and not result in a DoS.

@laanwj
Copy link
Member

laanwj commented Mar 24, 2022

Concept ACK

@maflcko maflcko closed this Mar 24, 2022
@maflcko maflcko reopened this Mar 24, 2022
@maflcko maflcko force-pushed the 2203-add- branch 2 times, most recently from faf47e5 to fafd77b Compare March 24, 2022 19:05
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.

Concept ACK

I think that this line in net_processing should be changed too, otherwise we'd still use adjusted time for addr relay.

However, addr relay can already deal with minor offsets of up to 60 minutes

Where does the 60 minute number come from? 

I can think of the following relevant times:
When receiving addr messages (relevant code):

  • If nTime is >10 minutes in the future relative to our time, we backdate nTime to (OurTime - 5days) for addrman and don't relay it further. 
  • If nTime is >10 minutes in the past, we don't relay it further (but accept it to addrman).

This means that addr gossip relay is relatively sensitive to what we think is the right time. If our time is off by more than 10 minutes, we will most likely not take part in it and not forward addresses received from others.
That would not prevent us from accepting addrs to addrman / finding outbound peers. But we wouldn't help the network and our own advertised address would be off by 10 minutes and not relayed by others as well, so we'd likely have a harder time getting inbound peers.

For GETADDR, we treat addresses as Terrible and don't include them in a GETADDR response if:

  • If nTime is more than 10 minutes in the future (unlikely to happen, we would have backdated nTime if it was in the future when receiving it in the first place)
  • If nTime is older than 30 days

So I think that GETADDR responses are not very sensitive at the time scales of AdjustedTime (minutes), especially since they are only calculated only every ~24h (GETADDR caching).

@naumenkogs mentioned here the possibility of fingerprinting:

Also, making it further from mainstream (not using adjusted time) might add more fingerprinting capabilities by looking at those timestamps, for nodes with broken clocks (and mildly for the rest, as a consequence)

I think that's an interesting question, there are probably two aspects:

  • Active, targeted fingerprinting by trying to adjust the time of a peer is made impossible by this.
  • Passive fingerprinting of nodes that happen to be a few seconds off (which could have been corrected by the network before) could become easier.

@maflcko maflcko marked this pull request as draft March 25, 2022 16:20
@DrahtBot
Copy link
Contributor

DrahtBot commented Mar 25, 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:

  • #25619 (net: avoid overriding non-virtual ToString() in CService and use better naming by vasild)

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.

@naumenkogs
Copy link
Member

naumenkogs commented Mar 28, 2022

Concept ACK.


This means that addr gossip relay is relatively sensitive to what we think is the right time. If our time is off by more than 10 minutes, we will most likely not take part in it and not forward addresses received from others.
That would not prevent us from accepting addrs to addrman / finding outbound peers. But we wouldn't help the network and our own advertised address would be off by 10 minutes and not relayed by others as well, so we'd likely have a harder time getting inbound peers.

I was thinking more about our own peer selection in this case, especially deprioritizing in the context of 10+ minutes in the future get 5 days of penalty.

I don't think this PR significantly worsens any existing behavior or opens any new attack surface.

For the "natural" behavior, it doesn't matter much because addr relay freshness has a lag of hours, not minutes (maybe an issue with immediate self-announcements, but those are already connected).
For the attacks, an attacker could always manipulate the addr timestamps how they wanted, and this PR doesn't make it easier.


Re fingerprinting, I think that would be cool to investigate even for the current master.


Otherwise I agree with the summary of @mzumsande.

@mzumsande
Copy link
Contributor

I was thinking more about our own peer selection in this case, especially deprioritizing in the context of 10+ minutes in the future get 5 days of penalty.

If I'm not missing something, we don't deprioritize based on nTime: In GetChance() which is called from Addrman::Select_(), there is logic to deprioritize based on (possibly failed) earlier attempts to connect, but I didn't find any influence of the timestamp on our own peer selection.

@maflcko maflcko changed the title addrman: Use sytem time instead of adjusted network time addrman: Use system time instead of adjusted network time Mar 28, 2022
@maflcko
Copy link
Member Author

maflcko commented Mar 28, 2022

I think that this line in net_processing should be changed too, otherwise we'd still use adjusted time for addr relay.

Good catch, fixed.

Where does the 60 minute number come from?

Thanks, fixed up. I think I incorrectly interpreted 600 as 60 minutes, whereas it is 10 minutes.

Passive fingerprinting of nodes that happen to be a few seconds off (which could have been corrected by the network before) could become easier.

Bitcoin Core will already send it's system time in the version message. See commit 14ba286, so I don't think fingerprinting gets worse by this?

@maflcko
Copy link
Member Author

maflcko commented Mar 28, 2022

An alternative idea to this pull (not sure if serious):

Since we "know" the time offset for each peer, at least incoming ones (and outgoing ones after commit 14ba286), an alternative might also be to adjust the timestamp of each addr message on receipt by the peer-specific offset. This would get rid of adjusted time, but presumably limit the slight negative effects of our clock being wrong on addr relay?

@laanwj
Copy link
Member

laanwj commented Apr 6, 2022

An alternative idea to this pull (not sure if serious):

It's an intriguing idea, but I don't think it's worth it. Peers that have time offsets large enough for this to matter are probably unreliable anyway, and if our own time is wrong for even a short while, when it gets corrected the entire addrman db has wrong lastseen timestamps. It's also quite some extra complexity to test.

@maflcko
Copy link
Member Author

maflcko commented Apr 6, 2022

Right, this is probably not worth to look into due to the complexity and questionable benefit.

I'll rebase the changes here once #24697 is merged.

@fanquake
Copy link
Member

fanquake commented Apr 7, 2022

Concept ACK

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

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

Concept ACK on the refactorings, modulo "addrman: Use system time instead of adjusted network time" that I think it would be wiser to hold off on for the time being (pun intended) (edit: or maybe code it in a way that is easily reversible).

fanquake added a commit 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 #24662.

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

Tree-SHA512: a50625e78036e7220a11997e6d9b6c6b317cb38ce02b1835fb41cbee2d8bfb1faf29b29d8990be78d6b5e15e9a9d8dec33bf25fa439b47610ef708950969724b
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 marked this pull request as ready for review July 30, 2022 09:04
@fanquake fanquake requested review from mzumsande and dergoegge July 30, 2022 09:33
@dergoegge
Copy link
Member

Code review ACK fadd8b2

@fanquake fanquake merged commit e038605 into bitcoin:master Aug 5, 2022
@maflcko maflcko deleted the 2203-add-🔍 branch August 5, 2022 08:10
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Aug 5, 2022
…work time

fadd8b2 addrman: Use system time instead of adjusted network time (MarcoFalke)

Pull request description:

  This changes addrman to use system time for address relay instead of the network adjusted time.

  This is an improvement, because network time has multiple issues:

  * It is non-monotonic, even if the system time is monotonic.
  * It may be wrong, even if the system time is correct.
  * It may be wrong, if the system time is wrong. For example, when the node has limited number of connections (`4`), or the system time is wrong by too much (more than +-70 minutes), or the system time only got wrong after timedata collected more than half of the entries while the time was correct, ...)

  This may slightly degrade addr relay for nodes where timedata successfully adjusted the time. Addr relay can already deal with minor offsets of up to 10 minutes. Offsets larger than this should still allow addr relay and not result in a DoS.

ACKs for top commit:
  dergoegge:
    Code review ACK fadd8b2

Tree-SHA512: b6c178fa01161544e5bc76c4cb23e11bcc30391f7b7a64accce864923766647bcfce2e8ae21d36fb1ffc1afa07bc46415aca612405bd8d4cc1f319c92a08498f
@bitcoin bitcoin locked and limited conversation to collaborators Aug 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants