Deterministic Functions
Problem
Blockchain consensus requires that every node produces identical output for identical input. Rust does not guarantee this. Floating point operations can produce different results on different architectures. Integer overflow behavior depends on debug/release mode. Memory layout of structs is unspecified.
Solution
The #[deterministic] attribute marks functions that must produce identical results on all platforms.
Syntax
Compile-Time Checks
Inside a #[deterministic] function, the compiler rejects:
| Rejected Construct | Reason | Error Code |
|---|---|---|
f32, f64 types |
Non-deterministic across platforms | RS201 |
as casts involving floats |
Rounding is platform-dependent | RS202 |
| Raw pointer arithmetic | Addresses are non-deterministic | RS203 |
std::time::Instant |
Wall clock is non-deterministic | RS204 |
rand::* |
Randomness is non-deterministic | RS205 |
Unchecked arithmetic (+, -, *) |
Overflow behavior differs debug/release | RS206 |
HashMap iteration |
Order is non-deterministic | RS207 |
| Inline assembly | Platform-specific by definition | RS208 |
Calling non-#[deterministic] functions |
Transitivity requirement | RS209 |
usize, isize types |
Width is platform-dependent (32 or 64 bit) | RS210 |
What IS Allowed
FixedPoint<T, DECIMALS>(Rs built-in fixed-point type)checked_add,checked_mul,checked_sub,checked_divsaturating_*arithmeticwrapping_*arithmetic (deterministic across platforms)overflowing_*arithmetic (returns value + overflow flag)BTreeMap,BTreeSet(deterministic iteration order) — inedition = "rs", useBoundedMap/BoundedSetinstead (stack-allocated);BTreeMaprequires#[allow(rs::heap)]- Arrays, slices with deterministic indexing
- Other
#[deterministic]functions const fn(already deterministic)- All comparison and logical operations
Transitivity
Determinism is contagious upward and required downward:
Built-in FixedPoint Type
Rs provides a built-in fixed-point numeric type:
// FixedPoint<BaseType, DecimalPlaces>
type Rank = ; // 18 decimal places, u128 backing
let a: Rank = from_integer;
let b: Rank = from_raw; // 42.0
let c = a.checked_add.unwrap;
let d = a.checked_mul.unwrap;
// All operations are deterministic, checked, no floats
Compiler implementation: ~400 lines (lint pass + diagnostics).
Error Reference
See errors/deterministic.md for detailed descriptions of RS201–RS210.