Repository navigation
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| /// The keypair at `path` to sign as some role, defaulting to [`Self::payer`]. | ||
| /// A Squads vault can't co-sign with other keypairs, so `path` is rejected | ||
| /// when proposing. | ||
| pub fn signer_or(&self, path: Option<String>) -> anyhow::Result<TxSigner<'_>> { | ||
| match (&self.squads, path) { | ||
| (Some(squads), None) => Ok(TxSigner::Vault(squads.vault)), | ||
| (Some(_), Some(path)) => anyhow::bail!( | ||
| "can't sign with {path} when proposing to a Squads multisig: the vault signs instead" | ||
| ), | ||
| (None, path) => read_keypair_or(path, &self.signer).map(TxSigner::Keypair), | ||
| } | ||
| } |
There was a problem hiding this comment.
some background on this function as it was kind of confusing when I first read it:
its used in cases where a secondary/co-signing key may be supported. The problem is squads does not support co-signing/being an additional signer, so we need to provide a function here to make sure the user doesn't expect their keypair to be used when it actually isn't.
| Some(index) => multisig.approve( | ||
| &member, | ||
| squads.vault_index, | ||
| ixs, | ||
| &multisig.fetch_transaction(&self.rpc, index)?, | ||
| )?, |
There was a problem hiding this comment.
this approve function is actually doing a lot of heavy lifting. While it doesn't look like it, it validates that the vault_index and ixs match up to the fetched transaction on line 122. If everything is good, it adds a signature to the multisig.
| ixs, | ||
| &multisig.fetch_transaction(&self.rpc, index)?, | ||
| )?, | ||
| None => multisig.propose(&member, squads.vault_index, ixs)?, |
There was a problem hiding this comment.
this also does some heavy lifting. its actually 3 instructions (VaultTransactionCreate, ProposalCreate, and ProposalApprove) rolled into one!
| const SEED_PREFIX: &[u8] = b"multisig"; | ||
| const SEED_VAULT: &[u8] = b"vault"; | ||
| const SEED_TRANSACTION: &[u8] = b"transaction"; | ||
| const SEED_PROPOSAL: &[u8] = b"proposal"; | ||
|
|
||
| /// `Permissions` mask bits a member needs to propose and to vote. | ||
| const PERMISSION_INITIATE: u8 = 1 << 0; | ||
| const PERMISSION_VOTE: u8 = 1 << 1; |
There was a problem hiding this comment.
apparently these seeds weren't, or are not able, to be included as part of the actual IDL or read from the generated codama library. sorry.
…ty-to-submit-transaction-to-a-squads-multisig-to
…ty-to-submit-transaction-to-a-squads-multisig-to
Description
Add
--multisig-addressglobal option, which allows for redirecting any transaction to be sent via the test cli to come through a Squads Multisig instead.Motivation
As we near launch, we need a way to propose transactions efficiently and safely. We are already executing many management operations via EOAs with the test cli, so being able to do this the same way would be very natural.
Implementation Strategy
Squads Instruction Setup & Encoding
3 operations need to be executed on the Squads multisig to stage and be the initial signer for a transaction:
VaultTransactionCreate-- writes the details of what should be executed on-chainProposalCreate-- creates a PDA to tally the votesProposalApprove-- approves the proposed transaction with a signerSquads provides an official library that is intended for this purpose, but it appears to be poorly maintained and primarily designed for use with their own CLI client.
Squads V4 is an Anchor program, which means it has an IDL, downloadable from the squads program on solscan. So using the existing tooling we already have for codama IDL generation in the repo, we can generate the squads library from IDL and have compatibility with our more modern libraries.
The generated files are checked into the repo and validated for no drift via a newly added CI job.
Where does the generated library go?
Right now its embedded within the test cli as a subcrate. Technically we could have also added it to our existing IDL generation facilities in
program/settlement/idl.Approving a transaction
The user may optional specify an additional transaction,
--squads-transaction-indexHow to test
When reviewing the PR, note that a lot of the code is generated. In general, don't get lost in the weeds for all of the files within
test-cli/src/utils/squads/, with the exception oftest-cli/src/utils/squads/mod.rswhich is not generated and used to tie the module together.Probably the hardest (and unfortunately most critical) part to review is the chain of logic for confirming a proposal corresponds to the correct/staged transaction.
Probably the easiest wya to test this is to run some test transactions.
I have already been able to execute quite a few multisig bound transactions using thi branch, such as creating an order (with ATA creation!), transfer authority, and solver add/remove.
There are some edge cases we should check: