entropyxyz / manul

Round-based distributed protocols
https://docs.rs/manul
GNU Affero General Public License v3.0
6 stars 1 forks source link

Logic fixes for rounds with partial echo #67

Closed fjarri closed 1 week ago

fjarri commented 3 weeks ago

Fixes #21

Imagine the following round configuration (which is possible during KeyResharing from synedrion):

After we received the initial broadcasts, we want an echo round where the nodes 1, 2, 3 echo received messages to each other. That is:

(note that node 1 does not send its broadcast the second time; that would be pointless)

This requires adding another method to Round specifying the exact behavior of the node, since this information cannot be obtained from existing methods. This PR introduces Round::echo_round_participation() and EchoRoundParticipation enum.

In most cases we can use the blanket implementation returning EchoRoundParticipation, which means that the node either sends and receives echo messages, or does neither. This means that we can deduce the properties of the echo round from Round::message_destinations() and Round::expecting_messages_from(). The case where the node only sends echo messages (node 0), we don't need any additional info other than this fact. For the case where the node only receives echo messages (node 3), it needs additional info specifying which nodes actually participate in the echo round.

Edit: another possible API here is to get rid of EchoRoundParticipation enum and instead have a method returning Option<BTreeSet<Id>>. None would cover both Default and Send, and we will distinguish between them by checking if expecting_messages_from() is empty or not. Would that work?

coveralls commented 3 weeks ago

Pull Request Test Coverage Report for Build 11864171410

Details


Totals Coverage Status
Change from base Build 11864158435: 0.8%
Covered Lines: 1773
Relevant Lines: 2539

💛 - Coveralls
fjarri commented 3 weeks ago

but I'm kind of stuck in my head on why we need this (despite the great PR description).

This is the exact scenario of what's happening during KeyResharing. There is a set of nodes that sends broadcasts, and there is a set of nodes that receives broadcasts, and these sets are not equal (maybe not even intersecting). The ones that send broadcasts are the old holders of key shares, and the receivers are the new holders.

The assumption I'm making here is that only the "target" nodes will need to participate in the echo round, making sure they each received the same messages; the senders can do without.

E.g. in the partial_echo test, how should I think about a real world scenario there? Would node 0 be like a "dealer" of some sort, broadcasting but not participating? And what would node 4 be, given it's not participating at all?

The node 4 is just to cover all possibilities, that's something that doesn't happen during KeyResharing.