Skip to content

Commit

Permalink
[DRAFT] chore: convert all instances of bytecode, calldata to Vec<u8> (
Browse files Browse the repository at this point in the history
…#309)

* chore: convert all instances of bytecode, calldata to `Vec<u8>`

* chore(decode): retype all instances of calldata as `Vec<u8>`

* fix(cache): doctests cannot access private mod `util`
  • Loading branch information
Jon-Becker authored Jan 26, 2024
1 parent 32b6e70 commit f168506
Show file tree
Hide file tree
Showing 21 changed files with 505 additions and 430 deletions.
2 changes: 1 addition & 1 deletion cache/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use error::Error;
use util::*;

pub mod error;
pub mod util;
pub(crate) mod util;

/// Clap argument parser for the cache subcommand
#[derive(Debug, Clone, Parser)]
Expand Down
54 changes: 0 additions & 54 deletions cache/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,11 @@ use std::{
use crate::error::Error;

/// Decode a hex string into a bytearray
///
/// ```
/// use heimdall_cache::util::decode_hex;
///
/// let hex = "48656c6c6f20576f726c64"; // "Hello World" in hex
/// let result = decode_hex(hex);
/// assert_eq!(result, Ok(vec![72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]));
/// ```
pub fn decode_hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
(0..s.len()).step_by(2).map(|i| u8::from_str_radix(&s[i..i + 2], 16)).collect()
}

/// Encode a bytearray into a hex string
///
/// ```
/// use heimdall_cache::util::encode_hex;
///
/// let bytes = vec![72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100];
/// let result = encode_hex(bytes);
/// assert_eq!(result, "48656c6c6f20576f726c64");
/// ```
pub fn encode_hex(s: Vec<u8>) -> String {
s.iter().fold(String::new(), |mut acc: String, b| {
write!(acc, "{b:02x}", b = b).expect("unable to write");
Expand All @@ -39,19 +23,6 @@ pub fn encode_hex(s: Vec<u8>) -> String {
}

/// Prettify bytes into a human-readable format \
/// e.g. 1024 -> 1 KB
///
/// ```
/// use heimdall_cache::util::prettify_bytes;
///
/// let bytes = 500;
/// let result = prettify_bytes(bytes);
/// assert_eq!(result, "500 B");
///
/// let bytes = 500_000;
/// let result = prettify_bytes(bytes);
/// assert_eq!(result, "488 KB");
/// ```
pub fn prettify_bytes(bytes: u64) -> String {
if bytes < 1024 {
format!("{bytes} B")
Expand All @@ -68,16 +39,6 @@ pub fn prettify_bytes(bytes: u64) -> String {
}

/// Write contents to a file on the disc
///
/// ```no_run
/// use heimdall_cache::util::write_file;
///
/// let path = "/tmp/test.txt";
/// let contents = "Hello, World!";
/// let result = write_file(path, contents);
///
/// assert!(result.is_ok());
/// ```
pub fn write_file(path_str: &str, contents: &str) -> Result<(), Error> {
let path = Path::new(path_str);

Expand All @@ -97,14 +58,6 @@ pub fn write_file(path_str: &str, contents: &str) -> Result<(), Error> {
}

/// Read contents from a file on the disc
///
/// ```no_run
/// use heimdall_cache::util::read_file;
///
/// let path = "/tmp/test.txt";
/// let contents = read_file(path);
/// assert!(contents.is_ok());
/// ```
pub fn read_file(path: &str) -> Result<String, Error> {
let path = Path::new(path);
let mut file = File::open(path)
Expand All @@ -115,13 +68,6 @@ pub fn read_file(path: &str) -> Result<String, Error> {
}

/// Delete a file or directory on the disc
///
/// ```no_run
/// use heimdall_cache::util::delete_path;
///
/// let path = "/tmp/test.txt";
/// let result = delete_path(path);
/// ```
pub fn delete_path(_path: &str) -> bool {
let path = match std::path::Path::new(_path).to_str() {
Some(path) => path,
Expand Down
21 changes: 19 additions & 2 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,25 @@ async fn main() -> Result<(), Error> {
let mut output_str = String::new();

if let Some(abi) = &result.abi {
output_str
.push_str(&format!("ABI:\n\n{}\n", serde_json::to_string_pretty(abi)?));
output_str.push_str(&format!(
"ABI:\n\n[{}]\n",
abi.iter()
.map(|x| {
match x {
ABIStructure::Function(x) => {
serde_json::to_string_pretty(x).map_err(Error::SerdeError)
}
ABIStructure::Error(x) => {
serde_json::to_string_pretty(x).map_err(Error::SerdeError)
}
ABIStructure::Event(x) => {
serde_json::to_string_pretty(x).map_err(Error::SerdeError)
}
}
})
.collect::<Result<Vec<String>, Error>>()?
.join(",\n")
));
}
if let Some(source) = &result.source {
output_str.push_str(&format!("Source:\n\n{}\n", source));
Expand Down
23 changes: 12 additions & 11 deletions common/src/ether/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ use super::rpc::get_code;
use crate::{
constants::{ADDRESS_REGEX, BYTECODE_REGEX},
error::Error,
utils::io::logging::Logger,
utils::{io::logging::Logger, strings::decode_hex},
};
use std::fs;

// TODO: this should return Vec<u8> instead of String
// TODO: we dont need to pass rpc_url here, we should be able to use Configuration::load().
/// Get the bytecode from the target, which can be a contract address, a bytecode or a file path.
pub async fn get_bytecode_from_target(target: &str, rpc_url: &str) -> Result<String, Error> {
let (logger, _) = Logger::new("");
pub async fn get_bytecode_from_target(target: &str, rpc_url: &str) -> Result<Vec<u8>, Error> {
let logger = Logger::default();

if ADDRESS_REGEX.is_match(target).unwrap_or(false) {
// Target is a contract address, so we need to fetch the bytecode from the RPC provider.
Expand All @@ -19,7 +17,7 @@ pub async fn get_bytecode_from_target(target: &str, rpc_url: &str) -> Result<Str
})
} else if BYTECODE_REGEX.is_match(target).unwrap_or(false) {
// Target is already a bytecode, so we just need to remove 0x from the begining
Ok(target.replacen("0x", "", 1))
Ok(decode_hex(target)?)
} else {
// Target is a file path, so we need to read the bytecode from the file.
let contents = fs::read_to_string(target).map_err(|e| {
Expand All @@ -29,10 +27,13 @@ pub async fn get_bytecode_from_target(target: &str, rpc_url: &str) -> Result<Str

let contents = contents.replace('\n', "");
if BYTECODE_REGEX.is_match(&contents).unwrap_or(false) && contents.len() % 2 == 0 {
Ok(contents.replacen("0x", "", 1))
Ok(decode_hex(&contents)?)
} else {
logger.error(&format!("file '{}' doesn't contain valid bytecode.", &target));
return Err(Error::ParseError("file doesn't contain valid bytecode.".to_string()));
return Err(Error::ParseError(format!(
"file '{}' doesn't contain valid bytecode.",
&target
)));
}
}
}
Expand All @@ -50,7 +51,7 @@ mod tests {
.await
.expect("failed to get bytecode from target");

assert!(BYTECODE_REGEX.is_match(&bytecode).expect("failed to match bytecode regex"));
assert!(!bytecode.is_empty());
}

#[tokio::test]
Expand All @@ -62,7 +63,7 @@ mod tests {
.await
.expect("failed to get bytecode from target");

assert!(BYTECODE_REGEX.is_match(&bytecode).expect("failed to match bytecode regex"));
assert!(!bytecode.is_empty());
}

#[tokio::test]
Expand All @@ -76,7 +77,7 @@ mod tests {
.await
.expect("failed to get bytecode from target");

assert!(BYTECODE_REGEX.is_match(&bytecode).expect("failed to match bytecode regex"));
assert_eq!(bytecode.len(), 52);

fs::remove_file(file_path).expect("failed to remove mock file");
}
Expand Down
Loading

0 comments on commit f168506

Please sign in to comment.