Repository navigation
Protocol 30 support (CAP-0084, CAP-0087, CAP-0088) - #237
Conversation
Repin go-stellar-sdk to the CAP-0084 XDR/strkey fork, bump MaxSupportedProtocolVersion to 30, add v30 test fixtures, and cover muxed-contract SAC destinations in ingestion tests.
XDR regenerated from stellar-xdr ee040cd6 with CAP_0084_MUXED_CONTRACT, matching stellar-core#5472.
Adds the muxed-contract SAC transfer/mint vectors and asserts destination_muxed_id survives ingestion.
P30 builds core #5472 from source (no -vnext artifact) and runs without a stellar-rpc image.
#5472 is merged and Jenkins has published its vnext deb and image, so the leg no longer builds the pre-merge head from source.
SAC transfers and mints to a CAP-0084 muxed contract now carry contract_muxed and contract_muxed_id, as account_credited does for muxed accounts. Repins go-stellar-sdk to #6015 (70bad4ef) for the new ContractCredited fields.
Brings in stellar#240 (asset filter on fee-bump inner operations) and stellar#242 (HTTP write and idle deadlines), which stellar#244 fast-forwards protocol-next to. The only conflict was the Unreleased CHANGELOG section, resolved by keeping both entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The single Protocol 30 SDK PR now regenerates XDR from stellar-xdr 4f524bba with CAP-0084, CAP-0087 and CAP-0088 ungated. This adds the CAP-0088 STELLAR_VALUE_SIGNED_MS and STELLAR_VALUE_EMPTY_TX_SET_MS StellarValue arms, without which no ledger after the Protocol 30 upgrade decodes, and the CAP-0087 ML-DSA ContractCostType names. 663a89a1 also merges go-stellar-sdk main (#6014, #6006, #6017), so the replace does not drop those fixes. #6017 removes the on-disk bucket cache APIs, none of which Horizon references. Horizon builds unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mock archive serves one account entry for every bucket hash, while the HAS listed 22 real testnet bucket hashes. go-stellar-sdk#6017 (in 663a89a1) makes CheckpointChangeReader fail every Read once a bucket's hash check fails, including Reads of entries already buffered, so the test failed about 70% of runs with "stream hash mismatch". Build the HAS with the served bucket's hash as its only bucket. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TestCoreLCMMuxedContractDestination now also checks the contract_credited effect of stellar-core's CAP-0084 transfer and mint vectors: contract keeps the base C address, and contract_muxed / contract_muxed_id carry the W address and id, decoded the way the /effects endpoint decodes them. A resourceadapter test checks that the stored details render into the SDK's ContractCredited fields, with contract_muxed_id as a JSON string like account_muxed_id, so ids above 2^53 survive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From Protocol 30 every ledger header's StellarValue uses the STELLAR_VALUE_SIGNED_MS or STELLAR_VALUE_EMPTY_TX_SET_MS arm. Add a processor runner test that decodes a SIGNED_MS LedgerCloseMeta and runs it through the transaction processors, and a test that ledgerHeaderToMap stores either arm with closed_at taken from the whole-second CloseTime and the arm intact in ledger_header. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
88d2431d7 merges v29.0.0 into master (#5476) on top of 73f2bdd1 (#5472, CAP-0084), and is the newest master commit Jenkins has published vnext packages for; master's later commits only add release notes. The leg still runs without CAP-0087 and CAP-0088, which core has not merged. Note on the P29 leg why it runs the P29 release for now, and on the P30 leg that a core with CAP-0087 needs a regenerated unlimited-config-v30.xdr. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cover all three CAPs: the CAP-0084 contract_muxed / contract_muxed_id effect fields, the CAP-0088 StellarValue arms (close times stay whole seconds, header_xdr carries the new arms), and CAP-0087 needing no Horizon changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stellar/stellar-core#5478 made protocol 30 the current protocol on master, with CAP-0084 and CAP-0087. Move the P30 leg from the pre-#5478 vnext build (88d2431d7) to master's ba6a4e6e3 build, and in the same change give unlimited-config-v30.xdr the 95 contract cost params core now requires at protocol 30. The 9 new ML-DSA entries (86-94) are core's v30 defaults from updateCpuCostParamsEntryForV30 / updateMemCostParamsEntryForV30; the other entries are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5dN6jqdJt52ve9XWyeggH
There was a problem hiding this comment.
🔵 Needs a closer look
The Protocol 30 SDK remains unreleased, P30 RPC tests are skipped, and the new write deadline can cut off transaction-submission responses.
3 open findings
What changed in this PR
This PR prepares Horizon to ingest and serve Protocol 30 data, including muxed contract destinations and millisecond close-time XDR.
Changes:
- Add Protocol 30 SDK support and muxed-contract effect handling.
- Extend ingestion fixtures and tests; fix asset filtering for fee-bump transactions.
- Update integration CI and add HTTP server timeouts.
| File | Description |
|---|---|
internal/resourceadapter/effects_test.go |
Tests muxed-contract effect rendering. |
internal/integration/testdata/unlimited-config-v30.xdr |
Adds Protocol 30 cost configuration. |
internal/ingest/testdata/test-lcms/InvokeHostFunctionTests/index.json |
Indexes new Core fixtures. |
internal/ingest/processors/operations_processor_test.go |
Tests muxed-contract operation parameters. |
internal/ingest/processors/effects_processor.go |
Records muxed-contract credit details. |
internal/ingest/processors/effects_processor_test.go |
Tests transfer and mint effects. |
internal/ingest/processor_runner_test.go |
Tests millisecond close-time ingestion. |
internal/ingest/main.go |
Raises the supported protocol to 30. |
internal/ingest/history_archive_adapter_test.go |
Corrects the mock bucket hash. |
internal/ingest/filters/asset.go |
Filters fee-bump inner operations. |
internal/ingest/filters/asset_test.go |
Tests fee-bump asset matching. |
internal/ingest/core_lcm_test.go |
Checks Core muxed-contract fixtures. |
internal/ingest/contractevents/events.go |
Clarifies muxed-ID event documentation. |
internal/ingest/contractevents/events_test.go |
Tests muxed-contract address parsing. |
internal/httpx/server.go |
Adds read, write, and idle timeouts. |
internal/httpx/server_timeouts_test.go |
Tests server timeout configuration. |
internal/db2/history/ledger_test.go |
Tests close-time storage and XDR. |
go.sum |
Updates SDK dependency checksums. |
go.mod |
Pins a temporary Protocol 30 SDK fork. |
CHANGELOG.md |
Documents Protocol 30 and the filter fix. |
.github/workflows/integration-tests.yml |
Allows runs without an RPC image. |
.github/workflows/horizon.yml |
Updates the P29 and P30 CI legs. |
🧠 Review effort: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| gopkg.in/yaml.v3 v3.0.1 // indirect | ||
| ) | ||
|
|
||
| replace github.com/stellar/go-stellar-sdk => github.com/sisuresh/go v0.0.0-20261008104555-663a89a12043 |
| core_deb_version: '29.0.1-3637.ba6a4e6e3.noble~buildtests' | ||
| core_docker_img: 'stellar/unsafe-stellar-core:29.0.1-3637.ba6a4e6e3.noble' | ||
| # No protocol-30 stellar-rpc image yet: NewTest() AMBER-skips RPC tests. | ||
| stellar_rpc_docker_img: '' |
| writeTimeout := defaultWriteTimeout | ||
| if connectionTimeout > 0 { | ||
| writeTimeout = connectionTimeout + writeTimeoutBuffer |
stellar/go-stellar-sdk#6015 merged into protocol-next as 990270d3, so drop the replace that pointed at the sisuresh/go fork (663a89a1) and require the upstream commit. This also picks up the fixes made in #6015 after 663a89a1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Build 3640 (0e49751aa) includes stellar/stellar-core#5423, so ledgers after the protocol 30 upgrade now use the millisecond close-time StellarValue arms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
30.0.0-3642.0e49751aa is built from the same commit as build 3640, so this changes the package under test, not the code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Reconcile the P30 CI image documentation and configure a valid Protocol 30 RPC image before merging.
5 open findings
Fix MarshalBinary call on non-addressable LedgerCloseMeta literal Replace unreleased Stellar SDK fork before merging to stable Reconcile P30 CI image pin with documented protocol coverage · New Prevent write timeout from expiring during transaction submission Pin P30 RPC image to enable integration tests and readiness checks
🧠 Review effort: Lite
| core_deb_version: '30.0.0-3642.0e49751aa.noble~buildtests' | ||
| core_docker_img: 'stellar/unsafe-stellar-core:30.0.0-3642.0e49751aa.noble' |
The P30 integration leg runs on the stellar-core 30.0.0 release candidate, so every ledger after the upgrade already exercises the CAP-0088 arms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Critical muxed-contract destination normalization issues remain in effects and balance-change processing.
6 open findings
Normalize muxed SAC destinations to underlying C address · New Decode muxed contract destinations before creating credited effects · New Replace unreleased Stellar SDK fork before merging to stable Reconcile P30 CI image pin with documented protocol coverage Prevent write timeout from expiring during transaction submission Pin P30 RPC image to enable integration tests and readiness checks
1 resolved since last review
🧠 Review effort: Lite
| require.Equal(t, want.changeType, change["type"]) | ||
| require.Equal(t, contract, change["to"]) | ||
| require.Equal(t, want.muxedID, change["destination_muxed_id"]) |
| var m strkey.MuxedContract | ||
| if err := m.SetContractID(contract); err != nil { | ||
| return err |


Adds Protocol 30 support.
MaxSupportedProtocolVersionto 30 and go-stellar-sdk to the Protocol 30 commit onprotocol-next(Protocol 30 (CAP-0084, CAP-0087, CAP-0088) go-stellar-sdk#6015).transferormintto a muxed contract (W...) gives thecontract_creditedeffectcontract_muxedandcontract_muxed_id, asaccount_muxedandaccount_muxed_iddo for muxed accounts. Tested with stellar-core#5472's transfer and mint LCMs.TestGetState_Read: the mock archive now serves a bucket whose hash matches its HAS, which the new SDK checks.unlimited-config-v30.xdrhas the 95 contract cost params core requires.Before release: move go-stellar-sdk to a release, and point the P29 and P30 legs at the released core and stellar-rpc images.
🤖 Generated with Claude Code