Skip to content

Accept Rust-style _ digit separators in numeric contract arguments - #2692

Open
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:feat/2447-number-separators
Open

Accept Rust-style _ digit separators in numeric contract arguments#2692
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:feat/2447-number-separators

Conversation

@Galmanus

Copy link
Copy Markdown

Closes #2447

What

stellar contract invoke -- fn --amount 100_0000000 now parses, instead of failing with Expected type i128 (signed 128-bit integer), but received: '100_0000000'.

How

Spec::from_string strips underscores before parsing when both hold:

  • the target type is numeric: u32/i32/u64/i64/u128/i128/u256/i256/timepoint/duration
  • every underscore sits strictly between two digits (Rust-literal style)

Everything else is passed through untouched:

  • malformed separators (_1000, 1000_, 1__000) still fail with the existing error
  • non-numeric types keep their underscores — hello_world as a Symbol, "1_000" as a String, byte payloads

Option<numeric> works via the existing recursion into the inner type.

Testing

  • New unit tests: separator acceptance across i128/u32/i64/u256 and Option<u32>, rejection of malformed forms, and non-numeric passthrough
  • cargo test -p soroban-spec-tools: 104 passed
  • cargo clippy -p soroban-spec-tools --all-targets: clean

Large numeric arguments like 1000000000 are hard to read and easy to
get wrong, which matters constantly on Stellar where amounts carry a
1e7 offset. Passing 100_0000000 previously failed with:

  Expected type i128 (signed 128-bit integer), but received: '100_0000000'

Spec::from_string now strips underscores before parsing when the target
type is numeric (u32/i32/u64/i64/u128/i128/u256/i256/timepoint/duration)
and every underscore sits between two digits. Malformed forms (_1000,
1000_, 1__000) and non-numeric types (symbols, strings, bytes) are left
untouched, so existing behavior is unchanged there.

Closes stellar#2447
Copilot AI balanced review requested due to automatic review settings August 22, 2026 00:43
@github-project-automation github-project-automation Bot moved this to Backlog (Not Ready) in DevX Aug 22, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds underscore separators to numeric contract arguments.

Changes:

  • Validates and strips separators for numeric types.
  • Adds acceptance, rejection, option, and passthrough tests.

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

Comment on lines +835 to +844
let well_formed = bytes.iter().enumerate().all(|(i, &b)| match b {
b'0'..=b'9' => true,
b'+' | b'-' => i == 0,
b'_' => {
i > 0
&& bytes[i - 1].is_ascii_digit()
&& bytes.get(i + 1).is_some_and(u8::is_ascii_digit)
}
_ => false,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Allow number separator for argument parsing

2 participants