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

[Design]: Aggregating Signer Votes in Clarity #36

Closed
3 tasks done
AshtonStephens opened this issue Apr 3, 2024 · 7 comments
Closed
3 tasks done

[Design]: Aggregating Signer Votes in Clarity #36

AshtonStephens opened this issue Apr 3, 2024 · 7 comments
Assignees
Labels
clarity The clarity smart contracts. design making a design decision. sbtc bootstrap signer The sBTC Bootstrap Signer. signer communication Communication across sBTC bootstrap signers. signer coordination The actions executed by the signer coordinator.

Comments

@AshtonStephens
Copy link
Collaborator

AshtonStephens commented Apr 3, 2024

Completing the issue description and arriving at a conclusion is the deliverable of this issue.

Design - Aggregating Signer Votes in Clarity

This ticket holds the design of how signer votes will be aggregated in Clarity and how it fits into sBTC-v1. Relates to the research in #33, where we determined that schnorr signatures cannot be verified in Clarity without changes to Clarity to support secp256k1.

1. Summary

In sBTC, signers will have to collectively make smart contract calls on Stacks. To ensure consensus, we'd ideally require them to sign their calls with aggregate signatures. However, since Clarity does not support Schnorr signature validation, we have no means of verifying an aggregate signature in Clarity.

Instead, we will require each signer to individually sign any Clarity contract call and ensure at least 70% of the signer signatures are present for each contract call to be valid.

2. Context & Purpose

To support deposits and withdrawals in sBTC, Signers must collectively make smart contract calls. These calls must have some sort of authorization mechanism to ensure not anyone (not even a bad signer) can make malicious calls.

Relevant Research Discussions
#33
#16

3. Design

3.1 Proposed Component Design

Any contract call made by signers takes an extra signatures parameter, which is a list of ECDSA signatures over a payload containing the function name and all parameters passed to the function call. The list should contain valid signatures from at least 70% of the signers to be considered valid.

3.1.1 Design Diagram

N/A

3.1.2 Considerations & Alternatives

An alternative would be to replace each single contract call with a voting mechanism, where each individual signer votes for the parameters of the call. This would lead to an excessive amount of sBTC transactions and fees, and is therefore less preferable to the proposed solution.

3.2 Areas of Ambiguity

We have not clearly defined the format of the signatures or how the logic for validating them looks in detail.


Closing Checklist

  • The design proposed in this issue is clearly documented in the description of this ticket.
  • Everyone necessary has reviewed the resolution and agrees with the proposal.
  • This ticket has or links all the information necessary to familiarize a contributor with the design decision, why it was made, and how it'll be included.
@AshtonStephens AshtonStephens added the design making a design decision. label Apr 3, 2024
@AshtonStephens AshtonStephens added this to the Low Level Design milestone Apr 3, 2024
@netrome
Copy link
Contributor

netrome commented Apr 4, 2024

I've added the proposed solution with a list of ECDSA signatures from the signers which we discussed yesterday. I'm curious to know if we need to sign anything beyond the function name and all parameters passed to it. If all function calls are idempotent and unique, that should be sufficient. Otherwise, we might need to add some unique key to the payload and as an argument to prevent replay attacks.

@netrome
Copy link
Contributor

netrome commented Apr 4, 2024

Once we close this, we must update the smart contract call definitions in #16 and #15

@netrome
Copy link
Contributor

netrome commented Apr 4, 2024

If we can reuse the voting mechanism from sBTC Mini, we might consider doing that instead #27

@AshtonStephens
Copy link
Collaborator Author

What will it take to nail down the approach such that we're as close to unequivocally comfortable with it as possible?

@netrome
Copy link
Contributor

netrome commented Apr 5, 2024

What will it take to nail down the approach such that we're as close to unequivocally comfortable with it as possible?

Good question. Since we're looking at two possible directions here, one based on voting and the other one based on verifying a batch of signatures I'd like to know:

  1. What is simpler from the Signer perspective? Each signer passing a signature to the coordinator before the coordinator creates a contract call, or each signer making their own contract call directly and broadcasting it?
  2. What is simpler in Clarity? Vote aggregation logic or signature verification logic?
  3. What is easier to implement in Clarity given that we already have some voting logic in place?

My take is that 1. and 2. both favor the signature batch. Moreover, after looking deeper into the voting logic in #27 (comment) I also believe it would take a significant effort to port it, compared to simply having logic for calling secp256k1-verify on a list of signatures over a message obtained by calling to-consensus-buff on the function arguments (and possibly some more information).

I'd love to hear thoughts on this reasoning from @setzeus and @hstove regarding the Clarity bits and @xoloki and @jferrant for the Signer part. If we all agree, we have a way forward. If we don't, there's more to explore here.

@setzeus
Copy link
Collaborator

setzeus commented Apr 5, 2024

  1. In general cheaper is better for signers so if signers can communicate all signatures or votes to coordinator before the contract acll that seems optimal
  2. Both are fairly trivial in Clarity. I imagine one would be a list of binary uints (0 | 1) [or maybe just the aggregate 'yays' as as single uint] & the other would be a list of signatures. Adding the signatures & checking if aggregate > 4 is straight-forward. Checking a list of small signatures also fairly straight-forward.
  3. Voting with a single uint, small task, voting with a list of uints, small task, voting with signatures, simple medium task.

I feel strongly about a single contract call vs. many (ie coordinator vs. per-signer) but don't feel necessarily strong towards the voting mechanic for aggregating signer votes either. I guess if I had to choose I'd lean towards consuming a list of signatures for visibility. As a user, if rejected, I'd like to see a live tally of the votes on a block explorer.

@AshtonStephens
Copy link
Collaborator Author

tl;dr: Instead of making a single signature using the threshold calculation we just send a list of ECDSA signatures that clarity actually supports and require that for the aggregate signer voting to be valid.

@netrome netrome closed this as completed Apr 5, 2024
@8marz8 8marz8 mentioned this issue Apr 8, 2024
3 tasks
@AshtonStephens AshtonStephens added sbtc bootstrap signer The sBTC Bootstrap Signer. signer coordination The actions executed by the signer coordinator. signer communication Communication across sBTC bootstrap signers. clarity The clarity smart contracts. labels Apr 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clarity The clarity smart contracts. design making a design decision. sbtc bootstrap signer The sBTC Bootstrap Signer. signer communication Communication across sBTC bootstrap signers. signer coordination The actions executed by the signer coordinator.
Projects
None yet
Development

No branches or pull requests

3 participants