An amount above 2^53 is not the amount that was given - #5
Open
tempoloss wants to merge 1 commit into
Open
Conversation
ActiveOrHistoricCurrencyAndAmount.value is f64, which holds integers exactly only below 2^53. 123456789012345678 parses as 123456789012345680 and nothing reports it. The pipeline cannot catch this: the round-trip compares parsed values, so a rounded amount matches itself, and the seven camt053 scenarios carry round balances f64 represents exactly. Feeding this amount through a scenario passes all four steps while the published XML reads 123456789012345680. Below 2^53 the text round-trips exactly, so this bites aggregate balances in currencies like VND or IDR rather than an ordinary CBPR+ payment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An amount above 2^53 is not the amount that was given
ActiveOrHistoricCurrencyAndAmount.valueisf64(src/document/camt_053_001_08.rs:342),and so is
AmountAndDirection35.amt(:691).f64holds integers exactly up to2^53, which is 9007199254740992. Above that the parsed amount is a different
number than the one on the wire, and the crate reports success either way.
tests/amount_precision.rsparses one amount and fails:The pipeline cannot see this. I put the same amount into a copy of
simplified_statement.jsonand ran it: Generate, Publish, Validate, Parse allreport 1/1 and the round-trip matches, while the published XML reads
<Amt Ccy="USD">123456789012345680</Amt>. Both sides of the comparison arealready
f64, so a rounded amount matches itself. The seven camt053 scenarioscarry 5000.0, 10000.0, 11500.0, 25000.0, 50000.0, 100000.0, 500000.0 and
750000.0, every one of which
f64represents exactly, so the corpus has neverput the type under pressure.
Two things this is not:
exactly, because Rust prints the shortest representation that parses back.
It starts to matter for aggregate balances in VND or IDR, where a
country-scale figure passes 9.0e15 on its own.
xsd/is gitignored, so the18 significant digits I am testing against come from the base ISO 20022
amount type, not from your CBPR+ SR2025 restriction. If SR2025 caps
totalDigitslower than 18, say so and this is a non-issue.The fix does not belong in
src/document/.generate.shopens withrm -rf src/document/, so a patched struct is gone at the next generation. Themapping is upstream in
xuri/xgen,utils.go,BuildInTypes, where the fifthcolumn is Rust:
The place that survives regeneration is the post-processing this repo already
runs,
apply-box-wrapping.pywithbox-config.json. A decimal string is whatthe other generated models use:
rust_iso20022keeps every scalar asStringand gives the reason in its README, lossless exact text with no float rounding.
This PR is the test only. It fails today.
Dropped before opening this: a second test asserting that
BkToCstmrStmt/Stmtshould be
Vec. It should not, for this crate.AccountStatement91in the samestruct has
bal: Vec<CashBalance81>andntry: Option<Vec<Box<ReportEntry101>>>,so xgen does emit a sequence when the schema says unbounded, which means the
singular
stmtcame from CBPR+ restricting it to 1..1. Base ISO 20022 modelssuch as
rust_iso20022andopen-payments-iso20022-camtuseVecthere, butthey are generated from the unrestricted schemas and are not comparable.