trie_test.go 15 KB

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