This repository was archived by the owner on Aug 27, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 275
[master] Otterscan final apis #3634
Merged
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
ed7b1ba
Add `erigon_getHeaderByNumber`
JamesHinshelwood 5722467
Add `ots_getApiLevel`
JamesHinshelwood 3859541
Add `ots_hasCode`
JamesHinshelwood 9223ace
Add `ots_getBlockDetails`
JamesHinshelwood 33ca374
Add `ots_getBlockTransactions`
JamesHinshelwood 4e9e359
Add `ots_getContractCreator`
JamesHinshelwood 101846e
Merge branch 'otterscan' into otter
n-hutton 6523035
WIP
n-hutton 9236492
WIP, first pass
n-hutton 68d8f66
adhere to otter pagination
n-hutton 65e6ed0
more cleanup
n-hutton 60d21df
add the otter tests too
n-hutton 0f51026
further cleanup
n-hutton 6ca45e3
hmm
n-hutton 087413b
Merge branch 'master' into otter
n-hutton c4893d3
cleanup
n-hutton ab7f98a
more fixes
n-hutton 6a7eb86
add before figuring out why ci fails
n-hutton 929029a
add before figuring out why ci fails2
n-hutton 30851ce
back to it..
n-hutton 8fcc60d
disable otter test...
n-hutton 4836ae4
remove debug
n-hutton 5012731
make mocha work better hopefully
n-hutton 6469aed
increase timeout...
n-hutton 6cc24be
readd batch transfer
n-hutton 31ede36
clean
n-hutton 1864f2f
bail on first test failure
n-hutton 4eb997d
hope it wasn't this...
n-hutton 1e6e02f
getting desperate..
n-hutton 1058cea
hard kill
n-hutton 6fc381a
make it an interrupt
n-hutton d47d12a
cleanup
n-hutton 1fa9076
Update evm-ds/src/evm_server_run.rs
n-hutton 339f80c
cleanup
n-hutton 40c669c
asdfsdf
n-hutton 0a41d1f
sigh
n-hutton File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,10 +5,7 @@ use std::sync::{Arc, Mutex}; | |
|
|
||
| use crate::CallContext; | ||
| use evm::executor::stack::MemoryStackSubstate; | ||
| use evm::{ | ||
| backend::Apply, | ||
| executor::stack::{MemoryStackState, StackSubstateMetadata}, | ||
| }; | ||
| use evm::{backend::Apply, executor::stack::{MemoryStackState, StackSubstateMetadata}}; | ||
| use evm::{Machine, Runtime}; | ||
|
|
||
| use log::{debug, error, info}; | ||
|
|
@@ -50,9 +47,9 @@ pub async fn run_evm_impl( | |
| // panic. (Using the parent runtime and dropping on stack unwind will mess up the parent runtime). | ||
| tokio::task::spawn_blocking(move || { | ||
| debug!( | ||
| "Running EVM: origin: {:?} address: {:?} gas: {:?} value: {:?} extras: {:?}, estimate: {:?}, cps: {:?}, tx_trace: {:?}", | ||
| "Running EVM: origin: {:?} address: {:?} gas: {:?} value: {:?} extras: {:?}, estimate: {:?} is_continuation: {:?}, cps: {:?}, \ntx_trace: {:?}, \ndata: {:02X?}, \ncode: {:02X?}", | ||
| backend.origin, address, gas_limit, apparent_value, | ||
| backend.extras, estimate, enable_cps, tx_trace); | ||
| backend.extras, estimate, node_continuation.is_none(), enable_cps, tx_trace, data, code); | ||
| let code = Rc::new(code); | ||
| let data = Rc::new(data); | ||
| // TODO: handle call_l64_after_gas problem: https://zilliqa-jira.atlassian.net/browse/ZIL-5012 | ||
|
|
@@ -157,25 +154,31 @@ pub async fn run_evm_impl( | |
| listener.finished_call(); | ||
|
|
||
| match exit_reason { | ||
| evm::ExitReason::Succeed(_) => {} | ||
| evm::ExitReason::Revert(_) => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when tx fails, capture error blob |
||
| listener.otter_transaction_error = format!("0x{}", hex::encode(runtime.machine().return_value())); | ||
| } | ||
| _ => { | ||
| debug!("Machine: position: {:?}, memory: {:?}, stack: {:?}", | ||
| runtime.machine().position(), | ||
| &runtime.machine().memory().data().iter().take(128).collect::<Vec<_>>(), | ||
| &runtime.machine().stack().data().iter().take(128).collect::<Vec<_>>()); | ||
| } | ||
| } | ||
|
|
||
| build_exit_result(executor, &runtime, &backend, &listener, &exit_reason, remaining_gas, is_static, continuations) | ||
| }, | ||
| CpsReason::CallInterrupt(i) => { | ||
| let cont_id = continuations.lock().unwrap().create_continuation(runtime.machine_mut(), executor.state().substate()); | ||
|
|
||
| build_call_result(executor, &runtime, &backend, i, &listener, remaining_gas, is_static, cont_id) | ||
| }, | ||
| CpsReason::CreateInterrupt(i) => { | ||
| let cont_id = continuations.lock().unwrap().create_continuation(runtime.machine_mut(), executor.into_state().substate()); | ||
|
|
||
| build_create_result(&runtime, i, &listener, remaining_gas, cont_id) | ||
| } | ||
| }; | ||
|
|
||
| info!( | ||
| "EVM execution summary: context: {:?}, origin: {:?} address: {:?} gas: {:?} value: {:?}, data: {:?}, extras: {:?}, estimate: {:?}, cps: {:?}, result: {}, returnVal: {}", | ||
| evm_context, backend.origin, address, gas_limit, apparent_value, | ||
|
|
@@ -322,6 +325,7 @@ fn build_call_result( | |
| context.set_apparent_value(interrupt.context.apparent_value.into()); | ||
| context.set_caller(interrupt.context.caller.into()); | ||
| context.set_destination(interrupt.context.address.into()); | ||
|
|
||
| trap_data_call.set_context(context); | ||
|
|
||
| if let Some(tran) = interrupt.transfer { | ||
|
|
@@ -414,4 +418,4 @@ fn handle_panic(trace: String, remaining_gas: u64, reason: &str) -> EvmProto::Ev | |
| result.set_tx_trace(trace.into()); | ||
| result.set_remaining_gas(remaining_gas); | ||
| result | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,6 +61,17 @@ struct Args { | |
| zil_scaling_factor: u64, | ||
| } | ||
|
|
||
| #[derive(Debug, Serialize, Deserialize, Default)] | ||
| struct OtterscanCallContext { | ||
| #[serde(rename = "type")] | ||
| pub call_type: String, | ||
| pub depth: usize, | ||
| pub from: String, | ||
| pub to: String, | ||
| pub value: String, | ||
| pub input: String, | ||
| } | ||
|
|
||
| #[derive(Debug, Serialize, Deserialize, Default)] | ||
| struct CallContext { | ||
| #[serde(rename = "type")] | ||
|
|
@@ -114,6 +125,10 @@ struct StructLog { | |
| struct LoggingEventListener { | ||
| call_tracer: Vec<CallContext>, | ||
| raw_tracer: StructLogTopLevel, | ||
| otter_internal_tracer: Vec<InternalOperationOtter>, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reuse transaction trace struct |
||
| otter_call_tracer: Vec<OtterscanCallContext>, | ||
| otter_transaction_error: String, | ||
| otter_addresses_called: Vec<String>, | ||
| enabled: bool, | ||
| } | ||
|
|
||
|
|
@@ -126,11 +141,24 @@ struct StructLogTopLevel { | |
| pub struct_logs: Vec<StructLog>, | ||
| } | ||
|
|
||
| #[derive(Debug, Serialize, Deserialize, Default)] | ||
| struct InternalOperationOtter { | ||
| #[serde(rename = "type")] | ||
| pub call_type: usize, | ||
| pub from: String, | ||
| pub to: String, | ||
| pub value: String, | ||
| } | ||
|
|
||
| impl LoggingEventListener { | ||
| fn new(enabled: bool) -> Self { | ||
| LoggingEventListener { | ||
| call_tracer: Default::default(), | ||
| raw_tracer: Default::default(), | ||
| otter_internal_tracer: Default::default(), | ||
| otter_call_tracer: Default::default(), | ||
| otter_transaction_error: "0x".to_string(), | ||
| otter_addresses_called: Default::default(), | ||
| enabled, | ||
| } | ||
| } | ||
|
|
@@ -142,11 +170,15 @@ impl evm::runtime::tracing::EventListener for LoggingEventListener { | |
| return; | ||
| } | ||
|
|
||
| let call_depth = self.call_tracer.len() - 1; | ||
|
|
||
| let mut struct_log = StructLog { | ||
| depth: self.call_tracer.len() - 1, | ||
| depth: call_depth, | ||
| ..Default::default() | ||
| }; | ||
|
|
||
| let mut intern_trace = None; | ||
|
|
||
| match event { | ||
| evm::runtime::tracing::Event::Step { | ||
| context: _, | ||
|
|
@@ -183,11 +215,94 @@ impl evm::runtime::tracing::EventListener for LoggingEventListener { | |
| } => { | ||
| struct_log.op = "SStore".to_string(); | ||
| } | ||
| evm::runtime::tracing::Event::TransactTransfer { | ||
| call_type, | ||
| address, | ||
| target, | ||
| balance, | ||
| input, | ||
| } => { | ||
| intern_trace = Some(InternalOperationOtter { | ||
| call_type: call_depth, | ||
| from: format!("{:?}", address), | ||
| to: format!("{:?}", target), | ||
| value: format!("{:0X?}", balance), | ||
| }); | ||
|
|
||
| self.otter_call_tracer.push(OtterscanCallContext{ | ||
| call_type: call_type.to_string(), | ||
| depth: call_depth, | ||
| from: format!("{:?}", address), | ||
| to: format!("{:?}", target), | ||
| value: format!("{:0X?}", balance), | ||
| input: input.to_string(),}); | ||
|
|
||
| let to_add = format!("{:?}", target); | ||
|
|
||
| // only push if doesn't exist in otter_addresses_called | ||
| if !self.otter_addresses_called.contains(&to_add) { | ||
| self.otter_addresses_called.push(to_add); | ||
| } | ||
| } | ||
| evm::runtime::tracing::Event::TransactSuicide { | ||
| address, | ||
| target, | ||
| balance, | ||
| } => { | ||
| intern_trace = Some(InternalOperationOtter { | ||
| call_type: 1, | ||
| from: format!("{:?}", address), | ||
| to: format!("{:?}", target), | ||
| value: format!("{:0X?}", balance), | ||
| }); | ||
|
|
||
| self.otter_call_tracer.push(OtterscanCallContext{ | ||
| call_type: "SELFDESTRUCT".to_string(), | ||
| depth: call_depth, | ||
| from: format!("{:?}", address), | ||
| to: format!("{:?}", target), | ||
| value: format!("{:0X?}", balance), | ||
| input: "".to_string(),}); | ||
| } | ||
| evm::runtime::tracing::Event::TransactCreate { | ||
| call_type, | ||
| address, | ||
| target, | ||
| balance, | ||
| is_create2, | ||
| input, | ||
| } => { | ||
| intern_trace = Some(InternalOperationOtter { | ||
| call_type: if is_create2 { 3 } else { 2 }, | ||
| from: format!("{:?}", address), | ||
| to: format!("{:?}", target), | ||
| value: format!("{:0X?}", balance), | ||
| }); | ||
|
|
||
| self.otter_call_tracer.push(OtterscanCallContext{ | ||
| call_type: call_type.to_string(), | ||
| depth: call_depth, | ||
| from: format!("{:?}", address), | ||
| to: format!("{:?}", target), | ||
| value: format!("{:0X?}", balance), | ||
| input: input.to_string(),}); | ||
|
|
||
| let to_add = format!("{:?}", target); | ||
|
|
||
| // only push if doesn't exist in otter_addresses_called | ||
| if !self.otter_addresses_called.contains(&to_add) { | ||
| self.otter_addresses_called.push(to_add); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if self.raw_tracer.struct_logs.len() < 5 { | ||
| self.raw_tracer.struct_logs.push(struct_log); | ||
| } | ||
|
|
||
| if let Some(intern_trace) = intern_trace { | ||
| self.otter_internal_tracer.push(intern_trace); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -118,9 +118,12 @@ else | |
|
|
||
| cd tests/EvmAcceptanceTests/ | ||
| npm install | ||
| DEBUG=true MOCHA_TIMEOUT=20000 npx hardhat test | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this has effect of not interleaving the hardhat output with the iso server output, it just dumps it after |
||
| DEBUG=true MOCHA_TIMEOUT=40000 npx hardhat test --bail 2>&1 > npx.out | ||
|
|
||
| retVal=$? | ||
|
|
||
| pkill -INT isolatedServer | ||
| cat npx.out | ||
| if [ $retVal -ne 0 ]; then | ||
| echo "!!!!!! Error with JS integration test !!!!!!" | ||
| exit 1 | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now a requirement of handler via the evm PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
get_create_addressactually used anywhere in this PR? I can't find any usages.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the other PR that adds evm functionality it adds it as a handler fn and is used there
impl<'a> Handler for CpsExecutor<'a>