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

Refactor - Cleanup error handling in program runtime #30693

Merged
merged 8 commits into from
Apr 5, 2023

Conversation

Lichtso
Copy link
Contributor

@Lichtso Lichtso commented Mar 13, 2023

Problem

We pack error types into deeply nested structures such as EbpfError::UserError(BpfError::SyscallError(SyscallError::InstructionError(err))) and
unpack and repack them multiple times when switching between the control flow of the program-runtime, the RBPF-VM and (CPI) syscalls. This is not only annoying to deal with, but also hinders the unification of built-in programs and syscalls, as that would require a common return type, which requires a common result type, which in turn requires a common error type.

Summary of Changes

  • Bumps solana_rbpf from v0.2.40 to v0.3.0
  • Removes these wrapped error types: BpfError::VerifierError, BpfError::SyscallError, rbpf::EbpfError::UserError, SyscallError::InstructionError
    and turns them into Box<dyn std::error::Error> instead.
  • Turns result of ProcessInstructionWithContext from InstructionError into Box<dyn std::error::Error>.
  • Changes stable log: Unifies the redundant error message "Program failed to complete: {error_message}" "Program {invoke_program_id} failed: Program failed to complete" into "Program {invoke_program_id} failed: {error_message}".

@Lichtso Lichtso force-pushed the refactor/cleanup_error_handling branch 7 times, most recently from 1e9ee81 to faa8fb3 Compare March 14, 2023 00:41
@Lichtso Lichtso force-pushed the refactor/cleanup_error_handling branch from faa8fb3 to 16115c6 Compare March 14, 2023 12:29
@codecov
Copy link

codecov bot commented Mar 14, 2023

Codecov Report

Merging #30693 (778c71d) into master (60c4a71) will decrease coverage by 0.1%.
The diff coverage is 56.3%.

@@            Coverage Diff            @@
##           master   #30693     +/-   ##
=========================================
- Coverage    81.5%    81.5%   -0.1%     
=========================================
  Files         728      728             
  Lines      205881   205825     -56     
=========================================
- Hits       167800   167751     -49     
+ Misses      38081    38074      -7     

@Lichtso Lichtso force-pushed the refactor/cleanup_error_handling branch 3 times, most recently from 5454672 to d5354d2 Compare March 21, 2023 12:17
@Lichtso Lichtso force-pushed the refactor/cleanup_error_handling branch from d5354d2 to 58fa39d Compare March 23, 2023 20:24
} else {
(entry.process_instruction)(self)
};
let logger = self.get_log_collector();
Copy link
Contributor

Choose a reason for hiding this comment

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

I always wondered what this extra if was for

pub fn program_failure(
log_collector: &Option<Rc<RefCell<LogCollector>>>,
program_id: &Pubkey,
err: &InstructionError,
err: &Box<dyn std::error::Error>,
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be &dyn Error and then you &* at the call site

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tried that already and it complains that the size of dyn std::error::Error is not known at compile time.
But I found a different solution: Use .as_ref() at call site.

Copy link
Contributor

Choose a reason for hiding this comment

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

as_ref returns &T which is also what deref() returns for Box, so &* should work? And it's the common way to box -> dyn

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -37,7 +37,20 @@ use {
},
};

pub type ProcessInstructionWithContext = fn(&mut InvokeContext) -> Result<(), InstructionError>;
#[macro_export]
macro_rules! declare_process_instruction {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a comment explaining what this is for. In the context of this PR is
clear, but if you only look at the call sites they look pretty weird so people
will wonder what's going on

Copy link
Contributor

@alessandrod alessandrod left a comment

Choose a reason for hiding this comment

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

lgtm, see minor nits

}
};
create_vm_time.stop();

execute_time = Measure::start("execute");
stable_log::program_invoke(&log_collector, &program_id, stack_height);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did you remove this log and the one when the program fails? The invoke
context will log with the loader id right? So this add a log with the actual
program id which is useful

Copy link
Contributor Author

Choose a reason for hiding this comment

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

InvokeContext::process_executable_chain() logs program_id as well, not builtin_id.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah that's what the cursed confusing if was for lol 😂

@Lichtso Lichtso force-pushed the refactor/cleanup_error_handling branch 6 times, most recently from cf2d255 to c535c9f Compare March 30, 2023 13:38
@Lichtso Lichtso force-pushed the refactor/cleanup_error_handling branch from c535c9f to fe328d8 Compare April 4, 2023 11:59
@Lichtso Lichtso requested a review from alessandrod April 4, 2023 15:59
… stable_log::program_failure() calls from bpf_loader into InvokeContext::process_executable_chain().
@Lichtso Lichtso force-pushed the refactor/cleanup_error_handling branch from fe328d8 to 778c71d Compare April 5, 2023 06:41
@Lichtso Lichtso merged commit 24a87f3 into solana-labs:master Apr 5, 2023
@Lichtso Lichtso deleted the refactor/cleanup_error_handling branch April 5, 2023 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants