Skip to content

Add optimistic collateral#885

Open
ZanCorDX wants to merge 4 commits intodevelopfrom
dx/relay-collateral
Open

Add optimistic collateral#885
ZanCorDX wants to merge 4 commits intodevelopfrom
dx/relay-collateral

Conversation

@ZanCorDX
Copy link
Collaborator

📝 Summary

Added a new cfg to the relays: optimistic_collateral_eth.
When set, if the bid is > optimistic_collateral_eth it will disable optimistic v3.
This will allow the relays to treat the bid as a non optimistic one instead of droping it.

✅ I have completed the following steps:

  • Run make lint
  • Run make test
  • Added tests (if applicable)

@ZanCorDX ZanCorDX requested a review from dvush as a code owner February 19, 2026 13:02
@claude
Copy link
Contributor

claude bot commented Feb 19, 2026

PR Review: Add optimistic collateral

  • Read repository guidelines (CLAUDE.md)
  • Gather context and read changed files
  • Analyze changes and provide review feedback

Working on it...

View job run

@claude
Copy link
Contributor

claude bot commented Feb 19, 2026

Claude finished @ZanCorDX's task in 2m 18s —— View job


PR Review: Add optimistic collateral

  • Read repository guidelines (CLAUDE.md)
  • Gather context and read changed files
  • Analyze changes and provide review feedback

The PR adds a new optimistic_collateral_eth config field that disables optimistic V3 submissions when the bid value exceeds the configured cap, falling back to regular (non-optimistic) submission instead of dropping the bid. The core logic is correct and the config plumbing is clean.

Issues raised inline:

  1. Missing observability (relay_submit.rs:429-433) — When optimistic V3 is silently disabled due to the collateral cap, there's no log output. This will make it hard to diagnose submission behavior in production. A trace-level log when the cap is triggered would help.

  2. Naming ambiguity (mod.rs:138-140) — optimistic_collateral_eth could be confused with the existing optimistic flag. Since this only affects optimistic_v3, a name like optimistic_v3_collateral_eth would be clearer.

Additional notes:

  • No tests were added. A unit test verifying the collateral cap correctly gates the is_none_or logic (bid at, below, and above cap) would be straightforward and valuable.
  • The fallback to non-optimistic submission correctly includes adjustment_data when optimistic_v3 is None (via the existing .filter(|_| optimistic_v3.is_none()) at line 458), so the data flow is sound.

Comment on lines 429 to 433
if relay.optimistic_v3()
&& relay
.optimistic_collateral()
.is_none_or(|cap| bid_value <= cap)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a trace/debug log when optimistic v3 is disabled due to the collateral cap. Silent downgrades from optimistic v3 to regular submission will be difficult to diagnose operationally.

Something like:

if relay.optimistic_v3() {
    if relay.optimistic_collateral().is_some_and(|cap| bid_value > cap) {
        trace!(
            bid_value = %bid_value,
            cap = %relay.optimistic_collateral().unwrap(),
            "Optimistic V3 disabled: bid exceeds collateral cap"
        );
    } else if let Some(config) = optimistic_v3_config {
        // ... existing logic
    }
}

Comment on lines 138 to 140
/// Do not use optimistic V3 when bid value is above this (ETH). None -> no cap.
#[serde(default)]
pub optimistic_collateral_eth: Option<String>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming nit: optimistic_collateral_eth suggests it applies to all optimistic modes, but it only gates optimistic_v3. Consider a more specific name like optimistic_v3_collateral_eth or optimistic_v3_max_bid_eth to avoid confusion with the existing optimistic flag.

@claude
Copy link
Contributor

claude bot commented Feb 19, 2026

Claude finished @ZanCorDX's task in 2m 38s —— View job


PR Review: Add optimistic collateral (re-review after update)

  • Read repository guidelines (CLAUDE.md)
  • Gather context and read changed files
  • Analyze changes and provide review feedback

The updated PR addresses the naming feedback from the first review — optimistic_collateral_eth is now optimistic_v3_max_bid_eth, and a log line has been added when the cap triggers. The config plumbing and core logic remain correct. The adjustment_data fallback path (line 464-466) is properly handled when optimistic_v3 is None due to the cap.

Issues raised inline:

  1. Collapsible else { if } (relay_submit.rs:439-456) — The else { if let ... } block should be collapsed into else if let ... to reduce nesting. This is also flagged by clippy::collapsible_else_if.

  2. Log level too high (relay_submit.rs:434) — info! will fire on every bid above the cap per submission cycle. For high-value bids this could be noisy. debug! or trace! would be more appropriate, consistent with the silent max_bid check on line 411.

  3. Doc comment inconsistency (relay_submit.rs:141) — The doc says >= but the code uses > (strictly greater). Since this PR already touched this line, it's a good opportunity to fix.

Comment on lines 439 to 456
} else {
if let Some(config) = optimistic_v3_config {
optimistic_v3 = create_optimistic_v3_request(
&config.builder_url,
request.as_ref(),
maybe_adjustment_data,
relay.optimistic_v3_bid_adjustment_required(),
)
.map(|request| (config.clone(), SubmitHeaderRequestWithMetadata {
submission: request,
metadata: bid_metadata.clone()
}))
.inspect_err(|error| {
error!(parent: submission_span, ?error, "Unable to create optimistic V3 request");
})
.ok();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: else { if ... } can be collapsed into else if ... to reduce nesting. This is also a clippy::collapsible_else_if lint.

Suggested change
} else {
if let Some(config) = optimistic_v3_config {
optimistic_v3 = create_optimistic_v3_request(
&config.builder_url,
request.as_ref(),
maybe_adjustment_data,
relay.optimistic_v3_bid_adjustment_required(),
)
.map(|request| (config.clone(), SubmitHeaderRequestWithMetadata {
submission: request,
metadata: bid_metadata.clone()
}))
.inspect_err(|error| {
error!(parent: submission_span, ?error, "Unable to create optimistic V3 request");
})
.ok();
}
}
} else if let Some(config) = optimistic_v3_config {
optimistic_v3 = create_optimistic_v3_request(
&config.builder_url,
request.as_ref(),
maybe_adjustment_data,
relay.optimistic_v3_bid_adjustment_required(),
)
.map(|request| (config.clone(), SubmitHeaderRequestWithMetadata {
submission: request,
metadata: bid_metadata.clone()
}))
.inspect_err(|error| {
error!(parent: submission_span, ?error, "Unable to create optimistic V3 request");
})
.ok();
}

.optimistic_v3_max_bid()
.is_some_and(|cap| bid_value > cap)
{
info!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

info! will fire for every bid above the cap on every block submission cycle. Given that high-value bids may be common in practice, this could produce significant log volume. Consider using trace! or debug! instead, matching the silent approach used by the existing max_bid check on line 411.

/// 0. We divide relays into optimistic and non-optimistic (defined in config file)
/// 1. We schedule submissions with non-optimistic key for all non-optimistic relays.
/// 1.1 If "optimistic_enabled" is false or bid_value >= "optimistic_max_bid_value" we schedule submissions with non-optimistic key
/// 1.1 If "optimistic_enabled" is false or bid_value >= "optimistic_v3_max_bid_eth" we schedule submissions with non-optimistic key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: this doc comment says >= but the actual code on line 432 uses > (strictly greater). Since this PR touched this line to rename the field, it would be a good opportunity to fix the inconsistency.

Suggested change
/// 1.1 If "optimistic_enabled" is false or bid_value >= "optimistic_v3_max_bid_eth" we schedule submissions with non-optimistic key
/// 1.1 If "optimistic_enabled" is false or bid_value > "optimistic_v3_max_bid_eth" we schedule submissions with non-optimistic key

@claude
Copy link
Contributor

claude bot commented Feb 19, 2026

Claude finished @ZanCorDX's task in 1m 40s —— View job


PR Review: Add optimistic collateral (re-review after latest push)

  • Read repository guidelines (CLAUDE.md)
  • Gather context and read changed files
  • Analyze changes and provide review feedback

The latest push addresses the else { if ... }else if ... collapsible lint from the previous review. The naming and logging feedback were already handled in the prior commit. Config plumbing and core logic remain correct.

Two outstanding issues from previous review, raised inline again:

  1. Doc comment still says >=, code uses > (relay_submit.rs:141) — The inconsistency between the doc comment and the actual comparison operator was flagged last round and is still present.

  2. Log level + redundant unwrap (relay_submit.rs:430-438) — info! is still used (previous review suggested debug!/trace!), and relay.optimistic_v3_max_bid() is called twice with an unwrap() that could be avoided by using if let Some(cap) instead.

Both are minor but worth addressing before merge.

/// 0. We divide relays into optimistic and non-optimistic (defined in config file)
/// 1. We schedule submissions with non-optimistic key for all non-optimistic relays.
/// 1.1 If "optimistic_enabled" is false or bid_value >= "optimistic_max_bid_value" we schedule submissions with non-optimistic key
/// 1.1 If "optimistic_enabled" is false or bid_value >= "optimistic_v3_max_bid_eth" we schedule submissions with non-optimistic key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc comment still says >= but the code on line 432 uses > (strictly greater than). This was flagged in the previous review. Please either update the doc to match the code or vice versa.

Suggested change
/// 1.1 If "optimistic_enabled" is false or bid_value >= "optimistic_v3_max_bid_eth" we schedule submissions with non-optimistic key
/// 1.1 If "optimistic_enabled" is false or bid_value > "optimistic_v3_max_bid_eth" we schedule submissions with non-optimistic key

Comment on lines +430 to +438
if relay
.optimistic_v3_max_bid()
.is_some_and(|cap| bid_value > cap)
{
info!(
bid_value = format_ether(bid_value),
cap = format_ether(relay.optimistic_v3_max_bid().unwrap()),
"Optimistic V3 disabled: bid exceeds max bid cap"
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two issues here:

  1. Log level: info! will fire on every bid above the cap per submission cycle. This was flagged in the previous review — debug! or trace! would be more appropriate, consistent with the silent max_bid check on line 411.

  2. Redundant getter + unwrap: relay.optimistic_v3_max_bid() is called twice — once in is_some_and and again with .unwrap(). Using if let Some(cap) avoids both the duplicate call and the unwrap:

if let Some(cap) = relay.optimistic_v3_max_bid() {
    if bid_value > cap {
        debug!(
            bid_value = format_ether(bid_value),
            cap = format_ether(cap),
            "Optimistic V3 disabled: bid exceeds max bid cap"
        );
    } else if let Some(config) = optimistic_v3_config {
        // ... existing logic
    }
} else if let Some(config) = optimistic_v3_config {
    // ... existing logic
}

Or keep the current structure but bind the cap:

if let Some(cap) = relay.optimistic_v3_max_bid().filter(|&cap| bid_value > cap) {
    debug!(
        bid_value = format_ether(bid_value),
        cap = format_ether(cap),
        "Optimistic V3 disabled: bid exceeds max bid cap"
    );
} else if let Some(config) = optimistic_v3_config {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments