-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Request Summary:
Should Mojaloop represent monetary amounts and position fields as integers (minor units per ISO 4217) instead of decimals, to improve accuracy and performance?
Request Details:
- Deadline: -
- Impact (Teams): Core Mojaloop developers, QA/testing, deployment/infra teams, API integrators (DFSPs, Hub Operators).
- Impact (Components):
- Mojaloop APIs (amount fields in schemas and position field in admin apis)
- Central Ledger DB schema (amount, position fields)
- ML-Number usage in services
- API documentation & developer guides
Background:
Currently, Mojaloop represents monetary amounts as strings with decimal values (e.g., "10.99"). This requires string parsing and arithmetic through the ML-Number library.
However, handling decimals in software introduces precision issues and performance overhead. For example, in many languages:
print(0.1 + 0.2)
# Output: 0.30000000000000004
This is not a bug, but a fundamental limitation of binary floating-point representation (IEEE 754) in computers.
- Humans can represent 1/3 in base-10 decimals only as an approximation (e.g., 0.3333…). It’s a repeating decimal that cannot be expressed with finite precision in base-10.
- Computers use base-2 (binary) floating-point. In the same way many decimal fractions (e.g., 0.1, 0.2) cannot be represented exactly in binary, leading to rounding errors.
While Mojaloop avoids direct floating-point usage by relying on ML-Number and string representations, this pushes the burden into software-emulated decimal operations, which are slower and less efficient than native CPU integer operations.
Industry Best Practice:
Financial systems commonly store amounts in integers (e.g., cents instead of dollars). This avoids floating-point pitfalls and simplifies comparisons, summations, and validations.
The ISO 4217 specification defines minor units for each currency (e.g., 2 decimal places for USD, 0 for JPY). By multiplying the amount by 10^minorUnits, we can store amounts as whole integers.
Proposed Change
- Store all amounts (including position fields) as integers, scaled by ISO 4217 minor units.
- Example:
10.99 USD→1099(cents).
- Example:
- Update API specifications to expect integer values.
- Remove reliance on
ML-Numberfor basic amount operations. - Update Mojaloop documentation to reflect this change.
Benefits
- Accuracy: Removes rounding errors.
- Performance: Leverages native CPU integer arithmetic.
- Simplicity: Easier for developers to handle values consistently.
- Consistency: Aligns Mojaloop with financial services industry best practices.
Risks & Considerations
- Backward compatibility: Integrations expect string decimals. We may need API versioning or string conversions.
- Currency variations: Some currencies have unusual minor units (e.g., 3 decimals for TND). Must ensure ISO 4217 mapping is consistently applied.
- Migration effort: DB schema changes, API refactor, and integration testing required.
Next Steps
- Run a PoC refactor for one service to integer-based amounts.
- Benchmark performance: throughput, latency, CPU utilization (with vs. without
ML-Number). - Develop a migration strategy (DB, APIs, integration impacts).
- Present results for DA decision.
Artifacts:
- Benchmark PoC results
Dependencies:
- API versioning strategy
- Migration path for existing integrations
Accountability:
- Owner:
- Raised By: Vijaya Kumar Guthi
Decision(s):
- Approved By: