Skip to content

Commit

Permalink
Merge pull request #52 from starknet-id/fix/check_failed_tx
Browse files Browse the repository at this point in the history
fix: add check for failed transactions
  • Loading branch information
Th0rgal authored Feb 28, 2024
2 parents 3552b8f + 8869c7e commit 5eaef46
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 4 deletions.
43 changes: 42 additions & 1 deletion bot/src/bot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,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};
Expand Down Expand Up @@ -383,6 +385,8 @@ pub async fn renew_domains(
aggregate_results.domains.len()
));
let mut nonce = account.get_nonce().await.unwrap();
let mut tx_results = Vec::<TxResult>::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()
Expand Down Expand Up @@ -420,6 +424,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;
}
Expand All @@ -434,12 +445,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} with {:?} domains has failed with reason: {:?}",
failure.tx_hash, failure.domains_renewed, failure.revert_reason
));
});
logger.severe("Stopping process.");
break;
}

println!("Waiting for 1 minute before sending the next transaction...");
sleep(TokioDuration::from_secs(60)).await;
}
Expand Down
10 changes: 9 additions & 1 deletion bot/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -90,6 +90,14 @@ pub struct States {
pub states: HashMap<String, State>,
}

#[derive(Debug, Clone)]
pub struct TxResult {
pub tx_hash: FieldElement,
pub reverted: Option<bool>,
pub revert_reason: Option<String>,
pub domains_renewed: usize,
}

pub trait Unzip5 {
type A;
type B;
Expand Down
60 changes: 58 additions & 2 deletions bot/src/starknet_utils.rs
Original file line number Diff line number Diff line change
@@ -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<HttpTransport> {
JsonRpcClient::new(HttpTransport::new(Url::parse(&conf.rpc.rpc_url).unwrap()))
}

pub async fn check_pending_transactions(conf: &Config, tx_results: &mut Vec<TxResult>) {
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
);
}
}
}
}
}

0 comments on commit 5eaef46

Please sign in to comment.