coral-xyz / anchor

⚓ Solana Sealevel Framework
https://anchor-lang.com
Apache License 2.0
3.61k stars 1.32k forks source link

Allow skipping instruction deserialization #994

Open archseer opened 2 years ago

archseer commented 2 years ago

I'd like to tag certain instructions as raw which would receive the payload as an undecoded byte slice. That way we can implement custom ser/de logic in instructions where it's too expensive to use borsh.

armaniferrante commented 2 years ago

You can do this with the fallback function. Example here https://github.com/project-serum/anchor/blob/master/tests/misc/programs/misc/src/lib.rs#L126-L132

archseer commented 2 years ago

Ah cool, I didn't know that would work 👍🏻

Seems like the feature is undocumented, so maybe this issue can be renamed to "document fallback functions"?

archseer commented 2 years ago

Ah, looks like this won't handle the account context for us though. Looks like I can manually construct it via Context::new

armaniferrante commented 2 years ago

Ah, looks like this won't handle the account context for us though. Looks like I can manually construct it via Context::new

Correct. It provides the raw solana entrypoint interface, which will execute if the provided instruction data doesn't contain an identifier matching any of the other instructions in the program module.

archseer commented 2 years ago

For my usecase, I'm trying to pass through the data as raw, but still use the Anchor context. I followed the skeleton code here: https://github.com/project-serum/anchor/blob/d1edf2653f13f908a095081ec95d4b2c85a0b2d2/lang/syn/src/codegen/program/handlers.rs#L598-L625

It's less convenient though because the generated account context isn't in the IDL so I have to manually construct the AccountMeta list in typescript. Could we support a signature like this?

    pub fn default(
        ctx: Context<Default>,
        data: &[u8],
    ) -> ProgramResult {
        // ...
    }

This way raw instructions would still be present in the IDL and callable from typescript. We can tell them apart from borsh instructions since &[u8] references aren't possible with borsh. Alternatively a #[raw] tag could be added.

paul-schaaf commented 2 years ago

I like it. could be done with a reserved argument name like raw_data too. prefer that or #[raw] over looking at the type. borsh might add &[u8] at some point and by not looking at the type we dont have to change anything if they do