trie_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. // Copyright 2014 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. "encoding/binary"
  20. "fmt"
  21. "io/ioutil"
  22. "math/rand"
  23. "os"
  24. "reflect"
  25. "testing"
  26. "testing/quick"
  27. "github.com/davecgh/go-spew/spew"
  28. "github.com/ethereum/go-ethereum/common"
  29. "github.com/ethereum/go-ethereum/ethdb"
  30. )
  31. func init() {
  32. spew.Config.Indent = " "
  33. spew.Config.DisableMethods = true
  34. }
  35. // Used for testing
  36. func newEmpty() *Trie {
  37. db, _ := ethdb.NewMemDatabase()
  38. trie, _ := New(common.Hash{}, db)
  39. return trie
  40. }
  41. func TestEmptyTrie(t *testing.T) {
  42. var trie Trie
  43. res := trie.Hash()
  44. exp := emptyRoot
  45. if res != common.Hash(exp) {
  46. t.Errorf("expected %x got %x", exp, res)
  47. }
  48. }
  49. func TestNull(t *testing.T) {
  50. var trie Trie
  51. key := make([]byte, 32)
  52. value := []byte("test")
  53. trie.Update(key, value)
  54. if !bytes.Equal(trie.Get(key), value) {
  55. t.Fatal("wrong value")
  56. }
  57. }
  58. func TestMissingRoot(t *testing.T) {
  59. db, _ := ethdb.NewMemDatabase()
  60. trie, err := New(common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), db)
  61. if trie != nil {
  62. t.Error("New returned non-nil trie for invalid root")
  63. }
  64. if _, ok := err.(*MissingNodeError); !ok {
  65. t.Errorf("New returned wrong error: %v", err)
  66. }
  67. }
  68. func TestMissingNode(t *testing.T) {
  69. db, _ := ethdb.NewMemDatabase()
  70. trie, _ := New(common.Hash{}, db)
  71. updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer")
  72. updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf")
  73. root, _ := trie.Commit()
  74. trie, _ = New(root, db)
  75. _, err := trie.TryGet([]byte("120000"))
  76. if err != nil {
  77. t.Errorf("Unexpected error: %v", err)
  78. }
  79. trie, _ = New(root, db)
  80. _, err = trie.TryGet([]byte("120099"))
  81. if err != nil {
  82. t.Errorf("Unexpected error: %v", err)
  83. }
  84. trie, _ = New(root, db)
  85. _, err = trie.TryGet([]byte("123456"))
  86. if err != nil {
  87. t.Errorf("Unexpected error: %v", err)
  88. }
  89. trie, _ = New(root, db)
  90. err = trie.TryUpdate([]byte("120099"), []byte("zxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcv"))
  91. if err != nil {
  92. t.Errorf("Unexpected error: %v", err)
  93. }
  94. trie, _ = New(root, db)
  95. err = trie.TryDelete([]byte("123456"))
  96. if err != nil {
  97. t.Errorf("Unexpected error: %v", err)
  98. }
  99. db.Delete(common.FromHex("e1d943cc8f061a0c0b98162830b970395ac9315654824bf21b73b891365262f9"))
  100. trie, _ = New(root, db)
  101. _, err = trie.TryGet([]byte("120000"))
  102. if _, ok := err.(*MissingNodeError); !ok {
  103. t.Errorf("Wrong error: %v", err)
  104. }
  105. trie, _ = New(root, db)
  106. _, err = trie.TryGet([]byte("120099"))
  107. if _, ok := err.(*MissingNodeError); !ok {
  108. t.Errorf("Wrong error: %v", err)
  109. }
  110. trie, _ = New(root, db)
  111. _, err = trie.TryGet([]byte("123456"))
  112. if err != nil {
  113. t.Errorf("Unexpected error: %v", err)
  114. }
  115. trie, _ = New(root, db)
  116. err = trie.TryUpdate([]byte("120099"), []byte("zxcv"))
  117. if _, ok := err.(*MissingNodeError); !ok {
  118. t.Errorf("Wrong error: %v", err)
  119. }
  120. trie, _ = New(root, db)
  121. err = trie.TryDelete([]byte("123456"))
  122. if _, ok := err.(*MissingNodeError); !ok {
  123. t.Errorf("Wrong error: %v", err)
  124. }
  125. }
  126. func TestInsert(t *testing.T) {
  127. trie := newEmpty()
  128. updateString(trie, "doe", "reindeer")
  129. updateString(trie, "dog", "puppy")
  130. updateString(trie, "dogglesworth", "cat")
  131. exp := common.HexToHash("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3")
  132. root := trie.Hash()
  133. if root != exp {
  134. t.Errorf("exp %x got %x", exp, root)
  135. }
  136. trie = newEmpty()
  137. updateString(trie, "A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
  138. exp = common.HexToHash("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab")
  139. root, err := trie.Commit()
  140. if err != nil {
  141. t.Fatalf("commit error: %v", err)
  142. }
  143. if root != exp {
  144. t.Errorf("exp %x got %x", exp, root)
  145. }
  146. }
  147. func TestGet(t *testing.T) {
  148. trie := newEmpty()
  149. updateString(trie, "doe", "reindeer")
  150. updateString(trie, "dog", "puppy")
  151. updateString(trie, "dogglesworth", "cat")
  152. for i := 0; i < 2; i++ {
  153. res := getString(trie, "dog")
  154. if !bytes.Equal(res, []byte("puppy")) {
  155. t.Errorf("expected puppy got %x", res)
  156. }
  157. unknown := getString(trie, "unknown")
  158. if unknown != nil {
  159. t.Errorf("expected nil got %x", unknown)
  160. }
  161. if i == 1 {
  162. return
  163. }
  164. trie.Commit()
  165. }
  166. }
  167. func TestDelete(t *testing.T) {
  168. trie := newEmpty()
  169. vals := []struct{ k, v string }{
  170. {"do", "verb"},
  171. {"ether", "wookiedoo"},
  172. {"horse", "stallion"},
  173. {"shaman", "horse"},
  174. {"doge", "coin"},
  175. {"ether", ""},
  176. {"dog", "puppy"},
  177. {"shaman", ""},
  178. }
  179. for _, val := range vals {
  180. if val.v != "" {
  181. updateString(trie, val.k, val.v)
  182. } else {
  183. deleteString(trie, val.k)
  184. }
  185. }
  186. hash := trie.Hash()
  187. exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
  188. if hash != exp {
  189. t.Errorf("expected %x got %x", exp, hash)
  190. }
  191. }
  192. func TestEmptyValues(t *testing.T) {
  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. }
  204. for _, val := range vals {
  205. updateString(trie, val.k, val.v)
  206. }
  207. hash := trie.Hash()
  208. exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
  209. if hash != exp {
  210. t.Errorf("expected %x got %x", exp, hash)
  211. }
  212. }
  213. func TestReplication(t *testing.T) {
  214. trie := newEmpty()
  215. vals := []struct{ k, v string }{
  216. {"do", "verb"},
  217. {"ether", "wookiedoo"},
  218. {"horse", "stallion"},
  219. {"shaman", "horse"},
  220. {"doge", "coin"},
  221. {"dog", "puppy"},
  222. {"somethingveryoddindeedthis is", "myothernodedata"},
  223. }
  224. for _, val := range vals {
  225. updateString(trie, val.k, val.v)
  226. }
  227. exp, err := trie.Commit()
  228. if err != nil {
  229. t.Fatalf("commit error: %v", err)
  230. }
  231. // create a new trie on top of the database and check that lookups work.
  232. trie2, err := New(exp, trie.db)
  233. if err != nil {
  234. t.Fatalf("can't recreate trie at %x: %v", exp, err)
  235. }
  236. for _, kv := range vals {
  237. if string(getString(trie2, kv.k)) != kv.v {
  238. t.Errorf("trie2 doesn't have %q => %q", kv.k, kv.v)
  239. }
  240. }
  241. hash, err := trie2.Commit()
  242. if err != nil {
  243. t.Fatalf("commit error: %v", err)
  244. }
  245. if hash != exp {
  246. t.Errorf("root failure. expected %x got %x", exp, hash)
  247. }
  248. // perform some insertions on the new trie.
  249. vals2 := []struct{ k, v string }{
  250. {"do", "verb"},
  251. {"ether", "wookiedoo"},
  252. {"horse", "stallion"},
  253. // {"shaman", "horse"},
  254. // {"doge", "coin"},
  255. // {"ether", ""},
  256. // {"dog", "puppy"},
  257. // {"somethingveryoddindeedthis is", "myothernodedata"},
  258. // {"shaman", ""},
  259. }
  260. for _, val := range vals2 {
  261. updateString(trie2, val.k, val.v)
  262. }
  263. if hash := trie2.Hash(); hash != exp {
  264. t.Errorf("root failure. expected %x got %x", exp, hash)
  265. }
  266. }
  267. func TestLargeValue(t *testing.T) {
  268. trie := newEmpty()
  269. trie.Update([]byte("key1"), []byte{99, 99, 99, 99})
  270. trie.Update([]byte("key2"), bytes.Repeat([]byte{1}, 32))
  271. trie.Hash()
  272. }
  273. type countingDB struct {
  274. Database
  275. gets map[string]int
  276. }
  277. func (db *countingDB) Get(key []byte) ([]byte, error) {
  278. db.gets[string(key)]++
  279. return db.Database.Get(key)
  280. }
  281. // TestCacheUnload checks that decoded nodes are unloaded after a
  282. // certain number of commit operations.
  283. func TestCacheUnload(t *testing.T) {
  284. // Create test trie with two branches.
  285. trie := newEmpty()
  286. key1 := "---------------------------------"
  287. key2 := "---some other branch"
  288. updateString(trie, key1, "this is the branch of key1.")
  289. updateString(trie, key2, "this is the branch of key2.")
  290. root, _ := trie.Commit()
  291. // Commit the trie repeatedly and access key1.
  292. // The branch containing it is loaded from DB exactly two times:
  293. // in the 0th and 6th iteration.
  294. db := &countingDB{Database: trie.db, gets: make(map[string]int)}
  295. trie, _ = New(root, db)
  296. trie.SetCacheLimit(5)
  297. for i := 0; i < 12; i++ {
  298. getString(trie, key1)
  299. trie.Commit()
  300. }
  301. // Check that it got loaded two times.
  302. for dbkey, count := range db.gets {
  303. if count != 2 {
  304. t.Errorf("db key %x loaded %d times, want %d times", []byte(dbkey), count, 2)
  305. }
  306. }
  307. }
  308. // randTest performs random trie operations.
  309. // Instances of this test are created by Generate.
  310. type randTest []randTestStep
  311. type randTestStep struct {
  312. op int
  313. key []byte // for opUpdate, opDelete, opGet
  314. value []byte // for opUpdate
  315. }
  316. const (
  317. opUpdate = iota
  318. opDelete
  319. opGet
  320. opCommit
  321. opHash
  322. opReset
  323. opItercheckhash
  324. opCheckCacheInvariant
  325. opMax // boundary value, not an actual op
  326. )
  327. func (randTest) Generate(r *rand.Rand, size int) reflect.Value {
  328. var allKeys [][]byte
  329. genKey := func() []byte {
  330. if len(allKeys) < 2 || r.Intn(100) < 10 {
  331. // new key
  332. key := make([]byte, r.Intn(50))
  333. randRead(r, key)
  334. allKeys = append(allKeys, key)
  335. return key
  336. }
  337. // use existing key
  338. return allKeys[r.Intn(len(allKeys))]
  339. }
  340. var steps randTest
  341. for i := 0; i < size; i++ {
  342. step := randTestStep{op: r.Intn(opMax)}
  343. switch step.op {
  344. case opUpdate:
  345. step.key = genKey()
  346. step.value = make([]byte, 8)
  347. binary.BigEndian.PutUint64(step.value, uint64(i))
  348. case opGet, opDelete:
  349. step.key = genKey()
  350. }
  351. steps = append(steps, step)
  352. }
  353. return reflect.ValueOf(steps)
  354. }
  355. // rand.Rand provides a Read method in Go 1.7 and later, but
  356. // we can't use it yet.
  357. func randRead(r *rand.Rand, b []byte) {
  358. pos := 0
  359. val := 0
  360. for n := 0; n < len(b); n++ {
  361. if pos == 0 {
  362. val = r.Int()
  363. pos = 7
  364. }
  365. b[n] = byte(val)
  366. val >>= 8
  367. pos--
  368. }
  369. }
  370. func runRandTest(rt randTest) bool {
  371. db, _ := ethdb.NewMemDatabase()
  372. tr, _ := New(common.Hash{}, db)
  373. values := make(map[string]string) // tracks content of the trie
  374. for _, step := range rt {
  375. switch step.op {
  376. case opUpdate:
  377. tr.Update(step.key, step.value)
  378. values[string(step.key)] = string(step.value)
  379. case opDelete:
  380. tr.Delete(step.key)
  381. delete(values, string(step.key))
  382. case opGet:
  383. v := tr.Get(step.key)
  384. want := values[string(step.key)]
  385. if string(v) != want {
  386. fmt.Printf("mismatch for key 0x%x, got 0x%x want 0x%x", step.key, v, want)
  387. return false
  388. }
  389. case opCommit:
  390. if _, err := tr.Commit(); err != nil {
  391. panic(err)
  392. }
  393. case opHash:
  394. tr.Hash()
  395. case opReset:
  396. hash, err := tr.Commit()
  397. if err != nil {
  398. panic(err)
  399. }
  400. newtr, err := New(hash, db)
  401. if err != nil {
  402. panic(err)
  403. }
  404. tr = newtr
  405. case opItercheckhash:
  406. checktr, _ := New(common.Hash{}, nil)
  407. it := tr.Iterator()
  408. for it.Next() {
  409. checktr.Update(it.Key, it.Value)
  410. }
  411. if tr.Hash() != checktr.Hash() {
  412. fmt.Println("hashes not equal")
  413. return false
  414. }
  415. case opCheckCacheInvariant:
  416. return checkCacheInvariant(tr.root, nil, tr.cachegen, false, 0)
  417. }
  418. }
  419. return true
  420. }
  421. func checkCacheInvariant(n, parent node, parentCachegen uint16, parentDirty bool, depth int) bool {
  422. var children []node
  423. var flag nodeFlag
  424. switch n := n.(type) {
  425. case *shortNode:
  426. flag = n.flags
  427. children = []node{n.Val}
  428. case *fullNode:
  429. flag = n.flags
  430. children = n.Children[:]
  431. default:
  432. return true
  433. }
  434. showerror := func() {
  435. fmt.Printf("at depth %d node %s", depth, spew.Sdump(n))
  436. fmt.Printf("parent: %s", spew.Sdump(parent))
  437. }
  438. if flag.gen > parentCachegen {
  439. fmt.Printf("cache invariant violation: %d > %d\n", flag.gen, parentCachegen)
  440. showerror()
  441. return false
  442. }
  443. if depth > 0 && !parentDirty && flag.dirty {
  444. fmt.Printf("cache invariant violation: child is dirty but parent isn't\n")
  445. showerror()
  446. return false
  447. }
  448. for _, child := range children {
  449. if !checkCacheInvariant(child, n, flag.gen, flag.dirty, depth+1) {
  450. return false
  451. }
  452. }
  453. return true
  454. }
  455. func TestRandom(t *testing.T) {
  456. if err := quick.Check(runRandTest, nil); err != nil {
  457. t.Fatal(err)
  458. }
  459. }
  460. func BenchmarkGet(b *testing.B) { benchGet(b, false) }
  461. func BenchmarkGetDB(b *testing.B) { benchGet(b, true) }
  462. func BenchmarkUpdateBE(b *testing.B) { benchUpdate(b, binary.BigEndian) }
  463. func BenchmarkUpdateLE(b *testing.B) { benchUpdate(b, binary.LittleEndian) }
  464. func BenchmarkHashBE(b *testing.B) { benchHash(b, binary.BigEndian) }
  465. func BenchmarkHashLE(b *testing.B) { benchHash(b, binary.LittleEndian) }
  466. const benchElemCount = 20000
  467. func benchGet(b *testing.B, commit bool) {
  468. trie := new(Trie)
  469. if commit {
  470. _, tmpdb := tempDB()
  471. trie, _ = New(common.Hash{}, tmpdb)
  472. }
  473. k := make([]byte, 32)
  474. for i := 0; i < benchElemCount; i++ {
  475. binary.LittleEndian.PutUint64(k, uint64(i))
  476. trie.Update(k, k)
  477. }
  478. binary.LittleEndian.PutUint64(k, benchElemCount/2)
  479. if commit {
  480. trie.Commit()
  481. }
  482. b.ResetTimer()
  483. for i := 0; i < b.N; i++ {
  484. trie.Get(k)
  485. }
  486. b.StopTimer()
  487. if commit {
  488. ldb := trie.db.(*ethdb.LDBDatabase)
  489. ldb.Close()
  490. os.RemoveAll(ldb.Path())
  491. }
  492. }
  493. func benchUpdate(b *testing.B, e binary.ByteOrder) *Trie {
  494. trie := newEmpty()
  495. k := make([]byte, 32)
  496. for i := 0; i < b.N; i++ {
  497. e.PutUint64(k, uint64(i))
  498. trie.Update(k, k)
  499. }
  500. return trie
  501. }
  502. func benchHash(b *testing.B, e binary.ByteOrder) {
  503. trie := newEmpty()
  504. k := make([]byte, 32)
  505. for i := 0; i < benchElemCount; i++ {
  506. e.PutUint64(k, uint64(i))
  507. trie.Update(k, k)
  508. }
  509. b.ResetTimer()
  510. for i := 0; i < b.N; i++ {
  511. trie.Hash()
  512. }
  513. }
  514. func tempDB() (string, Database) {
  515. dir, err := ioutil.TempDir("", "trie-bench")
  516. if err != nil {
  517. panic(fmt.Sprintf("can't create temporary directory: %v", err))
  518. }
  519. db, err := ethdb.NewLDBDatabase(dir, 256, 0)
  520. if err != nil {
  521. panic(fmt.Sprintf("can't create temporary database: %v", err))
  522. }
  523. return dir, db
  524. }
  525. func getString(trie *Trie, k string) []byte {
  526. return trie.Get([]byte(k))
  527. }
  528. func updateString(trie *Trie, k, v string) {
  529. trie.Update([]byte(k), []byte(v))
  530. }
  531. func deleteString(trie *Trie, k string) {
  532. trie.Delete([]byte(k))
  533. }