11// src/utils.rs
22
33use crate :: api;
4+ use crate :: backoff:: Backoff ;
45use crate :: cardano;
56use crate :: constants:: USER_AGENT ;
67use crate :: data_types:: {
@@ -216,18 +217,39 @@ pub fn run_single_mining_cycle(
216217 } ,
217218 Some ( nonce) => {
218219 println ! ( "\n ✅ Solution found: {}. Submitting..." , nonce) ;
219- match api:: submit_solution (
220- client, api_url, & mining_address, & challenge_params. challenge_id , & nonce,
221- ) {
222- Err ( e) => {
223- eprintln ! ( "⚠️ Solution submission failed. Details: {}" , e) ;
224- if e. contains ( "Solution already exists" ) {
225- MiningResult :: AlreadySolved
226- } else {
227- MiningResult :: MiningFailed
220+
221+ // NEW: Initialize backoff strategy for submission retries
222+ let mut backoff = Backoff :: new ( 5 , 300 , 2.0 ) ; // min 5s, max 300s, 2.0 factor
223+
224+ let submission_result = loop {
225+ match api:: submit_solution (
226+ client, api_url, & mining_address, & challenge_params. challenge_id , & nonce,
227+ ) {
228+ Ok ( receipt) => {
229+ // Success: break the submission loop
230+ break Ok ( receipt) ;
231+ } ,
232+ Err ( e) if e. contains ( "Network/Client Error" ) => {
233+ // Recoverable Error (Timeout, DNS, etc.): retry with backoff
234+ eprintln ! ( "⚠️ Solution submission failed (Network Error): {}. Retrying..." , e) ;
235+ backoff. sleep ( ) ;
236+ continue ;
237+ } ,
238+ Err ( e) => {
239+ // Non-recoverable Error (API Validation, Already Solved): break the submission loop
240+ eprintln ! ( "⚠️ Solution submission failed (API/Validation Error). Details: {}" , e) ;
241+ if e. contains ( "Solution already exists" ) {
242+ break Err ( MiningResult :: AlreadySolved ) ;
243+ } else {
244+ break Err ( MiningResult :: MiningFailed ) ;
245+ }
228246 }
229- } ,
247+ }
248+ } ;
249+
250+ match submission_result {
230251 Ok ( receipt) => {
252+ // Submission successful after one or more retries
231253 println ! ( "🚀 Submission successful!" ) ;
232254 let donation = donate_to_option. and_then ( |ref destination_address| {
233255 let donation_message = format ! ( "Assign accumulated Scavenger rights to: {}" , destination_address) ;
@@ -241,6 +263,7 @@ pub fn run_single_mining_cycle(
241263 } ) ;
242264 MiningResult :: FoundAndSubmitted ( ( receipt, donation) )
243265 }
266+ Err ( e) => e, // AlreadySolved or MiningFailed from the submission logic
244267 }
245268 } ,
246269 } ;
0 commit comments