-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Add Multisignture support #76
Conversation
@mvines @CriesofCarrots First stab, thoughts? |
@@ -8,6 +8,11 @@ use solana_sdk::{ | |||
}; | |||
use std::mem::size_of; | |||
|
|||
/// Maximum number of multisignature signers (max N) | |||
pub const MAX_SIGNERS: usize = 11; | |||
/// Minimum number of multisignature signers (max N) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe this?
/// Minimum number of multisignature signers (max N) | |
/// Minimum number of multisignature signers (min N) |
/// | ||
/// # Accounts expected by this instruction: | ||
/// | ||
/// 0. `[signer]` Multisignature account to initialize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need this account to sign (InitializeAccount/Mint eventually too). Same logic as #67 (comment). usecase: if the account is a derived address, that address literally can't be a signer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, was thinking about that and planning to address that together with the other instructions as a separate change
@@ -51,6 +66,7 @@ pub enum TokenInstruction { | |||
/// 1. `[writable]` Source/Delegate account. | |||
/// 2. `[writable]` Destination account. | |||
/// 3. Optional: `[writable]` Source account if key 1 is a delegate account. | |||
/// 4-14. Optional: `[Signer]` M multisignature Signer accounts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't the 0.
[signer] Owner of the source account.
account disappear?
The single owner concept is implicit 1x1 multisigner account, so it could just be included as the first multisignature Signer account.
That 3. Optional:
[writable] Source account if key 1 is a delegate account.
account is now clunky. I guess it goes away entirely when we drop from supporting N delegate accounts to just 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was planning to keep the single owner support as is which has a shorter code path and less required keys and les user steps then having to implore the multi-sig route for everyone.
Yeah, I thought clunky too, and left it to get suggestions. It would go away if we do single delegate but it's indicative of a clunkiness we will have with other programs in the future especially one's that support a group of optional sigs as multisig support does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeping single owner support makes sense to me. I'd think that from the interface perspective, using a single owner keypair would look identical to using a Multisig
account configured at 1x1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, it looks like with this approach, the multisig account itself always has to be a signer (in order for it to appear as the first account in the metas list and be marked as the owner). That doesn't seem right to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the accounts maybe be something more like this?
* (Multiple) `[signer]` Owner of the source account or M multisignature Signer accounts
1. `[writable]` Source/Delegate account.
2. `[writable]` Destination account.
3. (Optional) `[writable]` Source account if key 1 is a delegate account.
4. (Optional) `[]` Multisignature data account
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking:
/// 0. `[writable]` Source/Delegate account.
/// 1. `[writable]` Destination account.
/// 2. Optional: `[writable]` Source account if key 0 is a delegate account.
/// 2-12, or 3-13. `[Signer]` M multisignature Signer accounts (1 if a single owner address)
or
/// 0. `[writable]` Source/Delegate account.
/// 1. `[writable]` Destination account.
/// 2-M. `[Signer]` M multisignature Signer accounts (M=1 if a single owner address)
/// M+1. Optional: `[writable]` Source account if key 0 is a delegate account.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait that doesn't work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, so the complication of storing the multisig data in a separate account is that its address has to be passed in every time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming we drop the N delegate support, and each token only supports one delegate:
Single owner/delegate:
/// 0. `[writable]` Source account.
/// 1. `[writable]` Destination account.
/// 2. `[Signer]` Owner/delegate address
Multisig owner/delegate:
/// 0. `[writable]` Source account.
/// 1. `[writable]` Destination account.
/// 2. `[]` Multisig account
/// 3-M. `[Signer]` M multisignature Signer accounts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The single delegate simplifies things a lot. I like your suggestion @mvines, removing the "optional" from the docs makes things more clear. For Multisig owner/delegate we should to clarify that the multisig account can either be the owner or the delegate multisig account since the behavior is different between the two
2. '[]' Owner/delegate Multisig account
/// | ||
/// 0. `[signer]` Multisignature account to initialize | ||
/// 1-11. `[]` Signer accounts, must equal to N where 1 <= N <= 11 | ||
InitializeMultisig(u8), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wdyt about including N in the instruction data:
InitializeMultisig(u8), | |
InitializeMultisig {n: u8, m: u8}, |
N is implicit by the number of signer accounts provided but for the cost of an extra 8 bits, adding an explicit N seems to be more readable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do it's adding a possible failure point and more work internally to check that the user didn't mess it up (though on the other hand, it does add redundancy to make sure the user included the intended number of singers to the instruction
@@ -68,6 +85,7 @@ pub enum TokenInstruction { | |||
/// 0. `[signer]` Current owner of the token or account. | |||
/// 1. `[writable]` token or account to change the owner of. | |||
/// 2. `[]` New owner |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document that the new owner can be a Multisig
account?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I debated that, the InitializeMultisig
instruction documentation mentions that the multisig can take the place of any owner, I was avoiding adding a bunch of duplicate verbiage. I'm not opposed to adding it if you think it's worth it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I guess we just need one location that says, "owner could be either a multisig address, in which case M of the N signers must be present, or any other address where the matching signer must be present"
@mvines In general, what do you think of this approach? In particular, identifying the multisig account type by owner and size? Still think we should apply that to |
sgtm. Yeah, I feel like the Mint should support multisig too. |
Mint already supports multisignature since its owner can be a multisignature account. Later My question was what do you think about moving away from |
oh sry. Yep I think so. Ditch the enum entirely. It's weird to use it for some but not all the token accounts |
This PR is rendered obsolete by these changes: jackcmay#1 |
Downstream users would like to be able to ultilize multisignature on Token Accounts. A Multisig program would be an option down the road, when cross-program invocations are enabled.
In the meantime, the shortest path seems to be to add M-of-N multisig support in Token.
Instead of just one account owner, enable configuration of each Token account to have N authorities (1 <= N <= 11) and M required signers for transfers and updates to authorities and num-required-signers.
WIP TODO:
Fixes: #49