Repository navigation
Protocol 30 (CAP-0084, CAP-0087, CAP-0088) - #6015
Conversation
Adds the SC_ADDRESS_TYPE_MUXED_CONTRACT arm of SCAddress. Also picks up the widened contract spec name limits from upstream.
Adds the W... muxed contract strkey (vectors from rs-stellar-strkey@80085faa) and handles the new ScAddress arm in String() and Equals().
Match stellar-core stellar#5472's protocol-curr/xdr. Only CAP-0087 ifdef'd cost types differ from 01741cb6, and they stay disabled.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Muxed-contract transfers can be incorrectly recorded as holder balance deltas; the generated comment typo also remains.
Review effort: Lite
Findings: 1
Open (1)
What changed in this PR
Adds Protocol 30/CAP-0084 muxed contract (W...) support across XDR, strkey handling, and contract-event processing.
Changes:
- Regenerates XDR bindings with CAP-0084 enabled.
- Adds muxed-contract encoding, decoding, validation, formatting, and equality.
- Updates event processing, tests, generation settings, and changelog.
| File | Summary |
|---|---|
xdr/xdr_views_generated.go |
Adds generated muxed-contract views. |
xdr/xdr_generated.go |
Regenerates Protocol 30 XDR types and serialization; retains a “panicing” typo. |
xdr/xdr_commit_generated.txt |
Records the upstream XDR commit. |
xdr/Stellar-contract.x |
Defines muxed contract addresses. |
xdr/Stellar-contract-spec.x |
Updates contract-spec name limits. |
xdr/scval.go |
Supports muxed-contract formatting and equality. |
xdr/scval_test.go |
Tests muxed-contract formatting. |
support/contractevents/generate.go |
Accepts muxed-contract addresses in event fixtures. |
support/contractevents/event_test.go |
Tests muxed-contract event addresses. |
strkey/muxed_contract.go |
Implements muxed-contract strkey APIs. |
strkey/muxed_contract_test.go |
Tests muxed-contract vectors and validation. |
strkey/main.go |
Registers the muxed-contract version byte and validation. |
strkey/isvalid_length_test.go |
Tests muxed-contract payload lengths. |
strkey/encode_test.go |
Tests muxed-contract encoding. |
strkey/decode_test.go |
Tests muxed-contract decoding. |
strkey/decode_length_test.go |
Tests invalid muxed-contract lengths. |
processors/token_transfer/contract_events_test.go |
Adds muxed-contract transfer coverage; balance-delta filtering still requires correction. |
Makefile |
Pins Protocol 30 XDR generation settings. |
gxdr/xdr_generated.go |
Regenerates alternate XDR bindings. |
CHANGELOG.md |
Documents breaking changes and new APIs. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| createSymbol(TransferEvent), | ||
| createAddress(randomAccount), // from | ||
| createAddress(someMuxedContract1), // to |
Contract balances aren't derivable from contractData, so C... holders were already skipped; W... addresses are contracts too.
A CAP-0084 muxed contract destination is recorded on contract_credited the way account_muxed/account_muxed_id record a muxed account.
stellar-xdr main ungates CAP-0084, CAP-0087 and CAP-0088 (stellar#319, stellar#320, stellar#321), so XDR_FEATURES is now empty. This brings in the CAP-0088 millisecond close-time StellarValue arms, without which no ledger after the P30 upgrade decodes, and the CAP-0087 ML-DSA cost types. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 'bad checksum' W vector differed from a valid address only in the unused padding bit, so it was rejected as non-canonical before the CRC was checked. Keep it as a non-canonical case and add a vector with a real CRC mismatch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A SAC transfer to a muxed destination (CAP-0067 M, CAP-0084 W) carries
{amount, to_muxed_id} as its data. parseBalanceChangeEvent only accepted a
bare i128 and, because an earlier assignment had cleared err, returned a
zero amount with a nil error. Read the amount from the map form and return
ErrNotBalanceChangeEvent when there is no amount.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NodeID and Signature read only the SIGNED arm. Read the signature from the CAP-0088 millisecond arms (SIGNED_MS, EMPTY_TX_SET_MS), which every ledger after the Protocol 30 upgrade uses, and from the CAP-0083 EMPTY_TX_SET arm, which was previously missed so empty ledgers returned an error. Based on stellar#5998, rebased onto the stellar-xdr@4f524bba regeneration and renamed to the upstream TimePointMs type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| * protocols/rpc: Add queryEvents wire types and request validation (`QueryEventsRequest`/`QueryEventsResponse`, `QueryEventsFilter`, scan statuses, typed `error.data` payloads), transcribed from the [accepted proposal](https://github.com/orgs/stellar/discussions/1872) ([#5971](https://github.com/stellar/go-stellar-sdk/pull/5971)) | ||
|
|
||
| ### Bug Fixes | ||
| * support/contractevents: Read the amount from map event data (`{amount, to_muxed_id}`). A SAC transfer to a muxed destination (CAP-0067 `M...`, CAP-0084 `W...`) previously parsed as a transfer with `Amount` zero and no error. Event data with no amount now returns `ErrNotTransferEvent` instead of a zero-amount event. |
There was a problem hiding this comment.
thank you for this fix
| ## Pending | ||
|
|
||
| ### Breaking Changes | ||
| * xdr: Protocol 30 support (CAP-0084, CAP-0087, CAP-0088). Regenerated from stellar-xdr@4f524bba, where all three CAPs are ungated, so `XDR_FEATURES` is now empty. Contract spec UDT and event names are widened to `SC_SPEC_TYPE_NAME_LIMIT` (1024 bytes), and `ScSpecEventV0.Name` is now a `string` instead of an `ScSymbol`. |
There was a problem hiding this comment.
SC_SPEC_TYPE_NAME_LIMIT widening and ScSpecEventV0.Name ScSymbol to string change are attributed to the three CAPs. They come from stellar/stellar-xdr#312 ("Widen contract spec type and event name limits", 2026-09-09), a non-CAP change for the Rust SDK fully-qualified type names (stellar/stellar-protocol#2014).
Doc fix: split into its own bullet citing #312
There was a problem hiding this comment.
Done in f981faf. It is now its own Breaking Changes entry citing stellar/stellar-xdr#312, and says it is not part of any CAP.
| base.Asset | ||
| Contract string `json:"contract"` | ||
| Amount string `json:"amount"` | ||
| // Set when the destination was a muxed contract (CAP-0084). |
There was a problem hiding this comment.
this update to the endpoint also needs to be added to changelog
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| // Vectors generated with rs-stellar-strkey@80085faa. |
There was a problem hiding this comment.
There was a problem hiding this comment.
Added TestMuxedContractSEP23Vectors in f981faf with the 2 valid and 5 invalid W vectors from stellar/stellar-protocol#2020. All 7 pass against the current implementation, including the length 6 mod 8 and version byte low bits cases. The valid ones also re-encode to the same strkey.
| assert.Nil(t, event.Meta.GetToMuxedInfo()) | ||
| }, | ||
| }, { | ||
| name: "Transfer Event with muxed contract address in topics - Valid Sep-41 token", |
There was a problem hiding this comment.
this tests one case but not the other.
This case has the W.... address in the to topic and a bare i128 in data.
Only a custom SEP-41 token emits that shape. The SAC never does.
Per CAP-0084 Events, a SAC transfer to a W... address looks like this:
topics: ["transfer", from: G..., to: C... (plain, mux stripped), "USDC:GA..."]
data: { amount: 1000, to_muxed_id: 7 }
The processor already handles it (same path as M destinations) but no test pins it.
Can we add this case, plus a a test for mint as well?
{
name: "SAC transfer to muxed contract: plain C in topic, to_muxed_id in data",
setupEvent: func() xdr.ContractEvent {
topics := []xdr.ScVal{
createSymbol(TransferEvent),
createAddress(randomAccount), // from
createAddress(someContract1), // to: plain C, not W
createString(usdcAsset.StringCanonical()), // sep0011 asset
}
data := createScMap("amount", createInt128(thousand), "to_muxed_id", uint64(7))
return createContract(contractIdFromAsset(usdcAsset), topics, data)
},
validateEvent: func(t *testing.T, event *TokenTransferEvent) {
assert.Equal(t, someContract1, event.GetTransfer().To)
assert.EqualValues(t, 7, event.Meta.GetToMuxedInfo().GetId())
assert.NotNil(t, event.GetTransfer().Asset)
},
},There was a problem hiding this comment.
Added TestSacEventsToMuxedContractV4 in f981faf. It covers a SAC transfer and a SAC mint with the plain C... address in the topics and {amount, to_muxed_id: 7} as data, and checks To, Amount, the asset and ToMuxedInfo. The existing "V4 Transfer SAC Event - With Memo" case already had the transfer shape, but nothing tied it to CAP-0084, and mint was not covered.
| // StellarValue arm carries it: SIGNED, EMPTY_TX_SET (CAP-0083), or their | ||
| // millisecond close-time counterparts SIGNED_MS and EMPTY_TX_SET_MS (CAP-0088). | ||
| // Only BASIC has no signature. | ||
| func scpValueSignature(l xdr.LedgerCloseMeta) (xdr.LedgerCloseValueSignature, bool) { |
There was a problem hiding this comment.
Could scpValueSignature be exported?
stellar-etl has the exact bug this fixes: internal/transform/ledger.go:95 calls GetLcValueSignature() directly, so from the first P30 ledger its node_id and signature columns go empty.
If the SDK exports the 4-arm helper, etl and others call it instead of re-writing the switch.
cc @chowbao
There was a problem hiding this comment.
Exported it as a method on the XDR type in f981faf, so callers that only have a header can use it too: StellarValueExt.LedgerCloseValueSignature(). etl can replace ledgerHeader.ScpValue.Ext.GetLcValueSignature() with ledgerHeader.ScpValue.Ext.LedgerCloseValueSignature(). ledger.NodeID and ledger.Signature now use it as well, and since TransformLedger already receives the lcm, those would also work there.
- CHANGELOG: list the contract spec name widening as its own entry, citing stellar/stellar-xdr#312, and add the ContractCredited muxed contract fields - xdr: add StellarValueExt.LedgerCloseValueSignature, which reads the signature from every signed StellarValue arm, and use it in ingest/ledger - strkey: test the SEP-23 muxed contract vectors - processors/token_transfer: test SAC transfer and mint events to a muxed contract Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
The broad Protocol 30 and cross-component changes require final human review.
6 open findings
Avoid closing source before EOF hash validation Cancel active stream and wait for producer shutdown Extend signature accessor for Protocol 30 union arms Ingestion helpers fail to extract Protocol 30 signatures Reject muxed contract addresses from holder balance deltas Generated XDR commit and feature set mismatch
🧠 Review effort: Lite
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>
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>
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>
* Shift soroban-env window to P30 with CAP-0084 pins go-stellar-sdk replaced to sisuresh/go @ 50ebbb65; -prev now 28.0.1, -curr git-pinned to rs-soroban-env#1700 head with next; stellar-xdr git-pinned with cap_0084_muxed_contract. * methods: drop EventInfo.InSuccessfulContractCall Removed from protocols/rpc in the pinned go-stellar-sdk (#5995). * Repin CAP-0084 host window to merged upstream heads -prev now tracks core's protocol-29 stand-in (rs-soroban-env cb32250d, no crates.io release exists for it); -curr moves off the rs-soroban-env fork PR to its merged commit 169890d5 (protocol 30 by default, no `next` feature needed). stellar-xdr repinned to a9c9750e to match curr's own pin. go-stellar-sdk fork pin bumped to the PR #6015 head (still unmerged upstream). * ci: add P30 integration leg, copy P28 upgrade fixtures Drops the oldest P27 leg per the one-stanza-per-protocol convention. No -vnext core artifact exists yet for CAP-0084, so the P30 leg's core image is left unset. Upgrade fixtures copied from P28 unchanged since CAP-0084 doesn't touch ConfigSettings. * ci: test protocols 29 and 30 against merged stellar-core 73f2bdd1 The host window is now 29/30, so the P28 leg becomes P29 (with p29 upgrade fixtures copied from p28, as p30's were). Both legs use stellar-core 73f2bdd1's published artifacts. Host blocks declare their versions so check-dependencies.bash can find them. * ci: add apt.stellar.org unstable for unreleased core packages stellar-core 73f2bdd1's packages are only in the unstable component. * Repin go-stellar-sdk to the go-stellar-sdk#6015 head (663a89a1) #6015 is now the single P30 SDK PR: XDR regenerated from stellar-xdr 4f524bba with CAP-0084, CAP-0087 and CAP-0088, plus ingest/ledger NodeID/Signature handling for every signed StellarValue arm. 663a89a1 is 174b61f0 with go-stellar-sdk main (6c5e720f: #6006, #6014, #6017) merged in, so the replace does not drop fixes RPC would otherwise get from main. No compile breaks beyond the EventInfo.InSuccessfulContractCall removal already in this branch: RPC uses storage.ConnectOptions but none of the cache APIs #6017 removed. go mod tidy drops hashicorp/golang-lru, which only the removed on-disk cache needed. The replace stays allow-listed in .golangci.yml until #6015 merges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Repin the soroban host window to the real P29 host and P30 main - soroban-env-host/simulation-prev: cb32250d (core's p29 stand-in) -> rs-soroban-env v29.0.0 (a721944b), stellar-core's src/rust/soroban/p29 in v29.0.0 and master, pinned by git so it builds with the same dependency tree as core's p29 host. - soroban-env-host/simulation-curr: 169890d5 (CAP-0084 only) -> rs-soroban-env main 8abed902, with CAP-0084 and the CAP-0087 ML-DSA host functions ungated (#1737, #1744, #1745, #1746). This is the p30 host stellar-core #5478 pins; core master's p30 (fddfd567) predates ML-DSA. To be repinned to core's final p30 submodule once core #5455/#5478 merge. - stellar-xdr: a9c9750e -> 28f34cf5, curr's own pin (XDR from stellar-xdr 4f524bba, as in the Go SDK). CAP-0084, CAP-0087 and CAP-0088 are ungated there, so the cap_0084_muxed_contract feature goes away, and xdr2json can now decode CAP-0088 StellarValue arms (MS_CLOSE_TIME was a disabled feature at a9c9750e). The new ml-dsa dependency tree resolves to the versions in core's p30 dep-tree, except hybrid-array 0.4.10 (core: 0.4.15; 0.4.11+ needs typenum 1.20 and the lockfile has 1.18) and ctutils 0.4.3 (core: 0.4.2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5dN6jqdJt52ve9XWyeggH * methods: test serving CAP-0088 millisecond close time ledgers Ingests a protocol 30 ledger whose StellarValue uses STELLAR_VALUE_SIGNED_MS (and, separately, STELLAR_VALUE_EMPTY_TX_SET_MS) through the writers the ingestion service uses (ledger, transactions, events, fee windows, commit) and checks what getLatestLedger, getLedgers (XDR and JSON), getTransaction, getEvents and getFeeStats serve: every close time is the whole-second closeTime (closeTimeMs / 1000), the XDR is byte-identical, and xdr2json keeps the arm and closeTimeMs. RPC never reads StellarValue.ext, lcValueSignature or the node ID, so the only real requirement is that both XDR stacks decode the new arms. The JSON check fails on the previous rs-stellar-xdr pin (a9c9750e, MS_CLOSE_TIME gated off): getLedgers returns "xdr_to_json() failed: couldn't read LedgerCloseMeta: xdr value invalid". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: run P29 on stellar-core 29.0.0 and P30 on core master's vnext build - P29: stellar-core 29.0.0 (4eb833373), as on protocol-next. Its p29 host is rs-soroban-env v29.0.0 (a721944b), which soroban-env-host-prev now pins, instead of master 73f2bdd1 with the cb32250d stand-in. - P30: vnext build of master 88d2431d7 (merge of v29.0.0 into master), whose p30 host is fddfd567: CAP-0084 plus the v29.0.0 fixes. It differs from soroban-env-host-curr (8abed902) only by the ML-DSA commits. No core build with CAP-0087 (#5455/#5478) or CAP-0088 (#5423) is published yet. Its deb is only in the apt.stellar.org unstable component, which integration-tests.yml already adds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * integrationtest: drop the P28 upgrade fixtures No CI leg runs protocol 28 any more (P29 and P30 only), and the harness picks <name>.p<protocol>.xdr for the protocol under test. Following the docker/README convention of moving the oldest fixtures to the new protocol, this leaves p29 and p30, which are identical to the old p28 ones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * scripts: fix check-dependencies for the P29/P30 window and SDK replaces The dependency sanity check failed on this branch for two reasons that were not real mismatches: - It looked up `stellar-xdr@<protocol>`, assuming the crate's major version tracks the protocol. The protocol 29 and 30 hosts both use stellar-xdr 28.0.0 (crates.io for prev, git 28f34cf5 for curr), so there was no match and the Rust XDR revision came out empty. Each host's stellar-xdr now comes from that host's own dependency tree, and the comparison with core's dep-trees/p<N>-expect.txt uses the host for the same protocol rather than always the newest. - It derived the Go SDK commit from the required go-stellar-sdk version and fetched it from stellar/go-stellar-sdk, ignoring the replace directive. It now reads xdr/xdr_commit_generated.txt from the module the build actually uses (go list -m -f {{.Dir}}), which also handles tags. On this branch the check now passes: Go (#6015) and the curr host's rs-stellar-xdr both use stellar-xdr 4f524bba. It still reports, without failing, that core master's p30 uses rs-stellar-xdr a9c9750e. The updated script also passes against protocol-next's configuration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add Protocol 30 CHANGELOG entries Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: run the P30 leg on stellar-core master after protocol 30 landed stellar/stellar-core#5478 made protocol 30 the current protocol on master, with CAP-0084 and CAP-0087, and its p30 host is rs-soroban-env 8abed902, the same as soroban-env-host-curr. Move the P30 leg from the pre-#5478 vnext build (88d2431d7) to master's ba6a4e6e3 build. In the same change, give testnet.p30 and unlimited.p30 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; every other entry is unchanged. The .xdr files are re-encoded from the .json with stellar-xdr encode --type ConfigUpgradeSet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5dN6jqdJt52ve9XWyeggH * Require the merged go-stellar-sdk Protocol 30 commit 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> * Run the P30 leg on core 3640, which includes CAP-0088 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> * Run the P30 leg on the stellar-core 30.0.0 release candidate 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> * Correct how core's p30 host differs from -curr Core's p30 host also takes stellar-xdr 30.0.0 from crates.io, not only soroban-wasmi. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Trim comments and the CHANGELOG, drop the CAP-0088 unit test The P30 integration leg runs on the stellar-core 30.0.0 release candidate, so its ledgers use the CAP-0088 arms, and the integration tests already fetch them with getLedgers and getTransaction in JSON. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: tamirms <tamirms@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…, CAP-0088) (#98) * Pin go-stellar-sdk to the Protocol 30 SDK Replace go-stellar-sdk with the head of stellar/go-stellar-sdk#6015 (sisuresh/go p30-cap-0084-validate @ 174b61f0), the same pin Horizon and RPC use. It regenerates XDR from stellar-xdr 4f524bba with CAP-0084, CAP-0087 and CAP-0088. Galexie needs it to export Protocol 30 ledgers: every ledger closed after the upgrade carries one of CAP-0088's new StellarValue arms (STELLAR_VALUE_SIGNED_MS, STELLAR_VALUE_EMPTY_TX_SET_MS), which v0.7.2 cannot decode, so captive core's LedgerCloseMeta stream would fail at the first post-upgrade ledger. No Galexie code changes are needed against the 31 SDK commits since v0.7.2. go mod tidy only raises the aws-sdk-go-v2 group to the versions the SDK now requires. go-xdr is unchanged. Drop the replace and require the merged upstream commit or SDK release once #6015 lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test exporting CAP-0088 millisecond close-time ledgers Galexie passes LedgerCloseMeta through and reads only the ledger sequence, protocol version and whole-second close time, which fill the uploaded object's metadata. CAP-0088 keeps closeTime in whole seconds (closeTime == closeTimeMs / 1000), so the start-ledger-close-time and end-ledger-close-time metadata are unchanged in Protocol 30. Cover both new StellarValue arms (SIGNED_MS, EMPTY_TX_SET_MS): the metadata still reports seconds, and the batch survives the compressxdr encoding the uploader applies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: note the core pins to bump for Protocol 30 The integration tests can't run a Protocol 30 network yet: no stellar-core 30.x deb is in apt.stellar.org (noble unstable, testing or stable), and no quickstart image bundles a protocol 30 core. The workflow has no protocol matrix to hang a skipped leg on, so CI stays on core 29.0.0 against quickstart's protocol 28 network, which the P30 SDK still decodes. Record, next to the pins, what to change once core publishes P30 builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add CHANGELOG entry for the Protocol 30 SDK Start the v30.0.0 section, as the Protocol 28 work did on protocol-next. The stellar-core 30.0.0 bump gets its own line once core publishes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Repin go-stellar-sdk to the P30 SDK head with main's fixes go-stellar-sdk#6015 now includes the SDK's main (#6014 datastore listing fix, #6017 bucket download resume). A replace overrides require, so pinning the earlier head would have dropped them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Update test fixtures for the go-stellar-sdk datastore listing fix The SDK now guards against non-advancing listings (go-stellar-sdk#6014), so the fake datastores in these tests must list in real sort order. Same changes as #97, which brings that fix to main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Link the Protocol 30 PR in the CHANGELOG Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5dN6jqdJt52ve9XWyeggH * Require the merged go-stellar-sdk Protocol 30 commit 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> * Run the integration tests on a protocol 30 network Use the stellar-core 30.0.0 release candidate (30.0.0-3642.0e49751aa) for captive core and for the published image, and the nightly quickstart (core master at 66defff52) upgraded to protocol 30. Every ledger after the upgrade uses the CAP-0088 millisecond close-time StellarValue arm, so the tests now export and read protocol 30 ledgers. The test reads the protocol version from GALEXIE_INTEGRATION_TESTS_QUICKSTART_PROTOCOL_VERSION. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Drop the CAP-0088 archive unit test The integration tests now run on a protocol 30 network, so every ledger after the upgrade uses a CAP-0088 arm end to end, and go-stellar-sdk tests the new arms itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Trim comments and the CHANGELOG entry Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>


Changes
4f524bba(main). CAP-0084, CAP-0087 and CAP-0088 are all ungated there (Rename TimePointMilliseconds to TimePointMs stellar-xdr#319, Cant build horizon using stellar's go repo #320, Can't get friendbot to work on testnet (local) #321), soXDR_FEATURESis now empty. This adds:SC_ADDRESS_TYPE_MUXED_CONTRACT/MuxedContract.ContractCostTypevalues 86–94. These are names only: cost params are positional, so P30 config settings already decoded without them.StellarValuearms (STELLAR_VALUE_SIGNED_MS,STELLAR_VALUE_EMPTY_TX_SET_MS) andTimePointMs. Every ledger after the P30 upgrade uses one of these arms, so without them none of those ledgers decode.W…muxed contract (VersionByteMuxedContract = 22 << 3,MuxedContract,DecodeMuxedContract,IsValidMuxedContractAddress). The tests now include a real checksum-mismatch vector; the previous "bad checksum" vector differed only in the unused padding bit and is kept as a non-canonical case.ScAddress.String()/EqualsforSC_ADDRESS_TYPE_MUXED_CONTRACT.contract_muxed/contract_muxed_idtoContractCredited.{amount, to_muxed_id}event data. A SAC transfer to a muxed destination (M…since CAP-0067, now alsoW…) previously parsed as a transfer withAmount0 and no error.NodeIDandSignatureread the close-value signature from every signedStellarValuearm. That covers the CAP-0088 millisecond arms (STELLAR_VALUE_SIGNED_MS,STELLAR_VALUE_EMPTY_TX_SET_MS), which every ledger after the upgrade uses, andSTELLAR_VALUE_EMPTY_TX_SET(CAP-0083), which was previously missed, so empty ledgers returned an error and no signature. Whole-secondCloseTimeis unchanged.This is the single Protocol 30 PR. It supersedes #6003 (CAP-0087) and #5998 (CAP-0088), whose changes are included here, with #5998's
ingest/ledgerchange renamed to the upstreamTimePointMstype.Upstream
src/protocol-curr/xdrsince Bump to protocol 30 and ungate CAP-0084 and CAP-0087 stellar-core#5478, which made protocol 30 current with CAP-0084 and CAP-0087.Downstream
stellar/stellar-horizon#237, stellar/stellar-rpc#1050 and stellar/stellar-galexie#98 build against this branch through a
replace. Once this merges, they switch to the mergedprotocol-nextcommit.Testing
go build ./..., plusgo testforstrkey,support/contractevents,ingest/ledgerandsupport/datastore.🤖 Generated with Claude Code
https://claude.ai/code/session_01J5dN6jqdJt52ve9XWyeggH