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

perf(*): purge unnecessary .clone()s #442

Merged
merged 3 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading