From 847f193969e571c0bb34021b9bc0ad5bafc5099b Mon Sep 17 00:00:00 2001 From: Iris Date: Tue, 27 Feb 2024 11:53:09 +0100 Subject: [PATCH 1/3] fix: add check for failed transactions --- bot/src/bot.rs | 44 +++++++++++++++++++++++++++- bot/src/models.rs | 10 ++++++- bot/src/starknet_utils.rs | 60 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 110 insertions(+), 4 deletions(-) diff --git a/bot/src/bot.rs b/bot/src/bot.rs index bcef35b..01fb434 100644 --- a/bot/src/bot.rs +++ b/bot/src/bot.rs @@ -13,6 +13,7 @@ use futures::stream::{self, StreamExt}; use futures::TryStreamExt; use mongodb::options::FindOneOptions; use starknet::accounts::ConnectedAccount; +use starknet::core::types::ExecutionResult; use starknet::core::types::{BlockTag, FunctionCall}; use starknet::{ accounts::{Account, Call, SingleOwnerAccount}, @@ -25,9 +26,11 @@ use starknet_id::encode; use tokio::time::{sleep, Duration as TokioDuration}; use crate::logger::Logger; +use crate::models::TxResult; use crate::models::{ AggregateResult, AggregateResults, DomainAggregateResult, MetadataDoc, Unzip5, }; +use crate::starknet_utils::check_pending_transactions; use crate::starknet_utils::create_jsonrpc_client; use crate::starknetid_utils::get_renewal_price; use crate::utils::{from_uint256, hex_to_bigdecimal, to_uint256}; @@ -383,6 +386,8 @@ pub async fn renew_domains( aggregate_results.domains.len() )); let mut nonce = account.get_nonce().await.unwrap(); + let mut tx_results = Vec::::new(); + // If we have: i32 more than 75 domains to renew we make multiple transactions to avoid hitting the 3M steps limit while !aggregate_results.domains.is_empty() && !aggregate_results.renewers.is_empty() @@ -420,6 +425,13 @@ pub async fn renew_domains( domains_to_renew.len(), nonce, )); + tx_results.push(TxResult { + tx_hash, + reverted: None, + revert_reason: None, + domains_renewed: domains_to_renew.len(), + }); + // We only inscrease nonce if no error occurred in the previous transaction nonce += FieldElement::ONE; } @@ -434,12 +446,42 @@ pub async fn renew_domains( } else { logger.severe(format!( "Error while renewing domains: {:?} for domains: {:?}", - e, domains_to_renew + e, + domains_to_renew.len() )); return Err(e); } } } + + check_pending_transactions(config, &mut tx_results).await; + + let filtered_results: Vec<&TxResult> = tx_results + .iter() + .filter(|tx| tx.reverted.is_some()) + .collect(); + + let failed_count = filtered_results + .iter() + .rev() + .take(3) + .filter(|tx| tx.reverted == Some(true)) + .count(); + + // If 3 transactions have failed, we stop the process + if failed_count == 3 { + logger.severe("The last 3 transactions have failed. Stopping process."); + logger.info(format!("Sent {:?} transactions", tx_results.len())); + filtered_results.iter().rev().take(3).for_each(|failure| { + logger.severe(format!( + "Transaction 0x{:x} has failed with reason: {:?}", + failure.tx_hash, failure.revert_reason + )); + }); + logger.severe("Stopping process."); + break; + } + println!("Waiting for 1 minute before sending the next transaction..."); sleep(TokioDuration::from_secs(60)).await; } diff --git a/bot/src/models.rs b/bot/src/models.rs index b6c6539..ad5d3a2 100644 --- a/bot/src/models.rs +++ b/bot/src/models.rs @@ -4,7 +4,7 @@ use bigdecimal::BigDecimal; use bson::DateTime; use mongodb::Database; use serde::{Deserialize, Serialize}; -use starknet::core::types::FieldElement; +use starknet::core::types::{FieldElement, TransactionExecutionStatus}; pub struct AppState { pub db: Database, @@ -90,6 +90,14 @@ pub struct States { pub states: HashMap, } +#[derive(Debug, Clone)] +pub struct TxResult { + pub tx_hash: FieldElement, + pub reverted: Option, + pub revert_reason: Option, + pub domains_renewed: usize, +} + pub trait Unzip5 { type A; type B; diff --git a/bot/src/starknet_utils.rs b/bot/src/starknet_utils.rs index dc36d66..1bba5e3 100644 --- a/bot/src/starknet_utils.rs +++ b/bot/src/starknet_utils.rs @@ -1,7 +1,63 @@ -use crate::config::Config; -use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient}; +use crate::{config::Config, models::TxResult}; +use starknet::{ + core::types::{ + MaybePendingTransactionReceipt, PendingTransactionReceipt, TransactionExecutionStatus, + TransactionReceipt, + }, + providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, +}; use url::Url; pub fn create_jsonrpc_client(conf: &Config) -> JsonRpcClient { JsonRpcClient::new(HttpTransport::new(Url::parse(&conf.rpc.rpc_url).unwrap())) } + +pub async fn check_pending_transactions(conf: &Config, tx_results: &mut Vec) { + let client = create_jsonrpc_client(conf); + for tx_result in tx_results.iter_mut() { + if tx_result.reverted.is_none() { + match client.get_transaction_receipt(tx_result.tx_hash).await { + Ok(receipt) => match receipt { + MaybePendingTransactionReceipt::PendingReceipt(pending_receipt) => { + if let PendingTransactionReceipt::Invoke(invocation) = pending_receipt { + match invocation.execution_result.status() { + TransactionExecutionStatus::Succeeded => { + tx_result.reverted = Some(false); + } + TransactionExecutionStatus::Reverted => { + tx_result.reverted = Some(true); + tx_result.revert_reason = invocation + .execution_result + .revert_reason() + .map(|s| s.to_owned()); + } + } + } + } + MaybePendingTransactionReceipt::Receipt(receipt) => { + if let TransactionReceipt::Invoke(invocation) = receipt { + match invocation.execution_result.status() { + TransactionExecutionStatus::Succeeded => { + tx_result.reverted = Some(false); + } + TransactionExecutionStatus::Reverted => { + tx_result.reverted = Some(true); + tx_result.revert_reason = invocation + .execution_result + .revert_reason() + .map(|s| s.to_owned()); + } + } + } + } + }, + Err(e) => { + eprintln!( + "Error checking status for tx_hash {}: {}", + tx_result.tx_hash, e + ); + } + } + } + } +} From fff57008f89c95681aa547d2f7d037955e7527be Mon Sep 17 00:00:00 2001 From: Iris Date: Tue, 27 Feb 2024 11:54:16 +0100 Subject: [PATCH 2/3] fix: remove unused import --- bot/src/bot.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/bot/src/bot.rs b/bot/src/bot.rs index 01fb434..dcf3f94 100644 --- a/bot/src/bot.rs +++ b/bot/src/bot.rs @@ -13,7 +13,6 @@ use futures::stream::{self, StreamExt}; use futures::TryStreamExt; use mongodb::options::FindOneOptions; use starknet::accounts::ConnectedAccount; -use starknet::core::types::ExecutionResult; use starknet::core::types::{BlockTag, FunctionCall}; use starknet::{ accounts::{Account, Call, SingleOwnerAccount}, From 8869c7ef02b48ae35e6b34a86a07927b0f8a4ec9 Mon Sep 17 00:00:00 2001 From: Iris Date: Tue, 27 Feb 2024 11:55:13 +0100 Subject: [PATCH 3/3] fix: update logs --- bot/src/bot.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/src/bot.rs b/bot/src/bot.rs index dcf3f94..33807a5 100644 --- a/bot/src/bot.rs +++ b/bot/src/bot.rs @@ -473,8 +473,8 @@ pub async fn renew_domains( logger.info(format!("Sent {:?} transactions", tx_results.len())); filtered_results.iter().rev().take(3).for_each(|failure| { logger.severe(format!( - "Transaction 0x{:x} has failed with reason: {:?}", - failure.tx_hash, failure.revert_reason + "Transaction 0x{:x} with {:?} domains has failed with reason: {:?}", + failure.tx_hash, failure.domains_renewed, failure.revert_reason )); }); logger.severe("Stopping process.");