edb_engine/eval/
common.rs

1// EDB - Ethereum Debugger
2// Copyright (C) 2024 Zhuo Zhang and Wuqi Zhang
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Affero General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Affero General Public License for more details.
13//
14// You should have received a copy of the GNU Affero General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17//! Common evaluation utilities and convenience functions.
18//!
19//! This module provides high-level convenience functions for expression evaluation
20//! that are commonly used throughout the EDB system.
21
22use std::sync::Arc;
23
24use alloy_dyn_abi::DynSolValue;
25use eyre::Result;
26use revm::{database::CacheDB, Database, DatabaseCommit, DatabaseRef};
27
28use crate::{EngineContext, ExpressionEvaluator};
29
30/// Evaluate a Solidity expression string within the context of a specific debug snapshot.
31///
32/// This is a convenience function that creates an EDB-configured expression evaluator
33/// and evaluates the given expression against the specified snapshot.
34///
35/// # Arguments
36/// * `context` - The EDB engine context containing snapshots and trace data
37/// * `expr` - The expression string to evaluate (e.g., "balances[msg.sender]")
38/// * `snapshot_id` - The ID of the debug snapshot to evaluate against
39///
40/// # Returns
41/// The result of the expression evaluation as a [`DynSolValue`]
42///
43/// # Errors
44/// Returns an error if:
45/// - The expression cannot be parsed
46/// - The snapshot ID is invalid
47/// - The expression evaluation fails (e.g., variable not found, function call fails)
48///
49/// # Examples
50/// ```rust,ignore
51/// // Evaluate a balance check
52/// let result = eval_on_snapshot(context, "balances[msg.sender] > 1000", snapshot_id)?;
53///
54/// // Evaluate a function call
55/// let supply = eval_on_snapshot(context, "totalSupply()", snapshot_id)?;
56///
57/// // Evaluate blockchain context
58/// let is_recent = eval_on_snapshot(context, "block.timestamp - lastUpdate < 3600", snapshot_id)?;
59/// ```
60pub fn eval_on_snapshot<DB>(
61    context: Arc<EngineContext<DB>>,
62    expr: &str,
63    snapshot_id: usize,
64) -> Result<DynSolValue>
65where
66    DB: Database + DatabaseCommit + DatabaseRef + Clone + Send + Sync + 'static,
67    <CacheDB<DB> as Database>::Error: Clone + Send + Sync,
68    <DB as Database>::Error: Clone + Send + Sync,
69{
70    let evaluator = ExpressionEvaluator::new_edb(context);
71    evaluator.eval(expr, snapshot_id)
72}