feat(sdk-core): consume slug_name's canonical string carrier - #83
Conversation
A pre-builtin depot emits a slug_name as an object — the reflected struct is object-only — and the depot still accepts that shape inbound. A string-only reader cannot straddle the landing window, so #83 could not merge before the node change; with this it can. slugValue is now the one decoder for every carrier (string, number, bigint, or the { value } object) and both per-contract readers delegate to it instead of duplicating the body. Matches wire-tools' slugUtils, which already takes all three. Delete SlugNameObject once no depot emits the object form. Change-Id: Icfbe2e544e4416194ab12e2434e90cb795189c7a
jglanz
left a comment
There was a problem hiding this comment.
Be sure to rebase before trying to merge.
Nit: Number("123") is dangerous, parseInt("123",10) is the correct approach
A slug field now arrives and leaves as its canonical spelling, matching
the depot's ABI builtin (wire-sysio#619). The two row unwrappers and the
two {value} writers are gone, and chainSlugValue/reserveSlugValue no
longer read a digit-only string as a decimal — "12345678" is a valid slug
whose packed value is nothing like it, so that branch silently mis-decoded.
ChainsSlugName and ReservSlugName stop being Struct subclasses and become
ABISerializableObject types modelled on Name. A Struct cannot express this:
the object decoder dispatches on type.fields before consulting a class's
own from(), so a struct-shaped slug can only ever be written {value}. Wire
bytes are unchanged — a struct of one uint64 packs as that uint64.
Regenerates SysioContractTypes against the generator's new slug_name
builtin mapping; the diff is slug-only.
Change-Id: Id1e57c61100d20daa53d6275ed39c886a02e04d8
A code must start with a letter, so SlugName.from refuses a digit- or underscore-leading spelling rather than packing one the depot will reject — the failure surfaces at the parse with its reason instead of at pushAction as an opaque ABI error. toString stays total: it is a reader, and a throwing renderer in a scan loop is what stalls a consumer. Change-Id: Ibfcfee56719a9800f1ab7e41719f1dd527062576
A pre-builtin depot emits a slug_name as an object — the reflected struct is object-only — and the depot still accepts that shape inbound. A string-only reader cannot straddle the landing window, so #83 could not merge before the node change; with this it can. slugValue is now the one decoder for every carrier (string, number, bigint, or the { value } object) and both per-contract readers delegate to it instead of duplicating the body. Matches wire-tools' slugUtils, which already takes all three. Delete SlugNameObject once no depot emits the object form. Change-Id: Icfbe2e544e4416194ab12e2434e90cb795189c7a
…ster Generated from the wire-sysio#619 ABIs, which carry master's sysio.liq and sysio.swap contracts; slug_name fields are the builtin string carrier. Change-Id: Ia77e57d060a151de76b36d5bbfc4f74a8cd7d50b
Number() coerces "", " 12 ", "0x10" and "1e3", and parseInt stops at the
first non-digit, so neither rejects a malformed { value } carrier. Parse through
UInt64.from, which accepts only a base-10 integer or a safe integer, and convert
the slug structs with toNumber(), which throws past 53 bits instead of rounding.
Change-Id: Iff04918124c7dce134becefa1cc9e1a53ebf9e1e
041a4e9 to
7420cd2
Compare
|
@jglanz Rebased onto master: the only conflict was the generated On the |
Landing 5 of the
slug_namecarrier unification. Merge after wire-sysio#619 — the string carrier only exists once the depot's ABI builtin renders it.What changes
A slug field arrives from a table read, and leaves in an action, as its canonical spelling. Both row unwrappers (
rowSlugValue,reserveRowSlugValue) and both{value}writers (chainSlugData,reserveSlugData) are deleted — with the string carrier they were identity or wrong, and their call sites now usechainSlugValue/reserveSlugValueandchainSlugString/reserveSlugStringdirectly.A silent mis-decode removed
chainSlugValueandreserveRowSlugValueeach had a numeric-string branch reading a digit-only string as a decimal. But the slug alphabet contains digits, so"12345678"is a legitimate code whose packed value is nothing like 12345678 — the branch mis-decoded exactly the codes that look like numbers. The packed form is passed as anumber; a string is always parsed as a slug. This is the same ambiguity #619 closes host-side, and it is why the carrier could never have been a numeric string.*SlugNamestop beingStructsubclassesChainsSlugNameandReservSlugNameare nowABISerializableObjecttypes modelled onName. AStructcannot express this type: the object decoder dispatches ontype.fieldsbefore consulting a class's ownfrom()(Decoder.ts:364-366), so a struct-shaped slug can only ever be written{value}— overridingstatic fromto accept the string fails there, which is how this was found.Wire bytes are unchanged: a struct of one
uint64packs as thatuint64, so the new type emits identical bytes. The synchronous codec path and theAnyActionABI fallback now both take the same spelling.They stay per contract. One shared
chain/SlugName.tsbesideNamewould be the right home, but that name collides with the publishedSlugNamepacking utility whosefrom()returns anumber, and renaming that breaks av1.0.90surface. The duplication predates this — both already existed as@Struct.type("slug_name")structs, andStructs.tsis organised per contract.Scope note
The plan listed this landing as "regenerate
SysioContractTypes.tsonce". That was under-specified: the regen alone leaves the four reader/writer helpers anduwrit/Client.ts'sReserveIdentitySlugstyped against the old object shape. All are converted here;ReserveIdentitySlugsnow derives its three fields by indexed access off the generateduwreqsrow so a future codegen change propagates.The regenerated
SysioContractTypes.tscomes from #619's newslug_namebuiltin mapping ingenerate-sysio-contract-types.py(the generator had no entry at all, and every slug field would have becomeunknownonce abigen stops emitting the struct_def). Its diff is slug-only. A further regen follows landing 4's field conversions.Verification
pnpm buildclean,pnpm lintclean, 556/556 jest across 53 suites.New coverage: the digit-only-code case (
"12345678"parses as a slug, not its decimal, and a packed value passed as a string is rejected), and both forms of the new type asserted together — the packed wire value and the canonical spelling itstoJSONreturns.pnpm-lock.yamlis deliberately not in this commit; the local delta is worktree sibling-link churn.