trie_test.go 14 KB

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