-
Notifications
You must be signed in to change notification settings - Fork 923
refactor(experimental): allow the nonce authority account to be writable #1777
Conversation
Current dependencies on/for this PR:
This stack of pull requests is managed by Graphite. |
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.
Lgtm mate!
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.
This is the case if the nonce authority is also the fee payer, for example in a transaction created with the CLI:
Hang on though; the way that transactions are compiled in the new web3.js is such that the AccountRole
on any individual instruction has no bearing alone on what the AccountRole
will be at the level of the entire transaction.
If the advance nonce instruction specifies account 'abc' as READONLY_SIGNER
and the transaction fee payer is set to account 'abc', the transaction compiler will combine all of the AccountRoles
of 'abc' in the transaction and compute the highest role (ie. WRITABLE_SIGNER
in that case).
solana-web3.js/packages/instructions/src/roles.ts
Lines 38 to 50 in df45965
export function mergeRoles(roleA: AccountRole.WRITABLE, roleB: AccountRole.READONLY_SIGNER): AccountRole.WRITABLE_SIGNER; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole.READONLY_SIGNER, roleB: AccountRole.WRITABLE): AccountRole.WRITABLE_SIGNER; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole, roleB: AccountRole.WRITABLE_SIGNER): AccountRole.WRITABLE_SIGNER; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole.WRITABLE_SIGNER, roleB: AccountRole): AccountRole.WRITABLE_SIGNER; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole, roleB: AccountRole.READONLY_SIGNER): AccountRole.READONLY_SIGNER; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole.READONLY_SIGNER, roleB: AccountRole): AccountRole.READONLY_SIGNER; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole, roleB: AccountRole.WRITABLE): AccountRole.WRITABLE; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole.WRITABLE, roleB: AccountRole): AccountRole.WRITABLE; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole.READONLY, roleB: AccountRole.READONLY): AccountRole.READONLY; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole, roleB: AccountRole): AccountRole; // prettier-ignore | |
export function mergeRoles(roleA: AccountRole, roleB: AccountRole): AccountRole { | |
return roleA | roleB; | |
} |
It should be fine, therefore, to type the AdvanceNonce
instruction with the lowest AccountRole
necessary to advance the nonce, and let the transaction compiler decide the ultimate role for every account at the transaction level.
(instruction.accounts[2].role === AccountRole.READONLY_SIGNER || | ||
instruction.accounts[2].role === AccountRole.WRITABLE_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.
You can use isSignerRole()
here if you feel like it.
@@ -129,6 +129,29 @@ describe('assertIsDurableNonceTransaction()', () => { | |||
assertIsDurableNonceTransaction({ ...durableNonceTx }); | |||
}).not.toThrow(); | |||
}); | |||
it('does not throw when the nonce authority is a writeable 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.
it('does not throw when the nonce authority is a writeable signer', () => { | |
it('does not throw when the nonce authority is a writable 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.
I don't even have the excuse of saying that's a British spelling!
- this is required because the nonce authority can be writable, eg as the transaction fee payer
dc76c9d
to
773645a
Compare
Discussed on Slack, but just so it's here too - I forgot to mention that this is related to decompiling a transaction. In a compiled transaction the account has had its roles merged, and when we apply the merged role to the instruction it may be different to what it originally had in that instruction (eg in this case the read-only signer is now a writable signer because of something else making it writable) So basically it's something else that's lossy when we compile. We could special case the instruction on decompile but I think that would lead to more complexity. |
🎉 This PR is included in version 1.87.3 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Because there has been no activity on this PR for 14 days since it was merged, it has been automatically locked. Please open a new issue if it requires a follow up. |
This PR updates the logic to determine whether a given instruction is a durable nonce transaction. Specifically, the nonce authority address can now be writeable. This is the case if the nonce authority is also the fee payer, for example in a transaction created with the CLI: https://explorer.solana.com/tx/2FZPN5ZJqi5LSMe18auxx59G1VZAP71p8KLCDvyH1WAFgqEXfag6xmC8KnzXQW3KSdbmEyWp8rdd1VnmxMsTrUdG?cluster=devnet
I don't think any change is required for other accounts