Main#8
Open
jlaguilarm wants to merge 1955 commits into
Open
Conversation
…ed to the secret (#1792) ### Description - Check and add secret validation to configurations related to the secret ### Context - Improve developer experience
### Description - SEP-24 fiat asset casted to stellar asset ``` ClassCastException class org.stellar.anchor.api.asset.FiatAssetInfo cannot be cast to class org.stellar.anchor.api.asset.StellarAssetInfo (org.stellar.anchor.api.asset.FiatAssetInfo and org.stellar.anchor.api.asset.StellarAssetInfo are in unnamed module of loader org.springframework.boot.loader.launch.LaunchedClassLoader @50040f0c) ``` ### Context - Bug fixes
…_to_develop (#1798) ### Description - Add concurrency configurations to on_pull_request and on_push_to_develop ### Context - This is trying to avoid cancelling the waiting jobs of extended and essential tests.
### Description - [ANCHOR-1059] SEP-24 fiat asset casted to stellar asset ### Context - Hotfix the fiat asset cast exception and make 3.1.4 bug fix release. [ANCHOR-1059]: https://stellarorg.atlassian.net/browse/ANCHOR-1059?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
…to DB (#1794) ### Description - In SEP-6 handling, there is an unnecessary database call. We should optimize it by constructing the response without the database query. ### Context - Optimization
### Description - Merge `main` with `develop` for release `3.1.4` ### Context - Post release maintenance.
…int (#1917) ### Description - Add 50KB size limit on `transaction` field in SEP-10 POST `/auth` before XDR parsing - Reduce existing SEP-45 `authorization_entries` size limit from 100KB to 50KB ### Context Valid SEP-10/SEP-45 auth payloads are small (a few KB). Limiting input size before XDR deserialization prevents unnecessary memory allocation from oversized payloads. ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
### Description This bumps the version to 4.2.1 ### Context Patch release ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
… range (#1918) ### Description - Fix MEMO_ID validation to support the full Stellar uint64 range (0 to 18,446,744,073,709,551,615) - Replace Long.parseLong and Long.longValue() with BigInteger for MEMO_ID parsing and conversion - Consolidate memo ID creation into a shared MemoHelper.makeMemoId() method ### Context Partner reported that SEP-24 requests with refund_memo 11872666534918305457 were rejected with "Invalid Memo" due to this refund_memo value above Java's `Long.MAX_VALUE `(9,223,372,036,854,775,807) Stellar protocol defines `MEMO_ID` as uint64, but the platform was using Java's signed long for parsing, which only supports half the range. The same issue existed in SEP-10 memo validation, `xdrMemoToString` (used by the payment observer for memo matching), and muxed account memo handling in `DefaultPaymentListener` ### Testing - ./gradlew test - Added new unit tests to cover all cases ### Documentation N/A ### Known limitations N/A
### Description Merge `release/4.2.1` to `main` ### Context Git flow ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
Comment on lines
+8
to
+10
| uses: ./.github/workflows/sub_gradle_build.yml | ||
|
|
||
| rust_build: |
Comment on lines
+11
to
+13
| uses: ./.github/workflows/sub_rust_build.yml | ||
|
|
||
| essential_tests: |
Comment on lines
+14
to
+20
| needs: [ gradle_build ] | ||
| uses: ./.github/workflows/sub_essential_tests.yml | ||
| concurrency: | ||
| group: ap-test-job | ||
| cancel-in-progress: false | ||
|
|
||
| extended_tests: |
Comment on lines
+21
to
+27
| needs: [ gradle_build, essential_tests ] | ||
| uses: ./.github/workflows/sub_extended_tests.yml | ||
| concurrency: | ||
| group: ap-test-job | ||
| cancel-in-progress: false | ||
|
|
||
| complete: |
Comment on lines
+28
to
+33
| if: always() | ||
| needs: [ gradle_build, essential_tests, extended_tests, rust_build ] | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') | ||
| run: exit 1 |
Comment on lines
+28
to
+67
| name: Push to DockerHub (tag=stellar/anchor-platform:${{ github.event.release.tag_name }}) - AMD64 | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Get EXPECTED_RELEASE_TAG | ||
| shell: bash | ||
| run: echo "EXPECTED_RELEASE_TAG=$(./gradlew -q printVersionName)" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
| with: | ||
| install: true | ||
| driver: docker-container | ||
| driver-opts: | | ||
| image=moby/buildkit:latest | ||
|
|
||
| - name: Docker Login | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
| password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
|
|
||
| - name: Build and push Docker images - AMD64 | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| context: . | ||
| file: ./Dockerfile | ||
| push: true | ||
| platforms: linux/amd64 | ||
| build-args: | | ||
| TARGETARCH=amd64 | ||
| tags: | | ||
| stellar/anchor-platform:${{ env.EXPECTED_RELEASE_TAG }} | ||
| stellar/anchor-platform:latest | ||
| # add build cache for faster rebuilds | ||
| cache-from: type=gha | ||
| cache-to: type=gha,mode=max | ||
|
|
||
| build_and_push_docker_image_arm64: |
Comment on lines
+68
to
+109
| name: Push to DockerHub (tag=stellar/anchor-platform:${{ github.event.release.tag_name }}) - ARM64 | ||
| # Having a separate job for ARM64 helps to reduce overall build time. | ||
| # The multi-arch build takes longer if running the arm build on an amd64 runner via emulation. | ||
| runs-on: ubuntu-24.04-arm | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Get EXPECTED_RELEASE_TAG | ||
| shell: bash | ||
| run: echo "EXPECTED_RELEASE_TAG=$(./gradlew -q printVersionName)" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
| with: | ||
| install: true | ||
| driver: docker-container | ||
| driver-opts: | | ||
| image=moby/buildkit:latest | ||
|
|
||
| - name: Docker Login | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
| password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
|
|
||
| - name: Build and push Docker images - ARM64 | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| context: . | ||
| file: ./Dockerfile | ||
| push: true | ||
| platforms: linux/arm64 | ||
| build-args: | | ||
| TARGETARCH=arm64 | ||
| tags: | | ||
| stellar/anchor-platform:${{ env.EXPECTED_RELEASE_TAG }} | ||
| stellar/anchor-platform:latest | ||
| # Optional: add build cache for faster rebuilds | ||
| cache-from: type=gha | ||
| cache-to: type=gha,mode=max | ||
|
|
||
| complete: |
Comment on lines
+110
to
+115
| if: always() | ||
| needs: [ build_and_push_docker_image_amd64, build_and_push_docker_image_arm64, check_release_tag ] | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') | ||
| run: exit 1 |
Comment on lines
+13
to
+115
| name: Run Essential Tests (Integration Tests, Faster End-2-End Tests, Unit Tests, and Stellar Validation Tools) | ||
| runs-on: ubuntu-latest | ||
| env: | ||
| # Anchor Platform secrets | ||
| SECRET_SEP10_SIGNING_SEED: ${{ vars.SECRET_SEP10_SIGNING_SEED }} | ||
| APP__PAYMENT_SIGNING_SEED: ${{ vars.APP__PAYMENT_SIGNING_SEED }} | ||
| SECRET__KEY: ${{ vars.SECRET__KEY }} | ||
|
|
||
| # Test secrets | ||
| TEST_CLIENT_WALLET_SECRET: ${{ vars.TEST_CLIENT_WALLET_SECRET }} | ||
| TEST_CLIENT_SMART_WALLET_ACCOUNT: ${{ vars.TEST_CLIENT_SMART_WALLET_ACCOUNT }} | ||
| TEST_CLIENT_WALLET_EXTRA_SIGNER_1_SECRET: ${{ vars.TEST_CLIENT_WALLET_EXTRA_SIGNER_1_SECRET }} | ||
| TEST_CLIENT_WALLET_EXTRA_SIGNER_2_SECRET: ${{ vars.TEST_CLIENT_WALLET_EXTRA_SIGNER_2_SECRET }} | ||
| TEST_WITHDRAW_FUND_CLIENT_SECRET_1: ${{ vars.TEST_WITHDRAW_FUND_CLIENT_SECRET_1 }} | ||
| TEST_WITHDRAW_FUND_CLIENT_SECRET_2: ${{ vars.TEST_WITHDRAW_FUND_CLIENT_SECRET_2 }} | ||
| TEST_DEPOSIT_FUND_CLIENT_SECRET_1: ${{ vars.TEST_DEPOSIT_FUND_CLIENT_SECRET_1 }} | ||
| TEST_DEPOSIT_FUND_CLIENT_SECRET_2: ${{ vars.TEST_DEPOSIT_FUND_CLIENT_SECRET_2 }} | ||
| steps: | ||
| ############################################# | ||
| # Setup JDK 17 | ||
| # Download, and Extract anchor-platform.tar | ||
| # Setup hostnames (/etc/hosts) | ||
| ############################################# | ||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v3 | ||
| with: | ||
| java-version: '17' | ||
| distribution: 'adopt' | ||
|
|
||
| - name: Download anchor-platform.tar | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: anchor-platform-tar | ||
| path: /home/runner/ | ||
|
|
||
| - name: Extract anchor-platform.tar | ||
| run: | | ||
| cd /home/runner | ||
| tar -xf /home/runner/anchor-platform.tar | ||
| cd /home/runner/anchor-platform | ||
|
|
||
| - name: Set up hostnames (/etc/hosts) | ||
| run: | | ||
| sudo echo "127.0.0.1 db" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 kafka" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 sep24-reference-ui" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 reference-server" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 reference-db" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 wallet-server" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 platform" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 host.docker.internal" | sudo tee -a /etc/hosts | ||
|
|
||
| ############################################# | ||
|
|
||
|
|
||
| - name: Pull Stellar Validation Tests Docker Image | ||
| run: docker pull stellar/anchor-tests:latest & | ||
|
|
||
| - name: Run Kafka, Postgres, and Sep24 UI with docker compose | ||
| run: docker compose -f /home/runner/anchor-platform/service-runner/src/main/resources/docker-compose-test.yaml up -d --build | ||
|
|
||
| - name: Start `default` configuration | ||
| env: | ||
| TEST_PROFILE_NAME: default | ||
| SEP1_TOML_VALUE: /home/runner/anchor-platform/service-runner/src/main/resources/config/stellar.host.docker.internal.toml | ||
| SEP10_WEB_AUTH_DOMAIN: host.docker.internal:8080 | ||
| SEP10_HOME_DOMAINS: host.docker.internal:8080,*.stellar.org | ||
| SEP45_WEB_AUTH_DOMAIN: host.docker.internal:8080 | ||
| SEP45_HOME_DOMAINS: host.docker.internal:8080,*.stellar.org | ||
| TOML_PATH: /home/runner/anchor-platform/wallet-reference-server/src/main/resources/toml | ||
| KT_REFERENCE_SERVER_CONFIG: /home/runner/anchor-platform/service-runner/src/main/resources/config/reference-config.yaml | ||
| run: | | ||
| cd /home/runner/anchor-platform | ||
| ./gradlew startServersWithTestProfile & | ||
| echo "PID=$!" >> $GITHUB_ENV | ||
|
|
||
| - name: Wait for the sep server to start and get ready | ||
| uses: mydea/action-wait-for-api@v1 | ||
| with: | ||
| url: "http://host.docker.internal:8080/.well-known/stellar.toml" | ||
| interval: "1" | ||
| timeout: "600" | ||
| - name: Run Essential Tests | ||
| env: | ||
| TEST_PROFILE_NAME: default | ||
| RUN_DOCKER: false | ||
| ANCHOR_DOMAIN: http://host.docker.internal:8080 | ||
| run: | | ||
| cd /home/runner/anchor-platform | ||
| ./gradlew clean runEssentialTests | ||
| # do not call "kill -9 $PID" to continue running the servers for Stellar Validation Tool | ||
|
|
||
| - name: Run Stellar validation tool | ||
| run: | | ||
| docker run --network host -v /home/runner/anchor-platform/platform/src/test/resources://config stellar/anchor-tests:latest --home-domain http://host.docker.internal:8080 --seps 1 6 10 12 24 31 38 --sep-config //config/stellar-anchor-tests-sep-config.json --asset-code USDC --verbose | ||
|
|
||
| - name: Upload Essential Tests report | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: essential-tests-report | ||
| path: | | ||
| /home/runner/anchor-platform/essential-tests/build/reports/ |
Comment on lines
+13
to
+154
| name: Run Extended Tests | ||
| runs-on: ubuntu-latest | ||
| env: | ||
| # Anchor Platform secrets | ||
| SECRET_SEP10_SIGNING_SEED: ${{ vars.SECRET_SEP10_SIGNING_SEED }} | ||
| APP__PAYMENT_SIGNING_SEED: ${{ vars.APP__PAYMENT_SIGNING_SEED }} | ||
| SECRET__KEY: ${{ vars.SECRET__KEY }} | ||
|
|
||
| # Test secrets | ||
| TEST_CLIENT_WALLET_SECRET: ${{ vars.TEST_CLIENT_WALLET_SECRET }} | ||
| TEST_CLIENT_SMART_WALLET_ACCOUNT: ${{ vars.TEST_CLIENT_SMART_WALLET_ACCOUNT }} | ||
| TEST_CLIENT_WALLET_EXTRA_SIGNER_1_SECRET: ${{ vars.TEST_CLIENT_WALLET_EXTRA_SIGNER_1_SECRET }} | ||
| TEST_CLIENT_WALLET_EXTRA_SIGNER_2_SECRET: ${{ vars.TEST_CLIENT_WALLET_EXTRA_SIGNER_2_SECRET }} | ||
| TEST_WITHDRAW_FUND_CLIENT_SECRET_1: ${{ vars.TEST_WITHDRAW_FUND_CLIENT_SECRET_1 }} | ||
| TEST_WITHDRAW_FUND_CLIENT_SECRET_2: ${{ vars.TEST_WITHDRAW_FUND_CLIENT_SECRET_2 }} | ||
| TEST_DEPOSIT_FUND_CLIENT_SECRET_1: ${{ vars.TEST_DEPOSIT_FUND_CLIENT_SECRET_1 }} | ||
| TEST_DEPOSIT_FUND_CLIENT_SECRET_2: ${{ vars.TEST_DEPOSIT_FUND_CLIENT_SECRET_2 }} | ||
| steps: | ||
| ############################################# | ||
| # Setup JDK 17 | ||
| # Download, and Extract anchor-platform.tar | ||
| # Setup hostnames (/etc/hosts) | ||
| ############################################# | ||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v3 | ||
| with: | ||
| java-version: '17' | ||
| distribution: 'adopt' | ||
|
|
||
| - name: Download anchor-platform.tar | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: anchor-platform-tar | ||
| path: /home/runner/ | ||
|
|
||
| - name: Extract anchor-platform.tar | ||
| run: | | ||
| cd /home/runner | ||
| tar -xf /home/runner/anchor-platform.tar | ||
| cd /home/runner/anchor-platform | ||
|
|
||
| - name: Set up hostnames (/etc/hosts) | ||
| run: | | ||
| sudo echo "127.0.0.1 db" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 kafka" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 sep24-reference-ui" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 reference-server" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 reference-db" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 wallet-server" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 platform" | sudo tee -a /etc/hosts | ||
| sudo echo "127.0.0.1 host.docker.internal" | sudo tee -a /etc/hosts | ||
|
|
||
| ############################################# | ||
|
|
||
| - name: Run Kafka, Postgres, and Sep24 UI with docker compose | ||
| run: docker compose -f /home/runner/anchor-platform/service-runner/src/main/resources/docker-compose-test.yaml up -d --build | ||
|
|
||
| # `auth-apikey-platform` Tests | ||
| - name: Start `auth-apikey-platform` configuration | ||
| env: | ||
| TEST_PROFILE_NAME: auth-apikey-platform | ||
| KT_REFERENCE_SERVER_CONFIG: /home/runner/anchor-platform/service-runner/src/main/resources/config/reference-config.yaml | ||
| run: | | ||
| cd /home/runner/anchor-platform | ||
| ./gradlew startServersWithTestProfile & | ||
| echo "PID=$!" >> $GITHUB_ENV | ||
|
|
||
| - name: Wait for the platform server to start and get ready | ||
| uses: mydea/action-wait-for-api@v1 | ||
| with: | ||
| url: "http://localhost:8085/health" | ||
| expected-status: "200" | ||
| interval: "1" | ||
| timeout: "600" | ||
|
|
||
| - name: Run `auth-apikey-platform` configuration tests | ||
| env: | ||
| TEST_PROFILE_NAME: auth-apikey-platform | ||
| run: | | ||
| cd /home/runner/anchor-platform | ||
| ./gradlew :extended-tests:test --tests org.stellar.anchor.platform.suite.AuthApikeyPlatformTestSuite | ||
| kill -9 $PID | ||
|
|
||
| # `auth-jwt-platform` Tests | ||
| - name: Start `auth-jwt-platform` configuration | ||
| env: | ||
| TEST_PROFILE_NAME: auth-jwt-platform | ||
| KT_REFERENCE_SERVER_CONFIG: /home/runner/anchor-platform/service-runner/src/main/resources/config/reference-config.yaml | ||
| run: | | ||
| cd /home/runner/anchor-platform | ||
| ./gradlew startServersWithTestProfile & | ||
| echo "PID=$!" >> $GITHUB_ENV | ||
|
|
||
| - name: Wait for the platform server to start and get ready | ||
| uses: mydea/action-wait-for-api@v1 | ||
| with: | ||
| url: "http://localhost:8085/health" | ||
| expected-status: "200" | ||
| interval: "1" | ||
| timeout: "600" | ||
|
|
||
| - name: Run `auth-jwt-platform` configuration tests | ||
| env: | ||
| TEST_PROFILE_NAME: auth-jwt-platform | ||
| run: | | ||
| cd /home/runner/anchor-platform | ||
| ./gradlew :extended-tests:test --tests org.stellar.anchor.platform.suite.AuthJwtPlatformTestSuite | ||
| kill -9 $PID | ||
|
|
||
| # `default-horizon` end-2-end Tests | ||
| - name: Start `default-horizon` configuration | ||
| env: | ||
| TEST_PROFILE_NAME: default-horizon | ||
| KT_REFERENCE_SERVER_CONFIG: /home/runner/anchor-platform/service-runner/src/main/resources/config/reference-config.yaml | ||
| run: | | ||
| cd /home/runner/anchor-platform | ||
| ./gradlew startServersWithTestProfile & | ||
| echo "PID=$!" >> $GITHUB_ENV | ||
|
|
||
| - name: Wait for the sep server to start and get ready | ||
| uses: mydea/action-wait-for-api@v1 | ||
| with: | ||
| url: "http://localhost:8080/.well-known/stellar.toml" | ||
| interval: "1" | ||
| timeout: "600" | ||
|
|
||
| - name: Run limited `end-2-end` tests | ||
| env: | ||
| TEST_PROFILE_NAME: default-horizon | ||
| run: | | ||
| cd /home/runner/anchor-platform | ||
| ./gradlew :service-runner:clean :extended-tests:clean :extended-tests:test --tests org.stellar.anchor.platform.suite.End2EndTestSuite | ||
| kill -9 $PID | ||
|
|
||
| - name: Upload Extended Tests Report | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: extended-tests-report | ||
| path: | | ||
| /home/runner/anchor-platform/extended-tests/build/reports/ | ||
|
|
### Description Each release job now pushes to a temporary arch-specific tag (-amd64, -arm64), and a new `create_multi_arch_manifest` job combines them into a single multi-arch manifest. Same for `on_push_to_develop` ### Context Since 4.1.1, the release workflow has been publishing only one architecture per release due to a race condition, the amd64 and arm64 jobs both push to the same Docker tag, so whichever finishes last overwrites the other. ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
### Description - Switch to Docker's recommended pattern: - Build jobs push by digest only (no intermediate -amd64 -arm64 tags) - Then a `create_multi_arch_manifest` job uses `docker buildx imagetools create` to merge both digests into a single multi-arch manifest. - Apply the same fix to `on_push_to_develop` ### Context #1922 failed because `docker manifest create` (used to merge the amd64 and arm64 builds) expects each source image to be a plain image manifest. However, `build-push-action` v6 with buildx wraps each single-platform image into a manifest list (containing the image + provenance attestation), so the command rejects them with the error "is a manifest list" ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
) ### Description Include HTTP status code and response body in the error message string instead of passing the exception object, matching the existing pattern in `RpcService`. Remove the dangerous `(String, Throwable)` constructors to prevent this class of bug. ### Context When Horizon fails (e.g., rate limiting, network issues), the platform tries to return an error but crashes on serializing the exception, resulting in an unhelpful HTTP 500 (`HttpMessageNotWritableException`). Root cause: `InternalErrorException(message, Throwable)` looks like it sets the Java exception cause, but actually passes the `Throwable` into `RpcException`'s `additionalData` field (an `Object`). Spring then tries to JSON-serialize that `Throwable` and fails because `Throwable#detailMessage` is a private field. ### Testing - `./gradlew test` - Updated assertions in `NotifyOnchainFundsReceivedHandlerTest`, `NotifyOnchainFundsSentHandlerTest` ### Documentation N/A ### Known limitations N/A
…oding (#1925) ### Description Fix muxed (M-address) payment destinations were discarded after resolved, causing deposit matching to silently fail ### Context stellar/internal-agents#93 Finding 11 — Muxed Account Address Discarded → NPE ### Testing - `./gradlew test` - Added unit tests asserting `convert()` returns a non-null M-address for muxed destinations across `PAYMENT`, `PATH_PAYMENT_STRICT_RECEIVE`, and `PATH_PAYMENT_STRICT_SEND` ### Documentation N/A ### Known limitations N/A --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
### Description This bumps the version to 4.2.2 ### Context Patch release ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
### Description Merge `release/4.2.2` to `main` ### Context Git flow ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
…generator (#1929) ### Description Use `SecureRandom.nextLong(1, Long.MAX_VALUE)` to replace non-atomic memo ID generation - Thread-safe within a JVM - Collision-resistant across HA instances - Excludes 0 to avoid downstream sentinel-value confusion - 2^63 space → birthday-paradox collision expected at ~3 billion memos, far beyond any realistic anchor lifetime ### Context `DepositInfoSelfGeneratorBase.generateMemoId()` previously used a non-atomic post-increment on a shared static `long`, so concurrent calls (especially across HA instances initializing from `System.currentTimeMillis()`) can emit the same memo ID. Two transactions then collide on `(withdraw_anchor_account, memo, status)` and the matcher (`findOneBy...`, no `ORDER BY`) can credit an inbound payment to the wrong customer's transaction. ### Testing - `./gradlew test` - New `DepositInfoSelfGeneratorBaseTest` adds a 64-thread × 2,000-call concurrency regression test asserting zero collisions ### Documentation N/A ### Known limitations Does not repair pre-fix transactions that already collided if any.
…nsaction (#1930) ### Description - For muxed accounts, storage at all six creation sites (`Sep24Service` deposit/withdraw, `Sep6Service` deposit/depositExchange/withdraw/withdrawExchange) now writes the **muxed M-address** as `webAuthAccount` instead of the underlying G-address, using `Objects.requireNonNullElse(token.getMuxedAccount(), token.getAccount())`. - Validation on `GET/transactions` in both SEPs. The database is queried for rows where `webAuthAccount` matches the JWT's muxed M-address if it has one, and the G-account otherwise. A muxed customer only sees rows whose `webAuthAccount` equals their M-address now. - G-accounts stay unaffected. ### Context `Sep24Service` and `Sep6Service` previously stored `webAuthAccount = token.getAccount()`, which collapses muxed JWTs' sub-id to the underlying G-address. Two muxed customers on a shared custodial G could read each other's transactions. ### Testing - `./gradlew test` - New tests verify storage behavior, post-fix isolation, findTransactions, findTransaction by id ### Documentation N/A ### Known limitations **Breaking changes for muxed accounts** - `GET /transactions` endpoint will no longer return muxed customers'pre-fix legacy rows; those must be fetched by direct ID. - On `GET /transaction?id=..` endpoint, if customer A learns customer B' transaction ID for a row created before this change, customer A can still fetch that row's details. Both customers' rows were stored with `webAuthAccount = G_shared` and `accountMemo = null`, and the muxed sub-ID was never recorded, so we can't tell their pre-change rows apart.
### Description This bumps the version to 4.3.0 ### Context minor release ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
### Description Merge `release/4.3.0` to `main` ### Context Git flow ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
* update soroban-sdk to version 26.0.0
### Description update soroban-sdk to version 26.0.0 ### Testing `cd soroban && cargo test` ### Documentation N/A ### Known limitations N/A
### Description Adds Gateway API (`Gateway` + `HTTPRoute`) support to all three Anchor Platform helm charts. ### Context Gateway Migration ### Testing - `./gradlew test` - `helm lint` passes for all three charts. - `helm template` with default. Ingress still emitted, no Gateway/HTTPRoute. - `helm template` with Gateway API enabled. renders match the shape in `stellar/kube`. - Server-side dry-run not available locally ### Documentation N/A ### Known limitations N/A
#1940) ### Description - adds an `httpRoute.responseHeaders` values block that emits a Gateway API filter to set security response headers - Explicit `namespace` + `sectionName` on `parentRefs` when using the chart-managed Gateway ### Context The first migration PR dropped the existing `ingress.responseHeaders` block. Adding `namespace` + `sectionName` on `parentRefs` is purely a consistency fix to match the established Gateway API pattern. ### Testing - `helm lint` passes for all three charts. - `helm template` with Gateway API enabled. ### Documentation N/A ### Known limitations N/A
…d allows cross-customer KYC disclosure and payout destination overwrite (#1946) ### Description Before this change, \`Sep12Service.validateGetOrPutRequest\` enforced authorization on \`request.account\` and \`request.memo\` only. When a caller supplied \`request.id\` without \`account\`, the account check short-circuited entirely, allowing any valid SEP-10 session to \`GET\` or \`PUT\` any customer record by its \`id\` — regardless of who created it. The \`id\` was forwarded unmodified to the business-server callback, so any conforming business server would act on it. The fix introduces a \`sep12_customer_ownership\` table. Every successful \`PUT /sep12/customer\` writes the caller's identity (\`stellar_account\`, \`memo\`) as the owner of the returned \`customer_id\`. Subsequent \`GET\` or \`PUT\` requests that supply \`id\` are checked against this table: if the stored owner does not match the token, the request is rejected with 403 before the business server is called. No business server contract changes are required. **Changes** - [x] \`Sep12CustomerOwnership\` / \`Sep12CustomerOwnershipStore\`: new core interfaces defining the ownership record model and its storage contract. - [x] \`JdbcSep12CustomerOwnership\` / \`JdbcSep12CustomerOwnershipRepo\` / \`JdbcSep12CustomerOwnershipStore\`: platform JDBC implementation backed by the new \`sep12_customer_ownership\` table. - [x] \`V29__add_sep12_customer_ownership.sql\`: Flyway migration creating the table (\`customer_id PK\`, \`stellar_account NOT NULL\`, \`memo\`). - [x] \`Sep12Service.putCustomer\`: after every successful callback response, saves \`(customer_id, token_account, token_memo)\` to the ownership store, overwriting any prior record on update. - [x] \`Sep12Service.validateGetOrPutRequest\`: when \`id\` is present and \`transactionId\` is absent, looks up the ownership record. If a record exists and the token's identity does not match, returns 403 before reaching the business server. If no record exists (customer predates the fix or SEP-31 first-time access), the request is allowed through with the caller's account injected, preserving backward compatibility. - [x] \`SepBeans\` / \`DataBeans\`: wire \`Sep12CustomerOwnershipStore\` into the Spring context. - [x] \`Sep12ServiceTest\`: mocked \`Sep12CustomerOwnershipStore\`; updated existing id-path tests; added IDOR unit tests covering mismatched account rejection, mismatched memo rejection, no-record allow-through, ownership save on PUT (plain and muxed), transactionId path bypass, and forward-account-to-callback behaviour. - [x] \`Sep12Tests\`: added \`test cross-account id access is rejected\` integration test — registers a victim customer (ownership row written), attempts raw HTTP \`GET\` and \`PUT\` against that \`id\` from a different SEP-10 session, asserts 403 on both, and verifies the victim's record is unchanged. **Acceptance Criteria** - [x] \`GET /sep12/customer?id=<id>\` with a SEP-10 token that does not own that customer returns 403. - [x] \`PUT /sep12/customer\` with \`{"id":"<id>", ...}\` from a different SEP-10 session returns 403. - [x] The same \`GET\` and \`PUT\` succeed when issued by the token that owns the customer record. - [x] No ownership record (first access or pre-existing customer) allows the request through with the caller's account injected. - [x] The \`transactionId\` path is unaffected. - [x] All existing \`Sep12ServiceTest\` tests pass. ### Context [HackerOne #3735379](https://hackerone.com/reports/3735379) ### Testing - Unit: \`./gradlew :core:test --tests "org.stellar.anchor.sep12.Sep12ServiceTest"\` - Integration: \`./gradlew runEssentialTests\` — covers \`test cross-account id access is rejected\` in \`Sep12Tests\` ### Documentation N/A ### Known limitations Customers created before this migration has run have no ownership record. On their next \`PUT /customer\`, the record is written and all subsequent id-based requests are fully enforced. Until then, id-based access for those customers falls back to the caller's account being injected, relying on the business server's own id+account consistency check.
* update project version in `build.gradle.kts` * update docker badge in `readme.md` * update `version-info.properties`
### Description This bumps the version to 4.4.0 ### Context Release ### Testing - `./gradlew test` ### Documentation N/A ### Known limitations N/A
### Description Merges `release/4.4.0` into `main` for the 4.4.0 release. ### Context - **[ANCHOR-1215]** Fix SEP-12 IDOR via unvalidated customer `id` — prevents cross-customer KYC disclosure and payout destination overwrite (#1946) - **[ANCHOR-1943]** Fix RPC observer DoS via malformed Soroban transfer event (#1944) - **[ANCHOR-1939]** Add per-client event isolation and ambiguous payment routing safety (#1941, #1942) - **[ANCHOR-1934]** Enforce single-use on SEP-38 quotes (#1935) - **[ANCHOR-1206]** Add Gateway API support to Helm charts and carry forward security headers (#1936, #1940) - **[Chore]** Bump Soroban SDK from v22 to v26 (#1937) - **[Chore]** Bump version to 4.4.0 [ANCHOR-1215]: https://stellarorg.atlassian.net/browse/ANCHOR-1215?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [ANCHOR-1206]: https://stellarorg.atlassian.net/browse/ANCHOR-1206?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Checklist
PR Structure
otherwise).
paymentservice.stellar, orallordocif the changes are broad or impact manypackages.
Thoroughness
What
[TODO: Short statement about what is changing.]
Why
[TODO: Why this change is being made. Include any context required to understand the why.]
Known limitations
[TODO or N/A]