@@ -17,6 +17,9 @@ var log = logger.GetOrCreate("process/asyncExecution")
1717
1818const timeToSleep = time .Millisecond * 5
1919const timeToSleepOnError = time .Millisecond * 300
20+ const maxRetryAttempts = 10
21+ const maxBackoffTime = time .Second * 5
22+ const validationInterval = time .Minute * 1
2023
2124// ArgsHeadersExecutor holds all the components needed to create a new instance of *headersExecutor
2225type ArgsHeadersExecutor struct {
@@ -72,6 +75,8 @@ func (he *headersExecutor) StartExecution() {
7275
7376// PauseExecution pauses the execution
7477func (he * headersExecutor ) PauseExecution () {
78+ log .Debug ("headersExecutor.PauseExecution: pausing execution" )
79+
7580 he .mutPaused .Lock ()
7681 defer he .mutPaused .Unlock ()
7782
@@ -84,6 +89,8 @@ func (he *headersExecutor) PauseExecution() {
8489
8590// ResumeExecution resumes the execution
8691func (he * headersExecutor ) ResumeExecution () {
92+ log .Debug ("headersExecutor.ResumeExecution: resuming execution" )
93+
8794 he .mutPaused .Lock ()
8895 defer he .mutPaused .Unlock ()
8996
@@ -93,10 +100,19 @@ func (he *headersExecutor) ResumeExecution() {
93100func (he * headersExecutor ) start (ctx context.Context ) {
94101 log .Debug ("headersExecutor.start: starting execution" )
95102
103+ validationTicker := time .NewTicker (validationInterval )
104+ defer validationTicker .Stop ()
105+
96106 for {
97107 select {
98108 case <- ctx .Done ():
99109 return
110+ case <- validationTicker .C :
111+ // Periodic queue validation
112+ err := he .blocksQueue .ValidateQueueIntegrity ()
113+ if err != nil {
114+ log .Error ("headersExecutor.start: queue integrity validation failed" , "err" , err )
115+ }
100116 default :
101117 he .mutPaused .RLock ()
102118 isPaused := he .isPaused
@@ -129,43 +145,74 @@ func (he *headersExecutor) start(ctx context.Context) {
129145}
130146
131147func (he * headersExecutor ) handleProcessError (ctx context.Context , pair queue.HeaderBodyPair ) {
132- for {
148+ retryCount := 0
149+ backoffTime := timeToSleepOnError
150+
151+ for retryCount < maxRetryAttempts {
133152 pairFromQueue , ok := he .blocksQueue .Peek ()
134153 if ok && pairFromQueue .Header .GetNonce () == pair .Header .GetNonce () {
135154 // continue the processing (pop the next header from queue)
136155 return
137156 }
157+
138158 select {
139159 case <- ctx .Done ():
140160 return
141161 default :
142162 // retry with the same pair
143163 err := he .process (pair )
144164 if err == nil {
165+ log .Debug ("headersExecutor.handleProcessError - retry succeeded" ,
166+ "nonce" , pair .Header .GetNonce (),
167+ "retry_count" , retryCount )
145168 return
146169 }
147- time .Sleep (timeToSleepOnError )
170+ retryCount ++
171+ log .Warn ("headersExecutor.handleProcessError - retry failed" ,
172+ "nonce" , pair .Header .GetNonce (),
173+ "retry_count" , retryCount ,
174+ "max_retries" , maxRetryAttempts ,
175+ "err" , err )
176+
177+ // Exponential backoff with maximum limit
178+ time .Sleep (backoffTime )
179+ backoffTime = backoffTime * 2
180+ if backoffTime > maxBackoffTime {
181+ backoffTime = maxBackoffTime
182+ }
148183 }
149184 }
185+
186+ log .Error ("headersExecutor.handleProcessError - max retries exceeded, skipping block" ,
187+ "nonce" , pair .Header .GetNonce (),
188+ "max_retries" , maxRetryAttempts )
150189}
151190
152191func (he * headersExecutor ) process (pair queue.HeaderBodyPair ) error {
153192 executionResult , err := he .blockProcessor .ProcessBlockProposal (pair .Header , pair .Body )
154193 if err != nil {
155194 log .Warn ("headersExecutor.process process block failed" ,
156195 "nonce" , pair .Header .GetNonce (),
196+ "prevHash" , pair .Header .GetPrevHash (),
157197 "err" , err ,
158198 )
159199 return err
160200 }
161201
202+ // Validate execution result
203+ if check .IfNil (executionResult ) {
204+ log .Warn ("headersExecutor.process - nil execution result received" ,
205+ "nonce" , pair .Header .GetNonce ())
206+ return ErrNilExecutionResult
207+ }
208+
162209 err = he .executionTracker .AddExecutionResult (executionResult )
163210 if err != nil {
164211 log .Warn ("headersExecutor.process add execution result failed" ,
165212 "nonce" , pair .Header .GetNonce (),
166213 "err" , err ,
167214 )
168- return nil
215+ return err
169216 }
170217
171218 he .blockChain .SetFinalBlockInfo (
0 commit comments