Skip to content
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

PDA derivation with string seed incorrect for Anchor #337

Open
swimricky opened this issue Nov 29, 2024 · 1 comment
Open

PDA derivation with string seed incorrect for Anchor #337

swimricky opened this issue Nov 29, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@swimricky
Copy link

swimricky commented Nov 29, 2024

solana-program/create-solana-program#108

if you have an Anchor program like the following

 #[program]
mod drp_test_scaffold {
    use super::*;

    pub fn create(ctx: Context<Create>, name: String, authority: Pubkey) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.name = name;
        counter.authority = authority;
        counter.count = 0;
        Ok(())
    }
}

#[derive(Accounts)]
#[instruction(name: String)]
pub struct Create<'info> {
    #[account(
        init, 
        seeds = [name.as_bytes()],
        bump,
        payer = payer, space = 8 + Counter::INIT_SPACE
    )]
    pub counter: Account<'info, Counter>,
    #[account(mut)]
    pub payer: Signer<'info>,
    pub system_program: Program<'info, System>,
}

the generated Encoder for the seeds is incorrect.
it generates the following snippet for resolving the counter account if not provided

 // Resolve default values.
  if (!accounts.counter.value) {
    accounts.counter.value = await getProgramDerivedAddress({
      programAddress,
      seeds: [
        addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder()).encode(
          expectSome(args.name)
        ),
      ],
    });
  }

it should be using

 getUtf8Encoder().encode(
          expectSome(args.name)
        ),
@swimricky swimricky changed the title PDA derivation with string seed uses incorrect type for length for Anchor PDA derivation with string seed incorrect for Anchor Nov 29, 2024
@lorisleiva
Copy link
Member

lorisleiva commented Dec 2, 2024

Thanks for opening a separate issue.

I've added my thoughts on this bug here. Copy/pasting below to close the other thread:


Thanks for the detailed updates guys!

Yes, I can see now that the Anchor macro says seeds = [name.as_bytes()], which basically means "remove the u32 size prefix of the String type.

The really annoying thing is that this is actually not exposed on the IDL whatsoever.

"pda": {
  "seeds": [
    {
      "kind": "arg",
      "path": "name" // argument "name" is `string`, not `string.as_bytes()` or something.
    }
  ]
}

So from the perspective of Codama, you're just getting the string type which, by default with Anchor, is a u32 prefixed string.

Since I believe this is the way most people using string as seeds anyway, it may be okay to just assume that string seed should never have any prefix. But that would introduce a bug for anyone that currently uses u32 prefixed strings for seeds.

I think it's still worth doing but maybe best to release it in 2.0. 🤔

@lorisleiva lorisleiva added the bug Something isn't working label Dec 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants