Skip to content

Commit ca219ec

Browse files
committed
Re-pin XDR to stellar-xdr#307 head and split curr/next feature gates
The Makefile pinned 68fa1ac5, which predates the CAP-0084 XDR commit, and left XDR_FEATURES undefined, so `make generate` could not reproduce the committed generated codec. Pin XDR_BASE_URL_{CURR,NEXT} to stellar-xdr@787382ef (CAP-0084 muxed-contract arm) and split into XDR_FEATURES_CURR=CAP_0083 / XDR_FEATURES_NEXT=CAP_0083,CAP_0084_MUXED_CONTRACT so curr excludes and next includes the muxed-contract arm, mirroring stellar/js-stellar-base#981. Drop `docker run -it` for non-TTY/CI regen and wire the xdrgen#152 const-inlining post-process (scripts/post-process-generated.py) for curr and next. Regen deferred: Docker is unavailable in this environment, so `make generate` was not re-run. The Makefile is now reproducible against 787382ef and the const post-process is wired but not yet executed; the committed src/base/generated/* (correct CAP-0084 arm content, CI green) are unchanged.
1 parent b9c5748 commit ca219ec

2 files changed

Lines changed: 71 additions & 8 deletions

File tree

Makefile

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
XDR_BASE_URL_CURR=https://github.com/stellar/stellar-xdr/raw/68fa1ac55692f68ad2a2ca549d0a283273554439
1+
# CAP-83 + CAP-84 pre-release: pin to the protocol-28 .x and resolve
2+
# feature gates via `stellar-xdr xfile preprocess` (rs-stellar-xdr #503) before
3+
# xdrgen, since the Ruby xdrgen used here does not understand #ifdef.
4+
# CAP_0084_MUXED_CONTRACT is gated to the `next` channel only: the muxed
5+
# contract address arm is not enabled on `curr` until protocol 28 ships.
6+
XDR_BASE_URL_CURR=https://github.com/stellar/stellar-xdr/raw/787382ef2099cca168ca1cb282730d6b7b9e2f16
27
XDR_BASE_LOCAL_CURR=xdr/curr
8+
XDR_FEATURES_CURR=CAP_0083
9+
XDR_FEATURES_NEXT=CAP_0083,CAP_0084_MUXED_CONTRACT
310
XDR_FILES_CURR= \
411
Stellar-SCP.x \
512
Stellar-ledger-entries.x \
@@ -15,7 +22,7 @@ XDR_FILES_CURR= \
1522
Stellar-exporter.x
1623
XDR_FILES_LOCAL_CURR=$(addprefix xdr/curr/,$(XDR_FILES_CURR))
1724

18-
XDR_BASE_URL_NEXT=https://github.com/stellar/stellar-xdr/raw/68fa1ac55692f68ad2a2ca549d0a283273554439
25+
XDR_BASE_URL_NEXT=https://github.com/stellar/stellar-xdr/raw/787382ef2099cca168ca1cb282730d6b7b9e2f16
1926
XDR_BASE_LOCAL_NEXT=xdr/next
2027
XDR_FILES_NEXT= \
2128
Stellar-SCP.x \
@@ -43,23 +50,25 @@ generate: src/base/generated/curr_generated.js src/base/generated/curr.d.ts src/
4350
src/base/generated/curr_generated.js: $(XDR_FILES_LOCAL_CURR)
4451
mkdir -p $(dir $@)
4552
> $@
46-
docker run -it --rm -v $$PWD:/wd -w /wd ruby:3.1 /bin/bash -c '\
53+
docker run --rm -v $$PWD:/wd -w /wd ruby:3.1 /bin/bash -c '\
4754
gem install specific_install -v 0.3.8 && \
4855
gem specific_install https://github.com/stellar/xdrgen.git -b $(XDRGEN_COMMIT) && \
4956
xdrgen --language javascript --namespace curr --output src/base/generated $^ \
5057
'
58+
python3 scripts/post-process-generated.py $@
5159

5260
src/base/generated/next_generated.js: $(XDR_FILES_LOCAL_NEXT)
5361
mkdir -p $(dir $@)
5462
> $@
55-
docker run -it --rm -v $$PWD:/wd -w /wd ruby:3.1 /bin/bash -c '\
63+
docker run --rm -v $$PWD:/wd -w /wd ruby:3.1 /bin/bash -c '\
5664
gem install specific_install -v 0.3.8 && \
5765
gem specific_install https://github.com/stellar/xdrgen.git -b $(XDRGEN_COMMIT) && \
5866
xdrgen --language javascript --namespace next --output src/base/generated $^ \
5967
'
68+
python3 scripts/post-process-generated.py $@
6069

6170
src/base/generated/curr.d.ts: src/base/generated/curr_generated.js
62-
docker run -it --rm -v $$PWD:/wd -w / --entrypoint /bin/sh node:22-alpine -c '\
71+
docker run --rm -v $$PWD:/wd -w / --entrypoint /bin/sh node:22-alpine -c '\
6372
apk add --update git && \
6473
corepack enable && \
6574
corepack prepare pnpm@$(PNPM_VERSION) --activate && \
@@ -73,7 +82,7 @@ src/base/generated/curr.d.ts: src/base/generated/curr_generated.js
7382
'
7483

7584
src/base/generated/next.d.ts: src/base/generated/next_generated.js
76-
docker run -it --rm -v $$PWD:/wd -w / --entrypoint /bin/sh node:22-alpine -c '\
85+
docker run --rm -v $$PWD:/wd -w / --entrypoint /bin/sh node:22-alpine -c '\
7786
apk add --update git && \
7887
corepack enable && \
7988
corepack prepare pnpm@$(PNPM_VERSION) --activate && \
@@ -92,12 +101,12 @@ clean:
92101
$(XDR_FILES_LOCAL_CURR):
93102
mkdir -p $(dir $@)
94103
curl -L -o $@ $(XDR_BASE_URL_CURR)/$(notdir $@)
95-
stellar-xdr xfile preprocess --features "$(XDR_FEATURES)" $@ > $@.pp && mv -f $@.pp $@
104+
stellar-xdr xfile preprocess --features "$(XDR_FEATURES_CURR)" $@ > $@.pp && mv -f $@.pp $@
96105

97106
$(XDR_FILES_LOCAL_NEXT):
98107
mkdir -p $(dir $@)
99108
curl -L -o $@ $(XDR_BASE_URL_NEXT)/$(notdir $@)
100-
stellar-xdr xfile preprocess --features "$(XDR_FEATURES)" $@ > $@.pp && mv -f $@.pp $@
109+
stellar-xdr xfile preprocess --features "$(XDR_FEATURES_NEXT)" $@ > $@.pp && mv -f $@.pp $@
101110
reset-xdr:
102111
rm -f xdr/*/*.x
103112
rm -f src/base/generated/*.js

scripts/post-process-generated.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
"""Post-process xdrgen JS output to inline xdr.const values at usage sites.
3+
4+
xdrgen master emits `xdr.const("NAME", N);` to register a constant in the
5+
xdr namespace, then uses the bare identifier later (`xdr.string(NAME)`).
6+
But `@stellar/js-xdr`'s TypeBuilder.const() does not put NAME into JS scope,
7+
so the bare identifier ReferenceErrors at runtime.
8+
9+
Injecting `var NAME = N;` at the IIFE top fixes runtime but gets DCE'd by
10+
terser in the production browser dist. The robust fix is to inline the
11+
literal at each usage site so there's no identifier for terser to drop.
12+
13+
The `xdr.const("NAME", N);` declaration itself is left untouched: the NAME
14+
there is a string literal (preceded by a quote), so the negative lookbehind
15+
below skips it. Constants only referenced via `xdr.lookup("NAME")` string
16+
lookups are likewise untouched.
17+
"""
18+
import re
19+
import pathlib
20+
import sys
21+
22+
23+
def inline_consts(path: pathlib.Path) -> int:
24+
s = path.read_text()
25+
consts = dict(re.findall(
26+
r'xdr\.const\("([A-Z][A-Z0-9_]+)",\s*(0x[0-9a-fA-F]+|\d+)\);', s
27+
))
28+
n_replaced = 0
29+
for name, value in consts.items():
30+
# Replace bare identifier (not preceded by quote or word char,
31+
# not followed by quote or word char). This skips string literals
32+
# like "NAME" and xdr.lookup("NAME"), so the xdr.const(...)
33+
# declaration's string name is preserved.
34+
new_s, count = re.subn(
35+
rf'(?<![\w"\'$]){re.escape(name)}(?![\w"\'$])',
36+
value,
37+
s,
38+
)
39+
if count > 0:
40+
s = new_s
41+
n_replaced += count
42+
path.write_text(s)
43+
return n_replaced
44+
45+
46+
if __name__ == "__main__":
47+
files = sys.argv[1:] or [
48+
"src/base/generated/curr_generated.js",
49+
"src/base/generated/next_generated.js",
50+
]
51+
for f in files:
52+
p = pathlib.Path(f)
53+
n = inline_consts(p)
54+
print(f"{f}: inlined {n} bare-identifier const reference(s)")

0 commit comments

Comments
 (0)