In an attempt to decrease protocol overhead when communicating proposals in the preround
stage, a suggestion has been made to encode the proposal IDs (currently 20-byte blake3
proposal IDs) in a compacted way such that a receiver may attempt to reconstruct the original message using the provided hints, then try to recover the signature provided in the message.
The suggestion made by Dmitry (click) was that a compact encoding be done using SipHash (or HalfSipHash) to compact the proposal IDs. The message signature would be generated using the full proposal IDs prior to compaction with SipHash. The message validation flow could be described as follows:
- A receiver would attempt to reconstruct the message from the compacted proposals.
- A receiver could ask for clarifications from the sender. These subsequent requests are done on a separate 1-1 stateful channel between the peers (not over pubsub).
- The sender would then respond with the full proposal IDs that were requested to disambiguate back to the receiver.
- After a round of possible clarifications the receiver attempts to recover the signature of the message from the content and compares it to the message.
- If the signature validation fails, we again ask the sender for a full clarification, resulting in a message with the full proposal IDs (untruncated
20-byte blake3
IDs). - The receiver attempts a second signature validation
- If the signature validation passes, the message is cached (as to help peers that would be gossiped the same message to inquire about it further down the pubsub cascade)
- Message gossiping continues, with the cached messages evicted within 2 layers
The message exchange (worst case) can be described by the following sequence diagram:
Having already implemented this proposal, the following points should be taken into account:
- We don’t know which collisions are going to happen, because different peers may have different views of proposals in the network
- Therefore a collision (shared prefix of a shortened proposal ID) at the sender does not necessarily mean a collision at the receiver (and vice versa, see next)
- The receiver may have a different proposal that collides with a proposal that the sender does not have (sender has only one proposal that starts with
0x1b
but receiver has two proposals0x1b00
and0x1b01
). Therefore, the sender may provide further data about proposals that share prefixes preemptively however that does not guarantee that this information is of any use to the receiver (since the actual proposals are communicated off-band, not with the preround message). - The interactive approach is flawed because it may open the protocol up to more attacks (i.e. senders that spam the receivers and send them into unnecessary rounds and slowing their processing of messages)
After discussing the matter with @iddo yesterday, we’ve converged on the following approach for now:
- Remove the interactive part completely - no clarification rounds are allowed
- Sender constructs the message by compacting the original proposal IDs (truncates them to 2 bytes)
- For proposals that share prefixes, we add further 4 bytes (implementation details are orthogonal here)
- The message will be signed just as it is now - with the original full proposal IDs, and sent without the full IDs (just compacts)
- If a downstream (receiver) peer receives the message and cannot reconstruct the original (i.e. do the magic and verify the signature), it does NOT gossip the message to other peers
- No message caching is needed in this approach
Some thoughts and concerns I have with this approach are the following:
- If the consensus about the proposals themselves is not strong, we may have a difficulty to guarantee that messages get forwarded as hops increase in the network.
- This may increase splits in the view of the network
- Some network topologies may resolve this
- This approach still doesn’t resolve the problem that the sender does not know which proposal prefixes may collide at the receiver, causing it to never be able to recover the signature
- Today, a situation where the signature cannot be recovered is technically not possible in the
preround
, and I suspect that allowing for a situation where gossip cascades may be interrupted can be dangerous (we don’t have a way to simulate the real network conditions we’re facing) - Perhaps, as a first phase, we could go with a compaction to more than 2-bytes (maybe 6-bytes with possible extra info in case a collision is found) and see if we see any problems in achieving concensus
- Later on we can further lower the size of compacted prefixes and see how that looks
- We may opt-in to test this on mainnet between our own nodes that participate in
hare
and collect metrics on how often collisions happen (only they run the further-compacted-hare variation and use that in parallel)