From ad6bee4050b0f8c6d34915106249a5388662bc26 Mon Sep 17 00:00:00 2001 From: scx1332 Date: Tue, 27 Feb 2024 16:06:30 +0100 Subject: [PATCH] f --- crates/erc20_payment_lib/src/runtime.rs | 11 +- crates/erc20_payment_lib/src/service.rs | 156 +++++++++++--------- crates/erc20_payment_lib/src/transaction.rs | 22 ++- src/main.rs | 1 + 4 files changed, 113 insertions(+), 77 deletions(-) diff --git a/crates/erc20_payment_lib/src/runtime.rs b/crates/erc20_payment_lib/src/runtime.rs index 73f2e6b6..f72ed56d 100644 --- a/crates/erc20_payment_lib/src/runtime.rs +++ b/crates/erc20_payment_lib/src/runtime.rs @@ -3,6 +3,7 @@ use crate::transaction::{ create_faucet_mint, create_free_allocation, create_free_allocation_internal, create_lock_deposit, create_lock_withdraw, create_make_allocation, create_make_allocation_internal, create_token_transfer, find_receipt_extended, + FindReceiptParseResult, }; use crate::{err_custom_create, err_from}; use erc20_payment_lib_common::create_sqlite_connection; @@ -1531,7 +1532,15 @@ pub async fn verify_transaction( glm_address: Address, ) -> Result { let (chain_tx_dao, transfers) = - find_receipt_extended(web3, tx_hash, chain_id, glm_address).await?; + match find_receipt_extended(web3, tx_hash, chain_id, glm_address).await? { + FindReceiptParseResult::Success((chain_tx_dao, transfers)) => (chain_tx_dao, transfers), + FindReceiptParseResult::Failure(str) => { + return Ok(VerifyTransactionResult::Rejected(format!( + "Transaction cannot be parsed {str}" + ))) + } + }; + if chain_tx_dao.chain_status == 1 { //one transaction can contain multiple transfers. Search for ours. for transfer in transfers { diff --git a/crates/erc20_payment_lib/src/service.rs b/crates/erc20_payment_lib/src/service.rs index d21dae4f..2f1e543a 100644 --- a/crates/erc20_payment_lib/src/service.rs +++ b/crates/erc20_payment_lib/src/service.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use crate::error::{ErrorBag, PaymentError}; use erc20_payment_lib_common::ops::*; -use crate::transaction::find_receipt_extended; +use crate::transaction::{find_receipt_extended, FindReceiptParseResult}; use crate::utils::{ConversionError, U256ConvExt}; use crate::err_from; @@ -73,6 +73,7 @@ pub async fn transaction_from_chain_and_into_db( chain_id: i64, tx_hash: &str, glm_address: Address, + get_balances: bool, ) -> Result, PaymentError> { println!("tx_hash: {tx_hash}"); let tx_hash = web3::types::H256::from_str(tx_hash) @@ -88,91 +89,100 @@ pub async fn transaction_from_chain_and_into_db( } let (mut chain_tx_dao, transfers) = - find_receipt_extended(web3.clone(), tx_hash, chain_id, glm_address).await?; + match find_receipt_extended(web3.clone(), tx_hash, chain_id, glm_address).await? { + FindReceiptParseResult::Success((c, t)) => (c, t), + FindReceiptParseResult::Failure(str) => { + log::warn!("Transaction cannot be parsed: {}", str); + return Ok(None); + } + }; if chain_tx_dao.chain_status != 1 { return Ok(None); } - let mut loop_no = 0; - let balance = loop { - loop_no += 1; - match web3 - .clone() - .eth_balance( - Address::from_str(&chain_tx_dao.from_addr).unwrap(), - Some(BlockNumber::Number(chain_tx_dao.block_number.into())), - ) - .await - { - Ok(v) => break Some(v), - Err(e) => { - log::debug!("Error getting balance: {}", e); - if loop_no > 1000 { - break None; + if get_balances { + let mut loop_no = 0; + + let balance = loop { + loop_no += 1; + match web3 + .clone() + .eth_balance( + Address::from_str(&chain_tx_dao.from_addr).unwrap(), + Some(BlockNumber::Number(chain_tx_dao.block_number.into())), + ) + .await + { + Ok(v) => break Some(v), + Err(e) => { + log::debug!("Error getting balance: {}", e); + if loop_no > 1000 { + break None; + } } - } + }; + tokio::time::sleep(std::time::Duration::from_millis(100)).await; }; - tokio::time::sleep(std::time::Duration::from_millis(100)).await; - }; - - log::info!( - "Balance: {:.5} for block {}", - balance.unwrap_or_default().to_eth().unwrap(), - chain_tx_dao.block_number - ); - loop_no = 0; - let token_balance = loop { - let call_data = - encode_erc20_balance_of(Address::from_str(&chain_tx_dao.from_addr).unwrap()) - .map_err(err_from!())?; - match web3 - .clone() - .eth_call( - CallRequest { - from: None, - to: Some(glm_address), - gas: None, - gas_price: None, - value: None, - data: Some(web3::types::Bytes::from(call_data)), - transaction_type: None, - access_list: None, - max_fee_per_gas: None, - max_priority_fee_per_gas: None, - }, - Some(web3::types::BlockId::Number(BlockNumber::Number( - chain_tx_dao.block_number.into(), - ))), - ) - .await - { - Ok(v) => { - if v.0.len() == 32 { - break Some(U256::from_big_endian(&v.0)); + log::info!( + "Balance: {:.5} for block {}", + balance.unwrap_or_default().to_eth().unwrap(), + chain_tx_dao.block_number + ); + + loop_no = 0; + let token_balance = loop { + let call_data = + encode_erc20_balance_of(Address::from_str(&chain_tx_dao.from_addr).unwrap()) + .map_err(err_from!())?; + match web3 + .clone() + .eth_call( + CallRequest { + from: None, + to: Some(glm_address), + gas: None, + gas_price: None, + value: None, + data: Some(web3::types::Bytes::from(call_data)), + transaction_type: None, + access_list: None, + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + }, + Some(web3::types::BlockId::Number(BlockNumber::Number( + chain_tx_dao.block_number.into(), + ))), + ) + .await + { + Ok(v) => { + if v.0.len() == 32 { + break Some(U256::from_big_endian(&v.0)); + } } + Err(e) => { + log::debug!("Error getting token balance: {}", e); + } + }; + if loop_no > 1000 { + break None; } - Err(e) => { - log::debug!("Error getting token balance: {}", e); - } + tokio::time::sleep(std::time::Duration::from_millis(100)).await; }; - if loop_no > 1000 { - break None; - } - tokio::time::sleep(std::time::Duration::from_millis(100)).await; - }; - log::info!( - "Token balance: {:.5} for block {}", - token_balance - .map(|v| v.to_eth().unwrap()) - .unwrap_or_default(), - chain_tx_dao.block_number - ); + log::info!( + "Token balance: {:.5} for block {}", + token_balance + .map(|v| v.to_eth().unwrap()) + .unwrap_or_default(), + chain_tx_dao.block_number + ); - chain_tx_dao.balance_eth = balance.map(|b| b.to_string()); - chain_tx_dao.balance_glm = token_balance.map(|v| v.to_string()); + chain_tx_dao.balance_eth = balance.map(|b| b.to_string()); + chain_tx_dao.balance_glm = token_balance.map(|v| v.to_string()); + } let mut db_transaction = conn.begin().await.map_err(err_from!())?; diff --git a/crates/erc20_payment_lib/src/transaction.rs b/crates/erc20_payment_lib/src/transaction.rs index 3c53d2a4..2176acf0 100644 --- a/crates/erc20_payment_lib/src/transaction.rs +++ b/crates/erc20_payment_lib/src/transaction.rs @@ -855,15 +855,21 @@ pub async fn find_receipt( } } +#[allow(clippy::large_enum_variant)] +pub enum FindReceiptParseResult { + Success((ChainTxDbObj, Vec)), + Failure(String), +} + pub async fn find_receipt_extended( web3: Arc, tx_hash: H256, chain_id: i64, glm_address: Address, -) -> Result<(ChainTxDbObj, Vec), PaymentError> { +) -> Result { let mut chain_tx_dao = ChainTxDbObj { id: -1, - tx_hash: tx_hash.to_string(), + tx_hash: format!("{:#x}", tx_hash), method: "".to_string(), from_addr: "".to_string(), to_addr: "".to_string(), @@ -1024,6 +1030,11 @@ pub async fn find_receipt_extended( let from = Address::from_slice(&log.topics[1][12..]); let to = Address::from_slice(&log.topics[2][12..]); let amount = U256::from(log.data.0.as_slice()); + println!( + "ERC20 transfer from {:#x} to {:#x} amount {:#x}", + from, to, amount + ); + if to == tx_to { if let Some(tcf) = &transfered_to_contract_from { if from != *tcf { @@ -1064,6 +1075,11 @@ pub async fn find_receipt_extended( if from == tx_to { if Some(log.address) != transfered_to_contract_token { + if transfered_to_contract_token.is_none() { + return Ok(FindReceiptParseResult::Failure( + "Transfer from contract without contract from".to_string(), + )); + } return Err(err_custom_create!( "Transfer from contract different token {:#x} != {:#x}", log.address, @@ -1103,7 +1119,7 @@ pub async fn find_receipt_extended( } } - Ok((chain_tx_dao, transfers)) + Ok(FindReceiptParseResult::Success((chain_tx_dao, transfers))) } pub async fn get_erc20_logs( diff --git a/src/main.rs b/src/main.rs index 17c00e40..cc036051 100644 --- a/src/main.rs +++ b/src/main.rs @@ -831,6 +831,7 @@ async fn main_internal() -> Result<(), PaymentError> { chain_cfg.chain_id, &format!("{tx:#x}"), chain_cfg.token.address, + scan_blockchain_options.import_balances, ) .await {