Skip to content

Commit

Permalink
fix(tracing/js): error not set in result_fn (paradigmxyz#222)
Browse files Browse the repository at this point in the history
We only set step's error, but missing the result's one. 


use this tx to test it

```json
{
  "jsonrpc": "2.0",
  "method": "debug_traceTransaction",
  "id": "1",
  "params": [
    "0x18ba7c5bcb851072612c0451377f55ac4ef83986ec8d9f87a2ce07c9a7d6371f", 
	{
      "tracer": "{ fault: function() {}, result: function(ctx, _) { return { error: !!ctx.error }; } }"
    }
  ]
}
```

for geth/erigon's response is:

```json
{
  "id": "1",
  "jsonrpc": "2.0",
  "result": {
    "error": true
  }
}
```

currently reth's response is:

```json
{
  "id": "1",
  "jsonrpc": "2.0",
  "result": {
    "error": false
  }
}
```

---------

Signed-off-by: jsvisa <delweng@gmail.com>
  • Loading branch information
jsvisa authored and lwedge99 committed Jan 3, 2025
1 parent 0830416 commit 762f51d
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 6 deletions.
8 changes: 7 additions & 1 deletion src/tracing/js/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,9 +672,11 @@ pub(crate) struct JsEvmContext {
/// Number, block number
pub(crate) block: u64,
pub(crate) output: Bytes,
/// Number, block number
/// Number, block timestamp
pub(crate) time: String,
pub(crate) transaction_ctx: TransactionContext,
/// returns information about the error if one occurred, otherwise returns undefined
pub(crate) error: Option<String>,
}

impl JsEvmContext {
Expand All @@ -693,6 +695,7 @@ impl JsEvmContext {
output,
time,
transaction_ctx,
error,
} = self;
let obj = JsObject::default();

Expand Down Expand Up @@ -724,6 +727,9 @@ impl JsEvmContext {
if let Some(tx_hash) = transaction_ctx.tx_hash {
obj.set(js_string!("txHash"), to_byte_array(tx_hash.0, ctx)?, false, ctx)?;
}
if let Some(error) = error {
obj.set(js_string!("error"), js_string!(error), false, ctx)?;
}

Ok(obj)
}
Expand Down
16 changes: 11 additions & 5 deletions src/tracing/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ impl JsInspector {
let gas_used = result.gas_used();
let mut to = None;
let mut output_bytes = None;
let mut error = None;
match result {
ExecutionResult::Success { output, .. } => match output {
Output::Call(out) => {
Expand All @@ -247,17 +248,21 @@ impl JsInspector {
}
},
ExecutionResult::Revert { output, .. } => {
error = Some("execution reverted".to_string());
output_bytes = Some(output);
}
ExecutionResult::Halt { .. } => {}
ExecutionResult::Halt { reason, .. } => {
error = Some(format!("execution halted: {:?}", reason));
}
};

if let TransactTo::Call(target) = env.tx.transact_to {
to = Some(target);
}

let ctx = JsEvmContext {
r#type: match env.tx.transact_to {
TransactTo::Call(target) => {
to = Some(target);
"CALL"
}
TransactTo::Call(_) => "CALL",
TransactTo::Create => "CREATE",
}
.to_string(),
Expand All @@ -273,6 +278,7 @@ impl JsInspector {
time: env.block.timestamp.to_string(),
intrinsic_gas: 0,
transaction_ctx: self.transaction_context,
error,
};
let ctx = ctx.into_js_object(&mut self.ctx)?;
let db = db.into_js_object(&mut self.ctx)?;
Expand Down
104 changes: 104 additions & 0 deletions tests/it/geth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ use revm::{
};
use revm_inspectors::tracing::{MuxInspector, TracingInspector, TracingInspectorConfig};

#[cfg(feature = "js-tracer")]
use revm_inspectors::tracing::js::JsInspector;

#[test]
fn test_geth_calltracer_logs() {
/*
Expand Down Expand Up @@ -335,3 +338,104 @@ fn test_geth_inspector_reset() {
1000000
);
}

#[test]
#[cfg(feature = "js-tracer")]
fn test_geth_jstracer_revert() {
/*
pragma solidity ^0.8.13;
contract Foo {
event Log(address indexed addr, uint256 value);
function foo() external {
emit Log(msg.sender, 0);
}
function bar() external {
emit Log(msg.sender, 0);
require(false, "barbarbar");
}
}
*/

let code = hex!("608060405261023e806100115f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063c298557814610038578063febb0f7e14610042575b5f80fd5b61004061004c565b005b61004a61009c565b005b3373ffffffffffffffffffffffffffffffffffffffff167ff950957d2407bed19dc99b718b46b4ce6090c05589006dfb86fd22c34865b23e5f6040516100929190610177565b60405180910390a2565b3373ffffffffffffffffffffffffffffffffffffffff167ff950957d2407bed19dc99b718b46b4ce6090c05589006dfb86fd22c34865b23e5f6040516100e29190610177565b60405180910390a25f61012a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610121906101ea565b60405180910390fd5b565b5f819050919050565b5f819050919050565b5f819050919050565b5f61016161015c6101578461012c565b61013e565b610135565b9050919050565b61017181610147565b82525050565b5f60208201905061018a5f830184610168565b92915050565b5f82825260208201905092915050565b7f62617262617262617200000000000000000000000000000000000000000000005f82015250565b5f6101d4600983610190565b91506101df826101a0565b602082019050919050565b5f6020820190508181035f830152610201816101c8565b905091905056fea2646970667358221220e058dc2c4bd629d62405850cc8e08e6bfad0eea187260784445dfe8f3ee0bea564736f6c634300081a0033");
let deployer = Address::ZERO;

let mut db = CacheDB::new(EmptyDB::default());

let cfg = CfgEnvWithHandlerCfg::new(CfgEnv::default(), HandlerCfg::new(SpecId::CANCUN));

let env = EnvWithHandlerCfg::new_with_cfg_env(
cfg.clone(),
BlockEnv::default(),
TxEnv {
caller: deployer,
gas_limit: 1000000,
transact_to: TransactTo::Create,
data: code.into(),
..Default::default()
},
);

let mut insp = TracingInspector::new(TracingInspectorConfig::default_geth());

// Create contract
let (res, _) = inspect(&mut db, env, &mut insp).unwrap();
let addr = match res.result {
ExecutionResult::Success { output, .. } => match output {
Output::Create(_, addr) => addr.unwrap(),
_ => panic!("Create failed"),
},
_ => panic!("Execution failed: {:?}", res.result),
};
db.commit(res.state);

let code = r#"
{
fault: function() {},
result: function(ctx) { return { error: !!ctx.error }; },
}"#;

// test with normal operation
let env = EnvWithHandlerCfg::new_with_cfg_env(
cfg.clone(),
BlockEnv::default(),
TxEnv {
caller: deployer,
gas_limit: 1000000,
transact_to: TransactTo::Call(addr),
data: hex!("c2985578").into(), // call foo
..Default::default()
},
);
let mut insp = JsInspector::new(code.to_string(), serde_json::Value::Null).unwrap();
let (res, _) = inspect(&mut db, env.clone(), &mut insp).unwrap();
assert!(res.result.is_success());

let result = insp.json_result(res, &env, &db).unwrap();

// sucessful operation
assert!(!result["error"].as_bool().unwrap());

// test with reverted operation
let env = EnvWithHandlerCfg::new_with_cfg_env(
cfg,
BlockEnv::default(),
TxEnv {
caller: deployer,
gas_limit: 1000000,
transact_to: TransactTo::Call(addr),
data: hex!("febb0f7e").into(), // call bar
..Default::default()
},
);
let mut insp = JsInspector::new(code.to_string(), serde_json::Value::Null).unwrap();
let (res, _) = inspect(&mut db, env.clone(), &mut insp).unwrap();
assert!(!res.result.is_success());

let result = insp.json_result(res, &env, &db).unwrap();

// reverted operation
assert!(result["error"].as_bool().unwrap());
}

0 comments on commit 762f51d

Please sign in to comment.