Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(snapshot): code split #198

Merged
merged 24 commits into from
Dec 11, 2023

Conversation

iankressin
Copy link
Contributor

Motivation

The core logic for the snapshot module is currently implemented into a single function. At times, due to its length, this function can be hard to fully grasp. Also the internal logic is not testable at the moment, which can make debugging hard in the future.

Solution

This PR aims to improve code quality, testability and maintainability of snapshot module by splitting its core logic into smaller chunks

Copy link
Owner

@Jon-Becker Jon-Becker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great so far! Just a few nitpicks but awesome work :)

})
}

fn set_logger_env(verbosity: &clap_verbosity_flag::Verbosity) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's move extra funcs to separate files, mod.rs should be for the main function only imo

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could also be a heimdall-common function since I use it in each module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completely agree. The first step was to split the function into smaller ones, now I want to distribute this functions to other files or group them into structs

Copy link
Owner

@Jon-Becker Jon-Becker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking awesome so far! Mostly just nits, such as using the new common functions throughout the codebase.

Great work <3

let (logger, _) = Logger::new("");

if ADDRESS_REGEX.is_match(target)? {
// We are snapshotting a contract address, so we need to fetch the bytecode from the RPC
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update comments to be module agnostic

logger.debug_max("using provided bytecode for snapshotting.");
Ok(target.replacen("0x", "", 1))
} else {
logger.debug_max("using provided file for snapshotting.");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsure if debug_max! macro exists in this PR context, but worth noting that i should update these calls later.

see #215 or #216 for details

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it's available. I had to merge main in this PR due to some conflicts and already updated some places to use the new macro, but ended up missing this one

@@ -144,7 +144,7 @@ pub async fn get_code(
None,
);

Ok(bytecode_as_bytes.to_string())
Ok(bytecode_as_bytes.to_string().replacen("0x", "", 1))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i added this, which normalizes the get_code response and never includes the 0x prefix.

previously, we stored the value in cache without the prefix, and returned it with the prefix. this just keeps everything consistent.

use crate::debug_max;

// Find all function selectors and all the data associated to this function, represented by
// [`ResolvedFunction`]
pub async fn get_resolved_selectors(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooh nice! we should use this function in other modules (such as decompile)

};
use std::fs;

pub async fn get_contract_bytecode(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use this function in other modules as well, such as decompile

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we do this in this PR or in a separate one? I can def do on this one, it's just a matter of how you prefer reviewing the code.

the same question stands for get_resolved_selectors and get_shortned_target

resolved_selectors =
resolve_selectors::<ResolvedFunction>(selectors.keys().cloned().collect()).await;

// if resolved selectors are empty, we can't perform symbolic execution
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update comment, we dont do symbolic execution here

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, if resolved_selectors is empty, nothing fails. heimdall can guess things!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this log can be removed, right?

/// let verbosity = clap_verbosity_flag::Verbosity::new(-1, 0);
/// set_logger_env(&verbosity);
/// ```
pub fn set_logger_env(verbosity: &clap_verbosity_flag::Verbosity) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:D nice!

/// let verbosity = clap_verbosity_flag::Verbosity::new(-1, 0);
/// get_logger_and_trace(&verbosity);
/// ```
pub fn get_logger_and_trace(verbosity: &clap_verbosity_flag::Verbosity) -> (Logger, TraceFactory) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now you can actually just use Logger::new, it'll return (Logger, TraceFactory)

I do have #126 open which will update this functionality eventually (all logger methods being moved to macros, TraceFactory separated from Logger.

/// let long_target = "0".repeat(80);
/// let shortened_target = get_shortned_target(&long_target);
/// ```
pub fn get_shortned_target(target: &String) -> String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! let's make sure to use this function throughout the codebase

Ok(())
}

async fn resolve_custom_events_signatures(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to resolve_event_signatures

@iankressin iankressin marked this pull request as ready for review December 9, 2023 15:43
Copy link
Owner

@Jon-Becker Jon-Becker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome work :)

@Jon-Becker Jon-Becker merged commit 23addf5 into Jon-Becker:main Dec 11, 2023
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants