github.com/mavryk-network/mvgo@v1.19.9/mavryk/zarith_test.go (about) 1 // Copyright (c) 2022 Blockwatch Data Inc. 2 // Author: stefan@blockwatch.cc 3 4 package mavryk 5 6 import ( 7 "bytes" 8 "io" 9 "math/big" 10 "math/rand" 11 "testing" 12 ) 13 14 type ZarithDecodeTest struct { 15 name string 16 buf []byte 17 res []uint64 18 sign int 19 err error 20 } 21 22 var zarithDecodeCases = []ZarithDecodeTest{ 23 { 24 name: "e0", 25 buf: []byte{}, 26 err: io.ErrShortBuffer, 27 }, 28 { 29 name: "e1", 30 buf: []byte{0xc0}, 31 err: io.ErrShortBuffer, 32 }, 33 { 34 name: "e9", 35 buf: []byte{0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}, 36 err: io.ErrShortBuffer, 37 }, 38 { 39 name: "l1", 40 buf: []byte{0x20}, 41 res: []uint64{0x20}, 42 }, 43 { 44 name: "l9", 45 buf: []byte{0xa0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40}, 46 res: []uint64{0x2040810204081020}, 47 }, 48 { 49 name: "l10", 50 buf: []byte{0xa0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40}, 51 res: []uint64{0x10, 0x2040810204081020}, 52 }, 53 { 54 name: "l18", 55 buf: []byte{0xa0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40}, 56 res: []uint64{0x1020408102040810, 0x2040810204081020}, 57 }, 58 { 59 name: "l19", 60 buf: []byte{0xa0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40}, 61 res: []uint64{0x08, 0x1020408102040810, 0x2040810204081020}, 62 }, 63 { 64 name: "n1", 65 buf: []byte{0x60}, 66 res: []uint64{0x20}, 67 sign: 1, 68 }, 69 { 70 name: "n9", 71 buf: []byte{0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40}, 72 res: []uint64{0x2040810204081020}, 73 sign: 1, 74 }, 75 { 76 name: "n10", 77 buf: []byte{0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40}, 78 res: []uint64{0x10, 0x2040810204081020}, 79 sign: 1, 80 }, 81 { 82 name: "n18", 83 buf: []byte{0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40}, 84 res: []uint64{0x1020408102040810, 0x2040810204081020}, 85 sign: 1, 86 }, 87 { 88 name: "n19", 89 buf: []byte{0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40}, 90 res: []uint64{0x08, 0x1020408102040810, 0x2040810204081020}, 91 sign: 1, 92 }, 93 } 94 95 func TestDecodeBuffer(t *testing.T) { 96 for _, c := range zarithDecodeCases { 97 var z Z 98 err := z.DecodeBuffer(bytes.NewBuffer(c.buf)) 99 if got, want := err, c.err; got != want { 100 t.Errorf("%s: unexpected error %v, expected %v", c.name, got, want) 101 } 102 if err != nil { 103 continue 104 } 105 res := big.NewInt(0) 106 n := new(big.Int) 107 for _, v := range c.res { 108 n.SetUint64(v) 109 res.Or(res.Lsh(res, 64), n) 110 } 111 if c.sign != 0 { 112 res.Neg(res) 113 } 114 if got, want := z, (Z)(*res); got.Cmp(want) != 0 { 115 t.Errorf("%s: unexpected result %v, expected %v", c.name, got, want) 116 } 117 } 118 } 119 120 type benchmarkSize struct { 121 name string 122 l int 123 } 124 125 var benchmarkSizes = []benchmarkSize{ 126 {"6bit", 1}, 127 {"62bit", 9}, 128 {"125bit", 18}, 129 {"251bit", 36}, 130 {"510bit", 73}, 131 } 132 133 func randZarithSlice(n int) []byte { 134 s := make([]byte, n) 135 if n == 1 { 136 s[0] = byte(rand.Intn(0x40)) 137 return s 138 } 139 140 s[0] = byte(rand.Intn(0x40)) | 0x80 141 for i := 1; i < n-1; i++ { 142 s[i] = byte(rand.Intn(0x80)) | 0x80 143 } 144 s[n-1] = byte(rand.Intn(0x80)) 145 return s 146 } 147 148 func BenchmarkDecodeBuffer(b *testing.B) { 149 for _, bm := range benchmarkSizes { 150 buf := randZarithSlice(bm.l) 151 var z Z 152 b.Run(bm.name, func(b *testing.B) { 153 b.SetBytes(int64(bm.l)) 154 for i := 0; i < b.N; i++ { 155 z.DecodeBuffer(bytes.NewBuffer(buf)) 156 } 157 }) 158 } 159 }