Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Fixes the calculation of the compute_meter_consumption #21944

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions program-runtime/src/invoke_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,15 +642,15 @@ 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,
instruction: &CompiledInstruction,
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
Expand All @@ -661,20 +661,24 @@ 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
.is_active(&demote_program_write_locks::id());
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
Expand Down Expand Up @@ -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),
Expand Down
6 changes: 2 additions & 4 deletions runtime/src/message_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,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);
}
Expand Down