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 }