The core idea is to have a similar functionality to move where you load dependent accounts from within another account. There isn't the same idea of ownership between accounts / addresses as move. All of this leads back to the core goal of anchor which is to make it easy to write secure contracts on solana. One of the main aspects of solana security being that you're 100% sure that the accounts you're loading are the ones you expect them to be and not maliciously created accounts that will lead to unwanted behaviour from the contracts, e.g. token draining exploits like the cashio hack. From the other hackmd example ```rust= #[account( mut, seeds = [DATA_SEED, &[vault.epoch]], bump = vault.bumps.epoch, import = [ authority, market::{authority, reserve}, ... ], signers = [ authority, market::authority ], writable = [ market::reserve ] )] pub position: Box<Account<'info, Position>>, ``` The accounts related to this would really have to look more like ```rust= #[account] pub struct Position { authority: SystemAccount<'info>, market: Account<'info, Market>, } #[account] pub struct Market { authority: SystemAccount<'info>, reserve: Account<'info, Reserve>, } ``` Key thing to note here is that `authorty`, `market` and `reserver` have their pubkeys stored on the position struct. And that the two `authority` pubkeys might be different. - will this work ok when you are initializing multiple accounts in the stack simultaneously (like init market and position in the same function). - where do we want to put the `init` restrictions? In the `#[accout]` struct or in the `#[derive(Accounts)]` struct? ### Notes ``` #[account(discriminator = "Position")] #[account(discriminator = "Position")] struct PositionMut{...} ``` make a new macro ``` #[account_move] ``` and maybe something new with the derive macro too. #### PDA Seeds Use PDA seeds as a way of specifying related and/or dependent accounts. PDAs that don't require calling `getAccount` on the client side are more useful than ones which require an additional RPC call. So if the user knows the basis of the seeds then that should just be an input option. so maybe: move seeds definition out of the `Position` struct ```rust= #[account] pub struct Position { seeds/namespace: { market_id: [u8], authority: Pubkey, } authority: SystemAccount<'info>, market: Account<'info, Market>, } ``` One way to think about this is that it's taking the way I already use PDAs seeds (and account relationships) and trying to formalize it into the framework. The only issue being whether it's _too_ opinionated or too restrictive (people are always wanting to do dumb stuff for random reasons without realising what they're really trying to do or understanding that there's a simpler way). Making everything PDAs also helps to ensure all accounts are unique and duplicate accounts are maliciously passed when initializing. ### extra thoughts / questions - How will the accounts stuff support - optional accounts - multiple accounts - accounts that are loosely connected, maybe they share some of the same PDA seeds but haven't been explicitly initialized together. Do we have some kind of check between seeds that share the same variable names in them? - Already mentioned but: what does initialization look like? Where do the extra constraints needed for initialization go (into the `account` struct or the `derive(Accounts)` struct). - What about passing in args from somewhere else, namely in the instruction or maybe even just from a function. - Will we support custom code execution somewhere inside the constraints to allow for easier debugging (some of the constraints, like `space =` allow for a `{}` block of code that will do some custom calculations that return a `usize` variable.) - Is this going to be too complicated to actually gain adoption? - What does the client now look like with this setup? - What happens to the IDL? - Will we be able to take inputs for dependent values in the PDAs in the client (so as to avoid an extra RPC call if the data is already available). - Will this new approach for constraints be flexible enough to cover most/all use cases? - Will we be able to error now when someone tries to mutably access a variable on an account that hasn't been marked as `mut`? ### Key concerns - The original hackmd mentioned something about needing to load accounts using zerocopy (to allow this accessing of variables on sub-accounts). Is this ok/safe? There were some issues with zerocopy mentioned before, are they gone or is it no longer something to worry about? - The design/constraints are getting further and further away from what's actually happening underneath. Particularly when it comes to what is stored in the account data + what the account instructions look like - Also note that a lot of this design stuff is currently quite high level in the sense that I'm not really taking into consideration how the macros / code will work because it's not something I'm particularly familiar with yet. Though getting the design right is obviously the more important factor, it's possible that some of the desired design choices might be made impossible or difficult by the practicalities of rust macros / solana run time. We'll have to see how it goes and adapt as needed.