diff --git a/.gitignore b/.gitignore index 1de5659..aadec13 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -target \ No newline at end of file +target +acceptevm.log diff --git a/Cargo.lock b/Cargo.lock index 7f151c2..37ec32b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,8 @@ version = "0.1.0" dependencies = [ "alloy", "bincode", + "log", + "log4rs", "reqwest", "serde", "sha2", @@ -15,6 +17,7 @@ dependencies = [ "thiserror", "tokio", "uuid", + "zeroize", ] [[package]] @@ -448,6 +451,33 @@ dependencies = [ "url", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "ark-ff" version = "0.3.0" @@ -783,6 +813,18 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets 0.52.5", +] + [[package]] name = "const-hex" version = "1.11.3" @@ -932,6 +974,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "destructure_traitobject" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7" + [[package]] name = "digest" version = "0.9.0" @@ -1368,6 +1416,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "1.3.1" @@ -1424,6 +1478,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.5.0" @@ -1574,6 +1651,43 @@ name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +dependencies = [ + "serde", +] + +[[package]] +name = "log-mdc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" + +[[package]] +name = "log4rs" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0816135ae15bd0391cf284eab37e6e3ee0a6ee63d2ceeb659862bd8d0a984ca6" +dependencies = [ + "anyhow", + "arc-swap", + "chrono", + "derivative", + "fnv", + "humantime", + "libc", + "log", + "log-mdc", + "once_cell", + "parking_lot 0.12.2", + "rand", + "serde", + "serde-value", + "serde_json", + "serde_yaml", + "thiserror", + "thread-id", + "typemap-ors", + "winapi", +] [[package]] name = "lru" @@ -1733,6 +1847,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + [[package]] name = "parity-scale-codec" version = "3.6.9" @@ -1770,6 +1893,16 @@ dependencies = [ "parking_lot_core 0.8.6", ] +[[package]] +name = "parking_lot" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.10", +] + [[package]] name = "parking_lot_core" version = "0.8.6" @@ -2286,6 +2419,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.200" @@ -2320,6 +2463,19 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "sha2" version = "0.10.8" @@ -2373,7 +2529,7 @@ dependencies = [ "fxhash", "libc", "log", - "parking_lot", + "parking_lot 0.11.2", ] [[package]] @@ -2513,6 +2669,16 @@ dependencies = [ "syn 2.0.60", ] +[[package]] +name = "thread-id" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0ec81c46e9eb50deaa257be2f148adf052d1fb7701cfd55ccfab2525280b70b" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "threadpool" version = "1.8.1" @@ -2692,6 +2858,15 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typemap-ors" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a68c24b707f02dd18f1e4ccceb9d49f2058c2fb86384ef9972592904d7a28867" +dependencies = [ + "unsafe-any-ors", +] + [[package]] name = "typenum" version = "1.17.0" @@ -2743,6 +2918,21 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unsafe-any-ors" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a303d30665362d9680d7d91d78b23f5f899504d4f08b3c4cf08d055d87c0ad" +dependencies = [ + "destructure_traitobject", +] + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "url" version = "2.5.0" @@ -2903,6 +3093,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 2bbfffe..3be364d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,6 @@ sha2 = "0.10.8" tokio = "1.37.0" uuid = {version="1.8.0",features=["v4"]} reqwest = "0.12.4" +log4rs = "1.3.0" +log = "0.4.21" +zeroize = {version="1.7.0",features=["zeroize_derive"]} diff --git a/src/audit/mod.rs b/src/audit/mod.rs deleted file mode 100644 index 9afddfe..0000000 --- a/src/audit/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::{env, fs}; -use uuid::Uuid; - -/// Internal logging function used to log errors. -/// Can be disabled by setting environment variable ACCEPTEVM to 0 -pub fn log_sync(data: &str) { - match env::var("ACCEPTEVM_LOGS") { - Ok(value) => { - if value == *"0" { - return; - } - } - Err(_error) => { - return; - } - } - let path = format!("{}.error.log.txt", Uuid::new_v4()); - let write_result = fs::write(path, format!("{}\n", data)); - match write_result { - Ok(()) => {} - Err(error) => { - panic!("LOGGER FAILURE! COULD NOT LOG DATA! {}", error) - } - } -} diff --git a/src/common/mod.rs b/src/common/mod.rs index 27b041c..ea42dcf 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1,22 +1,16 @@ -use std::time::{Duration, SystemTime, UNIX_EPOCH}; +use std::time::{SystemTime, UNIX_EPOCH}; use thiserror::Error; /// Retrieve the current unix time in nanoseconds pub fn get_unix_time_millis() -> u128 { let now = SystemTime::now(); - let duration = now.duration_since(UNIX_EPOCH).unwrap_or_else(|_| { - println!("Failed computing UNIX timestamp during admin login!"); - Duration::from_secs(0) - }); + let duration = now.duration_since(UNIX_EPOCH).unwrap_or_default(); duration.as_millis() } /// Retrieve the current unix time in nanoseconds pub fn get_unix_time_seconds() -> u64 { let now = SystemTime::now(); - let duration = now.duration_since(UNIX_EPOCH).unwrap_or_else(|_| { - println!("Failed computing UNIX timestamp during admin login!"); - Duration::from_secs(0) - }); + let duration = now.duration_since(UNIX_EPOCH).unwrap_or_default(); duration.as_secs() } @@ -36,4 +30,6 @@ pub enum DatabaseError { Serialize, #[error("Could not delete from database")] NoDelete, + #[error("Database internal error: {0}")] + SledError(#[from] sled::Error), } diff --git a/src/db/mod.rs b/src/db/mod.rs index d5f7842..55b5cf4 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,51 +1,35 @@ use crate::common::DatabaseError; -use crate::{audit::log_sync, types::Serializable}; +use crate::types::Serializable; use sled::Tree; /// Retrieve a value by key from a tree. async fn get_from_tree(db: &Tree, key: &str) -> Result, DatabaseError> { - match db.get(key) { - Ok(result) => match result { - Some(value) => Ok(value.to_vec()), - None => Err(DatabaseError::NotFound), - }, - Err(_error) => Err(DatabaseError::Get), - } + Ok(db.get(key)?.ok_or(DatabaseError::NotFound)?.to_vec()) } /// Retrieve all key,value pairs from a specified tree async fn get_all_from_tree(db: &Tree) -> Result, Vec)>, DatabaseError> { - let mut all = Vec::new(); - for el in db.iter() { - match el { - Ok(value) => { - let el_bin_key = value.0.to_vec(); - let el_bin_value = value.1.to_vec(); - all.push((el_bin_key, el_bin_value)); - } - Err(error) => { - log_sync(&format!("Db Interaction Error: {}", error)); - return Err(DatabaseError::Get); - } - } - } - Ok(all) + db.iter() + .map(|res| { + res.map_err(|error| { + log::error!("Db Interaction Error: {}", error); + DatabaseError::Get + }) + .map(|(key, value)| (key.to_vec(), value.to_vec())) + }) + .collect() } /// Retrieve the last added item to the tree async fn get_last_from_tree(db: &Tree) -> Result<(Vec, Vec), DatabaseError> { - match db.last() { - Ok(value) => match value { - Some(tuple) => { - let el_bin_key = tuple.0.to_vec(); - let el_bin_value = tuple.1.to_vec(); - Ok((el_bin_key, el_bin_value)) - } - None => Err(DatabaseError::NotFound), - }, - Err(error) => { - log_sync(&format!("Db Interaction Error: {}", error)); - Err(DatabaseError::Get) + let last_value = db.last()?; + + match last_value { + Some(tuple) => { + let el_bin_key = tuple.0.to_vec(); + let el_bin_value = tuple.1.to_vec(); + Ok((el_bin_key, el_bin_value)) } + None => Err(DatabaseError::NotFound), } } @@ -54,13 +38,13 @@ pub async fn get_last(tree: &sled::Tree) -> Result<(String, T), let binary_data = get_last_from_tree(tree).await?; // Convert binary key to String let key = String::from_utf8(binary_data.0).map_err(|error| { - log_sync(&format!("Db Interaction Error: {}", error)); + log::error!("Db Interaction Error: {}", error); DatabaseError::Deserialize })?; // Deserialize binary value to T let value = T::from_bin(binary_data.1).map_err(|error| { - log_sync(&format!("Db Interaction Error: {}", error)); + log::error!("Db Interaction Error: {}", error); DatabaseError::Deserialize })?; Ok((key, value)) @@ -71,17 +55,17 @@ pub async fn get_all( tree: &sled::Tree, ) -> Result, DatabaseError> { let binary_data = get_all_from_tree(tree).await?; - let mut all = Vec::new(); + let mut all = Vec::with_capacity(binary_data.len()); for (binary_key, binary_value) in binary_data { // Convert binary key to String let key = String::from_utf8(binary_key.to_vec()).map_err(|error| { - log_sync(&format!("Db Interaction Error: {}", error)); + log::error!("Db Interaction Error: {}", error); DatabaseError::Deserialize })?; // Deserialize binary value to T let value = T::from_bin(binary_value).map_err(|error| { - log_sync(&format!("Db Interaction Error: {}", error)); + log::error!("Db Interaction Error: {}", error); DatabaseError::Deserialize })?; @@ -94,7 +78,7 @@ pub async fn get_all( pub async fn get(tree: &Tree, key: &str) -> Result { let binary_data = get_from_tree(tree, key).await?; T::from_bin(binary_data).map_err(|error| { - log_sync(&format!("Db Interaction Error: {}", error)); + log::error!("Db Interaction Error: {}", error); DatabaseError::Deserialize }) } @@ -104,7 +88,7 @@ async fn set_to_tree(db: &Tree, key: &str, bin: Vec) -> Result<(), DatabaseE match db.insert(key, bin) { Ok(_) => Ok(()), Err(error) => { - log_sync(&format!("Db Interaction Error: {}", error)); + log::error!("Db Interaction Error: {}", error); Err(DatabaseError::Set) } } @@ -113,7 +97,7 @@ async fn set_to_tree(db: &Tree, key: &str, bin: Vec) -> Result<(), DatabaseE /// Wrapper for setting a value to a tree pub async fn set(tree: &Tree, key: &str, data: T) -> Result<(), DatabaseError> { let binary_data = T::to_bin(&data).map_err(|error| { - log_sync(&format!("Db Interaction Error: {}", error)); + log::error!("Db Interaction Error: {}", error); DatabaseError::Serialize })?; set_to_tree(tree, key, binary_data) @@ -124,14 +108,9 @@ pub async fn set(tree: &Tree, key: &str, data: T) -> Result<(), /// Used to delete from a tree pub async fn delete(tree: &Tree, key: &str) -> Result<(), DatabaseError> { - match tree.remove(key) { - Ok(result) => match result { - Some(_deleted_value) => Ok(()), - None => Err(DatabaseError::NotFound), - }, - Err(error) => { - log_sync(&format!("Db Interaction Error: {}", error)); - Err(DatabaseError::NoDelete) - } + let result = tree.remove(key)?; + match result { + Some(_deleted_value) => Ok(()), + None => Err(DatabaseError::NotFound), } } diff --git a/src/erc20/mod.rs b/src/erc20/mod.rs index 3c961ae..29847c2 100644 --- a/src/erc20/mod.rs +++ b/src/erc20/mod.rs @@ -26,13 +26,13 @@ impl ERC20Token { } /// Retrieves the token balance of a specified address - pub async fn get_balance(&self, address: String) -> Result, Error> { - let IERC20::balanceOfReturn { _0 } = self + pub async fn get_balance(&self, address: &str) -> Result, Error> { + let IERC20::balanceOfReturn { _0: balance } = self .contract .balanceOf(address.parse().unwrap()) .call() .await?; - Ok(_0) + Ok(balance) } } @@ -55,7 +55,7 @@ mod tests { "0x2170ed0880ac9a755fd29b2688956bd959f933f8".to_string(), ); let balance = token - .get_balance("0xC882b111A75C0c657fC507C04FbFcD2cC984F071".to_string()) + .get_balance(&"0xC882b111A75C0c657fC507C04FbFcD2cC984F071".to_string()) .await .unwrap(); println!("Balance check: {}", balance); diff --git a/src/gateway/mod.rs b/src/gateway/mod.rs index 5101af0..b465e3f 100644 --- a/src/gateway/mod.rs +++ b/src/gateway/mod.rs @@ -7,6 +7,13 @@ use alloy::{ signers::wallet::LocalWallet, transports::http::Http, }; +use log::LevelFilter; +use log4rs::{ + append::file::FileAppender, + config::{Appender, Root}, + encode::pattern::PatternEncoder, + Config, +}; use reqwest::{Client, Url}; use sled::Tree; use tokio::sync::Mutex; @@ -15,7 +22,7 @@ use crate::{ common::{get_unix_time_millis, get_unix_time_seconds, DatabaseError}, db::{get, get_all, get_last, set}, poller::poll_payments, - types::{Invoice, PaymentMethod}, + types::{self, Invoice, PaymentMethod}, }; use self::hash::hash_now; @@ -90,6 +97,23 @@ impl PaymentGateway { Box::pin(callback(invoice)) as Pin + Send>> })); + // Setup logging + let logfile = FileAppender::builder() + .encoder(Box::new(PatternEncoder::new("{l} - {m}\n"))) + .build("./acceptevm.log") + .unwrap(); + + let config = Config::builder() + .appender(Appender::builder().build("logfile", Box::new(logfile))) + .build(Root::builder().appender("logfile").build(LevelFilter::Info)) + .unwrap(); + + // Try to initialize and catch error silently if already initialized + // during tests this make this function throw error + if log4rs::init_config(config).is_err() { + println!("Logger already initialized."); + } + // TODO: When implementing token transfers allow the user to add their gas wallet here. PaymentGateway { @@ -151,7 +175,9 @@ impl PaymentGateway { let signer = LocalWallet::random(); let invoice = Invoice { to: signer.address().to_string(), - wallet: signer.to_bytes(), + wallet: types::ZeroizedB256 { + inner: signer.to_bytes(), + }, amount, method, message, diff --git a/src/lib.rs b/src/lib.rs index e44f9a2..f681131 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,3 @@ -mod audit; mod common; mod db; mod erc20; diff --git a/src/poller/mod.rs b/src/poller/mod.rs index e33e33d..f6147d7 100644 --- a/src/poller/mod.rs +++ b/src/poller/mod.rs @@ -1,5 +1,4 @@ use crate::{ - audit::log_sync, common::get_unix_time_seconds, db::{delete, get_all}, erc20::ERC20Token, @@ -7,7 +6,6 @@ use crate::{ transfers::{errors::TransferError, gas_transfers::transfer_gas_to_treasury}, types::Invoice, }; - use alloy::{ primitives::Uint, providers::{Provider, RootProvider}, @@ -21,9 +19,9 @@ use sled::Tree; /// at a certain address. async fn check_if_token_received( token: ERC20Token, - invoice: Invoice, + invoice: &Invoice, ) -> Result { - let balance_of_recipient = token.get_balance(invoice.to).await?; + let balance_of_recipient = token.get_balance(&invoice.to).await?; if balance_of_recipient.ge(&invoice.amount) { return Ok(true); } @@ -32,8 +30,8 @@ async fn check_if_token_received( /// Retrieves the gas token balance of the specified address on the specified web3 instance async fn get_native_balance( - provider: RootProvider>, - address: String, + provider: &RootProvider>, + address: &str, ) -> Result, alloy::contract::Error> { Ok(provider .get_balance(address.parse().unwrap(), alloy::eips::BlockId::latest()) @@ -42,10 +40,10 @@ async fn get_native_balance( /// Used to check if the invoice recipient has received enough money to cover the invoice async fn check_if_native_received( - provider: RootProvider>, - invoice: Invoice, + provider: &RootProvider>, + invoice: &Invoice, ) -> Result { - let balance_of_recipient = get_native_balance(provider, invoice.to).await?; + let balance_of_recipient = get_native_balance(provider, &invoice.to).await?; if balance_of_recipient.ge(&invoice.amount) { return Ok(true); } @@ -54,22 +52,22 @@ async fn check_if_native_received( /// A function that branches control flow depending on the invoice shall /// be paid by an ERC20-compatible token or the native gas token on the network -async fn check_and_process(provider: RootProvider>, invoice: Invoice) -> bool { +async fn check_and_process(provider: RootProvider>, invoice: &Invoice) -> bool { match invoice.clone().method.token_address { Some(address) => { let token = ERC20Token::new(provider, address); match check_if_token_received(token, invoice).await { Ok(result) => result, Err(error) => { - log_sync(&format!("Failed to check balance: {}", error)); + log::error!("Failed to check balance: {}", error); false } } } - None => match check_if_native_received(provider, invoice).await { + None => match check_if_native_received(&provider, invoice).await { Ok(result) => result, Err(error) => { - log_sync(&format!("Failed to check balance: {}", error)); + log::error!("Failed to check balance: {}", error); false } }, @@ -81,10 +79,7 @@ async fn delete_invoice(tree: &Tree, key: String) { match delete(tree, &key).await { Ok(()) => {} Err(error) => { - log_sync(&format!( - "Could not remove invoice, did not callback: {}", - error - )); + log::error!("Could not remove invoice, did not callback: {}", error); } } } @@ -112,7 +107,7 @@ pub async fn poll_payments(gateway: PaymentGateway) { } // Check if the invoice was paid let check_result = - check_and_process(gateway.config.provider.clone(), entry.clone().1).await; + check_and_process(gateway.config.provider.clone(), &entry.1).await; if check_result { // Attempt transfer to treasury @@ -121,10 +116,10 @@ pub async fn poll_payments(gateway: PaymentGateway) { entry.1.receipt = Some(receipt); } Err(error) => { - log_sync(&format!( + log::error!( "Could not transfer paid invoice to treasury: {}", error - )); + ); } } @@ -144,10 +139,7 @@ pub async fn poll_payments(gateway: PaymentGateway) { } } Err(error) => { - log_sync(&format!( - "Could not get all invoices, did not callback: {}", - error - )); + log::error!("Could not get all invoices, did not callback: {}", error); } } // To prevent busy idling we sleep here too. @@ -173,8 +165,8 @@ mod tests { let provider = ProviderBuilder::new() .on_http(Url::from_str("https://bsc-dataseed1.binance.org/").unwrap()); let balance = get_native_balance( - provider, - "0x2170ed0880ac9a755fd29b2688956bd959f933f8".to_string(), + &provider, + &"0x2170ed0880ac9a755fd29b2688956bd959f933f8".to_string(), ) .await .unwrap(); diff --git a/src/transfers/gas_transfers/mod.rs b/src/transfers/gas_transfers/mod.rs index dd2d116..4d2567d 100644 --- a/src/transfers/gas_transfers/mod.rs +++ b/src/transfers/gas_transfers/mod.rs @@ -18,7 +18,6 @@ use reqwest::Client; use std::ops::Mul; use crate::{ - audit::log_sync, gateway::{PaymentGateway, PaymentGatewayConfiguration}, types::Invoice, }; @@ -74,7 +73,7 @@ pub async fn transfer_gas_to_treasury( gateway: PaymentGateway, invoice: Invoice, ) -> Result { - let signer = LocalWallet::from_bytes(&invoice.wallet).unwrap(); + let signer = LocalWallet::from_bytes(&invoice.clone().wallet).unwrap(); let chain_id = get_chain_id(gateway.config.provider.clone()).await?; let gas_price = get_gas_price(gateway.config.provider.clone()).await?; @@ -86,13 +85,13 @@ pub async fn transfer_gas_to_treasury( match send_transaction(tx_encoded, gateway.config.provider).await { Ok(receipt) => Ok(receipt), Err(error) => { - log_sync(&format!("Could not send transaction: {}", error)); + log::error!("Could not send transaction: {}", error); Err(TransferError::SendTransaction) } } } Err(error) => { - log_sync(&format!("Could not create transaction: {}", error)); + log::error!("Could not send transaction: {}", error); Err(TransferError::CreateTransaction) } } diff --git a/src/transfers/mod.rs b/src/transfers/mod.rs index 2ca6000..d1ff45f 100644 --- a/src/transfers/mod.rs +++ b/src/transfers/mod.rs @@ -7,8 +7,6 @@ use alloy::{ }; use reqwest::Client; -use crate::audit::log_sync; - use self::errors::TransferError; // Retrieves the chain id from the provider. @@ -16,7 +14,7 @@ async fn get_chain_id(provider: RootProvider>) -> Result Ok(chain_id), Err(error) => { - log_sync(&format!("Could not get chain id: {}", error)); + log::error!("Could not get chain id: {}", error); Err(TransferError::ChainId) } } @@ -27,10 +25,10 @@ async fn get_gas_price(provider: RootProvider>) -> Result Ok(gas_price), Err(error) => { - log_sync(&format!( + log::error!( "Could not get gas price (maybe chain uses EIP-1559?): {}", error - )); + ); Err(TransferError::ChainId) } } diff --git a/src/types/mod.rs b/src/types/mod.rs index 00f6026..7b466d8 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -1,10 +1,13 @@ mod errors; +use std::ops::{Deref, DerefMut}; + use self::errors::SerializableError; use alloy::{ primitives::{B256, U256}, rpc::types::eth::TransactionReceipt, }; use serde::{Deserialize, Serialize}; +use zeroize::ZeroizeOnDrop; pub trait Serializable { fn to_bin(&self) -> Result, Box>; fn from_bin(data: Vec) -> Result @@ -22,12 +25,32 @@ pub struct PaymentMethod { pub token_address: Option, } +#[derive(ZeroizeOnDrop, Clone, Deserialize, Serialize)] +pub struct ZeroizedB256 { + pub inner: B256, +} + +// To automatically dereference into B256 type for restoring wallet +impl Deref for ZeroizedB256 { + type Target = B256; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for ZeroizedB256 { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + #[derive(Clone, Deserialize, Serialize)] pub struct Invoice { /// Recipient address pub to: String, /// Recipient instance - pub wallet: B256, + pub wallet: ZeroizedB256, /// Amount requested pub amount: U256, /// Method used for payment