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

Extend multisig contract with weights #285

Closed
4 of 5 tasks
ethanfrey opened this issue Jan 22, 2019 · 11 comments · Fixed by #416
Closed
4 of 5 tasks

Extend multisig contract with weights #285

ethanfrey opened this issue Jan 22, 2019 · 11 comments · Fixed by #416

Comments

@ethanfrey
Copy link
Contributor

ethanfrey commented Jan 22, 2019

We want to allow for election scenarios to happen off-chain. In many cases, different actors will have different voting power (just like validators).

We can do much of the vote aggregation off-chain, and use a multi-sig contract to control execution. However, it is missing the ability to provide different voting power to different keys.

Two proposal:

  • Extend multisig to allow variable voting power per key (default to 1 if not defined for backwards compatibility)
  • Define a new "voting" contract that contains different weights per key (and maybe other features?)

Decision

We will update the existing multisig to hold a weight per voter. However, there is no need for backwards compatibility if we can get this into a 0.12.x on zebranet, as so far we have no client code outside of this repo that uses the multi-sig feature.

  • Add a weight (uint8?) value along with each address, in all models and messages for multisig
  • Support reading this weight from genesis file as well
  • Enforce a range for weights, 0 < x < 256 (reject any tx/init with missing weights, weight=0)
  • Update all logic to use the weights to calculate if it meets threshold
  • Note breaking change in the CHANGELOG

Technical Spec

  • Weight: 1-255
  • ActivationThreshold: > 0 && <= sum of all weighted signatures
  • AdminThreshold: >0 < 2^63 ( can be > total sum of weighted signatures to lock contract)
  • Max signatures in a contract: 100 to prevent cpu burning
  • Cost is proportional to number of signatures
  • Contract must have 1 member with weight > 0

To think about...

Currently the multisig.UpdateContractMsg behaves like a POST and overwrites the existing contract with a new state. All fields must be set like the original Create. However, the zero-value is illegal for all fields. We could modify this to PATCH and Update will only overwrite the fields defined. This means:

  1. Admin and Activation Threshold of 0 means "don't change"
  2. No Sigs means "don't change"

If there are Sigs, we must clarify what that means... overwrite current set with that new set? or do a diff, like with validators... setting weight=0 to mark current members for removal, and positive weight to update or add a member.

We could also allow CreateContractMsg, UpdateContractMsg (POST) and PatchContractMsg (ony apply diff.

(Read below in comments to see some example usages from @alpe 's doc)

@alpe
Copy link
Contributor

alpe commented Mar 1, 2019

I am voting for option 1. :-)

I have seen the weight in multisig contracts at stellar before and it made sense for me as it enables more use cases than the equal weight contract. No need to restrict this to "voting" scenarios IMHO.

@ethanfrey ethanfrey added validated design Needs design work and removed validated labels Mar 4, 2019
@ethanfrey
Copy link
Contributor Author

@alpe please propose a clear spec for this...

eg. max weight

how to handle weight: 0 vs weight: missing (the second is the same as weight: 1, the first??) - this is both for protobuf and init file. how to detect this even???

ensure backwards compatibility for old clients

how to properly remove members from the mutlisig

maybe some ideas for test cases that should be covered (tricky conditions)

@ethanfrey
Copy link
Contributor Author

Nice link to stellar by the way. I don't really understand why a transaction shoulf fail if it has too many signatures, but there are lots of good ideas there, seem like more thought out versions of much of what I have designed and built in weave. We can gladly incorporate some inspiration from that.

@alpe
Copy link
Contributor

alpe commented Mar 8, 2019

Q: How many members (individual signatures) do we need to support within the voting use case?
Just to clarify: with the multisig, we won't catch the No votes nor can we enforce a timeout on the process. This needs to be handled off-chain in a transparent way.

@ethanfrey
Copy link
Contributor Author

Yes for no votes and timeouts, we need a different contract.
However, there is an implicit timeout if any of the signers use their account for anything else and thus invalidate the nonce.

I would say this only works for short-period voting for a relatively small group of people (eg. 30 for governance). For general voting, you are right, it is missing many features.

It may also be useful for some sort of social backup. Like using a 3 of 7 multisig to hold my balance... I have 3 votes, 4 of my friends each have one. If I cannot access my account, I need to get 3 of those 4 to update my key (multisig member).

Maybe we should be more explicit about possible uses before going deeper in the design

@alpe
Copy link
Contributor

alpe commented Mar 11, 2019

Signatures verification consume significant CPU resources. Of course, using a dozen of signitures for each submitted transaction won't result in the network congestion, however it can slow down ledger closing. Therefore, it's rather a protection from lazy developers which may tend to use as many signers as possible in multisig schemes in order to avoid coding elaborate algorithms and dealing with thresholds.

https://stellar.stackexchange.com/questions/2291/why-can-a-multisig-transaction-fail-on-too-many-signers/

@ethanfrey
Copy link
Contributor Author

Nice, but you can also increase the gas cost / minimum fee for the signatures. Not to be put a hard limit, but rather charge for it.

@ethanfrey ethanfrey added validated and removed design Needs design work labels Mar 14, 2019
@ethanfrey
Copy link
Contributor Author

@ethanfrey will review @alpe spec document https://docs.google.com/document/d/1J3zUUKw06E6yLviwrRUlVMO_MMa_NDxgov3xlmLctrs/edit and integrate it into the above requirements.

Please pause work on this issue until requirements are clarified (before Wednesday)

@ethanfrey
Copy link
Contributor Author

Scenario

To make use of the weighted multisig contract the following examples describe some use cases which are inspired by the Stellar doc.

Stellar Example 1: Anchors

A backup master key + Signing key

  • Master key weight: 1
  • Signing key weight: 1
  • ActivationThreshold: 1
  • AdminThreshold: 2

Stellar Example 2: Joint Accounts

Any of 3 people can authorize a Tx but only all of them together change the contract

  • First person key weight: 1
  • Second person key weight: 1
  • Third person key weight: 1
  • ActivationThreshold: 1
  • AdminThreshold: 3

Stellar Example 3: Company Accounts

Any 3 of 6 employees need to agree for a Tx

  • Everybody's key weight: 1
  • ActivationThreshold: 3
  • AdminThreshold: 3..?

Stellar Example 4: Expense Accounts

The contract is controlled by 1 admin but Diyuan or Emil can authorize TX, too. Only the Admin can modify the contract, though.

  • Admin key weight: 3
  • Diyuan's key weight: 1
  • Emil's key weight: 1
  • ActivationThreshold: 1
  • AdminThreshold: 3

Lock an account

A signing key can authorize TX but the contract is locked and can not be modified anymore

  • Signing key weight: 1
  • ActivationThreshold: 1
  • AdminThreshold: 2 ( > sum of all weighted signatures)

@husio
Copy link
Contributor

husio commented Mar 20, 2019

For the last example Lock an account this was originally not possible as the validation was preventing from creation with such configuration. Maybe instead of using admin threshold greater than sum of weights it is better to add a random signature to bump the total weight value.

@ethanfrey
Copy link
Contributor Author

We could also consider changing the validation.
Activation threshold must always be reachable.
Admin maybe not??

I just didn't want people to remove a member and accidentally render the contract un-usable

husio added a commit that referenced this issue Mar 21, 2019
- update authentication to consider signature weights
- cleanup tests and code
- redo handlers tests

resolve #285
husio added a commit that referenced this issue Mar 21, 2019
`x/multisig` extension was updated and now each signature is having a
weight that defines what is the power of that signature.

- each signature power/weight must be greater than 0,
- activation threshold must be less or equal to the sum of all signature
  powers,
- admin threshold can be greater than the sum of all signature powers.
  This can be used to create a contract that can be only activated but
  never changed,
- multisig contract must have at least one participant/signature
  declared,
- maximum number of participants is 100 in order to prevent CPU burning,

resolve #285
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants