Skip to content

[nodes] has_one account resolution #605

@ChewingGlass

Description

@ChewingGlass

Let's say you have an endpoint like this:

#[derive(Accounts)]
pub struct DequeuetaskV0<'info> {
    pub queue_authority: Signer<'info>,
    /// CHECK: Via has one
    #[account(mut)]
    pub rent_refund: AccountInfo<'info>,
    #[account(
        seeds = [b"task_queue_authority", task_queue.key().as_ref(), queue_authority.key().as_ref()],
        bump = task_queue_authority.bump_seed,
    )]
    pub task_queue_authority: Box<Account<'info, TaskQueueAuthorityV0>>,
    #[account(mut)]
    pub task_queue: Box<Account<'info, TaskQueueV0>>,
    #[account(
        mut,
        close = rent_refund,
        has_one = rent_refund,
        has_one = task_queue,
    )]
    pub task: Box<Account<'info, TaskV0>>,
}

In Anchor, the code to use this endpoint is:

await program.methods
          .dequeueTaskV0()
          .accounts({
            task,
          })
          .rpc();

In Codama, the code is:

 const task = ... // fetch task account
await dequeueTaskV0(umi, {
  task,
  queueAuthority,
  rentRefund: task.rentRefund,
  taskQueue: task.taskQueue 
}).sendAndConfirm(umi, options);

For more complex endpoints with 10+ accounts, and lots of has_ones, you end up with heaps of boilerplate just to get what needs to be passed to the function.

It would be nice if Codama could use anchor's has_one information from the IDL to make accounts optional in typescript. If you pass them, you avoid an extra fetch. If you don't, it fetches them for you.

So, for example, the code becomes:

await dequeueTaskV0(umi, { task }).sendAndConfirm(umi, options);

Another optimization on top of this would be to implement a global cache of accounts, similar to Helium's Account Fetch Cache that makes it so you can omit passing optional accounts for more legible code, without the worry about a performance hit.

This feature also becomes useful if you need to add accounts to an endpoint without breaking old clients. If the clients are smart enough to resolve has_one's, a new account pulled in through has_one is a non-breaking change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    anchorImproves conversion from Anchor IDLproposalSuggesting a change / new featurev2Something to look into when updating the Codama standard to v2

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions