Direct headers announcement #5982

issue sipa openend this issue on April 8, 2015
  1. sipa commented at 4:40 am on April 8, 2015: member

    Currently, on a new block we send an inv out with the hash of the new tip (and, after #5307, of all new blocks). With headers-first sync, we could instead just send out the headers immediately (they’re only 2.5 larger, and the peer would likely be fetching those anyway).

    To do so, we need several changes:

    1. Have a means of negotiating that the peer wants headers instead of block invs.
    2. Modify the code to send out the headers immediately and bypass sending invs.
    3. Be able to trigger the direct-download fetch strategy based on learned headers. @sdaftuar Are you interested in this? You’ve been doing other block relay improvements.
  2. sdaftuar commented at 1:52 pm on April 8, 2015: member
    Yep I agree this would be good; I’ll think about this for a bit and likely come back to you with a few questions…
  3. sdaftuar commented at 11:49 pm on April 10, 2015: member

    For negotiating headers versus inv’s, I guess the method that occurs to me is to bump the protocol version number, is that what you had in mind?

    It seems to me that the chief problem to solve is making sure that when we send headers to a peer, they will be accepted – not rejected because of a missing prior header. As I understand the code, none of the state we’re currently keeping would tell us what headers a given peer has already seen. The approach I’m working on now would be to start keeping track of the last header we’ve sent a peer, and combine that with pindexBestKnownBlock (best block that the peer has announced to us) to estimate our peer’s best header. Then, in the places where we currently inv a block, I’d send headers to the peer, the range of which I’d calculate by starting at the block being inv’ed, and walking back until I either get to the last header I’ve sent that peer (pindexLastHeaderSent), or pindexBestKnownBlock, or an ancestor of either (ie in the event of a reorg).

    And I was also thinking that in the event that either pindexBestKnownBlock & pindexLastHeaderSent are both NULL or that the above algorithm would generate a too-long headers chain (not sure what value to use here, maybe only be willing to send up to 8 or 16 headers or something?), I’d revert to just sending an inv, and letting the peer figure out what to do. If we let that value be too large, then a node doing initial block download would be inundated with headers from all its peers if a block is announced during the download, which seems undesirable. On the other hand, I want it to not be so small as to be useless during a reorg.

    Any thoughts on this approach?

  4. sipa commented at 10:05 am on April 11, 2015: member

    You’re going further than I imagined, nice :)

    So, for the negotiation: either a protocol version bump, or sending some new and optional (thus otherwise ignored) message type to indicate being fine with being fed headers for block propagation. In either case, this probably requires a small BIP (like BIP 35 or BIP 61).

    I was just thinking about relaying whatever new block index entries become part of our new best block chain (see the code touched by #5307, but send a headers message rather than an inv). Assuming peers actively try to synchronize with us, typically just sending our new best chain entries should suffice to let them keep up.

    Trying to figure out which headers they already have may help of course, but we should avoid trying to push headers to a node that is still in initial sync mode, as that would just slow them down.

    Also, there is currently no infrastructure for avoiding duplication in headers announcement (while there is for inv messages). Perhaps the inv code should be reused/generalized. This may not be necessary if the handling logic is good enough to keep track of which headers a peer has.

  5. sipa commented at 2:05 pm on April 12, 2015: member
    Another random idea: if you want to try to keep track of which headers a peer knows about, you can probably process the entries in the CBlockLocator objects sent in getheaders commands.
  6. sdaftuar commented at 2:20 pm on April 29, 2015: member

    @sipa Thanks – that “random idea” was actually pretty important, I overlooked it initially.

    I believe I have a working implementation of this (it’s still a work in progress but you can see it here: https://github.com/bitcoin/bitcoin/commit/11a8da32f62c69402235c7231e6deb60660c9eea – I introduced a new “sendheaders” p2p message which requests that a peer announce blocks with headers rather than invs).

    I ran into one issue I wanted some advice on; it seems to me that we wouldn’t necessarily want to initiate headers-announcements with all our peers, because if a node has a lot of connections, the additional overhead from sending headers will at some point exceed the savings from eliminating getheaders messages (I think at around 15 or 16 peers).

    One option to address this could be to limit requesting headers announcements to, say, just our outbound peers, which would be a simple way of ensuring we haven’t added any overhead. But that’s not really optimal at all, as I think what we’re really interested in is having the peers that we’re most likely to send a getdata be the ones that announce blocks with headers, which may or may not be our outbound peers.

    An alternative idea would be to track peer getdata requests, so that if a peer’s requests are below some threshold (maybe something like, they’ve requested less than 4 blocks from us out of the last 64), we revert to sending them inv’s rather than headers, even if they have requested headers announcements. But before I go down this road too far I wanted to see if this is a reasonable direction to go at all?

  7. laanwj added the label P2P on May 18, 2015
  8. sipa commented at 6:13 pm on September 24, 2015: member
    Superseded by #6494.
  9. sipa closed this on Sep 24, 2015

  10. sipa reopened this on Sep 24, 2015

  11. sipa commented at 6:14 pm on September 24, 2015: member
    Oops, I forgot this was only an issue.
  12. MarcoFalke commented at 12:26 pm on November 29, 2015: member
    Could be closed, because #7129 is merged?
  13. sipa commented at 12:27 pm on November 29, 2015: member
    Fixed by #7129 (#6494).
  14. sipa closed this on Nov 29, 2015

  15. MarcoFalke locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-18 18:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me