trie_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. package trie
  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 NewEmptySecure() *SecureTrie {
  17. return NewSecure(nil, make(Db))
  18. }
  19. func TestEmptyTrie(t *testing.T) {
  20. trie := NewEmpty()
  21. res := trie.Hash()
  22. exp := crypto.Sha3(ethutil.Encode(""))
  23. if !bytes.Equal(res, exp) {
  24. t.Errorf("expected %x got %x", exp, res)
  25. }
  26. }
  27. func TestInsert(t *testing.T) {
  28. trie := NewEmpty()
  29. trie.UpdateString("doe", "reindeer")
  30. trie.UpdateString("dog", "puppy")
  31. trie.UpdateString("dogglesworth", "cat")
  32. exp := ethutil.Hex2Bytes("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3")
  33. root := trie.Hash()
  34. if !bytes.Equal(root, exp) {
  35. t.Errorf("exp %x got %x", exp, root)
  36. }
  37. trie = NewEmpty()
  38. trie.UpdateString("A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
  39. exp = ethutil.Hex2Bytes("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab")
  40. root = trie.Hash()
  41. if !bytes.Equal(root, exp) {
  42. t.Errorf("exp %x got %x", exp, root)
  43. }
  44. }
  45. func TestGet(t *testing.T) {
  46. trie := NewEmpty()
  47. trie.UpdateString("doe", "reindeer")
  48. trie.UpdateString("dog", "puppy")
  49. trie.UpdateString("dogglesworth", "cat")
  50. res := trie.GetString("dog")
  51. if !bytes.Equal(res, []byte("puppy")) {
  52. t.Errorf("expected puppy got %x", res)
  53. }
  54. unknown := trie.GetString("unknown")
  55. if unknown != nil {
  56. t.Errorf("expected nil got %x", unknown)
  57. }
  58. }
  59. func TestDelete(t *testing.T) {
  60. trie := NewEmpty()
  61. vals := []struct{ k, v string }{
  62. {"do", "verb"},
  63. {"ether", "wookiedoo"},
  64. {"horse", "stallion"},
  65. {"shaman", "horse"},
  66. {"doge", "coin"},
  67. {"ether", ""},
  68. {"dog", "puppy"},
  69. {"shaman", ""},
  70. }
  71. for _, val := range vals {
  72. if val.v != "" {
  73. trie.UpdateString(val.k, val.v)
  74. } else {
  75. trie.DeleteString(val.k)
  76. }
  77. }
  78. hash := trie.Hash()
  79. exp := ethutil.Hex2Bytes("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
  80. if !bytes.Equal(hash, exp) {
  81. t.Errorf("expected %x got %x", exp, hash)
  82. }
  83. }
  84. func TestEmptyValues(t *testing.T) {
  85. trie := NewEmpty()
  86. vals := []struct{ k, v string }{
  87. {"do", "verb"},
  88. {"ether", "wookiedoo"},
  89. {"horse", "stallion"},
  90. {"shaman", "horse"},
  91. {"doge", "coin"},
  92. {"ether", ""},
  93. {"dog", "puppy"},
  94. {"shaman", ""},
  95. }
  96. for _, val := range vals {
  97. trie.UpdateString(val.k, val.v)
  98. }
  99. hash := trie.Hash()
  100. exp := ethutil.Hex2Bytes("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
  101. if !bytes.Equal(hash, exp) {
  102. t.Errorf("expected %x got %x", exp, hash)
  103. }
  104. }
  105. func TestReplication(t *testing.T) {
  106. trie := NewEmpty()
  107. vals := []struct{ k, v string }{
  108. {"do", "verb"},
  109. {"ether", "wookiedoo"},
  110. {"horse", "stallion"},
  111. {"shaman", "horse"},
  112. {"doge", "coin"},
  113. {"ether", ""},
  114. {"dog", "puppy"},
  115. {"shaman", ""},
  116. {"somethingveryoddindeedthis is", "myothernodedata"},
  117. }
  118. for _, val := range vals {
  119. trie.UpdateString(val.k, val.v)
  120. }
  121. trie.Commit()
  122. trie2 := New(trie.roothash, trie.cache.backend)
  123. if string(trie2.GetString("horse")) != "stallion" {
  124. t.Error("expected to have horse => stallion")
  125. }
  126. hash := trie2.Hash()
  127. exp := trie.Hash()
  128. if !bytes.Equal(hash, exp) {
  129. t.Errorf("root failure. expected %x got %x", exp, hash)
  130. }
  131. }
  132. func TestReset(t *testing.T) {
  133. trie := NewEmpty()
  134. vals := []struct{ k, v string }{
  135. {"do", "verb"},
  136. {"ether", "wookiedoo"},
  137. {"horse", "stallion"},
  138. }
  139. for _, val := range vals {
  140. trie.UpdateString(val.k, val.v)
  141. }
  142. trie.Commit()
  143. before := ethutil.CopyBytes(trie.roothash)
  144. trie.UpdateString("should", "revert")
  145. trie.Hash()
  146. // Should have no effect
  147. trie.Hash()
  148. trie.Hash()
  149. // ###
  150. trie.Reset()
  151. after := ethutil.CopyBytes(trie.roothash)
  152. if !bytes.Equal(before, after) {
  153. t.Errorf("expected roots to be equal. %x - %x", before, after)
  154. }
  155. }
  156. func TestParanoia(t *testing.T) {
  157. t.Skip()
  158. trie := NewEmpty()
  159. vals := []struct{ k, v string }{
  160. {"do", "verb"},
  161. {"ether", "wookiedoo"},
  162. {"horse", "stallion"},
  163. {"shaman", "horse"},
  164. {"doge", "coin"},
  165. {"ether", ""},
  166. {"dog", "puppy"},
  167. {"shaman", ""},
  168. {"somethingveryoddindeedthis is", "myothernodedata"},
  169. }
  170. for _, val := range vals {
  171. trie.UpdateString(val.k, val.v)
  172. }
  173. trie.Commit()
  174. ok, t2 := ParanoiaCheck(trie, trie.cache.backend)
  175. if !ok {
  176. t.Errorf("trie paranoia check failed %x %x", trie.roothash, t2.roothash)
  177. }
  178. }
  179. // Not an actual test
  180. func TestOutput(t *testing.T) {
  181. t.Skip()
  182. base := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  183. trie := NewEmpty()
  184. for i := 0; i < 50; i++ {
  185. trie.UpdateString(fmt.Sprintf("%s%d", base, i), "valueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
  186. }
  187. fmt.Println("############################## FULL ################################")
  188. fmt.Println(trie.root)
  189. trie.Commit()
  190. fmt.Println("############################## SMALL ################################")
  191. trie2 := New(trie.roothash, trie.cache.backend)
  192. trie2.GetString(base + "20")
  193. fmt.Println(trie2.root)
  194. }
  195. func BenchmarkGets(b *testing.B) {
  196. trie := NewEmpty()
  197. vals := []struct{ k, v string }{
  198. {"do", "verb"},
  199. {"ether", "wookiedoo"},
  200. {"horse", "stallion"},
  201. {"shaman", "horse"},
  202. {"doge", "coin"},
  203. {"ether", ""},
  204. {"dog", "puppy"},
  205. {"shaman", ""},
  206. {"somethingveryoddindeedthis is", "myothernodedata"},
  207. }
  208. for _, val := range vals {
  209. trie.UpdateString(val.k, val.v)
  210. }
  211. b.ResetTimer()
  212. for i := 0; i < b.N; i++ {
  213. trie.Get([]byte("horse"))
  214. }
  215. }
  216. func BenchmarkUpdate(b *testing.B) {
  217. trie := NewEmpty()
  218. b.ResetTimer()
  219. for i := 0; i < b.N; i++ {
  220. trie.UpdateString(fmt.Sprintf("aaaaaaaaa%d", i), "value")
  221. }
  222. trie.Hash()
  223. }
  224. type kv struct {
  225. k, v []byte
  226. t bool
  227. }
  228. func TestLargeData(t *testing.T) {
  229. trie := NewEmpty()
  230. vals := make(map[string]*kv)
  231. for i := byte(0); i < 255; i++ {
  232. value := &kv{ethutil.LeftPadBytes([]byte{i}, 32), []byte{i}, false}
  233. value2 := &kv{ethutil.LeftPadBytes([]byte{10, i}, 32), []byte{i}, false}
  234. trie.Update(value.k, value.v)
  235. trie.Update(value2.k, value2.v)
  236. vals[string(value.k)] = value
  237. vals[string(value2.k)] = value2
  238. }
  239. it := trie.Iterator()
  240. for it.Next() {
  241. vals[string(it.Key)].t = true
  242. }
  243. var untouched []*kv
  244. for _, value := range vals {
  245. if !value.t {
  246. untouched = append(untouched, value)
  247. }
  248. }
  249. if len(untouched) > 0 {
  250. t.Errorf("Missed %d nodes", len(untouched))
  251. for _, value := range untouched {
  252. t.Error(value)
  253. }
  254. }
  255. }
  256. func TestSecureDelete(t *testing.T) {
  257. trie := NewEmptySecure()
  258. vals := []struct{ k, v string }{
  259. {"do", "verb"},
  260. {"ether", "wookiedoo"},
  261. {"horse", "stallion"},
  262. {"shaman", "horse"},
  263. {"doge", "coin"},
  264. {"ether", ""},
  265. {"dog", "puppy"},
  266. {"shaman", ""},
  267. }
  268. for _, val := range vals {
  269. if val.v != "" {
  270. trie.UpdateString(val.k, val.v)
  271. } else {
  272. trie.DeleteString(val.k)
  273. }
  274. }
  275. hash := trie.Hash()
  276. exp := ethutil.Hex2Bytes("29b235a58c3c25ab83010c327d5932bcf05324b7d6b1185e650798034783ca9d")
  277. if !bytes.Equal(hash, exp) {
  278. t.Errorf("expected %x got %x", exp, hash)
  279. }
  280. }