mirror of
https://github.com/luxfi/utils.git
synced 2026-10-30 15:13:57 +00:00
The set was Uint8/16/32/64 and Float32/64 — everything the P- and X-chains need and nothing the EVM does. A wei value, a token balance or a supply does not fit in 64 bits; an 18-decimal balance passes 2^64 at about 18.4 tokens. Every field of that shape reaching this boundary had to become a bare string or a hand-rolled big.Int at each site. uint256.Int rather than big.Int: a fixed-size value cannot be nil, so the zero Uint256 is zero rather than a panic, and it does not allocate. The module was already in the graph. It marshals as a quoted decimal like every type beside it, which is the point of this package — a JSON number is a float64, so even a uint64 above 2^53 does not survive one unquoted. The test asserts Uint64 REFUSES a value Uint256 accepts, which is the failure this type exists to prevent, and covers 2^256-1, null, and garbage.
68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package json
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"github.com/holiman/uint256"
|
|
)
|
|
|
|
func TestUint256RoundTrip(t *testing.T) {
|
|
for _, dec := range []string{
|
|
"0",
|
|
"18446744073709551615", // uint64 max
|
|
"18446744073709551616", // one past it
|
|
"1000000000000000000000", // 1000 tokens at 18 decimals
|
|
"115792089237316195423570985008687907853269984665640564039457584007913129639935", // 2^256-1
|
|
} {
|
|
u := Uint256(*uint256.MustFromDecimal(dec))
|
|
b, err := json.Marshal(u)
|
|
if err != nil {
|
|
t.Fatalf("%s: marshal: %v", dec, err)
|
|
}
|
|
if string(b) != `"`+dec+`"` {
|
|
t.Fatalf("%s: got %s", dec, b)
|
|
}
|
|
var back Uint256
|
|
if err := json.Unmarshal(b, &back); err != nil {
|
|
t.Fatalf("%s: unmarshal: %v", dec, err)
|
|
}
|
|
if v := uint256.Int(back); v.Dec() != dec {
|
|
t.Errorf("%s: round-tripped to %s", dec, v.Dec())
|
|
}
|
|
}
|
|
}
|
|
|
|
// The reason this type exists: the narrower one silently cannot hold the value.
|
|
func TestUint64CannotHoldWhatUint256Can(t *testing.T) {
|
|
const wei = "1000000000000000000000"
|
|
var small Uint64
|
|
if err := json.Unmarshal([]byte(`"`+wei+`"`), &small); err == nil {
|
|
t.Fatal("Uint64 accepted a 256-bit value")
|
|
}
|
|
var big Uint256
|
|
if err := json.Unmarshal([]byte(`"`+wei+`"`), &big); err != nil {
|
|
t.Fatalf("Uint256 refused it: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUint256NullLeavesValue(t *testing.T) {
|
|
u := Uint256(*uint256.NewInt(7))
|
|
if err := u.UnmarshalJSON([]byte(Null)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if v := uint256.Int(u); v.Dec() != "7" {
|
|
t.Errorf("null overwrote the value: %s", v.Dec())
|
|
}
|
|
}
|
|
|
|
func TestUint256RejectsGarbage(t *testing.T) {
|
|
var u Uint256
|
|
if err := json.Unmarshal([]byte(`"not-a-number"`), &u); err == nil {
|
|
t.Error("accepted garbage")
|
|
}
|
|
}
|