Skip to content
Open
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
8 changes: 6 additions & 2 deletions rholang/src/rust/interpreter/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ impl InterpreterImpl {
parsing_cost: Cost,
error: InterpreterError,
) -> Result<EvaluateResult, InterpreterError> {
// Calculate the evaluated cost (actual cost consumed so far)
let phlos_left = self.c.get();
let eval_cost = initial_cost.clone() - phlos_left;

match error {
// Parsing error consumes only parsing cost
InterpreterError::ParserError(_) => Ok(EvaluateResult {
Expand Down Expand Up @@ -147,9 +151,9 @@ impl InterpreterImpl {
mergeable: HashSet::new(),
}),

// InterpreterError is returned as a result
// InterpreterError is returned as a result with evaluated cost
_ => Ok(EvaluateResult {
cost: initial_cost,
cost: eval_cost,
errors: vec![error],
mergeable: HashSet::new(),
}),
Expand Down
57 changes: 57 additions & 0 deletions rholang/tests/interpreter_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,60 @@ async fn interpreter_should_charge_for_parsing_even_when_not_enough_phlo() {
})
.await
}

#[tokio::test]
async fn interpreter_should_return_actual_eval_cost_for_interpreter_errors() {
use rholang::rust::interpreter::accounting::costs::Cost;

with_runtime("eval-cost-error-spec-", |mut runtime| async move {
// This term will cause an InterpreterError during evaluation
// (consuming from stdout which is a system process requires specific patterns)
let stdout_consume_term = r#"
new stdout(`rho:io:stdout`) in {
for(_ <- stdout) {
Nil
}
}
"#;

let phlo_limit = 100000i64;
let initial_phlo = Cost::create(phlo_limit, "test".to_string());

let result = runtime
.evaluate_with_phlo(stdout_consume_term, initial_phlo.clone())
.await
.unwrap();

// Verify that an error occurred
assert!(
!result.errors.is_empty(),
"Expected InterpreterError to occur"
);

// Verify that the cost is greater than 0 (some evaluation happened)
assert!(
result.cost.value > 0,
"Expected cost > 0, but got {}",
result.cost.value
);

// Verify that the cost is less than the phlo limit (not all phlos consumed)
assert!(
result.cost.value < phlo_limit,
"Expected cost < {}, but got {}",
phlo_limit,
result.cost.value
);

// Verify that the cost is more than just parsing cost
// (it should include evaluation costs)
let parsing_cost_value = parsing_cost(stdout_consume_term).value;
assert!(
result.cost.value > parsing_cost_value,
"Expected cost {} > parsing cost {}, indicating evaluation occurred",
result.cost.value,
parsing_cost_value
);
})
.await
}
Loading