node_test.go 5.5 KB

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