trie_test.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. package ptrie
  2. import (
  3. "bytes"
  4. "fmt"
  5. "testing"
  6. "github.com/ethereum/go-ethereum/crypto"
  7. "github.com/ethereum/go-ethereum/ethutil"
  8. )
  9. type Db map[string][]byte
  10. func (self Db) Get(k []byte) ([]byte, error) { return self[string(k)], nil }
  11. func (self Db) Put(k, v []byte) { self[string(k)] = v }
  12. // Used for testing
  13. func NewEmpty() *Trie {
  14. return New(nil, make(Db))
  15. }
  16. func TestEmptyTrie(t *testing.T) {
  17. trie := NewEmpty()
  18. res := trie.Hash()
  19. exp := crypto.Sha3(ethutil.Encode(""))
  20. if !bytes.Equal(res, exp) {
  21. t.Errorf("expected %x got %x", exp, res)
  22. }
  23. }
  24. func TestInsert(t *testing.T) {
  25. trie := NewEmpty()
  26. trie.UpdateString("doe", "reindeer")
  27. trie.UpdateString("dog", "puppy")
  28. trie.UpdateString("dogglesworth", "cat")
  29. exp := ethutil.Hex2Bytes("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3")
  30. root := trie.Hash()
  31. if !bytes.Equal(root, exp) {
  32. t.Errorf("exp %x got %x", exp, root)
  33. }
  34. trie = NewEmpty()
  35. trie.UpdateString("A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
  36. exp = ethutil.Hex2Bytes("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab")
  37. root = trie.Hash()
  38. if !bytes.Equal(root, exp) {
  39. t.Errorf("exp %x got %x", exp, root)
  40. }
  41. }
  42. func TestGet(t *testing.T) {
  43. trie := NewEmpty()
  44. trie.UpdateString("doe", "reindeer")
  45. trie.UpdateString("dog", "puppy")
  46. trie.UpdateString("dogglesworth", "cat")
  47. res := trie.GetString("dog")
  48. if !bytes.Equal(res, []byte("puppy")) {
  49. t.Errorf("expected puppy got %x", res)
  50. }
  51. unknown := trie.GetString("unknown")
  52. if unknown != nil {
  53. t.Errorf("expected nil got %x", unknown)
  54. }
  55. }
  56. func TestDelete(t *testing.T) {
  57. trie := NewEmpty()
  58. vals := []struct{ k, v string }{
  59. {"do", "verb"},
  60. {"ether", "wookiedoo"},
  61. {"horse", "stallion"},
  62. {"shaman", "horse"},
  63. {"doge", "coin"},
  64. {"ether", ""},
  65. {"dog", "puppy"},
  66. {"shaman", ""},
  67. }
  68. for _, val := range vals {
  69. if val.v != "" {
  70. trie.UpdateString(val.k, val.v)
  71. } else {
  72. trie.DeleteString(val.k)
  73. }
  74. }
  75. hash := trie.Hash()
  76. exp := ethutil.Hex2Bytes("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
  77. if !bytes.Equal(hash, exp) {
  78. t.Errorf("expected %x got %x", exp, hash)
  79. }
  80. }
  81. func TestEmptyValues(t *testing.T) {
  82. trie := NewEmpty()
  83. vals := []struct{ k, v string }{
  84. {"do", "verb"},
  85. {"ether", "wookiedoo"},
  86. {"horse", "stallion"},
  87. {"shaman", "horse"},
  88. {"doge", "coin"},
  89. {"ether", ""},
  90. {"dog", "puppy"},
  91. {"shaman", ""},
  92. }
  93. for _, val := range vals {
  94. trie.UpdateString(val.k, val.v)
  95. }
  96. hash := trie.Hash()
  97. exp := ethutil.Hex2Bytes("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
  98. if !bytes.Equal(hash, exp) {
  99. t.Errorf("expected %x got %x", exp, hash)
  100. }
  101. }
  102. func TestReplication(t *testing.T) {
  103. trie := NewEmpty()
  104. vals := []struct{ k, v string }{
  105. {"do", "verb"},
  106. {"ether", "wookiedoo"},
  107. {"horse", "stallion"},
  108. {"shaman", "horse"},
  109. {"doge", "coin"},
  110. {"ether", ""},
  111. {"dog", "puppy"},
  112. {"shaman", ""},
  113. {"somethingveryoddindeedthis is", "myothernodedata"},
  114. }
  115. for _, val := range vals {
  116. trie.UpdateString(val.k, val.v)
  117. }
  118. trie.Commit()
  119. trie2 := New(trie.roothash, trie.cache.backend)
  120. if string(trie2.GetString("horse")) != "stallion" {
  121. t.Error("expected to have harse => stallion")
  122. }
  123. hash := trie2.Hash()
  124. exp := trie.Hash()
  125. if !bytes.Equal(hash, exp) {
  126. t.Errorf("root failure. expected %x got %x", exp, hash)
  127. }
  128. }
  129. func TestReset(t *testing.T) {
  130. trie := NewEmpty()
  131. vals := []struct{ k, v string }{
  132. {"do", "verb"},
  133. {"ether", "wookiedoo"},
  134. {"horse", "stallion"},
  135. }
  136. for _, val := range vals {
  137. trie.UpdateString(val.k, val.v)
  138. }
  139. trie.Commit()
  140. before := ethutil.CopyBytes(trie.roothash)
  141. trie.UpdateString("should", "revert")
  142. trie.Hash()
  143. // Should have no effect
  144. trie.Hash()
  145. trie.Hash()
  146. // ###
  147. trie.Reset()
  148. after := ethutil.CopyBytes(trie.roothash)
  149. if !bytes.Equal(before, after) {
  150. t.Errorf("expected roots to be equal. %x - %x", before, after)
  151. }
  152. }
  153. func TestParanoia(t *testing.T) {
  154. t.Skip()
  155. trie := NewEmpty()
  156. vals := []struct{ k, v string }{
  157. {"do", "verb"},
  158. {"ether", "wookiedoo"},
  159. {"horse", "stallion"},
  160. {"shaman", "horse"},
  161. {"doge", "coin"},
  162. {"ether", ""},
  163. {"dog", "puppy"},
  164. {"shaman", ""},
  165. {"somethingveryoddindeedthis is", "myothernodedata"},
  166. }
  167. for _, val := range vals {
  168. trie.UpdateString(val.k, val.v)
  169. }
  170. trie.Commit()
  171. ok, t2 := ParanoiaCheck(trie, trie.cache.backend)
  172. if !ok {
  173. t.Errorf("trie paranoia check failed %x %x", trie.roothash, t2.roothash)
  174. }
  175. }
  176. // Not an actual test
  177. func TestOutput(t *testing.T) {
  178. t.Skip()
  179. base := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  180. trie := NewEmpty()
  181. for i := 0; i < 50; i++ {
  182. trie.UpdateString(fmt.Sprintf("%s%d", base, i), "valueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
  183. }
  184. fmt.Println("############################## FULL ################################")
  185. fmt.Println(trie.root)
  186. trie.Commit()
  187. fmt.Println("############################## SMALL ################################")
  188. trie2 := New(trie.roothash, trie.cache.backend)
  189. trie2.GetString(base + "20")
  190. fmt.Println(trie2.root)
  191. }
  192. func BenchmarkGets(b *testing.B) {
  193. trie := NewEmpty()
  194. vals := []struct{ k, v string }{
  195. {"do", "verb"},
  196. {"ether", "wookiedoo"},
  197. {"horse", "stallion"},
  198. {"shaman", "horse"},
  199. {"doge", "coin"},
  200. {"ether", ""},
  201. {"dog", "puppy"},
  202. {"shaman", ""},
  203. {"somethingveryoddindeedthis is", "myothernodedata"},
  204. }
  205. for _, val := range vals {
  206. trie.UpdateString(val.k, val.v)
  207. }
  208. b.ResetTimer()
  209. for i := 0; i < b.N; i++ {
  210. trie.Get([]byte("horse"))
  211. }
  212. }
  213. func BenchmarkUpdate(b *testing.B) {
  214. trie := NewEmpty()
  215. b.ResetTimer()
  216. for i := 0; i < b.N; i++ {
  217. trie.UpdateString(fmt.Sprintf("aaaaaaaaa%d", i), "value")
  218. }
  219. trie.Hash()
  220. }