Also consider settle queue before rejecting solutions#4337
Also consider settle queue before rejecting solutions#4337MartinquaXD wants to merge 4 commits intomainfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the ensure_settle_queue_capacity method to include a check on the settlement queue's capacity. A logic error was identified where the capacity check is unreliable because requests are dequeued immediately, potentially leading to the driver accepting more auctions than it can handle concurrently. It is suggested to limit the number of concurrent spawned tasks to make the queue capacity check meaningful.
| if !self.submitter_pool.has_capacity() && self.settle_queue.capacity() == 0 { | ||
| tracing::warn!( |
There was a problem hiding this comment.
The check self.settle_queue.capacity() == 0 is unreliable for determining if the settlement backlog is full. The process_settle_requests loop dequeues requests and spawns tasks immediately, which means the settle_queue channel is almost always empty, even when many settlements are pending (waiting for a submission slot). While DoS concerns are not applicable for these trusted requests per repository rules, this logic error allows the driver to accept more auctions than it can handle concurrently, potentially leading to penalties for the solver due to settlements not being mined in time. To fix this, the process_settle_requests loop should be modified to limit the number of concurrent spawned tasks to total_slots. This would cause the settle_queue channel to actually buffer the backlog and make the capacity check meaningful.
| let permit = match self.submitter_pool.acquire().await { | ||
| Some(guard) => guard, | ||
| None => { | ||
| if let Err(err) = request.response_sender.send(Err(Error::SubmissionError)) { | ||
| tracing::warn!(?err, "failed to report submission error"); | ||
| } | ||
| return; | ||
| } | ||
| }; |
There was a problem hiding this comment.
| let permit = match self.submitter_pool.acquire().await { | |
| Some(guard) => guard, | |
| None => { | |
| if let Err(err) = request.response_sender.send(Err(Error::SubmissionError)) { | |
| tracing::warn!(?err, "failed to report submission error"); | |
| } | |
| return; | |
| } | |
| }; | |
| let Some(permit) = match self.submitter_pool.acquire().await else { | |
| if let Err(err) = request.response_sender.send(Err(Error::SubmissionError)) { | |
| tracing::warn!(?err, "failed to report submission error"); | |
| } | |
| return; | |
| }; |
|
Closing in favor of #4338 |

Description
The reference driver rejects new solutions when there is already a backlog of solutions that still need to be submitted because they will most likely not be mined in time. This is intended to protect very competitive solvers from penalties when they win too much but can't submit fast enough.
#4167 introduced a bug where the check whether to reject the
/solverequest only looks at the available tx submission slots but not the settle queue.This has the consequence that a solver with only a single submission EOA that won an auction will reject
/solverequests until the previous solution was submitted.Changes
Only reject new solutions if we don't have a submission slot AND the settle queue is full.