anchor icon indicating copy to clipboard operation
anchor copied to clipboard

FR: Allow custom entry point function

Open mina86 opened this issue 1 year ago • 10 comments

I’d like to be able to generate my own entrypoint function so that I can execute code before any other code (this includes Anchor’s entry function as well as entrypoint function provided by solana_program). I need this so that I can run custom initialisation on of the allocator.

As such, I’d like if the anchor_lang::program derive had an option not to include the solana_program::entrypoint! invocation when using program macro attribute. Specifically, I’m referring to lines 12 and 13 in entry.rs.

mina86 avatar Feb 08 '24 02:02 mina86

I need this so that I can run custom initialisation on of the allocator.

Does it not work if you enable custom-heap feature?

acheroncrypto avatar Feb 08 '24 23:02 acheroncrypto

I can replace global allocator with custom-heap but that’s not what I’m after. I need to perform actions early to initialise the allocator before any other code executes. See Solana issue #32607. In other words, what I want to do is replace global allocator (which custom-heap gives me) and then in entrypoint look through instructions to figure out heap size. (In fact I need to do more things before Anchor runs but let’s just limit discussion to allocator because the rest is more specific to my use case).

mina86 avatar Feb 08 '24 23:02 mina86

Got it, that seems reasonable to me. Another question I have is what's stopping you from enabling the no-entrypoint feature to avoid generating Solana's entrypoint! macro and then generating your own entrypoint logic?

acheroncrypto avatar Feb 09 '24 09:02 acheroncrypto

I suppose that would work but then the issue is that other crates might assume that if they enable no-entrypoint feature they will get all the accounts and instructions definitions without the entrypoint function. If I define entrypoint I then need another really-no-entrypoint feature and all crates that need my crate for API need to be aware of this new feature.

But I think you’re right in that features are the simplest way to deal with this. But perhaps something like Solana’s custom-heap. Maybe anchor-custom-entrypoint and then Anchor would generate the following:

#[cfg(not(any(
    feature = "no-entrypoint",
    feature = "anchor-custom-entrypoint",
)))]
anchor_lang::solana_program::entrypoint!(entry);

mina86 avatar Feb 09 '24 10:02 mina86

Wouldn't setting default features solve this problem?

[features]
default = ["no-entrypoint", "my-custom-entrypoint"]

and in code:

#[cfg(feature = "my-custom-entrypoint"]
// Custom entrypoint...

This way, you get your custom entrypoint by default and other crates can work with no-entrypoint like usual.

acheroncrypto avatar Feb 09 '24 17:02 acheroncrypto

Yes, that’s a good point, I think it’ll work. Let’s close this for now.

mina86 avatar Feb 09 '24 19:02 mina86

I’m reopening this because I think this is a bit too convoluted without explicit support from Anchor. If I define my-custom-entrypoint feature as suggested, in certain setups there’s no obvious way to depend on the crate without entry point being defined.

Specifically, I have a crate foo with custom entrypoint. In the same Cargo workspace, I have crate bar which depends on foo with cpi feature enabled. In bar I do something like:

[dependencies]
foo = { ..., default-features = false, features = ["cpi"] }

However, if I cargo build, the foo’s custom-entrypoint feature will be enabled since features will be collected from entire workspace. At least that’s how I interpret what is happening. (anchor build and cargo build -p bar work but for the project management it’s rather important that I can execute crate on whole workspace rather than having to dance around Anchor).

I think I can address this by introducing no-custom-entrypoint but that would get rather confusing. The interactions between no-entrypoint, custom-entrypoint and no-custom-entrypoint would be rather bemusing and I bet I won’t understand them in a quarter not to mention someone new coming to the project.

I think the cleanest would be#[anchor_lang::program(custom-entrypoint)] which would prevent the attribute macro from including the entrypoint declaration. Having Anchor explicitly support custom-entrypoint would be the second best option.

PS. I’ve tried doing this without changes to anchor-syn by adding no-custom-entrypoint and various feature implications but I couldn’t get things to work properly. Interaction of additive features, cargo build, anchor build etc. make it too convoluted to do.

mina86 avatar Feb 12 '24 12:02 mina86