github.com/ethereum/go-ethereum@v1.16.1/common/math/big_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package math 18 19 import ( 20 "bytes" 21 "encoding/hex" 22 "math/big" 23 "testing" 24 ) 25 26 func TestHexOrDecimal256(t *testing.T) { 27 tests := []struct { 28 input string 29 num *big.Int 30 ok bool 31 }{ 32 {"", big.NewInt(0), true}, 33 {"0", big.NewInt(0), true}, 34 {"0x0", big.NewInt(0), true}, 35 {"12345678", big.NewInt(12345678), true}, 36 {"0x12345678", big.NewInt(0x12345678), true}, 37 {"0X12345678", big.NewInt(0x12345678), true}, 38 // Tests for leading zero behaviour: 39 {"0123456789", big.NewInt(123456789), true}, // note: not octal 40 {"00", big.NewInt(0), true}, 41 {"0x00", big.NewInt(0), true}, 42 {"0x012345678abc", big.NewInt(0x12345678abc), true}, 43 // Invalid syntax: 44 {"abcdef", nil, false}, 45 {"0xgg", nil, false}, 46 // Larger than 256 bits: 47 {"115792089237316195423570985008687907853269984665640564039457584007913129639936", nil, false}, 48 } 49 for _, test := range tests { 50 var num HexOrDecimal256 51 err := num.UnmarshalText([]byte(test.input)) 52 if (err == nil) != test.ok { 53 t.Errorf("ParseBig(%q) -> (err == nil) == %t, want %t", test.input, err == nil, test.ok) 54 continue 55 } 56 if test.num != nil && (*big.Int)(&num).Cmp(test.num) != 0 { 57 t.Errorf("ParseBig(%q) -> %d, want %d", test.input, (*big.Int)(&num), test.num) 58 } 59 } 60 } 61 62 func TestMustParseBig256(t *testing.T) { 63 defer func() { 64 if recover() == nil { 65 t.Error("MustParseBig should've panicked") 66 } 67 }() 68 MustParseBig256("ggg") 69 } 70 71 func TestPaddedBigBytes(t *testing.T) { 72 tests := []struct { 73 num *big.Int 74 n int 75 result []byte 76 }{ 77 {num: big.NewInt(0), n: 4, result: []byte{0, 0, 0, 0}}, 78 {num: big.NewInt(1), n: 4, result: []byte{0, 0, 0, 1}}, 79 {num: big.NewInt(512), n: 4, result: []byte{0, 0, 2, 0}}, 80 {num: BigPow(2, 32), n: 4, result: []byte{1, 0, 0, 0, 0}}, 81 } 82 for _, test := range tests { 83 if result := PaddedBigBytes(test.num, test.n); !bytes.Equal(result, test.result) { 84 t.Errorf("PaddedBigBytes(%d, %d) = %v, want %v", test.num, test.n, result, test.result) 85 } 86 } 87 } 88 89 func BenchmarkPaddedBigBytesLargePadding(b *testing.B) { 90 bigint := MustParseBig256("123456789123456789123456789123456789") 91 for i := 0; i < b.N; i++ { 92 PaddedBigBytes(bigint, 200) 93 } 94 } 95 96 func BenchmarkPaddedBigBytesSmallPadding(b *testing.B) { 97 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 98 for i := 0; i < b.N; i++ { 99 PaddedBigBytes(bigint, 5) 100 } 101 } 102 103 func BenchmarkPaddedBigBytesSmallOnePadding(b *testing.B) { 104 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 105 for i := 0; i < b.N; i++ { 106 PaddedBigBytes(bigint, 32) 107 } 108 } 109 110 func BenchmarkByteAtOld(b *testing.B) { 111 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 112 for i := 0; i < b.N; i++ { 113 PaddedBigBytes(bigint, 32) 114 } 115 } 116 117 func TestReadBits(t *testing.T) { 118 check := func(input string) { 119 want, _ := hex.DecodeString(input) 120 n, _ := new(big.Int).SetString(input, 16) 121 buf := make([]byte, len(want)) 122 ReadBits(n, buf) 123 if !bytes.Equal(buf, want) { 124 t.Errorf("have: %x\nwant: %x", buf, want) 125 } 126 } 127 check("000000000000000000000000000000000000000000000000000000FEFCF3F8F0") 128 check("0000000000012345000000000000000000000000000000000000FEFCF3F8F0") 129 check("18F8F8F1000111000110011100222004330052300000000000000000FEFCF3F8F0") 130 } 131 132 func TestU256(t *testing.T) { 133 tests := []struct{ x, y *big.Int }{ 134 {x: big.NewInt(0), y: big.NewInt(0)}, 135 {x: big.NewInt(1), y: big.NewInt(1)}, 136 {x: BigPow(2, 255), y: BigPow(2, 255)}, 137 {x: BigPow(2, 256), y: big.NewInt(0)}, 138 {x: new(big.Int).Add(BigPow(2, 256), big.NewInt(1)), y: big.NewInt(1)}, 139 // negative values 140 {x: big.NewInt(-1), y: new(big.Int).Sub(BigPow(2, 256), big.NewInt(1))}, 141 {x: big.NewInt(-2), y: new(big.Int).Sub(BigPow(2, 256), big.NewInt(2))}, 142 {x: BigPow(2, -255), y: big.NewInt(1)}, 143 } 144 for _, test := range tests { 145 if y := U256(new(big.Int).Set(test.x)); y.Cmp(test.y) != 0 { 146 t.Errorf("U256(%x) = %x, want %x", test.x, y, test.y) 147 } 148 } 149 } 150 151 func TestU256Bytes(t *testing.T) { 152 ubytes := make([]byte, 32) 153 ubytes[31] = 1 154 155 unsigned := U256Bytes(big.NewInt(1)) 156 if !bytes.Equal(unsigned, ubytes) { 157 t.Errorf("expected %x got %x", ubytes, unsigned) 158 } 159 }