-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
Refactor - Cleanup error handling in program runtime #30693
Conversation
1e9ee81
to
faa8fb3
Compare
faa8fb3
to
16115c6
Compare
Codecov Report
@@ 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 |
5454672
to
d5354d2
Compare
d5354d2
to
58fa39d
Compare
} else { | ||
(entry.process_instruction)(self) | ||
}; | ||
let logger = self.get_log_collector(); |
There was a problem hiding this comment.
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
program-runtime/src/stable_log.rs
Outdated
pub fn program_failure( | ||
log_collector: &Option<Rc<RefCell<LogCollector>>>, | ||
program_id: &Pubkey, | ||
err: &InstructionError, | ||
err: &Box<dyn std::error::Error>, |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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
There was a problem hiding this 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); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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 😂
cf2d255
to
c535c9f
Compare
c535c9f
to
fe328d8
Compare
… stable_log::program_failure() calls from bpf_loader into InvokeContext::process_executable_chain().
…nto Box<dyn std::error::Error>.
fe328d8
to
778c71d
Compare
Problem
We pack error types into deeply nested structures such as
EbpfError::UserError(BpfError::SyscallError(SyscallError::InstructionError(err)))
andunpack 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
BpfError::VerifierError
,BpfError::SyscallError
,rbpf::EbpfError::UserError
,SyscallError::InstructionError
and turns them into
Box<dyn std::error::Error>
instead.ProcessInstructionWithContext
fromInstructionError
intoBox<dyn std::error::Error>
.