stacktrie_test.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package trie
  2. import (
  3. "bytes"
  4. "math/big"
  5. "testing"
  6. "github.com/ethereum/go-ethereum/common"
  7. "github.com/ethereum/go-ethereum/crypto"
  8. "github.com/ethereum/go-ethereum/ethdb/memorydb"
  9. )
  10. func TestSizeBug(t *testing.T) {
  11. st := NewStackTrie(nil)
  12. nt, _ := New(common.Hash{}, NewDatabase(memorydb.New()))
  13. leaf := common.FromHex("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")
  14. value := common.FromHex("94cf40d0d2b44f2b66e07cace1372ca42b73cf21a3")
  15. nt.TryUpdate(leaf, value)
  16. st.TryUpdate(leaf, value)
  17. if nt.Hash() != st.Hash() {
  18. t.Fatalf("error %x != %x", st.Hash(), nt.Hash())
  19. }
  20. }
  21. func TestEmptyBug(t *testing.T) {
  22. st := NewStackTrie(nil)
  23. nt, _ := New(common.Hash{}, NewDatabase(memorydb.New()))
  24. //leaf := common.FromHex("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")
  25. //value := common.FromHex("94cf40d0d2b44f2b66e07cace1372ca42b73cf21a3")
  26. kvs := []struct {
  27. K string
  28. V string
  29. }{
  30. {K: "405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace", V: "9496f4ec2bf9dab484cac6be589e8417d84781be08"},
  31. {K: "40edb63a35fcf86c08022722aa3287cdd36440d671b4918131b2514795fefa9c", V: "01"},
  32. {K: "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", V: "947a30f7736e48d6599356464ba4c150d8da0302ff"},
  33. {K: "c2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b", V: "02"},
  34. }
  35. for _, kv := range kvs {
  36. nt.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V))
  37. st.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V))
  38. }
  39. if nt.Hash() != st.Hash() {
  40. t.Fatalf("error %x != %x", st.Hash(), nt.Hash())
  41. }
  42. }
  43. func TestValLength56(t *testing.T) {
  44. st := NewStackTrie(nil)
  45. nt, _ := New(common.Hash{}, NewDatabase(memorydb.New()))
  46. //leaf := common.FromHex("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")
  47. //value := common.FromHex("94cf40d0d2b44f2b66e07cace1372ca42b73cf21a3")
  48. kvs := []struct {
  49. K string
  50. V string
  51. }{
  52. {K: "405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace", V: "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"},
  53. }
  54. for _, kv := range kvs {
  55. nt.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V))
  56. st.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V))
  57. }
  58. if nt.Hash() != st.Hash() {
  59. t.Fatalf("error %x != %x", st.Hash(), nt.Hash())
  60. }
  61. }
  62. // TestUpdateSmallNodes tests a case where the leaves are small (both key and value),
  63. // which causes a lot of node-within-node. This case was found via fuzzing.
  64. func TestUpdateSmallNodes(t *testing.T) {
  65. st := NewStackTrie(nil)
  66. nt, _ := New(common.Hash{}, NewDatabase(memorydb.New()))
  67. kvs := []struct {
  68. K string
  69. V string
  70. }{
  71. {"63303030", "3041"}, // stacktrie.Update
  72. {"65", "3000"}, // stacktrie.Update
  73. }
  74. for _, kv := range kvs {
  75. nt.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V))
  76. st.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V))
  77. }
  78. if nt.Hash() != st.Hash() {
  79. t.Fatalf("error %x != %x", st.Hash(), nt.Hash())
  80. }
  81. }
  82. // TestUpdateVariableKeys contains a case which stacktrie fails: when keys of different
  83. // sizes are used, and the second one has the same prefix as the first, then the
  84. // stacktrie fails, since it's unable to 'expand' on an already added leaf.
  85. // For all practical purposes, this is fine, since keys are fixed-size length
  86. // in account and storage tries.
  87. //
  88. // The test is marked as 'skipped', and exists just to have the behaviour documented.
  89. // This case was found via fuzzing.
  90. func TestUpdateVariableKeys(t *testing.T) {
  91. t.SkipNow()
  92. st := NewStackTrie(nil)
  93. nt, _ := New(common.Hash{}, NewDatabase(memorydb.New()))
  94. kvs := []struct {
  95. K string
  96. V string
  97. }{
  98. {"0x33303534636532393561313031676174", "303030"},
  99. {"0x3330353463653239356131303167617430", "313131"},
  100. }
  101. for _, kv := range kvs {
  102. nt.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V))
  103. st.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V))
  104. }
  105. if nt.Hash() != st.Hash() {
  106. t.Fatalf("error %x != %x", st.Hash(), nt.Hash())
  107. }
  108. }
  109. // TestStacktrieNotModifyValues checks that inserting blobs of data into the
  110. // stacktrie does not mutate the blobs
  111. func TestStacktrieNotModifyValues(t *testing.T) {
  112. st := NewStackTrie(nil)
  113. { // Test a very small trie
  114. // Give it the value as a slice with large backing alloc,
  115. // so if the stacktrie tries to append, it won't have to realloc
  116. value := make([]byte, 1, 100)
  117. value[0] = 0x2
  118. want := common.CopyBytes(value)
  119. st.TryUpdate([]byte{0x01}, value)
  120. st.Hash()
  121. if have := value; !bytes.Equal(have, want) {
  122. t.Fatalf("tiny trie: have %#x want %#x", have, want)
  123. }
  124. st = NewStackTrie(nil)
  125. }
  126. // Test with a larger trie
  127. keyB := big.NewInt(1)
  128. keyDelta := big.NewInt(1)
  129. var vals [][]byte
  130. getValue := func(i int) []byte {
  131. if i%2 == 0 { // large
  132. return crypto.Keccak256(big.NewInt(int64(i)).Bytes())
  133. } else { //small
  134. return big.NewInt(int64(i)).Bytes()
  135. }
  136. }
  137. for i := 0; i < 1000; i++ {
  138. key := common.BigToHash(keyB)
  139. value := getValue(i)
  140. st.TryUpdate(key.Bytes(), value)
  141. vals = append(vals, value)
  142. keyB = keyB.Add(keyB, keyDelta)
  143. keyDelta.Add(keyDelta, common.Big1)
  144. }
  145. st.Hash()
  146. for i := 0; i < 1000; i++ {
  147. want := getValue(i)
  148. have := vals[i]
  149. if !bytes.Equal(have, want) {
  150. t.Fatalf("item %d, have %#x want %#x", i, have, want)
  151. }
  152. }
  153. }
  154. // TestStacktrieSerialization tests that the stacktrie works well if we
  155. // serialize/unserialize it a lot
  156. func TestStacktrieSerialization(t *testing.T) {
  157. var (
  158. st = NewStackTrie(nil)
  159. nt, _ = New(common.Hash{}, NewDatabase(memorydb.New()))
  160. keyB = big.NewInt(1)
  161. keyDelta = big.NewInt(1)
  162. vals [][]byte
  163. keys [][]byte
  164. )
  165. getValue := func(i int) []byte {
  166. if i%2 == 0 { // large
  167. return crypto.Keccak256(big.NewInt(int64(i)).Bytes())
  168. } else { //small
  169. return big.NewInt(int64(i)).Bytes()
  170. }
  171. }
  172. for i := 0; i < 10; i++ {
  173. vals = append(vals, getValue(i))
  174. keys = append(keys, common.BigToHash(keyB).Bytes())
  175. keyB = keyB.Add(keyB, keyDelta)
  176. keyDelta.Add(keyDelta, common.Big1)
  177. }
  178. for i, k := range keys {
  179. nt.TryUpdate(k, common.CopyBytes(vals[i]))
  180. }
  181. for i, k := range keys {
  182. blob, err := st.MarshalBinary()
  183. if err != nil {
  184. t.Fatal(err)
  185. }
  186. newSt, err := NewFromBinary(blob, nil)
  187. if err != nil {
  188. t.Fatal(err)
  189. }
  190. st = newSt
  191. st.TryUpdate(k, common.CopyBytes(vals[i]))
  192. }
  193. if have, want := st.Hash(), nt.Hash(); have != want {
  194. t.Fatalf("have %#x want %#x", have, want)
  195. }
  196. }