github.com/jimmyx0x/go-ethereum@v1.10.28/trie/node_test.go (about)

     1  // Copyright 2016 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 trie
    18  
    19  import (
    20  	"bytes"
    21  	"testing"
    22  
    23  	"github.com/ethereum/go-ethereum/crypto"
    24  	"github.com/ethereum/go-ethereum/rlp"
    25  )
    26  
    27  func newTestFullNode(v []byte) []interface{} {
    28  	fullNodeData := []interface{}{}
    29  	for i := 0; i < 16; i++ {
    30  		k := bytes.Repeat([]byte{byte(i + 1)}, 32)
    31  		fullNodeData = append(fullNodeData, k)
    32  	}
    33  	fullNodeData = append(fullNodeData, v)
    34  	return fullNodeData
    35  }
    36  
    37  func TestDecodeNestedNode(t *testing.T) {
    38  	fullNodeData := newTestFullNode([]byte("fullnode"))
    39  
    40  	data := [][]byte{}
    41  	for i := 0; i < 16; i++ {
    42  		data = append(data, nil)
    43  	}
    44  	data = append(data, []byte("subnode"))
    45  	fullNodeData[15] = data
    46  
    47  	buf := bytes.NewBuffer([]byte{})
    48  	rlp.Encode(buf, fullNodeData)
    49  
    50  	if _, err := decodeNode([]byte("testdecode"), buf.Bytes()); err != nil {
    51  		t.Fatalf("decode nested full node err: %v", err)
    52  	}
    53  }
    54  
    55  func TestDecodeFullNodeWrongSizeChild(t *testing.T) {
    56  	fullNodeData := newTestFullNode([]byte("wrongsizechild"))
    57  	fullNodeData[0] = []byte("00")
    58  	buf := bytes.NewBuffer([]byte{})
    59  	rlp.Encode(buf, fullNodeData)
    60  
    61  	_, err := decodeNode([]byte("testdecode"), buf.Bytes())
    62  	if _, ok := err.(*decodeError); !ok {
    63  		t.Fatalf("decodeNode returned wrong err: %v", err)
    64  	}
    65  }
    66  
    67  func TestDecodeFullNodeWrongNestedFullNode(t *testing.T) {
    68  	fullNodeData := newTestFullNode([]byte("fullnode"))
    69  
    70  	data := [][]byte{}
    71  	for i := 0; i < 16; i++ {
    72  		data = append(data, []byte("123456"))
    73  	}
    74  	data = append(data, []byte("subnode"))
    75  	fullNodeData[15] = data
    76  
    77  	buf := bytes.NewBuffer([]byte{})
    78  	rlp.Encode(buf, fullNodeData)
    79  
    80  	_, err := decodeNode([]byte("testdecode"), buf.Bytes())
    81  	if _, ok := err.(*decodeError); !ok {
    82  		t.Fatalf("decodeNode returned wrong err: %v", err)
    83  	}
    84  }
    85  
    86  func TestDecodeFullNode(t *testing.T) {
    87  	fullNodeData := newTestFullNode([]byte("decodefullnode"))
    88  	buf := bytes.NewBuffer([]byte{})
    89  	rlp.Encode(buf, fullNodeData)
    90  
    91  	_, err := decodeNode([]byte("testdecode"), buf.Bytes())
    92  	if err != nil {
    93  		t.Fatalf("decode full node err: %v", err)
    94  	}
    95  }
    96  
    97  // goos: darwin
    98  // goarch: arm64
    99  // pkg: github.com/ethereum/go-ethereum/trie
   100  // BenchmarkEncodeShortNode
   101  // BenchmarkEncodeShortNode-8   	16878850	        70.81 ns/op	      48 B/op	       1 allocs/op
   102  func BenchmarkEncodeShortNode(b *testing.B) {
   103  	node := &shortNode{
   104  		Key: []byte{0x1, 0x2},
   105  		Val: hashNode(randBytes(32)),
   106  	}
   107  	b.ResetTimer()
   108  	b.ReportAllocs()
   109  
   110  	for i := 0; i < b.N; i++ {
   111  		nodeToBytes(node)
   112  	}
   113  }
   114  
   115  // goos: darwin
   116  // goarch: arm64
   117  // pkg: github.com/ethereum/go-ethereum/trie
   118  // BenchmarkEncodeFullNode
   119  // BenchmarkEncodeFullNode-8   	 4323273	       284.4 ns/op	     576 B/op	       1 allocs/op
   120  func BenchmarkEncodeFullNode(b *testing.B) {
   121  	node := &fullNode{}
   122  	for i := 0; i < 16; i++ {
   123  		node.Children[i] = hashNode(randBytes(32))
   124  	}
   125  	b.ResetTimer()
   126  	b.ReportAllocs()
   127  
   128  	for i := 0; i < b.N; i++ {
   129  		nodeToBytes(node)
   130  	}
   131  }
   132  
   133  // goos: darwin
   134  // goarch: arm64
   135  // pkg: github.com/ethereum/go-ethereum/trie
   136  // BenchmarkDecodeShortNode
   137  // BenchmarkDecodeShortNode-8   	 7925638	       151.0 ns/op	     157 B/op	       4 allocs/op
   138  func BenchmarkDecodeShortNode(b *testing.B) {
   139  	node := &shortNode{
   140  		Key: []byte{0x1, 0x2},
   141  		Val: hashNode(randBytes(32)),
   142  	}
   143  	blob := nodeToBytes(node)
   144  	hash := crypto.Keccak256(blob)
   145  
   146  	b.ResetTimer()
   147  	b.ReportAllocs()
   148  
   149  	for i := 0; i < b.N; i++ {
   150  		mustDecodeNode(hash, blob)
   151  	}
   152  }
   153  
   154  // goos: darwin
   155  // goarch: arm64
   156  // pkg: github.com/ethereum/go-ethereum/trie
   157  // BenchmarkDecodeShortNodeUnsafe
   158  // BenchmarkDecodeShortNodeUnsafe-8   	 9027476	       128.6 ns/op	     109 B/op	       3 allocs/op
   159  func BenchmarkDecodeShortNodeUnsafe(b *testing.B) {
   160  	node := &shortNode{
   161  		Key: []byte{0x1, 0x2},
   162  		Val: hashNode(randBytes(32)),
   163  	}
   164  	blob := nodeToBytes(node)
   165  	hash := crypto.Keccak256(blob)
   166  
   167  	b.ResetTimer()
   168  	b.ReportAllocs()
   169  
   170  	for i := 0; i < b.N; i++ {
   171  		mustDecodeNodeUnsafe(hash, blob)
   172  	}
   173  }
   174  
   175  // goos: darwin
   176  // goarch: arm64
   177  // pkg: github.com/ethereum/go-ethereum/trie
   178  // BenchmarkDecodeFullNode
   179  // BenchmarkDecodeFullNode-8   	 1597462	       761.9 ns/op	    1280 B/op	      18 allocs/op
   180  func BenchmarkDecodeFullNode(b *testing.B) {
   181  	node := &fullNode{}
   182  	for i := 0; i < 16; i++ {
   183  		node.Children[i] = hashNode(randBytes(32))
   184  	}
   185  	blob := nodeToBytes(node)
   186  	hash := crypto.Keccak256(blob)
   187  
   188  	b.ResetTimer()
   189  	b.ReportAllocs()
   190  
   191  	for i := 0; i < b.N; i++ {
   192  		mustDecodeNode(hash, blob)
   193  	}
   194  }
   195  
   196  // goos: darwin
   197  // goarch: arm64
   198  // pkg: github.com/ethereum/go-ethereum/trie
   199  // BenchmarkDecodeFullNodeUnsafe
   200  // BenchmarkDecodeFullNodeUnsafe-8   	 1789070	       687.1 ns/op	     704 B/op	      17 allocs/op
   201  func BenchmarkDecodeFullNodeUnsafe(b *testing.B) {
   202  	node := &fullNode{}
   203  	for i := 0; i < 16; i++ {
   204  		node.Children[i] = hashNode(randBytes(32))
   205  	}
   206  	blob := nodeToBytes(node)
   207  	hash := crypto.Keccak256(blob)
   208  
   209  	b.ResetTimer()
   210  	b.ReportAllocs()
   211  
   212  	for i := 0; i < b.N; i++ {
   213  		mustDecodeNodeUnsafe(hash, blob)
   214  	}
   215  }