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

Record instructions which are precompiles #24743

Merged
merged 2 commits into from
May 4, 2022

Conversation

Lichtso
Copy link
Contributor

@Lichtso Lichtso commented Apr 27, 2022

Problem

See #24705

Summary of Changes

Don't just skip instructions when is_precompile by continue,
instead have them be recorded in the transaction_context.

Additionally feature gated behind record_instruction_in_transaction_context_push.

Fixes #24705
Updates Feature Gate: #24965

@jstarry
Copy link
Member

jstarry commented Apr 27, 2022

Would it be too hacky to do self.transaction_context.record_precompile_ix() which directly does self.instruction_trace.push(vec![])? Looks like it would work ok here:

/// Convert from an InstructionTrace to InnerInstructionsList
pub fn inner_instructions_list_from_instruction_trace(
    instruction_trace: &InstructionTrace,
) -> InnerInstructionsList {
    instruction_trace
        .iter()
        .map(|inner_instructions_trace| {
            inner_instructions_trace
                .iter()
                .skip(1)
                .map(|instruction_context| {

@Lichtso
Copy link
Contributor Author

Lichtso commented Apr 27, 2022

Do you mean moving

                invoke_context
                    .transaction_context
                    .push(
                        program_indices,
                        &instruction_accounts,
                        &instruction.data,
                        true,
                    )
                    .and_then(|_| invoke_context.transaction_context.pop())

into a function TransactionContext::record_precompile_ix()?

Or to use TransactionContext::record_instruction() in the message_processor?
Because that is already on its way out.

Or, do you want to not actually record anything but sneak in fake entries in inner_instructions_list_from_instruction_trace()?
That would cause problems with the sibling instruction introspection I think.

@jstarry
Copy link
Member

jstarry commented Apr 27, 2022

Or, do you want to not actually record anything but sneak in fake entries in inner_instructions_list_from_instruction_trace()?

Yeah, this.

That would cause problems with the sibling instruction introspection I think.

Good point, could we protect against this with an enum? Precompiles will always need special handling so might be worth doing something like this:

pub type InstructionTrace = Vec<InstructionTraceRecord>;

pub enum InstructionTraceRecord {
  Precompile { program_id: Pubkey },
  ProgramInstruction(Vec<InstructionContext>),
}

@jstarry
Copy link
Member

jstarry commented Apr 27, 2022

I'm just hoping we can find a way to avoid adding too much complexity.. the precompile transition has had a lot of bugs from corner cases

@Lichtso
Copy link
Contributor Author

Lichtso commented Apr 28, 2022

The enum sounds like a lot more complexity. Keep in mind that in ABIv2 the instruction stack, trace and record are all the same thing. And it is designed to reflect the incoming message as close as possible.

@jstarry
Copy link
Member

jstarry commented Apr 28, 2022

The enum sounds like a lot more complexity. Keep in mind that in ABIv2 the instruction stack, trace and record are all the same thing. And it is designed to reflect the incoming message as close as possible.

How do precompiles fit into ABIv2?

@Lichtso
Copy link
Contributor Author

Lichtso commented Apr 28, 2022

That is actually a good question as they were not taken into account yet.
So with the current implementation they would just sit there in the instruction trace (so other instructions can see them) but not be executed. That way the instruction trace stays in sync with the message as long as no error occurs.

@jstarry
Copy link
Member

jstarry commented Apr 28, 2022

Got it, well I suggested the enum because I'd prefer avoiding trying to make a precompile act like an instruction because it's bound to introduce bugs. Using an enum forces us to handle precompiles explicitly.

@Lichtso Lichtso force-pushed the record_precompile branch from 45051b1 to d0a2f66 Compare May 4, 2022 09:32
@jstarry jstarry added the feature-gate Pull Request adds or modifies a runtime feature gate label May 4, 2022
jstarry
jstarry previously approved these changes May 4, 2022
Copy link
Member

@jstarry jstarry left a comment

Choose a reason for hiding this comment

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

Looks good. A bit hard to follow but I think when these feature gates get cleaned up in the future this should get more simplified.

Comment on lines 92 to 93
let is_precompile =
is_precompile(program_id, |id| invoke_context.feature_set.is_active(id));
Copy link
Member

Choose a reason for hiding this comment

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

Can you && this with the check that the prevent_calling_precompiles_as_programs feature is active? Technically there are no "precompiles" unless that feature is active. We should also ensure that the usage of is_precompile below also incorporates the feature gate check.

@mergify mergify bot dismissed jstarry’s stale review May 4, 2022 11:40

Pull request has been modified.

@Lichtso Lichtso added the automerge Merge this Pull Request automatically once CI passes label May 4, 2022
@mergify mergify bot removed the automerge Merge this Pull Request automatically once CI passes label May 4, 2022
@mergify
Copy link
Contributor

mergify bot commented May 4, 2022

automerge label removed due to a CI failure

@Lichtso Lichtso merged commit eae9a66 into solana-labs:master May 4, 2022
@Lichtso Lichtso deleted the record_precompile branch May 4, 2022 14:32
@Lichtso Lichtso added the v1.10 label May 5, 2022
mergify bot pushed a commit that referenced this pull request May 5, 2022
* Record instructions which are "is_precompile".

(cherry picked from commit eae9a66)
mergify bot added a commit that referenced this pull request May 5, 2022
* Record instructions which are "is_precompile".

(cherry picked from commit eae9a66)

Co-authored-by: Alexander Meißner <[email protected]>
jeffwashington pushed a commit to jeffwashington/solana that referenced this pull request Jun 29, 2022
* Record instructions which are "is_precompile".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-gate Pull Request adds or modifies a runtime feature gate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inner instruction indexes don't increment for precompiles
2 participants