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  }