Closed
Conversation
Contributor
Author
|
Likely improvement: flush adverts to all peers after a given buffer-read rather than just the peer the read finished on. |
df69ba1 to
90a1bb5
Compare
90a1bb5 to
56af488
Compare
56af488 to
5582869
Compare
5 tasks
Contributor
|
this was replaced by #3479 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull-mode flooding
High-level explanation of changes:
The change aims to reduce the amount of redundant flood-type traffic (that is, a message received by a peer along multiple connections). It does so in a very conventional fashion: switching from "eager" to "lazy" flooding.
Specifically, flood-type traffic is no longer propagated to neighbours as soon as it's received; rather it's advertized with much smaller and denser batches of short (64 bit SIPHash-2-4) keyed hash codes. Advertisements are sent fairly often but there's a slight buffering delay to allow combining a decent-sized number of them into a single message. When an advertisement is received, the receiver immediately responds with a demand for all the hashes it hasn't yet seen, which the sender then immediately sends using the existing message types. Since advertisements are typically less than a tenth the size of the messages they're advertizing, this reduces the total traffic accordingly.
This change only modifies the flow of data between the floodgate and the IO queues -- data we've already committed to informing our neighbours about. It is thus fairly narrow and late in the full set of system queueing disciplines, and does not change most decisions around tx-queue throttling, surge-pricing, SCP rebroadcasting, etc.
It also only modifies flood traffic -- fetch traffic is unaffected.
It does add 2 WAN RTTs to flood traffic latency, and adds two possible attack vectors (that I am aware of):
The change can coexist with existing (eager) connections that do not yet support lazy flooding, and in fact can decide message-by-message which mode to use, so one way to further mitigate both the cache-poisoning vectors and any potential latency problems is to vary the entire flooding strategy stochastically (eg. send 75% of traffic lazily and 25% eagerly). My plan is to do this and make it a config option, because it's a simple dial to understand and also allows the operator to just turn it off if it's misbehaving.
A more sophisticated strategy could opt to set a per-link policy to construct (eg.) an eager spanning tree with a backup lazy mesh (as in plumtree) but this has potentially more complex/fragile dynamics so I am deferring it for now.
As a "prior art" / comparing-notes aside: this is similar to Bitcoin Core's "compact block" / low-bandwidth mode BIP-152 except they use even smaller 6-byte truncated SipHash-2-4s (again keyed with the previous block hash).
Detailed explanation of changes:
The overlay protocol gets 2 new message types:
FLOOD_ADVERT: a list of short hashes available to be sentFLOOD_DEMAND: a list of short hashes requested to be sentEach
Peerobject gets 2 new fields:FLOOD_ADVERT, which accumulates outgoing 64-bit advert-codes (until it's ready to be flushed)The
Peerflushes its pending advert (sending it to its remote peer) on the earliest of 3 conditions:Floodgate::FloodRecordgets 2 new fields:The
FloodGategets 2 new maps:FloodRecords inmFloodMapThe implementations of
FloodGate::{addRecord,broadcast}are partly merged into a newFloodGate::insertmethod, andbroadcastis modified to push an advert into aPeer's pendingFLOOD_ADVERTwhen possible rather than sending a full eager message.FloodGateandOverlayManagerget 2 new methods:demandMissing, called in response to receivingFLOOD_ADVERT. Sends aFLOOD_DEMANDfor all the not-yet-known messages in the advert.fulfillDemand, called in response to receiving aFLOOD_DEMAND. Sends all the messages that were demanded.