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

Extract instruction crate #2405

Merged
merged 46 commits into from
Sep 13, 2024
Merged

Conversation

kevinheavey
Copy link

Problem

solana_program::instruction needs to be made available outside solana_program

This branches off #2394 so that needs to be merged first

Summary of Changes

  • Pull out a solana_instruction crate and re-export the relevant contents in solana_program::instruction for backwards compatibility
  • Move the numeric consts (ACCOUNT_ALREADY_INITIALIZED etc) and impl<T> From<T> for InstructionError from program_error.rs to solana-instruction. The compiler requires this.
  • Re-export the numeric consts in program_error.rs
  • Make bincode and serde optional in solana-instruction

Fun fact: a release build of the new crate without default features takes <1 second on my machine

Copy link

mergify bot commented Aug 9, 2024

The Firedancer team maintains a line-for-line reimplementation of the
native programs, and until native programs are moved to BPF, those
implementations must exactly match their Agave counterparts.
If this PR represents a change to a native program implementation (not
tests), please include a reviewer from the Firedancer team. And please
keep refactors to a minimum.

@kevinheavey kevinheavey force-pushed the extract-instruction branch from 68b1078 to b3d20cd Compare August 9, 2024 14:11
@kevinheavey kevinheavey force-pushed the extract-instruction branch 7 times, most recently from 3da2871 to 461914f Compare September 10, 2024 18:50
@kevinheavey kevinheavey marked this pull request as ready for review September 10, 2024 19:44
Copy link

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the lateness, this one was pretty chunky, and I wanted to figure out a future for syscall stubs. Looks great! Just some tiny things.

sdk/program/src/program_error.rs Show resolved Hide resolved
sdk/instruction/Cargo.toml Show resolved Hide resolved
sdk/instruction/Cargo.toml Outdated Show resolved Hide resolved
sdk/instruction/src/lib.rs Show resolved Hide resolved
// Warning: Any new error codes added here must also be:
// - Added to the below conversions
// - Added as an equivalent to ProgramError and InstructionError
// - Be featureized in the BPF loader to return `InstructionError::InvalidError`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit typo (I know you didn't do this, but now that it's being moved, we can fix it)

Suggested change
// - Be featureized in the BPF loader to return `InstructionError::InvalidError`
// - Be featurized in the BPF loader to return `InstructionError::InvalidError`

Comment on lines 278 to 284
/// Addition that returns [`InstructionError::InsufficientFunds`] on overflow.
///
/// This is an internal utility function.
#[doc(hidden)]
pub fn checked_add(a: u64, b: u64) -> Result<u64, InstructionError> {
a.checked_add(b).ok_or(InstructionError::InsufficientFunds)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so strange, but it looks like it has uses in the stake and system program. Can you leave it in solana_program with a note saying to remove it?

Comment on lines 286 to 310
/// Describes a single account read or written by a program during instruction
/// execution.
///
/// When constructing an [`Instruction`], a list of all accounts that may be
/// read or written during the execution of that instruction must be supplied.
/// Any account that may be mutated by the program during execution, either its
/// data or metadata such as held lamports, must be writable.
///
/// Note that because the Solana runtime schedules parallel transaction
/// execution around which accounts are writable, care should be taken that only
/// accounts which actually may be mutated are specified as writable. As the
/// default [`AccountMeta::new`] constructor creates writable accounts, this is
/// a minor hazard: use [`AccountMeta::new_readonly`] to specify that an account
/// is not writable.
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct AccountMeta {
/// An account's public key.
pub pubkey: Pubkey,
/// True if an `Instruction` requires a `Transaction` signature matching `pubkey`.
pub is_signer: bool,
/// True if the account data or metadata may be mutated during program execution.
pub is_writable: bool,
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move AccountMeta into a separate file? It'll make things neater when adding a new instruction type

serde(rename_all = "camelCase")
)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct CompiledInstruction {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Man, I really think this belongs more in Message than Instruction, but it's currently exported from instruction... what do you think about leaving this in solana_program for now, and then moving it to solana_message whenever that gets broken out? Without breaking the re-exports from solana_program, of course.

That'll also remove the dep on solana-sanitize

sdk/instruction/src/lib.rs Show resolved Hide resolved
sdk/instruction/src/lib.rs Outdated Show resolved Hide resolved
Copy link

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last question around AccountMeta, otherwise this is looking good!

"dep:rustc_version",
"dep:solana-frozen-abi",
"dep:solana-frozen-abi-macro",
"serde",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, I noticed this was needed while testing, thanks for fixing!

@@ -0,0 +1,105 @@
#[cfg(any(feature = "std", target_arch = "wasm32"))]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something -- why is this gated on the std feature / wasm32 arch? It should be usable regardless of features and all that, no?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I took another look and realised this can be much simpler, had been assuming the wasm32 code needed std because we have other places where that's the case but it's not the case here

/// default [`AccountMeta::new`] constructor creates writable accounts, this is
/// a minor hazard: use [`AccountMeta::new_readonly`] to specify that an account
/// is not writable.
#[cfg(any(feature = "std", target_arch = "wasm32"))]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with this, is the featurization / arch cfg needed?

/// an error be consistent across software versions. For example, it is
/// dangerous to include error strings from 3rd party crates because they could
/// change at any time and changes to them are difficult to detect.
#[cfg(feature = "std")]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing this is no-std because of the String in one of the errors, correct? I hope we can make a breaking change to make this no-std in the future...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct

@joncinque
Copy link

@yihau can you accept the ownership for solana-instruction once it gets passed over? This is very close to ready

Copy link

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to go from my side -- thanks for responding to all the feedback so quickly!

@kevinheavey kevinheavey added the automerge automerge Merge this Pull Request automatically once CI passes label Sep 13, 2024
Copy link

mergify bot commented Sep 13, 2024

automerge label removed due to a CI failure

@mergify mergify bot removed the automerge automerge Merge this Pull Request automatically once CI passes label Sep 13, 2024
@kevinheavey kevinheavey added the automerge automerge Merge this Pull Request automatically once CI passes label Sep 13, 2024
@yihau
Copy link
Member

yihau commented Sep 13, 2024

all green!

@joncinque joncinque merged commit b4ed7a4 into anza-xyz:master Sep 13, 2024
55 checks passed
ray-kast pushed a commit to abklabs/agave that referenced this pull request Nov 27, 2024
* extract instruction crate

* remove thiserror

* make bincode optional in solana-instruction

* make serde optional in solana-instruction

* fix doc tests

* fmt

* harmonize features

* fmt Cargo.toml

* clippy

* fix syscalls.rs imports

* update digests

* update digest

* unused imports

* post-rebase fmt

* fix doc links

* use workspace lints

* fmt

* make rustc_version dep optional

* update digest

* update digest

* update import

* fmt

* fix dup import

* remove dev-context-only-utils (no longer needed)

* fmt

* remove unnecessary allow()

* fix overwriting instruction syscall stubs

* fmt

* move get_processed_sibling_instruction and get_stack_height back to solana-program to avoid breaking change

* fix path

* fix typo

* move the checked_add utility function back to solana-program

* move AccountMeta to its own file

* fix bad import

* move ProcessedSiblingInstruction to syscalls.rs

* move CompiledInstruction back to solana-program

* move ProcessedSiblingInstruction back into lib.rs

* make std optional in solana-instruction

* fix required features for frozen-abi

* update digest

* update digest

* missing import

* update digest

* don't assume std is imported in frozen-abi macros

* fix import warnings

* simplify cfg usage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge automerge Merge this Pull Request automatically once CI passes need:merge-assist
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants