Skip to content

[ANCHOR-1261]: SEP-6/24/31-only deployments fail to start due to missing bean dependencies - #1985

Merged
amandagonsalves merged 3 commits into
developfrom
fix/anchor-1261
Jul 30, 2026
Merged

[ANCHOR-1261]: SEP-6/24/31-only deployments fail to start due to missing bean dependencies#1985
amandagonsalves merged 3 commits into
developfrom
fix/anchor-1261

Conversation

@amandagonsalves

@amandagonsalves amandagonsalves commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Description

SepBeans has two bean-gating bugs of the same shape: a bean is annotated with a @Conditional narrower than what its unconditionally-required consumers actually need, so a config enabling only one of SEP-6/24/31 fails to boot.

1. exchangeAmountsCalculator was gated with @OnAllSepsEnabled(seps = {"sep6", "sep24", "sep31"}), requiring all three SEPs to be enabled before the bean is registered. But each of the three consumers (sep6Service, sep24Service, sep31Service) is independently gated on only its own SEP being enabled, and each calls exchangeAmountsCalculator(...) unconditionally in its constructor arguments. Since SepBeans is a plain @Configuration class (default proxyBeanMethods = true), that in-class method call is intercepted by Spring's CGLIB proxy and resolved as a real bean lookup, not a plain Java call - so it's subject to the bean's own condition. Any deployment running SEP-24 without also running SEP-6 and SEP-31 hit this at startup: Sep24Service's own gate (sep24.enabled) passes, but the exchangeAmountsCalculator bean it depends on didn't exist.

2. clientFinder was gated with @OnAnySepsEnabled(seps = {"sep6", "sep10", "sep24"}), omitting "sep31" - but sep31Service takes ClientFinder clientFinder directly as a constructor parameter. A SEP-31-only deployment (SEP-6/10/24 all disabled) hit the identical failure mode for this bean instead.

ExchangeAmountsCalculator itself has no SEP-6/24/31-specific logic - it's a generic (Sep38QuoteStore, Clock) quote-amount calculator shared across all three. Both fixes widen the respective bean's condition to match what its consumers actually require, following the same @OnAnySepsEnabled pattern already used elsewhere in this file for other shared beans.

Also added a parameterized Spring-context test (SepBeansConditionalRegistrationTest) that boots a real ApplicationContextRunner against the actual SepBeans class - the existing SepBeansTest only calls bean methods directly as plain Java calls, which never exercises Spring's @Conditional evaluation and would not have caught either of these regressions, or a future reintroduction of either.

Changes

  • SepBeans.exchangeAmountsCalculator: @OnAllSepsEnabled(seps = {"sep6", "sep24", "sep31"})@OnAnySepsEnabled(seps = {"sep6", "sep24", "sep31"}).
  • SepBeans.clientFinder: @OnAnySepsEnabled(seps = {"sep6", "sep10", "sep24"})@OnAnySepsEnabled(seps = {"sep6", "sep10", "sep24", "sep31"}).
  • SepBeansConditionalRegistrationTest.kt (new): a real Spring ApplicationContextRunner test, parameterized across SEP-6-only / SEP-24-only / SEP-31-only, asserting the context starts successfully and exposes exactly one ExchangeAmountsCalculator bean in each case; a fourth case asserts zero ExchangeAmountsCalculator/ClientFinder/SepRequestValidator beans when none of the three are enabled.

Acceptance Criteria

  • A SEP server configured with only sep24.enabled: true (SEP-6 and SEP-31 disabled) starts successfully and serves GET /sep24/info.
  • The same holds symmetrically for a SEP-6-only or SEP-31-only configuration.
  • A SEP server with any combination of SEP-6/24/31 enabled together continues to start and share a single exchangeAmountsCalculator instance, unchanged from today.
  • A SEP server with none of SEP-6/24/31 enabled does not register the ExchangeAmountsCalculator, ClientFinder, or SepRequestValidator beans, unchanged from today.
  • CI fails if either bean's condition is narrowed again in a way that breaks a single-SEP deployment.

Context

Reported by an operator upgrading to 4.6.1: their service failed to start with SEP-24 enabled unless SEP-6 and SEP-31 were also enabled (with inert settings, purely to satisfy the bean condition), despite having no business logic or ops process behind those two protocols. Tracked as ANCHOR-1261. The clientFinder/SEP-31 gap was found while verifying the fix live across all three single-SEP configurations, ahead of writing the regression test.

Testing

  • ./gradlew :core:test :platform:test - BUILD SUCCESSFUL.
  • Manual, against a real Postgres instance and the built service-runner jar: booted the actual --sep-server process independently with SEP24_ENABLED=true/SEP6_ENABLED=true/SEP31_ENABLED=true (each alone, other two disabled) - all three start cleanly and serve requests (GET /sep24/info confirmed for the SEP-24 case).
  • Negative control, both fixes independently: reverted each bean's condition back to its buggy form, rebuilt, and confirmed the exact reported failure reproduces verbatim (... required a bean named 'exchangeAmountsCalculator' that could not be found / ... required a bean of type 'org.stellar.anchor.client.ClientFinder' that could not be found); confirmed the new automated test fails in exactly the corresponding case and no other; restored both fixes and confirmed clean passes.

Documentation

N/A

Known limitations

N/A

* refactor exchange amounts calculator bean activation

* update condition to activate if any sep6, sep24, or sep31 is enabled
Copilot AI review requested due to automatic review settings July 28, 2026 15:28
@amandagonsalves amandagonsalves self-assigned this Jul 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Corrects conditional bean registration so SEP-6, SEP-24, or SEP-31 can run independently.

Changes:

  • Registers ExchangeAmountsCalculator when any supported SEP is enabled.
  • Aligns the bean condition with its consumers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* add sep31 to the list of seps for clientfinder conditional enablement

* add new test file `sepbeansconditionalregistrationtest.kt`

* add scenarios to test clientfinder registration for sep6, sep10, sep24, or sep31 enablement

* add scenarios to test no registration of exchangeamountscalculator and clientfinder when no seps are enabled
@amandagonsalves amandagonsalves changed the title [ANCHOR-1261]: SEP-24-only deployments fail to start with a missing 'exchangeAmountsCalculator' bean [ANCHOR-1261]: SEP-6/24/31-only deployments fail to start due to missing bean dependencies Jul 29, 2026
@amandagonsalves
amandagonsalves merged commit 97cc612 into develop Jul 30, 2026
14 of 16 checks passed
@amandagonsalves
amandagonsalves deleted the fix/anchor-1261 branch July 30, 2026 16:25
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.

3 participants