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  }