Conversation
| #[derive(Clone, Debug, PartialEq, Eq, SchemaRead, SchemaWrite)] | ||
| pub struct AuthorityPolicy { | ||
| /// Number of member approvals required to authorize execution. | ||
| pub threshold: u8, |
There was a problem hiding this comment.
multisig could also be a standalone cpi-passthrough program. imagine this glorious future 🤓
sign(sign(sign(timelock(multisig(transfer())))))
There was a problem hiding this comment.
This design looks pretty, but composition might be tricky from the client-side. For example, if you need multiple signers, then you need to generate a different message for each nesting level, right?
There was a problem hiding this comment.
in theory we could make a version of this that allows the same payload to be signed by multiple authorities. only one would need to "own" the "nonce account"
There was a problem hiding this comment.
New design accepts a signed legacy transaction. This should mitigate nested custom message issues.
joncinque
left a comment
There was a problem hiding this comment.
This is definitely on the right track!
We were talking about this offline, and I mentioned that a good use-case to target is minting SPL tokens, where the mint authority is a multisig, which I think is essentially Trent's sign(sign(sign(... example.
As another consideration, if people want to use tools like Ledgers as their offline signer, I don't think the current format will be accepted. We might need these to look like a Solana transaction instead, so that existing tools Just Work ™️
| /// Counter that prevents reuse of signed messages. A signed message must | ||
| /// reference this exact value. Each successful signed action increments | ||
| /// this value, invalidating any previously signed messages. | ||
| pub nonce: U32, |
There was a problem hiding this comment.
We discussed this a bit offline, but wanted to flag here. By using an incremented integer nonce, it's possible to presign a bunch of messages to be executed.
This has some upsides and downsides, but most importantly, it is different from the current nonce behavior, where each nonce is practically random. Not saying it's good or bad, just pointing it out
There was a problem hiding this comment.
I could go either way. But considering this is going for the durable-nonce-replacement angle, updated this to a hash that gets recomputed on successes.
| #[derive(Clone, Debug, PartialEq, Eq, SchemaRead, SchemaWrite)] | ||
| pub struct AuthorityPolicy { | ||
| /// Number of member approvals required to authorize execution. | ||
| pub threshold: u8, |
There was a problem hiding this comment.
This design looks pretty, but composition might be tricky from the client-side. For example, if you need multiple signers, then you need to generate a different message for each nesting level, right?
|
what's status here? foundation wants an example to float to current durable nonce consumers |
|
@t-nelson sorry for the delay on iterating on this. Talked offline to Jon a bit about a simpler design today. Expect an update soon. |
|
inspired by jon This next iteration is an alternative design that simplifies the program a good deal. New flow:
It's no longer necessary to define a custom inner message format. This makes it friendlier to work with existing infra that expects signatures on the legacy transaction format. Also removed embedded deadline/multisig support. Delegates that responsibility to external CPIs. |
This PR adds base interfaces for the program: instructions, state, message schema, and PDA types.
Overall objective
Write a program that can serve as a functional replacement for the durable nonce usecase:
The difference is that durable nonces do this via special runtime functionality (that folks are interested in removing), while this program does it through a promoting a PDA to signer on a pre-signed tx message.
Inspiration
Trent's durable nonce replacement proposal: solana-foundation/solana-improvement-documents#456
& Jon's idea to take a pre-signed-tx and promote the PDA to a signer on that tx.
High-level design
The intended flow is:
a. Verifies the authority signed
b. Checks message.recent_blockhash == state.nonce
c. Executes each wrapped instruction by CPI, promoting NonceAuthorityPda to signer wherever referenced
d. Advances the nonce as sha256(tag ‖ state_pda ‖ old_nonce ‖ slot_hashes[0] ‖ sha256(wincode(tx.message))).
Divergences from original proposal
This follows the spirit of Trent's original proposal, but there are a few divergences:
What's next