Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vote stapling #1006

Closed
wants to merge 46 commits into from
Closed

Vote stapling #1006

wants to merge 46 commits into from

Conversation

PlasmaPower
Copy link
Contributor

@PlasmaPower PlasmaPower commented Jul 28, 2018

Simple explanation:
With vote stapling, when a node publishes a block, it will first communicate directly with representatives to make an aggregate signature. Then, the node will publish the block along with the aggregate signature in the same message. The aggregate signature is the same size as a normal signature, because it uses a multisignature protocol called MuSig: https://blockstream.com/2018/01/23/musig-key-aggregation-schnorr-signatures.html. This means that we can package up the entire voting process into the size of one vote.

Protocol explanation (knowledge of the MuSig protocol in the link above is required):

  1. musig_stage0_req: The block publisher sends a packet to top representatives containing the block it wants to publish, the rep it's looking for (or the burn address if it's blindly broadcasting), and a signature of that info with its node ID.
  2. musig_stage0_res: The representative responds with an R value for this session (referred to as rB in the code to prevent confusion with r), a request ID equal to the representative address xor the block hash, and a signature of that info as the representative.
  3. musig_stage1_req: Once the block publisher has received enough stage0 responses such that the vote weight totals at least 70% of the online stake, it will send a stage1 request containing the total R value, a hash of the public keys I'm calling l_base (in this scheme each participant's public key is H(H(pk[0] || pk[1] || ... || pk[n]) || pk[i]), and the inner hash is l_base), and a signature of that info with its node id.
  4. musig_stage1_res: The representative responds with an s value computed from that information and its r value. It deletes the stage0 info, but it caches the s value for a bit so that repeat requests can still get the s value.
  5. publish_vote_staple: The block publisher broadcasts the block, the signature, and the xor of all of the representatives used for signature (this is limited to the top 127 reps, so linear algebra is used to reverse the process and discover which representatives are in the signature). Other nodes check if the reps have quorum, and if the signature matches. If it checks out, the node processes the block, then rebroadcasts the packet.

TODO:

  • Write up a description of what this actually is
  • Fix node.send_single_many_peers (initialization fails)
  • Fix sporadic node.auto_bootstrap failure (may not be related to vote stapling, not sure) seems unrelated
  • Add tests specific to vote stapling (maybe some more, though this seems good)
  • Cleanup old stuff in vote_stapler and vote_staple_requester
  • Add additional validation before signing something (a bit of active graph?)
  • When increasing publish PoW, change how rebroadcast_info works to stick with vote stapling even if weight is low
  • Implement automatic rep blacklisting in case of bad behavior
  • Change RPC publish to use vote stapling when possible
  • Maybe support many to many request id to block hash mappings
  • Wallet queueing probably needs fixing with this: immediate process should fix this
  • Maybe prevent precomputing
  • Either add timestamps or store stapled votes in DB

{
chunks_xor ^= matrix[i][chunk] & free_cols_flip[f][chunk];
}
if (__builtin_parityl (chunks_xor))
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe add msvc compatibility to the PR's TODO list ? Possibly a compiler specific macro that does __builtin_popcount (gcc) or __popcnt (msvc) with an LSB mask.

@@ -125,7 +125,8 @@ TEST (node, send_single_observing_peer)
}
}

TEST (node, send_single_many_peers)
// TODO: rai::system fails to connect peers
TEST (node, DISABLED_send_single_many_peers)
Copy link
Contributor

Choose a reason for hiding this comment

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

Due to the max_peers_per_ip reduction it seems

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, nice catch. Thank you very much. I was wondering how that happened.

@PlasmaPower PlasmaPower added this to the V16.0 milestone Jul 30, 2018
@PlasmaPower PlasmaPower force-pushed the vote-stapling branch 4 times, most recently from 4b40cd4 to cac166e Compare August 19, 2018 01:39
@rkeene rkeene modified the milestones: V16.0, V17.0 Aug 22, 2018
@PlasmaPower PlasmaPower force-pushed the vote-stapling branch 2 times, most recently from 9b0b07d to 46062ea Compare August 24, 2018 02:55
@rkeene rkeene added the major This item indicates the need for or supplies a major or notable change label Aug 24, 2018
@rkeene
Copy link
Contributor

rkeene commented Sep 12, 2018

I'm moving this to V19 (V18 is still intended to be cleanup) since it will likely not be ready to merge in time for V17 and we don't want to rush the work on such a large change.

@rkeene rkeene modified the milestones: V17.0, V19.0 Sep 12, 2018
@funkspock funkspock mentioned this pull request Feb 23, 2019
@PlasmaPower
Copy link
Contributor Author

Some weaknesses have been found in the 2 round MuSig, so we'd definitely need to implement this with the 3 round MuSig or a pairing based multisignature scheme. I'm closing this PR because it's very out of date now, and a future implementation would probably need to be separate.

@zhyatt zhyatt removed this from the Research for Future Release milestone Feb 23, 2019
@argakiig argakiig deleted the vote-stapling branch May 20, 2019 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement major This item indicates the need for or supplies a major or notable change release_blocker
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants