Fixes the calculation of the "compute_meter_consumption" across process_instruction() and process_message(). (#21944) (#21945)
(cherry picked from commit 49cb161203
)
Co-authored-by: Alexander Meißner <AlexanderMeissner@gmx.net>
This commit is contained in:
@ -639,7 +639,7 @@ impl<'a> InvokeContext<'a> {
|
|||||||
Ok((message, caller_write_privileges, program_indices))
|
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(
|
pub fn process_instruction(
|
||||||
&mut self,
|
&mut self,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
@ -647,7 +647,7 @@ impl<'a> InvokeContext<'a> {
|
|||||||
program_indices: &[usize],
|
program_indices: &[usize],
|
||||||
account_indices: &[usize],
|
account_indices: &[usize],
|
||||||
caller_write_privileges: &[bool],
|
caller_write_privileges: &[bool],
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<u64, InstructionError> {
|
||||||
let is_lowest_invocation_level = self.invoke_stack.is_empty();
|
let is_lowest_invocation_level = self.invoke_stack.is_empty();
|
||||||
if !is_lowest_invocation_level {
|
if !is_lowest_invocation_level {
|
||||||
// Verify the calling program hasn't misbehaved
|
// Verify the calling program hasn't misbehaved
|
||||||
@ -658,11 +658,13 @@ impl<'a> InvokeContext<'a> {
|
|||||||
.push(message, instruction, program_indices, account_indices)
|
.push(message, instruction, program_indices, account_indices)
|
||||||
.and_then(|_| {
|
.and_then(|_| {
|
||||||
self.return_data = (*instruction.program_id(&message.account_keys), Vec::new());
|
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)?;
|
self.process_executable_chain(&instruction.data)?;
|
||||||
|
let post_remaining_units = self.compute_meter.borrow().get_remaining();
|
||||||
|
|
||||||
// Verify the called program has not misbehaved
|
// Verify the called program has not misbehaved
|
||||||
if is_lowest_invocation_level {
|
if is_lowest_invocation_level {
|
||||||
self.verify(message, instruction, program_indices)
|
self.verify(message, instruction, program_indices)?;
|
||||||
} else {
|
} else {
|
||||||
let demote_program_write_locks = self
|
let demote_program_write_locks = self
|
||||||
.feature_set
|
.feature_set
|
||||||
@ -670,8 +672,10 @@ impl<'a> InvokeContext<'a> {
|
|||||||
let write_privileges: Vec<bool> = (0..message.account_keys.len())
|
let write_privileges: Vec<bool> = (0..message.account_keys.len())
|
||||||
.map(|i| message.is_writable(i, demote_program_write_locks))
|
.map(|i| message.is_writable(i, demote_program_write_locks))
|
||||||
.collect();
|
.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
|
// Pop the invoke_stack to restore previous state
|
||||||
@ -1293,12 +1297,12 @@ mod tests {
|
|||||||
invoke_context.pop();
|
invoke_context.pop();
|
||||||
|
|
||||||
let cases = vec![
|
let cases = vec![
|
||||||
(MockInstruction::NoopSuccess, Ok(())),
|
(MockInstruction::NoopSuccess, Ok(0)),
|
||||||
(
|
(
|
||||||
MockInstruction::NoopFail,
|
MockInstruction::NoopFail,
|
||||||
Err(InstructionError::GenericError),
|
Err(InstructionError::GenericError),
|
||||||
),
|
),
|
||||||
(MockInstruction::ModifyOwned, Ok(())),
|
(MockInstruction::ModifyOwned, Ok(0)),
|
||||||
(
|
(
|
||||||
MockInstruction::ModifyNotOwned,
|
MockInstruction::ModifyNotOwned,
|
||||||
Err(InstructionError::ExternalAccountDataModified),
|
Err(InstructionError::ExternalAccountDataModified),
|
||||||
|
@ -104,17 +104,15 @@ impl MessageProcessor {
|
|||||||
invoke_context.instruction_recorder =
|
invoke_context.instruction_recorder =
|
||||||
Some(&instruction_recorders[instruction_index]);
|
Some(&instruction_recorders[instruction_index]);
|
||||||
}
|
}
|
||||||
let pre_remaining_units = invoke_context.get_compute_meter().borrow().get_remaining();
|
|
||||||
let mut time = Measure::start("execute_instruction");
|
let mut time = Measure::start("execute_instruction");
|
||||||
invoke_context
|
let compute_meter_consumption = invoke_context
|
||||||
.process_instruction(message, instruction, program_indices, &[], &[])
|
.process_instruction(message, instruction, program_indices, &[], &[])
|
||||||
.map_err(|err| TransactionError::InstructionError(instruction_index as u8, err))?;
|
.map_err(|err| TransactionError::InstructionError(instruction_index as u8, err))?;
|
||||||
time.stop();
|
time.stop();
|
||||||
let post_remaining_units = invoke_context.get_compute_meter().borrow().get_remaining();
|
|
||||||
timings.accumulate_program(
|
timings.accumulate_program(
|
||||||
instruction.program_id(&message.account_keys),
|
instruction.program_id(&message.account_keys),
|
||||||
time.as_us(),
|
time.as_us(),
|
||||||
pre_remaining_units - post_remaining_units,
|
compute_meter_consumption,
|
||||||
);
|
);
|
||||||
timings.accumulate(&invoke_context.timings);
|
timings.accumulate(&invoke_context.timings);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user