-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Feat: Optional Positional Accounts #2101
Conversation
…stegaBOB/anchor into stegaBOB/feat/optional-accounts
…/anchor into stegaBOB/feat/optional-accounts
Stega bob/feat/optional accounts
Feat: try to account info
# Conflicts: # client/example/src/main.rs # tests/misc/tests/misc/misc.ts
Best to keep the version changes to a separate PR, assuming I can get it merged quick enough for you |
I'll revert that for now. Merging the changes seems to have broken a bunch of things :( |
# Conflicts: # .github/workflows/tests.yaml # tests/misc/tests/misc/misc.ts
👏 big round of applause for such a massive contribution here. Looks good to merge but as with all things smart contract related should treated extremely carefully. The only major issue previously found with anchor was in the Thanks again for all the hard work @stegaBOB! |
Are optional accounts allocated in stack by default? If i want to box those accounts, how would i able to do that? /// This failed, due to access violation which i think is because it ran out of memory
escrow_account: Option<Box<Account<'info, TokenAccount>>>,
// But This worked
escrow_account: Box<Account<'info, TokenAccount>> How can i allocate optional accounts in heap? |
Problem
At the moment, the only way to handle accounts that may or may not be passed in to your program is through the
remaining_accounts
vec. The downside of this is there is no way to easily handle checks and deserialization with the remaining accounts vec, and programs would need to keep track of what accounts should be passed in and it's actually so horrible.Solution
Implement support for "optional" accounts in the
Accounts
struct. This would allow for significantly more flexibility while also providing safeguards from shooting oneself in the foot withremaining_accounts
In the example above, the
maybe_new
account is only created if it is passed in. If not,&ctx.accounts.maybe_new
will returnNone
.How this works?
The key to make everything work is the fact that repeated accounts don't add to the size of the transaction due to how Solana serializes accounts in transactions. We use this fact to denote an optional account with the program Id. When the accounts are passed in, if an account should be ignored, clients will send the program Id instead. In addition, with this implementation, adding on optional accounts at the end of an
Accounts
struct wouldn't be a breaking change and the program will treat the missing account asNone
(since older clients will not be passing in this new account).Thanks to @febo for working on this with me!