Skip to content

perf(strkey): reject by length and prefix before decodeCheck throws - #1629

Merged
Ryang-21 merged 1 commit into
v17-feature-branchfrom
perf/v17-regressions
Aug 10, 2026
Merged

perf(strkey): reject by length and prefix before decodeCheck throws#1629
Ryang-21 merged 1 commit into
v17-feature-branchfrom
perf/v17-regressions

Conversation

@Ryang-21

Copy link
Copy Markdown
Contributor

What

StrKey.isValid now screens the encoded length and the prefix before calling decodeCheck. Both checks live in a shared hasValidStrkeyFormat helper that returns a boolean; decodeCheck turns a false into its existing throw via strkeyFormatError, so error messages are unchanged.

Adds a cross-type test matrix asserting every isValid* predicate accepts its own strkey type and rejects the other eight.

Why

decodeCheck signals every rejection by throwing, and isValid called it unconditionally inside a try. The negative answer is the common case: decodeAddressToMuxedAccount asks isValidMed25519PublicKey about every destination address, so an ordinary G address constructed an Error with a stack trace and discarded it, twice per transaction build.

Measured against 16.2.0 on Node 24.7:

16.2.0 v17 before after
TransactionBuilder.build() 158k ops/s 85k ops/s 271k ops/s
isValidMed25519PublicKey(G…) 234,243k ops/s 309k ops/s 147,811k ops/s

build() was a ~46% regression against v16 and is now ahead of it.

The docs change is regenerated line numbers from the source edit.

@github-project-automation github-project-automation Bot moved this to Backlog (Not Ready) in DevX Aug 10, 2026
@Ryang-21
Ryang-21 requested a balanced review from Copilot August 10, 2026 22:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Optimizes StrKey validation by rejecting incompatible lengths and prefixes before decoding, avoiding exception overhead.

Changes:

  • Adds fast format and prefix checks.
  • Adds cross-type validation tests.
  • Regenerates API reference source links.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/base/strkey.ts Implements fast rejection while preserving decoding errors.
test/unit/base/strkey.test.ts Adds cross-type validation coverage.
docs/reference/core-keys.md Updates generated source line references.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@Ryang-21
Ryang-21 requested a review from quietbits August 10, 2026 22:19
@Ryang-21
Ryang-21 merged commit f4a91b2 into v17-feature-branch Aug 10, 2026
14 checks passed
@Ryang-21
Ryang-21 deleted the perf/v17-regressions branch August 10, 2026 22:56
@github-project-automation github-project-automation Bot moved this from Backlog (Not Ready) to Done in DevX Aug 10, 2026
Ryang-21 added a commit that referenced this pull request Aug 10, 2026
* Class XDR Implementation (#1422)

* feat(xdr): codegen tool + schema source

* feat(xdr): add class-based XDR runtime and sep51 JSON walker

* refactor(numbers): drop LargeInt classes, delegate to new XDR layer

* refactor(base): migrate src/base to new XDR layer; drop legacy xdr.ts + generated

* refactor: migrate downstream consumers (bindings/contract/horizon/rpc/webauth)

* feat(base/scval): add bool to ScValType

* allow opaque xdr types to be initalized via string

* refactor xdr strings to be represented soley via bytes with a dx friendly XdrString wrapper class

* generate a value getter function for void union cases

* add a is() function to the generated XDR union classes for instanceOf checks

* feat(xdr): regenerate schemas against @stellar/js-xdr and add CAP-71 credentials

* feat(xdr): wire the toJSON hook so JSON.stringify emits SEP-0051

* fix(bindings): emit Uint8Array for bytes/bytesN to match scValToNative

* refactor(contract): rename fromJSON to fromJson with deprecated aliases

* feat(xdr): accept ASCII asset codes with zero padding in constructors

* Migrate public API from Buffer to Uint8Array (#1564)

* feat(base): migrate crypto and strkey APIs to Uint8Array

* feat(base)!: migrate value types to Uint8Array

* feat(base)!: migrate transactions, operations, and auth to Uint8Array

* feat!: migrate contract, rpc, and webauth layers to Uint8Array

* build!: drop buffer polyfill and dependency

* fix(horizon): type manage_data value as string to match runtime API

* fix(xdr): emit SEP-51 key `type` instead of Rust-escaped `type_` (#1571)

* build(xdr): regenerate xdr.json via docker from pinned stellar-xdr commit (#1575)

* build(xdr): regenerate schema from stellar-xdr with CAP-83 and CAP-85 ungated (#1576)

* build(xdr): regenerate schema from stellar-xdr with CAP-83 and CAP-85 ungated

* fix(xdr): keep consumers compiling against the regenerated union arms

* fix(vitest): isolate browser dep cache per transport

* feat(xdr): support CAP-83 empty tx set values and CAP-85 external executables (#1577)

* build(xdr): fail the schema download instead of masking it in a pipe

* feat(xdr): support CAP-83 and CAP-85 protocol values

* fix(xdr): bound decimal string length before BigInt parse in JSON decode (#1581)

* fix(xdr): bound decimal string length before BigInt parse in json decode

* refactor(xdr): name the digit-budget constants in bigint-parts

* fix(xdr): restrict fromJson to SEP-0051 keys and reject unknown fields (#1582)

* fix(xdr): restrict fromJson to SEP-51 keys and reject unknown fields

* fix(test): correct horizon corpus fixture path so corpus tests run

* fix(strkey): bound decodeCheck input length before base32 decode (#1583)

* fix(xdr): reject AssetCode12 JSON codes shorter than 5 bytes (#1585)

* fix(horizon)!: make TransactionFailedExtras result_codes.operations optional (#1586)

* Fix: signed payload strkey framing (#1588)

* fix(strkey): validate signed payload framing in decodeCheck

* Fix: xdr json decode validation (#1592)

* fix(xdr): throw on unknown union discriminant in fromXdrObject

* fix(strkey): validate the claimable balance discriminant byte

* fix(xdr): reject non-decimal integer strings in JSON decoding

* V17.0.0 rc.1 (#1593)

* chore(release): cut v17.0.0-rc.1

* fix(spec): restore instanceof Map check lost in the v17 merge

* feat(xdr): add validateXdr static to every generated type (#1597)

* feat(xdr): add validateXdr static to every generated type

* fix(contract): declare error classes, make types self-contained (#1627)

* perf(strkey): reject by length and prefix before decodeCheck throws (#1629)

* fix: restore wide-int bounds statics, document Memo.text break (#1628)

* fix(xdr): restore wide-int MIN_VALUE/MAX_VALUE statics

---------

Co-authored-by: Iveta <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants