github.com/MetalBlockchain/subnet-evm@v0.4.9/trie/encoding_test.go (about)

     1  // (c) 2020-2021, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2014 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package trie
    28  
    29  import (
    30  	"bytes"
    31  	"encoding/hex"
    32  	"math/rand"
    33  	"testing"
    34  )
    35  
    36  func TestHexCompact(t *testing.T) {
    37  	tests := []struct{ hex, compact []byte }{
    38  		// empty keys, with and without terminator.
    39  		{hex: []byte{}, compact: []byte{0x00}},
    40  		{hex: []byte{16}, compact: []byte{0x20}},
    41  		// odd length, no terminator
    42  		{hex: []byte{1, 2, 3, 4, 5}, compact: []byte{0x11, 0x23, 0x45}},
    43  		// even length, no terminator
    44  		{hex: []byte{0, 1, 2, 3, 4, 5}, compact: []byte{0x00, 0x01, 0x23, 0x45}},
    45  		// odd length, terminator
    46  		{hex: []byte{15, 1, 12, 11, 8, 16 /*term*/}, compact: []byte{0x3f, 0x1c, 0xb8}},
    47  		// even length, terminator
    48  		{hex: []byte{0, 15, 1, 12, 11, 8, 16 /*term*/}, compact: []byte{0x20, 0x0f, 0x1c, 0xb8}},
    49  	}
    50  	for _, test := range tests {
    51  		if c := hexToCompact(test.hex); !bytes.Equal(c, test.compact) {
    52  			t.Errorf("hexToCompact(%x) -> %x, want %x", test.hex, c, test.compact)
    53  		}
    54  		if h := compactToHex(test.compact); !bytes.Equal(h, test.hex) {
    55  			t.Errorf("compactToHex(%x) -> %x, want %x", test.compact, h, test.hex)
    56  		}
    57  	}
    58  }
    59  
    60  func TestHexKeybytes(t *testing.T) {
    61  	tests := []struct{ key, hexIn, hexOut []byte }{
    62  		{key: []byte{}, hexIn: []byte{16}, hexOut: []byte{16}},
    63  		{key: []byte{}, hexIn: []byte{}, hexOut: []byte{16}},
    64  		{
    65  			key:    []byte{0x12, 0x34, 0x56},
    66  			hexIn:  []byte{1, 2, 3, 4, 5, 6, 16},
    67  			hexOut: []byte{1, 2, 3, 4, 5, 6, 16},
    68  		},
    69  		{
    70  			key:    []byte{0x12, 0x34, 0x5},
    71  			hexIn:  []byte{1, 2, 3, 4, 0, 5, 16},
    72  			hexOut: []byte{1, 2, 3, 4, 0, 5, 16},
    73  		},
    74  		{
    75  			key:    []byte{0x12, 0x34, 0x56},
    76  			hexIn:  []byte{1, 2, 3, 4, 5, 6},
    77  			hexOut: []byte{1, 2, 3, 4, 5, 6, 16},
    78  		},
    79  	}
    80  	for _, test := range tests {
    81  		if h := keybytesToHex(test.key); !bytes.Equal(h, test.hexOut) {
    82  			t.Errorf("keybytesToHex(%x) -> %x, want %x", test.key, h, test.hexOut)
    83  		}
    84  		if k := hexToKeybytes(test.hexIn); !bytes.Equal(k, test.key) {
    85  			t.Errorf("hexToKeybytes(%x) -> %x, want %x", test.hexIn, k, test.key)
    86  		}
    87  	}
    88  }
    89  
    90  func TestHexToCompactInPlace(t *testing.T) {
    91  	for i, keyS := range []string{
    92  		"00",
    93  		"060a040c0f000a090b040803010801010900080d090a0a0d0903000b10",
    94  		"10",
    95  	} {
    96  		hexBytes, _ := hex.DecodeString(keyS)
    97  		exp := hexToCompact(hexBytes)
    98  		sz := hexToCompactInPlace(hexBytes)
    99  		got := hexBytes[:sz]
   100  		if !bytes.Equal(exp, got) {
   101  			t.Fatalf("test %d: encoding err\ninp %v\ngot %x\nexp %x\n", i, keyS, got, exp)
   102  		}
   103  	}
   104  }
   105  
   106  func TestHexToCompactInPlaceRandom(t *testing.T) {
   107  	for i := 0; i < 10000; i++ {
   108  		l := rand.Intn(128)
   109  		key := make([]byte, l)
   110  		rand.Read(key)
   111  		hexBytes := keybytesToHex(key)
   112  		hexOrig := []byte(string(hexBytes))
   113  		exp := hexToCompact(hexBytes)
   114  		sz := hexToCompactInPlace(hexBytes)
   115  		got := hexBytes[:sz]
   116  
   117  		if !bytes.Equal(exp, got) {
   118  			t.Fatalf("encoding err \ncpt %x\nhex %x\ngot %x\nexp %x\n",
   119  				key, hexOrig, got, exp)
   120  		}
   121  	}
   122  }
   123  
   124  func BenchmarkHexToCompact(b *testing.B) {
   125  	testBytes := []byte{0, 15, 1, 12, 11, 8, 16 /*term*/}
   126  	for i := 0; i < b.N; i++ {
   127  		hexToCompact(testBytes)
   128  	}
   129  }
   130  
   131  func BenchmarkCompactToHex(b *testing.B) {
   132  	testBytes := []byte{0, 15, 1, 12, 11, 8, 16 /*term*/}
   133  	for i := 0; i < b.N; i++ {
   134  		compactToHex(testBytes)
   135  	}
   136  }
   137  
   138  func BenchmarkKeybytesToHex(b *testing.B) {
   139  	testBytes := []byte{7, 6, 6, 5, 7, 2, 6, 2, 16}
   140  	for i := 0; i < b.N; i++ {
   141  		keybytesToHex(testBytes)
   142  	}
   143  }
   144  
   145  func BenchmarkHexToKeybytes(b *testing.B) {
   146  	testBytes := []byte{7, 6, 6, 5, 7, 2, 6, 2, 16}
   147  	for i := 0; i < b.N; i++ {
   148  		hexToKeybytes(testBytes)
   149  	}
   150  }