Fixes the calculation of the "compute_meter_consumption" across process_instruction() and process_message(). (#21944)

This commit is contained in:
Alexander Meißner 2021-12-16 15:15:58 +01:00 committed by GitHub
parent 82672b40fd
commit 49cb161203
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 10 deletions

View File

@ -642,7 +642,7 @@ impl<'a> InvokeContext<'a> {
Ok((message, caller_write_privileges, program_indices))
}
/// Process a cross-program instruction
/// Processes a cross-program instruction and returns how many compute units were used
pub fn process_instruction(
&mut self,
message: &Message,
@ -650,7 +650,7 @@ impl<'a> InvokeContext<'a> {
program_indices: &[usize],
account_indices: &[usize],
caller_write_privileges: &[bool],
) -> Result<(), InstructionError> {
) -> Result<u64, InstructionError> {
let is_lowest_invocation_level = self.invoke_stack.is_empty();
if !is_lowest_invocation_level {
// Verify the calling program hasn't misbehaved
@ -661,11 +661,13 @@ impl<'a> InvokeContext<'a> {
.push(message, instruction, program_indices, account_indices)
.and_then(|_| {
self.return_data = (*instruction.program_id(&message.account_keys), Vec::new());
let pre_remaining_units = self.compute_meter.borrow().get_remaining();
self.process_executable_chain(&instruction.data)?;
let post_remaining_units = self.compute_meter.borrow().get_remaining();
// Verify the called program has not misbehaved
if is_lowest_invocation_level {
self.verify(message, instruction, program_indices)
self.verify(message, instruction, program_indices)?;
} else {
let demote_program_write_locks = self
.feature_set
@ -673,8 +675,10 @@ impl<'a> InvokeContext<'a> {
let write_privileges: Vec<bool> = (0..message.account_keys.len())
.map(|i| message.is_writable(i, demote_program_write_locks))
.collect();
self.verify_and_update(instruction, account_indices, &write_privileges)
self.verify_and_update(instruction, account_indices, &write_privileges)?;
}
Ok(pre_remaining_units.saturating_sub(post_remaining_units))
});
// Pop the invoke_stack to restore previous state
@ -1304,12 +1308,12 @@ mod tests {
invoke_context.pop();
let cases = vec![
(MockInstruction::NoopSuccess, Ok(())),
(MockInstruction::NoopSuccess, Ok(0)),
(
MockInstruction::NoopFail,
Err(InstructionError::GenericError),
),
(MockInstruction::ModifyOwned, Ok(())),
(MockInstruction::ModifyOwned, Ok(0)),
(
MockInstruction::ModifyNotOwned,
Err(InstructionError::ExternalAccountDataModified),

View File

@ -111,17 +111,15 @@ impl MessageProcessor {
invoke_context.instruction_recorder =
Some(&instruction_recorders[instruction_index]);
}
let pre_remaining_units = invoke_context.get_compute_meter().borrow().get_remaining();
let mut time = Measure::start("execute_instruction");
invoke_context
let compute_meter_consumption = invoke_context
.process_instruction(message, instruction, program_indices, &[], &[])
.map_err(|err| TransactionError::InstructionError(instruction_index as u8, err))?;
time.stop();
let post_remaining_units = invoke_context.get_compute_meter().borrow().get_remaining();
timings.accumulate_program(
instruction.program_id(&message.account_keys),
time.as_us(),
pre_remaining_units - post_remaining_units,
compute_meter_consumption,
);
timings.accumulate(&invoke_context.timings);
}