Skip to content

Commit cc25527

Browse files
authored
chore: documentation and linting overhaul (#549)
* wip * wip * wip * chore: docs * docs: Delete output.txt * documentation * documentation * documentation * documentation * docs: Remove unnecessary code comments
1 parent f5df5ff commit cc25527

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+1160
-224
lines changed

Cargo.toml

+66
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,72 @@ repository = "https://github.com/Jon-Becker/heimdall-rs"
4040
keywords = ["ethereum", "web3", "decompiler", "evm", "crypto"]
4141
exclude = [".github/"]
4242

43+
[workspace.lints]
44+
rust.missing_debug_implementations = "warn"
45+
rust.missing_docs = "warn"
46+
rust.unreachable_pub = "warn"
47+
rust.unused_must_use = "deny"
48+
rust.rust_2018_idioms = { level = "deny", priority = -1 }
49+
rustdoc.all = "warn"
50+
51+
[workspace.lints.clippy]
52+
# These are some of clippy's nursery (i.e., experimental) lints that we like.
53+
# By default, nursery lints are allowed. Some of the lints below have made good
54+
# suggestions which we fixed. The others didn't have any findings, so we can
55+
# assume they don't have that many false positives. Let's enable them to
56+
# prevent future problems.
57+
branches_sharing_code = "warn"
58+
clear_with_drain = "warn"
59+
derive_partial_eq_without_eq = "warn"
60+
empty_line_after_outer_attr = "warn"
61+
equatable_if_let = "warn"
62+
imprecise_flops = "warn"
63+
iter_on_empty_collections = "warn"
64+
iter_with_drain = "warn"
65+
large_stack_frames = "warn"
66+
manual_clamp = "warn"
67+
mutex_integer = "warn"
68+
needless_pass_by_ref_mut = "warn"
69+
nonstandard_macro_braces = "warn"
70+
or_fun_call = "warn"
71+
path_buf_push_overwrite = "warn"
72+
read_zero_byte_vec = "warn"
73+
redundant_clone = "warn"
74+
suboptimal_flops = "warn"
75+
suspicious_operation_groupings = "warn"
76+
trailing_empty_array = "warn"
77+
trait_duplication_in_bounds = "warn"
78+
transmute_undefined_repr = "warn"
79+
trivial_regex = "warn"
80+
tuple_array_conversions = "warn"
81+
uninhabited_references = "warn"
82+
unused_peekable = "warn"
83+
unused_rounding = "warn"
84+
useless_let_if_seq = "warn"
85+
86+
# These are nursery lints which have findings. Allow them for now. Some are not
87+
# quite mature enough for use in our codebase and some we don't really want.
88+
# Explicitly listing should make it easier to fix in the future.
89+
as_ptr_cast_mut = "allow"
90+
cognitive_complexity = "allow"
91+
collection_is_never_read = "allow"
92+
debug_assert_with_mut_call = "allow"
93+
empty_line_after_doc_comments = "allow"
94+
fallible_impl_from = "allow"
95+
future_not_send = "allow"
96+
iter_on_single_items = "allow"
97+
missing_const_for_fn = "allow"
98+
needless_collect = "allow"
99+
non_send_fields_in_send_ty = "allow"
100+
option_if_let_else = "allow"
101+
redundant_pub_crate = "allow"
102+
significant_drop_in_scrutinee = "allow"
103+
significant_drop_tightening = "allow"
104+
string_lit_as_bytes = "allow"
105+
type_repetition_in_bounds = "allow"
106+
unnecessary_struct_initialization = "allow"
107+
use_self = "allow"
108+
43109
[workspace.dependencies]
44110
heimdall-core = { path = "crates/core" }
45111
heimdall-cache = { path = "crates/cache" }

crates/cache/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ repository.workspace = true
1010
keywords.workspace = true
1111
exclude.workspace = true
1212

13+
[lints]
14+
workspace = true
15+
1316
[lib]
1417
bench = false
1518

crates/cache/src/error.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
//! Cache errors
2+
3+
/// Generic error type for heimdall cache operations
14
#[derive(Debug, thiserror::Error)]
25
pub enum Error {
6+
/// Generic error
37
#[error("Error: {0}")]
48
Generic(String),
9+
/// An IO error occurred
510
#[error("IO error: {0}")]
611
IOError(#[from] std::io::Error),
712
}

crates/cache/src/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
//! A simple cache system for heimdall-rs
2+
//! Stores objects in ~/.bifrost/cache as bincode serialized files
3+
//! Objects are stored with an expiry time, and are deleted if they are expired
4+
15
use clap::Parser;
26
use serde::{de::DeserializeOwned, Deserialize, Serialize};
37
#[allow(deprecated)]
@@ -17,6 +21,7 @@ pub(crate) mod util;
1721
override_usage = "heimdall cache <SUBCOMMAND>"
1822
)]
1923
pub struct CacheArgs {
24+
/// Cache subcommand
2025
#[clap(subcommand)]
2126
pub sub: Subcommands,
2227
}
@@ -33,12 +38,15 @@ pub struct NoArguments {}
3338
)]
3439
#[allow(clippy::large_enum_variant)]
3540
pub enum Subcommands {
41+
/// Clear the cache, removing all objects
3642
#[clap(name = "clean", about = "Removes all cached objects in ~/.bifrost/cache")]
3743
Clean(NoArguments),
3844

45+
/// List all cached objects
3946
#[clap(name = "ls", about = "Lists all cached objects in ~/.bifrost/cache")]
4047
Ls(NoArguments),
4148

49+
/// Print the size of the cache in ~/.bifrost/cache
4250
#[clap(name = "size", about = "Prints the size of the cache in ~/.bifrost/cache")]
4351
Size(NoArguments),
4452
}
@@ -47,7 +55,9 @@ pub enum Subcommands {
4755
/// The expiry time is a unix timestamp
4856
#[derive(Debug, Clone, Deserialize, Serialize)]
4957
pub struct Cache<T> {
58+
/// The value stored in the cache
5059
pub value: T,
60+
/// The expiry time of the cache object
5161
pub expiry: u64,
5262
}
5363

crates/cache/src/util.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@ use std::{
1010
use crate::error::Error;
1111

1212
/// Decode a hex string into a bytearray
13-
pub fn decode_hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
13+
pub(crate) fn decode_hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
1414
(0..s.len()).step_by(2).map(|i| u8::from_str_radix(&s[i..i + 2], 16)).collect()
1515
}
1616

1717
/// Encode a bytearray into a hex string
18-
pub fn encode_hex(s: Vec<u8>) -> String {
18+
pub(crate) fn encode_hex(s: Vec<u8>) -> String {
1919
s.iter().fold(String::new(), |mut acc: String, b| {
2020
write!(acc, "{b:02x}", b = b).expect("unable to write");
2121
acc
2222
})
2323
}
2424

25-
/// Prettify bytes into a human-readable format \
26-
pub fn prettify_bytes(bytes: u64) -> String {
25+
/// Prettify bytes into a human-readable format
26+
pub(crate) fn prettify_bytes(bytes: u64) -> String {
2727
if bytes < 1024 {
2828
format!("{bytes} B")
2929
} else if bytes < 1024 * 1024 {
@@ -39,7 +39,8 @@ pub fn prettify_bytes(bytes: u64) -> String {
3939
}
4040

4141
/// Write contents to a file on the disc
42-
pub fn write_file(path_str: &str, contents: &str) -> Result<(), Error> {
42+
/// If the parent directory does not exist, it will be created
43+
pub(crate) fn write_file(path_str: &str, contents: &str) -> Result<(), Error> {
4344
let path = Path::new(path_str);
4445

4546
if let Some(prefix) = path.parent() {
@@ -58,7 +59,8 @@ pub fn write_file(path_str: &str, contents: &str) -> Result<(), Error> {
5859
}
5960

6061
/// Read contents from a file on the disc
61-
pub fn read_file(path: &str) -> Result<String, Error> {
62+
/// Returns the contents as a string
63+
pub(crate) fn read_file(path: &str) -> Result<String, Error> {
6264
let path = Path::new(path);
6365
let mut file = File::open(path)
6466
.map_err(|e| Error::IOError(std::io::Error::new(std::io::ErrorKind::Other, e)))?;
@@ -68,7 +70,8 @@ pub fn read_file(path: &str) -> Result<String, Error> {
6870
}
6971

7072
/// Delete a file or directory on the disc
71-
pub fn delete_path(_path: &str) -> bool {
73+
/// Returns true if the operation was successful
74+
pub(crate) fn delete_path(_path: &str) -> bool {
7275
let path = match std::path::Path::new(_path).to_str() {
7376
Some(path) => path,
7477
None => return false,

crates/cfg/Cargo.toml

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ repository.workspace = true
1010
keywords.workspace = true
1111
exclude.workspace = true
1212

13+
[lints]
14+
workspace = true
15+
1316
[lib]
1417
bench = false
1518

@@ -25,7 +28,11 @@ eyre = "0.6.12"
2528
futures = "0.3.30"
2629
lazy_static = "1.4.0"
2730
petgraph = "0.6.2"
28-
alloy = { version = "0.3.3", features = ["full", "rpc-types-debug", "rpc-types-trace"] }
31+
alloy = { version = "0.3.3", features = [
32+
"full",
33+
"rpc-types-debug",
34+
"rpc-types-trace",
35+
] }
2936

3037
heimdall-disassembler.workspace = true
3138
heimdall-vm.workspace = true

crates/cfg/src/core/graph.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ use std::collections::HashSet;
1010

1111
/// convert a symbolic execution [`VMTrace`] into a [`Graph`] of blocks, illustrating the
1212
/// control-flow graph found by the symbolic execution engine.
13-
// TODO: should this be a trait for VMTrace to implement?
14-
pub fn build_cfg(
13+
pub(crate) fn build_cfg(
1514
vm_trace: &VMTrace,
1615
contract_cfg: &mut Graph<String, String>,
1716
parent_node: Option<NodeIndex<u32>>,

crates/cfg/src/core/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ use super::CfgArgs;
1414
use crate::{core::graph::build_cfg, error::Error};
1515
use tracing::{debug, info};
1616

17+
/// The result of the cfg command. Contains the generated control flow graph.
1718
#[derive(Debug, Clone)]
1819
pub struct CfgResult {
20+
/// The generated control flow graph of the contract.
1921
pub graph: Graph<String, String>,
2022
}
2123

2224
impl CfgResult {
25+
/// Returns the control flow graph as a graphviz formatted string.
2326
pub fn as_dot(&self, color_edges: bool) -> String {
2427
let output = format!("{}", Dot::with_config(&self.graph, &[]));
2528

@@ -45,6 +48,7 @@ impl CfgResult {
4548
}
4649
}
4750

51+
/// Generates a control flow graph for the target contract.
4852
pub async fn cfg(args: CfgArgs) -> Result<CfgResult, Error> {
4953
// init
5054
let start_time = Instant::now();

crates/cfg/src/error.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1+
//! CFG Errors
2+
3+
/// Generic error type for the CFG Module
14
#[derive(Debug, thiserror::Error)]
25
pub enum Error {
6+
/// Error when trying to fetch information from the chain
37
#[error("Fetch error: {0}")]
48
FetchError(String),
9+
/// Error when disassembling contract bytecode
510
#[error("Disassembly error: {0}")]
611
DisassemblyError(#[from] heimdall_disassembler::Error),
12+
/// Generic error
713
#[error("Internal error: {0}")]
814
Eyre(#[from] eyre::Report),
915
}

crates/cfg/src/interfaces/args.rs

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use eyre::Result;
44
use heimdall_common::ether::bytecode::get_bytecode_from_target;
55
use heimdall_config::parse_url_arg;
66

7+
/// Arguments for the CFG subcommand
78
#[derive(Debug, Clone, Parser, Builder)]
89
#[clap(
910
about = "Generate a visual control flow graph for EVM bytecode",
@@ -43,12 +44,14 @@ pub struct CfgArgs {
4344
}
4445

4546
impl CfgArgs {
47+
/// Get the bytecode for the target
4648
pub async fn get_bytecode(&self) -> Result<Vec<u8>> {
4749
get_bytecode_from_target(&self.target, &self.rpc_url).await
4850
}
4951
}
5052

5153
impl CfgArgsBuilder {
54+
/// Create a new instance of the [`CfgArgsBuilder`]
5255
pub fn new() -> Self {
5356
Self {
5457
target: Some(String::new()),

crates/cfg/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//! The CFG module is responsible for generating control-flow graphs from the given
2+
//! contract's source code via symbolic execution.
3+
14
mod error;
25

36
mod core;

crates/cli/Cargo.toml

+9-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,17 @@ tracing = "0.1.40"
2626
tracing-subscriber = "0.3.18"
2727
eyre = "0.6.12"
2828
alloy-json-abi = "0.8.3"
29-
alloy = { version = "0.3.3", features = ["full", "rpc-types-debug", "rpc-types-trace"] }
29+
alloy = { version = "0.3.3", features = [
30+
"full",
31+
"rpc-types-debug",
32+
"rpc-types-trace",
33+
] }
3034
async-trait = "0.1.51"
3135

36+
[lints]
37+
workspace = true
38+
39+
3240
[[bin]]
3341
name = "heimdall"
3442
path = "src/main.rs"

crates/cli/src/args.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use tracing::{level_filters::LevelFilter, Level};
2020

2121
#[derive(Debug, Parser)]
2222
#[clap(name = "heimdall", author = "Jonathan Becker <jonathan@jbecker.dev>", version)]
23-
pub struct Arguments {
23+
pub(crate) struct Arguments {
2424
#[clap(subcommand)]
2525
pub sub: Subcommands,
2626

@@ -34,7 +34,7 @@ pub struct Arguments {
3434
after_help = "For more information, read the wiki: https://jbecker.dev/r/heimdall-rs/wiki"
3535
)]
3636
#[allow(clippy::large_enum_variant)]
37-
pub enum Subcommands {
37+
pub(crate) enum Subcommands {
3838
#[clap(name = "disassemble", about = "Disassemble EVM bytecode to assembly")]
3939
Disassemble(DisassemblerArgs),
4040

@@ -66,7 +66,7 @@ pub enum Subcommands {
6666
/// The log configuration.
6767
#[derive(Debug, Args)]
6868
#[clap(next_help_heading = "LOGGING")]
69-
pub struct LogArgs {
69+
pub(crate) struct LogArgs {
7070
/// The format to use for logs written to stdout.
7171
#[clap(long = "log.stdout.format", value_name = "FORMAT", global = true, default_value_t = LogFormat::Terminal)]
7272
pub log_stdout_format: LogFormat,
@@ -115,7 +115,7 @@ impl LogArgs {
115115
}
116116

117117
/// Initializes tracing with the configured options from cli args.
118-
pub fn init_tracing(&self) -> eyre::Result<Option<FileWorkerGuard>> {
118+
pub(crate) fn init_tracing(&self) -> eyre::Result<Option<FileWorkerGuard>> {
119119
let mut tracer = HeimdallTracer::new();
120120

121121
let stdout = self.layer(self.log_stdout_format, self.log_stdout_filter.clone(), true);
@@ -132,7 +132,7 @@ impl LogArgs {
132132

133133
/// The color mode for the cli.
134134
#[derive(Debug, Copy, Clone, ValueEnum, Eq, PartialEq)]
135-
pub enum ColorMode {
135+
pub(crate) enum ColorMode {
136136
/// Colors on
137137
Always,
138138
/// Colors on
@@ -167,7 +167,7 @@ impl FromStr for ColorMode {
167167
/// The verbosity settings for the cli.
168168
#[derive(Debug, Copy, Clone, Args)]
169169
#[clap(next_help_heading = "DISPLAY")]
170-
pub struct Verbosity {
170+
pub(crate) struct Verbosity {
171171
/// Set the minimum log level.
172172
///
173173
/// -v Warnings & Errors
@@ -185,7 +185,7 @@ pub struct Verbosity {
185185
impl Verbosity {
186186
/// Get the corresponding [Directive] for the given verbosity, or none if the verbosity
187187
/// corresponds to silent.
188-
pub fn directive(&self) -> Directive {
188+
pub(crate) fn directive(&self) -> Directive {
189189
if self.quiet {
190190
LevelFilter::OFF.into()
191191
} else {

crates/cli/src/main.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! The Heimdall CLI is a command line interface for interacting with Heimdall modules.
2+
13
pub(crate) mod args;
24
pub(crate) mod output;
35

@@ -19,6 +21,7 @@ use heimdall_core::{
1921
heimdall_disassembler::disassemble, heimdall_dump::dump, heimdall_inspect::inspect,
2022
};
2123

24+
#[allow(clippy::large_stack_frames)]
2225
#[tokio::main]
2326
async fn main() -> Result<()> {
2427
let args = Arguments::parse();

0 commit comments

Comments
 (0)