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