Skip to content

Commit

Permalink
perf(*): purge unnecessary .clone()s (#442)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon-Becker authored Jun 13, 2024
1 parent f378814 commit 97e4bd8
Show file tree
Hide file tree
Showing 35 changed files with 159 additions and 295 deletions.
15 changes: 7 additions & 8 deletions crates/cfg/src/core/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,22 @@ pub fn build_cfg(

// add the current operations to the cfg
for operation in &vm_trace.operations {
let instruction = operation.last_instruction.clone();

let opcode_name = instruction
let opcode_name = operation
.last_instruction
.opcode_details
.clone()
.as_ref()
.ok_or_eyre("failed to get opcode details for instruction")?
.name;

let assembly = format!(
"{} {} {}",
encode_hex_reduced(U256::from(instruction.instruction)),
encode_hex_reduced(U256::from(operation.last_instruction.instruction)),
opcode_name,
if opcode_name.contains("PUSH") {
encode_hex_reduced(
*instruction
*operation
.last_instruction
.outputs
.clone()
.first()
.ok_or_eyre("failed to get output for PUSH instruction")?,
)
Expand Down Expand Up @@ -65,7 +64,7 @@ pub fn build_cfg(
.ok_or_eyre("failed to get first operation")?
.last_instruction
.opcode_details
.clone()
.as_ref()
.ok_or_eyre("failed to get opcode details")?
.name ==
"JUMPDEST",
Expand Down
2 changes: 1 addition & 1 deletion crates/common/src/ether/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ pub async fn get_code(contract_address: &str, rpc_url: &str) -> Result<Vec<u8>,
// cache the results
store_cache(
&format!("contract.{}.{}", &chain_id, &contract_address),
bytecode_as_bytes.clone().to_vec(),
bytecode_as_bytes.to_vec(),
None,
)
.map_err(|_| error!("failed to cache bytecode for contract: {:?}", &contract_address))?;
Expand Down
8 changes: 4 additions & 4 deletions crates/common/src/ether/signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl ResolveSelector for ResolvedError {
}

// cache the results
let _ = store_cache(&format!("selector.{selector}"), signature_list.clone(), None)
let _ = store_cache(&format!("selector.{selector}"), &signature_list, None)
.map_err(|e| trace!("error storing signatures in cache: {}", e));

Ok(match signature_list.len() {
Expand Down Expand Up @@ -207,7 +207,7 @@ impl ResolveSelector for ResolvedLog {
}

// cache the results
let _ = store_cache(&format!("selector.{selector}"), signature_list.clone(), None)
let _ = store_cache(&format!("selector.{selector}"), &signature_list, None)
.map_err(|e| trace!("error storing signatures in cache: {}", e));

Ok(match signature_list.len() {
Expand Down Expand Up @@ -295,7 +295,7 @@ impl ResolveSelector for ResolvedFunction {
}

// cache the results
let _ = store_cache(&format!("selector.{selector}"), signature_list.clone(), None)
let _ = store_cache(&format!("selector.{selector}"), &signature_list, None)
.map_err(|e| trace!("error storing signatures in cache: {}", e));

Ok(match signature_list.len() {
Expand Down Expand Up @@ -386,7 +386,7 @@ impl TryFrom<&ResolvedFunction> for TraceFactory {
}

// add to trace and decoded string
trace.add_message(decode_call, 1, decoded_inputs_as_message.clone());
trace.add_message(decode_call, 1, decoded_inputs_as_message);
}

Ok(trace)
Expand Down
2 changes: 1 addition & 1 deletion crates/common/src/resources/openai.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub async fn complete(prompt: &str, api_key: &str) -> Option<String> {
match client.completions().create(request).await {
Ok(response) => {
if !response.choices.is_empty() {
Some(response.choices[0].text.clone())
Some(response.choices[0].text.to_owned())
} else {
None
}
Expand Down
141 changes: 9 additions & 132 deletions crates/common/src/resources/transpose.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use backoff::ExponentialBackoff;
use indicatif::ProgressBar;
use reqwest::header::HeaderMap;
use serde_json::Value;
use std::time::{Duration, Instant};

use crate::{info_spinner, Error};
use serde::{Deserialize, Serialize};
use tracing::{debug, error, trace};

Expand Down Expand Up @@ -32,7 +30,10 @@ async fn call_transpose(query: &str, api_key: &str) -> Option<TransposeResponse>
|| async {
// build the headers
let mut headers = HeaderMap::new();
headers.insert("Content-Type", "application/json".parse().expect("failed to parse Content-Type header"));
headers.insert(
"Content-Type",
"application/json".parse().expect("failed to parse Content-Type header"),
);
headers.insert("X-API-KEY", api_key.parse().expect("failed to parse API key header"));

// clone the query
Expand All @@ -47,7 +48,7 @@ async fn call_transpose(query: &str, api_key: &str) -> Option<TransposeResponse>

let response = match client
.post("https://api.transpose.io/sql")
.body(query.clone())
.body(query)
.headers(headers)
.send()
.await
Expand All @@ -56,7 +57,7 @@ async fn call_transpose(query: &str, api_key: &str) -> Option<TransposeResponse>
Err(e) => {
error!("failed to call Transpose .");
error!("error: {}", e);
return Err(backoff::Error::Permanent(()))
return Err(backoff::Error::Permanent(()));
}
};

Expand All @@ -65,146 +66,22 @@ async fn call_transpose(query: &str, api_key: &str) -> Option<TransposeResponse>
Ok(body) => Ok(match serde_json::from_str(&body) {
Ok(json) => json,
Err(e) => {
error!("Transpose request unsucessful.");
debug!("curl: curl -X GET \"https://api.transpose.io/sql\" -H \"accept: application/json\" -H \"Content-Type: application/json\" -H \"X-API-KEY: {}\" -d {}", api_key, query);
error!("error: {}", e);
debug!("response body: {:?}", body);
return Err(backoff::Error::Permanent(()))
return Err(backoff::Error::Permanent(()));
}
}),
Err(e) => {
error!("failed to parse Transpose response body.");
error!("error: {}", e);
Err(backoff::Error::Permanent(()))
}
}
},
).await
)
.await
.ok()
}

/// Get all interactions with the given address. Includes transactions to, from, as well as internal
/// transactions to and from the address.
///
/// ```
/// use heimdall_common::resources::transpose::get_transaction_list;
///
/// let chain = "ethereum";
/// let address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
/// let api_key = "YOUR_API_KEY";
/// let bounds = (0, 1); // block number bounds
///
/// // let transactions = get_transaction_list(chain, address, api_key, bounds).await;
/// ```
pub async fn get_transaction_list(
chain: &str,
address: &str,
api_key: &str,
bounds: (&u128, &u128),
) -> Result<Vec<(u128, String)>, Error> {
// get a new progress bar
let transaction_list_progress = ProgressBar::new_spinner();
transaction_list_progress.enable_steady_tick(Duration::from_millis(100));
transaction_list_progress.set_style(info_spinner!());
transaction_list_progress.set_message(format!("fetching transactions from '{address}' ."));
let start_time = Instant::now();

// build the SQL query
let query = format!(
"{{\"sql\":\"SELECT block_number, transaction_hash FROM (SELECT transaction_hash, block_number FROM {chain}.transactions WHERE to_address = '{}' AND block_number BETWEEN {} AND {} UNION SELECT transaction_hash, block_number FROM {chain}.traces WHERE to_address = '{}' AND block_number BETWEEN {} AND {}) x\",\"parameters\":{{}},\"options\":{{\"timeout\": 999999999}}}}",
address,
bounds.0,
bounds.1,
address,
bounds.0,
bounds.1
);

let response = call_transpose(&query, api_key)
.await
.ok_or(Error::Generic("failed to get transaction list from Transpose".to_string()))?;

transaction_list_progress.finish_and_clear();
debug!("fetching transactions took {:?}", start_time.elapsed());

let mut transactions = Vec::new();

// parse the results
for result in response.results {
let block_number = result
.get("block_number")
.ok_or(Error::Generic("failed to parse block_number from Transpose".to_string()))?
.as_u64()
.ok_or(Error::Generic("failed to parse block_number from Transpose".to_string()))?
as u128;

let transaction_hash = result
.get("transaction_hash")
.ok_or(Error::Generic("failed to parse transaction_hash from Transpose".to_string()))?
.as_str()
.ok_or(Error::Generic("failed to parse transaction_hash from Transpose".to_string()))?
.to_string();

transactions.push((block_number, transaction_hash));
}

// sort the transactions by block number
transactions.sort_by(|a, b| a.0.cmp(&b.0));

Ok(transactions)
}

/// Get the contract creation block and transaction hash for the given address.
///
/// ```
/// use heimdall_common::resources::transpose::get_contract_creation;
///
/// let chain = "ethereum";
/// let address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
/// let api_key = "YOUR_API_KEY";
///
/// // let contract_creation = get_contract_creation(chain, address, api_key).await;
/// ```
pub async fn get_contract_creation(
chain: &str,
address: &str,
api_key: &str,
) -> Option<(u128, String)> {
// get a new progress bar
let transaction_list_progress = ProgressBar::new_spinner();
transaction_list_progress.enable_steady_tick(Duration::from_millis(100));
transaction_list_progress.set_style(info_spinner!());
transaction_list_progress.set_message(format!("fetching '{address}''s creation tx ."));
let start_time = Instant::now();

// build the SQL query
let query = format!(
"{{\"sql\":\"SELECT block_number, transaction_hash FROM {chain}.transactions WHERE TIMESTAMP = ( SELECT created_timestamp FROM {chain}.accounts WHERE address = '{address}' ) AND contract_address = '{address}'\",\"parameters\":{{}},\"options\":{{\"timeout\": 999999999}}}}",
);

let response = call_transpose(&query, api_key).await?;

transaction_list_progress.finish_and_clear();
debug!("fetching contract creation took {:?}", start_time.elapsed());

// parse the results
if let Some(result) = response.results.into_iter().next() {
let block_number = result
.get("block_number")
.and_then(|block_number| block_number.as_u64())
.map(|block_number| block_number as u128)?;

let transaction_hash = result
.get("transaction_hash")
.and_then(|transaction_hash| transaction_hash.as_str())
.map(|transaction_hash| transaction_hash.to_string())?;

return Some((block_number, transaction_hash));
};

None
}

/// Get the label for the given address.
///
/// ```
Expand Down
2 changes: 1 addition & 1 deletion crates/common/src/utils/hex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ impl ToLowerHex for Bytes {

impl ToLowerHex for Vec<u8> {
fn to_lower_hex(&self) -> String {
encode_hex(self.to_vec())
encode_hex(self)
}
}
8 changes: 4 additions & 4 deletions crates/common/src/utils/io/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ impl TraceFactory {
&mut self,
parent_index: u32,
instruction: u32,
name: String,
args: Vec<String>,
name: &str,
args: &[String],
) -> u32 {
let log = format!("{}({})", name.purple(), args.join(", "));
self.add("log", parent_index, instruction, vec![log])
Expand Down Expand Up @@ -487,8 +487,8 @@ mod tests {
trace.add_emission(
parent,
125,
"ContractCreated".to_string(),
vec!["contractAddress: 0x0000000000000000000000000000000000000000".to_string()],
"ContractCreated",
&["contractAddress: 0x0000000000000000000000000000000000000000".to_string()],
);
trace.add_raw_emission(
parent,
Expand Down
12 changes: 6 additions & 6 deletions crates/common/src/utils/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ pub fn decode_hex(mut s: &str) -> Result<Vec<u8>, Error> {
/// use heimdall_common::utils::strings::encode_hex;
///
/// let bytes = vec![72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100];
/// let result = encode_hex(bytes);
/// let result = encode_hex(&bytes);
/// assert_eq!(result, "48656c6c6f20576f726c64");
/// ```
pub fn encode_hex(s: Vec<u8>) -> String {
pub fn encode_hex(s: &[u8]) -> String {
s.iter().fold(String::new(), |mut acc, b| {
write!(acc, "{b:02x}", b = b).expect("unable to write");
acc
Expand Down Expand Up @@ -330,7 +330,7 @@ pub fn tokenize(s: &str) -> Vec<String> {
if separators.contains(&c) || c.is_whitespace() {
// If the current token is not empty, push it to the vector
if !token.is_empty() {
tokens.push(token.clone());
tokens.push(token.to_owned());
token.clear();
}

Expand Down Expand Up @@ -453,15 +453,15 @@ mod tests {
#[test]
fn test_encode_hex() {
let bytes = vec![72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]; // "Hello world"
let result = encode_hex(bytes);
let result = encode_hex(&bytes);
assert_eq!(result, "48656c6c6f20776f726c64");

let bytes = vec![171, 205, 239];
let result = encode_hex(bytes);
let result = encode_hex(&bytes);
assert_eq!(result, "abcdef");

let bytes = vec![1, 35, 69];
let result = encode_hex(bytes);
let result = encode_hex(&bytes);
assert_eq!(result, "012345");
}

Expand Down
2 changes: 1 addition & 1 deletion crates/core/tests/test_decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ mod integration_tests {
let results = task_pool(txids, 10, move |txid: String| {
let args = DecodeArgsBuilder::new()
.target(txid.to_string())
.rpc_url(rpc_url.clone())
.rpc_url(rpc_url.to_owned())
.build()
.expect("failed to build args");

Expand Down
Loading

0 comments on commit 97e4bd8

Please sign in to comment.