trie_test.go 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130
  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. "hash"
  23. "math/big"
  24. "math/rand"
  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/core/rawdb"
  31. "github.com/ethereum/go-ethereum/core/types"
  32. "github.com/ethereum/go-ethereum/crypto"
  33. "github.com/ethereum/go-ethereum/ethdb"
  34. "github.com/ethereum/go-ethereum/ethdb/memorydb"
  35. "github.com/ethereum/go-ethereum/rlp"
  36. "golang.org/x/crypto/sha3"
  37. )
  38. func init() {
  39. spew.Config.Indent = " "
  40. spew.Config.DisableMethods = false
  41. }
  42. func TestEmptyTrie(t *testing.T) {
  43. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  44. res := trie.Hash()
  45. exp := emptyRoot
  46. if res != exp {
  47. t.Errorf("expected %x got %x", exp, res)
  48. }
  49. }
  50. func TestNull(t *testing.T) {
  51. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  52. key := make([]byte, 32)
  53. value := []byte("test")
  54. trie.Update(key, value)
  55. if !bytes.Equal(trie.Get(key), value) {
  56. t.Fatal("wrong value")
  57. }
  58. }
  59. func TestMissingRoot(t *testing.T) {
  60. trie, err := New(common.Hash{}, common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), NewDatabase(memorydb.New()))
  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 TestMissingNodeDisk(t *testing.T) { testMissingNode(t, false) }
  69. func TestMissingNodeMemonly(t *testing.T) { testMissingNode(t, true) }
  70. func testMissingNode(t *testing.T, memonly bool) {
  71. diskdb := memorydb.New()
  72. triedb := NewDatabase(diskdb)
  73. trie := NewEmpty(triedb)
  74. updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer")
  75. updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf")
  76. root, nodes, _ := trie.Commit(false)
  77. triedb.Update(NewWithNodeSet(nodes))
  78. if !memonly {
  79. triedb.Commit(root, true, nil)
  80. }
  81. trie, _ = New(common.Hash{}, root, triedb)
  82. _, err := trie.TryGet([]byte("120000"))
  83. if err != nil {
  84. t.Errorf("Unexpected error: %v", err)
  85. }
  86. trie, _ = New(common.Hash{}, root, triedb)
  87. _, err = trie.TryGet([]byte("120099"))
  88. if err != nil {
  89. t.Errorf("Unexpected error: %v", err)
  90. }
  91. trie, _ = New(common.Hash{}, root, triedb)
  92. _, err = trie.TryGet([]byte("123456"))
  93. if err != nil {
  94. t.Errorf("Unexpected error: %v", err)
  95. }
  96. trie, _ = New(common.Hash{}, root, triedb)
  97. err = trie.TryUpdate([]byte("120099"), []byte("zxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcv"))
  98. if err != nil {
  99. t.Errorf("Unexpected error: %v", err)
  100. }
  101. trie, _ = New(common.Hash{}, root, triedb)
  102. err = trie.TryDelete([]byte("123456"))
  103. if err != nil {
  104. t.Errorf("Unexpected error: %v", err)
  105. }
  106. hash := common.HexToHash("0xe1d943cc8f061a0c0b98162830b970395ac9315654824bf21b73b891365262f9")
  107. if memonly {
  108. delete(triedb.dirties, hash)
  109. } else {
  110. diskdb.Delete(hash[:])
  111. }
  112. trie, _ = New(common.Hash{}, root, triedb)
  113. _, err = trie.TryGet([]byte("120000"))
  114. if _, ok := err.(*MissingNodeError); !ok {
  115. t.Errorf("Wrong error: %v", err)
  116. }
  117. trie, _ = New(common.Hash{}, root, triedb)
  118. _, err = trie.TryGet([]byte("120099"))
  119. if _, ok := err.(*MissingNodeError); !ok {
  120. t.Errorf("Wrong error: %v", err)
  121. }
  122. trie, _ = New(common.Hash{}, root, triedb)
  123. _, err = trie.TryGet([]byte("123456"))
  124. if err != nil {
  125. t.Errorf("Unexpected error: %v", err)
  126. }
  127. trie, _ = New(common.Hash{}, root, triedb)
  128. err = trie.TryUpdate([]byte("120099"), []byte("zxcv"))
  129. if _, ok := err.(*MissingNodeError); !ok {
  130. t.Errorf("Wrong error: %v", err)
  131. }
  132. trie, _ = New(common.Hash{}, root, triedb)
  133. err = trie.TryDelete([]byte("123456"))
  134. if _, ok := err.(*MissingNodeError); !ok {
  135. t.Errorf("Wrong error: %v", err)
  136. }
  137. }
  138. func TestInsert(t *testing.T) {
  139. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  140. updateString(trie, "doe", "reindeer")
  141. updateString(trie, "dog", "puppy")
  142. updateString(trie, "dogglesworth", "cat")
  143. exp := common.HexToHash("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3")
  144. root := trie.Hash()
  145. if root != exp {
  146. t.Errorf("case 1: exp %x got %x", exp, root)
  147. }
  148. trie = NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  149. updateString(trie, "A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
  150. exp = common.HexToHash("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab")
  151. root, _, err := trie.Commit(false)
  152. if err != nil {
  153. t.Fatalf("commit error: %v", err)
  154. }
  155. if root != exp {
  156. t.Errorf("case 2: exp %x got %x", exp, root)
  157. }
  158. }
  159. func TestGet(t *testing.T) {
  160. db := NewDatabase(rawdb.NewMemoryDatabase())
  161. trie := NewEmpty(db)
  162. updateString(trie, "doe", "reindeer")
  163. updateString(trie, "dog", "puppy")
  164. updateString(trie, "dogglesworth", "cat")
  165. for i := 0; i < 2; i++ {
  166. res := getString(trie, "dog")
  167. if !bytes.Equal(res, []byte("puppy")) {
  168. t.Errorf("expected puppy got %x", res)
  169. }
  170. unknown := getString(trie, "unknown")
  171. if unknown != nil {
  172. t.Errorf("expected nil got %x", unknown)
  173. }
  174. if i == 1 {
  175. return
  176. }
  177. root, nodes, _ := trie.Commit(false)
  178. db.Update(NewWithNodeSet(nodes))
  179. trie, _ = New(common.Hash{}, root, db)
  180. }
  181. }
  182. func TestDelete(t *testing.T) {
  183. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  184. vals := []struct{ k, v string }{
  185. {"do", "verb"},
  186. {"ether", "wookiedoo"},
  187. {"horse", "stallion"},
  188. {"shaman", "horse"},
  189. {"doge", "coin"},
  190. {"ether", ""},
  191. {"dog", "puppy"},
  192. {"shaman", ""},
  193. }
  194. for _, val := range vals {
  195. if val.v != "" {
  196. updateString(trie, val.k, val.v)
  197. } else {
  198. deleteString(trie, val.k)
  199. }
  200. }
  201. hash := trie.Hash()
  202. exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
  203. if hash != exp {
  204. t.Errorf("expected %x got %x", exp, hash)
  205. }
  206. }
  207. func TestEmptyValues(t *testing.T) {
  208. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  209. vals := []struct{ k, v string }{
  210. {"do", "verb"},
  211. {"ether", "wookiedoo"},
  212. {"horse", "stallion"},
  213. {"shaman", "horse"},
  214. {"doge", "coin"},
  215. {"ether", ""},
  216. {"dog", "puppy"},
  217. {"shaman", ""},
  218. }
  219. for _, val := range vals {
  220. updateString(trie, val.k, val.v)
  221. }
  222. hash := trie.Hash()
  223. exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
  224. if hash != exp {
  225. t.Errorf("expected %x got %x", exp, hash)
  226. }
  227. }
  228. func TestReplication(t *testing.T) {
  229. triedb := NewDatabase(rawdb.NewMemoryDatabase())
  230. trie := NewEmpty(triedb)
  231. vals := []struct{ k, v string }{
  232. {"do", "verb"},
  233. {"ether", "wookiedoo"},
  234. {"horse", "stallion"},
  235. {"shaman", "horse"},
  236. {"doge", "coin"},
  237. {"dog", "puppy"},
  238. {"somethingveryoddindeedthis is", "myothernodedata"},
  239. }
  240. for _, val := range vals {
  241. updateString(trie, val.k, val.v)
  242. }
  243. exp, nodes, err := trie.Commit(false)
  244. if err != nil {
  245. t.Fatalf("commit error: %v", err)
  246. }
  247. triedb.Update(NewWithNodeSet(nodes))
  248. // create a new trie on top of the database and check that lookups work.
  249. trie2, err := New(common.Hash{}, exp, triedb)
  250. if err != nil {
  251. t.Fatalf("can't recreate trie at %x: %v", exp, err)
  252. }
  253. for _, kv := range vals {
  254. if string(getString(trie2, kv.k)) != kv.v {
  255. t.Errorf("trie2 doesn't have %q => %q", kv.k, kv.v)
  256. }
  257. }
  258. hash, nodes, err := trie2.Commit(false)
  259. if err != nil {
  260. t.Fatalf("commit error: %v", err)
  261. }
  262. if hash != exp {
  263. t.Errorf("root failure. expected %x got %x", exp, hash)
  264. }
  265. // recreate the trie after commit
  266. if nodes != nil {
  267. triedb.Update(NewWithNodeSet(nodes))
  268. }
  269. trie2, err = New(common.Hash{}, hash, triedb)
  270. if err != nil {
  271. t.Fatalf("can't recreate trie at %x: %v", exp, err)
  272. }
  273. // perform some insertions on the new trie.
  274. vals2 := []struct{ k, v string }{
  275. {"do", "verb"},
  276. {"ether", "wookiedoo"},
  277. {"horse", "stallion"},
  278. // {"shaman", "horse"},
  279. // {"doge", "coin"},
  280. // {"ether", ""},
  281. // {"dog", "puppy"},
  282. // {"somethingveryoddindeedthis is", "myothernodedata"},
  283. // {"shaman", ""},
  284. }
  285. for _, val := range vals2 {
  286. updateString(trie2, val.k, val.v)
  287. }
  288. if hash := trie2.Hash(); hash != exp {
  289. t.Errorf("root failure. expected %x got %x", exp, hash)
  290. }
  291. }
  292. func TestLargeValue(t *testing.T) {
  293. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  294. trie.Update([]byte("key1"), []byte{99, 99, 99, 99})
  295. trie.Update([]byte("key2"), bytes.Repeat([]byte{1}, 32))
  296. trie.Hash()
  297. }
  298. // TestRandomCases tests som cases that were found via random fuzzing
  299. func TestRandomCases(t *testing.T) {
  300. var rt = []randTestStep{
  301. {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 0
  302. {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 1
  303. {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000002")}, // step 2
  304. {op: 2, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("")}, // step 3
  305. {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 4
  306. {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 5
  307. {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 6
  308. {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 7
  309. {op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000008")}, // step 8
  310. {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000009")}, // step 9
  311. {op: 2, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("")}, // step 10
  312. {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 11
  313. {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 12
  314. {op: 0, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("000000000000000d")}, // step 13
  315. {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 14
  316. {op: 1, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("")}, // step 15
  317. {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 16
  318. {op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000011")}, // step 17
  319. {op: 5, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 18
  320. {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 19
  321. {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000014")}, // step 20
  322. {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000015")}, // step 21
  323. {op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000016")}, // step 22
  324. {op: 5, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 23
  325. {op: 1, key: common.Hex2Bytes("980c393656413a15c8da01978ed9f89feb80b502f58f2d640e3a2f5f7a99a7018f1b573befd92053ac6f78fca4a87268"), value: common.Hex2Bytes("")}, // step 24
  326. {op: 1, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("")}, // step 25
  327. }
  328. runRandTest(rt)
  329. }
  330. // randTest performs random trie operations.
  331. // Instances of this test are created by Generate.
  332. type randTest []randTestStep
  333. type randTestStep struct {
  334. op int
  335. key []byte // for opUpdate, opDelete, opGet
  336. value []byte // for opUpdate
  337. err error // for debugging
  338. }
  339. const (
  340. opUpdate = iota
  341. opDelete
  342. opGet
  343. opHash
  344. opCommit
  345. opItercheckhash
  346. opNodeDiff
  347. opMax // boundary value, not an actual op
  348. )
  349. func (randTest) Generate(r *rand.Rand, size int) reflect.Value {
  350. var allKeys [][]byte
  351. genKey := func() []byte {
  352. if len(allKeys) < 2 || r.Intn(100) < 10 {
  353. // new key
  354. key := make([]byte, r.Intn(50))
  355. r.Read(key)
  356. allKeys = append(allKeys, key)
  357. return key
  358. }
  359. // use existing key
  360. return allKeys[r.Intn(len(allKeys))]
  361. }
  362. var steps randTest
  363. for i := 0; i < size; i++ {
  364. step := randTestStep{op: r.Intn(opMax)}
  365. switch step.op {
  366. case opUpdate:
  367. step.key = genKey()
  368. step.value = make([]byte, 8)
  369. binary.BigEndian.PutUint64(step.value, uint64(i))
  370. case opGet, opDelete:
  371. step.key = genKey()
  372. }
  373. steps = append(steps, step)
  374. }
  375. return reflect.ValueOf(steps)
  376. }
  377. func runRandTest(rt randTest) bool {
  378. var (
  379. triedb = NewDatabase(memorydb.New())
  380. tr = NewEmpty(triedb)
  381. values = make(map[string]string) // tracks content of the trie
  382. origTrie = NewEmpty(triedb)
  383. )
  384. tr.tracer = newTracer()
  385. for i, step := range rt {
  386. // fmt.Printf("{op: %d, key: common.Hex2Bytes(\"%x\"), value: common.Hex2Bytes(\"%x\")}, // step %d\n",
  387. // step.op, step.key, step.value, i)
  388. switch step.op {
  389. case opUpdate:
  390. tr.Update(step.key, step.value)
  391. values[string(step.key)] = string(step.value)
  392. case opDelete:
  393. tr.Delete(step.key)
  394. delete(values, string(step.key))
  395. case opGet:
  396. v := tr.Get(step.key)
  397. want := values[string(step.key)]
  398. if string(v) != want {
  399. rt[i].err = fmt.Errorf("mismatch for key %#x, got %#x want %#x", step.key, v, want)
  400. }
  401. case opHash:
  402. tr.Hash()
  403. case opCommit:
  404. hash, nodes, err := tr.Commit(false)
  405. if err != nil {
  406. rt[i].err = err
  407. return false
  408. }
  409. if nodes != nil {
  410. triedb.Update(NewWithNodeSet(nodes))
  411. }
  412. newtr, err := New(common.Hash{}, hash, triedb)
  413. if err != nil {
  414. rt[i].err = err
  415. return false
  416. }
  417. tr = newtr
  418. tr.tracer = newTracer()
  419. origTrie = tr.Copy()
  420. case opItercheckhash:
  421. checktr := NewEmpty(triedb)
  422. it := NewIterator(tr.NodeIterator(nil))
  423. for it.Next() {
  424. checktr.Update(it.Key, it.Value)
  425. }
  426. if tr.Hash() != checktr.Hash() {
  427. rt[i].err = fmt.Errorf("hash mismatch in opItercheckhash")
  428. }
  429. case opNodeDiff:
  430. var (
  431. inserted = tr.tracer.insertList()
  432. deleted = tr.tracer.deleteList()
  433. origIter = origTrie.NodeIterator(nil)
  434. curIter = tr.NodeIterator(nil)
  435. origSeen = make(map[string]struct{})
  436. curSeen = make(map[string]struct{})
  437. )
  438. for origIter.Next(true) {
  439. if origIter.Leaf() {
  440. continue
  441. }
  442. origSeen[string(origIter.Path())] = struct{}{}
  443. }
  444. for curIter.Next(true) {
  445. if curIter.Leaf() {
  446. continue
  447. }
  448. curSeen[string(curIter.Path())] = struct{}{}
  449. }
  450. var (
  451. insertExp = make(map[string]struct{})
  452. deleteExp = make(map[string]struct{})
  453. )
  454. for path := range curSeen {
  455. _, present := origSeen[path]
  456. if !present {
  457. insertExp[path] = struct{}{}
  458. }
  459. }
  460. for path := range origSeen {
  461. _, present := curSeen[path]
  462. if !present {
  463. deleteExp[path] = struct{}{}
  464. }
  465. }
  466. if len(insertExp) != len(inserted) {
  467. rt[i].err = fmt.Errorf("insert set mismatch")
  468. }
  469. if len(deleteExp) != len(deleted) {
  470. rt[i].err = fmt.Errorf("delete set mismatch")
  471. }
  472. for _, insert := range inserted {
  473. if _, present := insertExp[string(insert)]; !present {
  474. rt[i].err = fmt.Errorf("missing inserted node")
  475. }
  476. }
  477. for _, del := range deleted {
  478. if _, present := deleteExp[string(del)]; !present {
  479. rt[i].err = fmt.Errorf("missing deleted node")
  480. }
  481. }
  482. }
  483. // Abort the test on error.
  484. if rt[i].err != nil {
  485. return false
  486. }
  487. }
  488. return true
  489. }
  490. func TestRandom(t *testing.T) {
  491. if err := quick.Check(runRandTest, nil); err != nil {
  492. if cerr, ok := err.(*quick.CheckError); ok {
  493. t.Fatalf("random test iteration %d failed: %s", cerr.Count, spew.Sdump(cerr.In))
  494. }
  495. t.Fatal(err)
  496. }
  497. }
  498. func BenchmarkGet(b *testing.B) { benchGet(b) }
  499. func BenchmarkUpdateBE(b *testing.B) { benchUpdate(b, binary.BigEndian) }
  500. func BenchmarkUpdateLE(b *testing.B) { benchUpdate(b, binary.LittleEndian) }
  501. const benchElemCount = 20000
  502. func benchGet(b *testing.B) {
  503. triedb := NewDatabase(rawdb.NewMemoryDatabase())
  504. trie := NewEmpty(triedb)
  505. k := make([]byte, 32)
  506. for i := 0; i < benchElemCount; i++ {
  507. binary.LittleEndian.PutUint64(k, uint64(i))
  508. trie.Update(k, k)
  509. }
  510. binary.LittleEndian.PutUint64(k, benchElemCount/2)
  511. b.ResetTimer()
  512. for i := 0; i < b.N; i++ {
  513. trie.Get(k)
  514. }
  515. b.StopTimer()
  516. }
  517. func benchUpdate(b *testing.B, e binary.ByteOrder) *Trie {
  518. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  519. k := make([]byte, 32)
  520. b.ReportAllocs()
  521. for i := 0; i < b.N; i++ {
  522. e.PutUint64(k, uint64(i))
  523. trie.Update(k, k)
  524. }
  525. return trie
  526. }
  527. // Benchmarks the trie hashing. Since the trie caches the result of any operation,
  528. // we cannot use b.N as the number of hashing rouns, since all rounds apart from
  529. // the first one will be NOOP. As such, we'll use b.N as the number of account to
  530. // insert into the trie before measuring the hashing.
  531. // BenchmarkHash-6 288680 4561 ns/op 682 B/op 9 allocs/op
  532. // BenchmarkHash-6 275095 4800 ns/op 685 B/op 9 allocs/op
  533. // pure hasher:
  534. // BenchmarkHash-6 319362 4230 ns/op 675 B/op 9 allocs/op
  535. // BenchmarkHash-6 257460 4674 ns/op 689 B/op 9 allocs/op
  536. // With hashing in-between and pure hasher:
  537. // BenchmarkHash-6 225417 7150 ns/op 982 B/op 12 allocs/op
  538. // BenchmarkHash-6 220378 6197 ns/op 983 B/op 12 allocs/op
  539. // same with old hasher
  540. // BenchmarkHash-6 229758 6437 ns/op 981 B/op 12 allocs/op
  541. // BenchmarkHash-6 212610 7137 ns/op 986 B/op 12 allocs/op
  542. func BenchmarkHash(b *testing.B) {
  543. // Create a realistic account trie to hash. We're first adding and hashing N
  544. // entries, then adding N more.
  545. addresses, accounts := makeAccounts(2 * b.N)
  546. // Insert the accounts into the trie and hash it
  547. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  548. i := 0
  549. for ; i < len(addresses)/2; i++ {
  550. trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
  551. }
  552. trie.Hash()
  553. for ; i < len(addresses); i++ {
  554. trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
  555. }
  556. b.ResetTimer()
  557. b.ReportAllocs()
  558. //trie.hashRoot(nil, nil)
  559. trie.Hash()
  560. }
  561. // Benchmarks the trie Commit following a Hash. Since the trie caches the result of any operation,
  562. // we cannot use b.N as the number of hashing rouns, since all rounds apart from
  563. // the first one will be NOOP. As such, we'll use b.N as the number of account to
  564. // insert into the trie before measuring the hashing.
  565. func BenchmarkCommitAfterHash(b *testing.B) {
  566. b.Run("no-onleaf", func(b *testing.B) {
  567. benchmarkCommitAfterHash(b, false)
  568. })
  569. b.Run("with-onleaf", func(b *testing.B) {
  570. benchmarkCommitAfterHash(b, true)
  571. })
  572. }
  573. func benchmarkCommitAfterHash(b *testing.B, collectLeaf bool) {
  574. // Make the random benchmark deterministic
  575. addresses, accounts := makeAccounts(b.N)
  576. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  577. for i := 0; i < len(addresses); i++ {
  578. trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
  579. }
  580. // Insert the accounts into the trie and hash it
  581. trie.Hash()
  582. b.ResetTimer()
  583. b.ReportAllocs()
  584. trie.Commit(collectLeaf)
  585. }
  586. func TestTinyTrie(t *testing.T) {
  587. // Create a realistic account trie to hash
  588. _, accounts := makeAccounts(5)
  589. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  590. trie.Update(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000001337"), accounts[3])
  591. if exp, root := common.HexToHash("8c6a85a4d9fda98feff88450299e574e5378e32391f75a055d470ac0653f1005"), trie.Hash(); exp != root {
  592. t.Errorf("1: got %x, exp %x", root, exp)
  593. }
  594. trie.Update(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000001338"), accounts[4])
  595. if exp, root := common.HexToHash("ec63b967e98a5720e7f720482151963982890d82c9093c0d486b7eb8883a66b1"), trie.Hash(); exp != root {
  596. t.Errorf("2: got %x, exp %x", root, exp)
  597. }
  598. trie.Update(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000001339"), accounts[4])
  599. if exp, root := common.HexToHash("0608c1d1dc3905fa22204c7a0e43644831c3b6d3def0f274be623a948197e64a"), trie.Hash(); exp != root {
  600. t.Errorf("3: got %x, exp %x", root, exp)
  601. }
  602. checktr := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  603. it := NewIterator(trie.NodeIterator(nil))
  604. for it.Next() {
  605. checktr.Update(it.Key, it.Value)
  606. }
  607. if troot, itroot := trie.Hash(), checktr.Hash(); troot != itroot {
  608. t.Fatalf("hash mismatch in opItercheckhash, trie: %x, check: %x", troot, itroot)
  609. }
  610. }
  611. func TestCommitAfterHash(t *testing.T) {
  612. // Create a realistic account trie to hash
  613. addresses, accounts := makeAccounts(1000)
  614. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  615. for i := 0; i < len(addresses); i++ {
  616. trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
  617. }
  618. // Insert the accounts into the trie and hash it
  619. trie.Hash()
  620. trie.Commit(false)
  621. root := trie.Hash()
  622. exp := common.HexToHash("72f9d3f3fe1e1dd7b8936442e7642aef76371472d94319900790053c493f3fe6")
  623. if exp != root {
  624. t.Errorf("got %x, exp %x", root, exp)
  625. }
  626. root, _, _ = trie.Commit(false)
  627. if exp != root {
  628. t.Errorf("got %x, exp %x", root, exp)
  629. }
  630. }
  631. func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
  632. // Make the random benchmark deterministic
  633. random := rand.New(rand.NewSource(0))
  634. // Create a realistic account trie to hash
  635. addresses = make([][20]byte, size)
  636. for i := 0; i < len(addresses); i++ {
  637. data := make([]byte, 20)
  638. random.Read(data)
  639. copy(addresses[i][:], data)
  640. }
  641. accounts = make([][]byte, len(addresses))
  642. for i := 0; i < len(accounts); i++ {
  643. var (
  644. nonce = uint64(random.Int63())
  645. root = emptyRoot
  646. code = crypto.Keccak256(nil)
  647. )
  648. // The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
  649. // and will consume different amount of data from the rand source.
  650. //balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil))
  651. // Therefore, we instead just read via byte buffer
  652. numBytes := random.Uint32() % 33 // [0, 32] bytes
  653. balanceBytes := make([]byte, numBytes)
  654. random.Read(balanceBytes)
  655. balance := new(big.Int).SetBytes(balanceBytes)
  656. data, _ := rlp.EncodeToBytes(&types.StateAccount{Nonce: nonce, Balance: balance, Root: root, CodeHash: code})
  657. accounts[i] = data
  658. }
  659. return addresses, accounts
  660. }
  661. // spongeDb is a dummy db backend which accumulates writes in a sponge
  662. type spongeDb struct {
  663. sponge hash.Hash
  664. id string
  665. journal []string
  666. }
  667. func (s *spongeDb) Has(key []byte) (bool, error) { panic("implement me") }
  668. func (s *spongeDb) Get(key []byte) ([]byte, error) { return nil, errors.New("no such elem") }
  669. func (s *spongeDb) Delete(key []byte) error { panic("implement me") }
  670. func (s *spongeDb) NewBatch() ethdb.Batch { return &spongeBatch{s} }
  671. func (s *spongeDb) NewBatchWithSize(size int) ethdb.Batch { return &spongeBatch{s} }
  672. func (s *spongeDb) NewSnapshot() (ethdb.Snapshot, error) { panic("implement me") }
  673. func (s *spongeDb) Stat(property string) (string, error) { panic("implement me") }
  674. func (s *spongeDb) Compact(start []byte, limit []byte) error { panic("implement me") }
  675. func (s *spongeDb) Close() error { return nil }
  676. func (s *spongeDb) Put(key []byte, value []byte) error {
  677. valbrief := value
  678. if len(valbrief) > 8 {
  679. valbrief = valbrief[:8]
  680. }
  681. s.journal = append(s.journal, fmt.Sprintf("%v: PUT([%x...], [%d bytes] %x...)\n", s.id, key[:8], len(value), valbrief))
  682. s.sponge.Write(key)
  683. s.sponge.Write(value)
  684. return nil
  685. }
  686. func (s *spongeDb) NewIterator(prefix []byte, start []byte) ethdb.Iterator { panic("implement me") }
  687. // spongeBatch is a dummy batch which immediately writes to the underlying spongedb
  688. type spongeBatch struct {
  689. db *spongeDb
  690. }
  691. func (b *spongeBatch) Put(key, value []byte) error {
  692. b.db.Put(key, value)
  693. return nil
  694. }
  695. func (b *spongeBatch) Delete(key []byte) error { panic("implement me") }
  696. func (b *spongeBatch) ValueSize() int { return 100 }
  697. func (b *spongeBatch) Write() error { return nil }
  698. func (b *spongeBatch) Reset() {}
  699. func (b *spongeBatch) Replay(w ethdb.KeyValueWriter) error { return nil }
  700. // TestCommitSequence tests that the trie.Commit operation writes the elements of the trie
  701. // in the expected order, and calls the callbacks in the expected order.
  702. // The test data was based on the 'master' code, and is basically random. It can be used
  703. // to check whether changes to the trie modifies the write order or data in any way.
  704. func TestCommitSequence(t *testing.T) {
  705. for i, tc := range []struct {
  706. count int
  707. expWriteSeqHash []byte
  708. expCallbackSeqHash []byte
  709. }{
  710. {20, common.FromHex("873c78df73d60e59d4a2bcf3716e8bfe14554549fea2fc147cb54129382a8066"),
  711. common.FromHex("ff00f91ac05df53b82d7f178d77ada54fd0dca64526f537034a5dbe41b17df2a")},
  712. {200, common.FromHex("ba03d891bb15408c940eea5ee3d54d419595102648d02774a0268d892add9c8e"),
  713. common.FromHex("f3cd509064c8d319bbdd1c68f511850a902ad275e6ed5bea11547e23d492a926")},
  714. {2000, common.FromHex("f7a184f20df01c94f09537401d11e68d97ad0c00115233107f51b9c287ce60c7"),
  715. common.FromHex("ff795ea898ba1e4cfed4a33b4cf5535a347a02cf931f88d88719faf810f9a1c9")},
  716. } {
  717. addresses, accounts := makeAccounts(tc.count)
  718. // This spongeDb is used to check the sequence of disk-db-writes
  719. s := &spongeDb{sponge: sha3.NewLegacyKeccak256()}
  720. db := NewDatabase(s)
  721. trie := NewEmpty(db)
  722. // Another sponge is used to check the callback-sequence
  723. callbackSponge := sha3.NewLegacyKeccak256()
  724. // Fill the trie with elements
  725. for i := 0; i < tc.count; i++ {
  726. trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
  727. }
  728. // Flush trie -> database
  729. root, nodes, _ := trie.Commit(false)
  730. db.Update(NewWithNodeSet(nodes))
  731. // Flush memdb -> disk (sponge)
  732. db.Commit(root, false, func(c common.Hash) {
  733. // And spongify the callback-order
  734. callbackSponge.Write(c[:])
  735. })
  736. if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
  737. t.Errorf("test %d, disk write sequence wrong:\ngot %x exp %x\n", i, got, exp)
  738. }
  739. if got, exp := callbackSponge.Sum(nil), tc.expCallbackSeqHash; !bytes.Equal(got, exp) {
  740. t.Errorf("test %d, call back sequence wrong:\ngot: %x exp %x\n", i, got, exp)
  741. }
  742. }
  743. }
  744. // TestCommitSequenceRandomBlobs is identical to TestCommitSequence
  745. // but uses random blobs instead of 'accounts'
  746. func TestCommitSequenceRandomBlobs(t *testing.T) {
  747. for i, tc := range []struct {
  748. count int
  749. expWriteSeqHash []byte
  750. expCallbackSeqHash []byte
  751. }{
  752. {20, common.FromHex("8e4a01548551d139fa9e833ebc4e66fc1ba40a4b9b7259d80db32cff7b64ebbc"),
  753. common.FromHex("450238d73bc36dc6cc6f926987e5428535e64be403877c4560e238a52749ba24")},
  754. {200, common.FromHex("6869b4e7b95f3097a19ddb30ff735f922b915314047e041614df06958fc50554"),
  755. common.FromHex("0ace0b03d6cb8c0b82f6289ef5b1a1838306b455a62dafc63cada8e2924f2550")},
  756. {2000, common.FromHex("444200e6f4e2df49f77752f629a96ccf7445d4698c164f962bbd85a0526ef424"),
  757. common.FromHex("117d30dafaa62a1eed498c3dfd70982b377ba2b46dd3e725ed6120c80829e518")},
  758. } {
  759. prng := rand.New(rand.NewSource(int64(i)))
  760. // This spongeDb is used to check the sequence of disk-db-writes
  761. s := &spongeDb{sponge: sha3.NewLegacyKeccak256()}
  762. db := NewDatabase(s)
  763. trie := NewEmpty(db)
  764. // Another sponge is used to check the callback-sequence
  765. callbackSponge := sha3.NewLegacyKeccak256()
  766. // Fill the trie with elements
  767. for i := 0; i < tc.count; i++ {
  768. key := make([]byte, 32)
  769. var val []byte
  770. // 50% short elements, 50% large elements
  771. if prng.Intn(2) == 0 {
  772. val = make([]byte, 1+prng.Intn(32))
  773. } else {
  774. val = make([]byte, 1+prng.Intn(4096))
  775. }
  776. prng.Read(key)
  777. prng.Read(val)
  778. trie.Update(key, val)
  779. }
  780. // Flush trie -> database
  781. root, nodes, _ := trie.Commit(false)
  782. db.Update(NewWithNodeSet(nodes))
  783. // Flush memdb -> disk (sponge)
  784. db.Commit(root, false, func(c common.Hash) {
  785. // And spongify the callback-order
  786. callbackSponge.Write(c[:])
  787. })
  788. if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
  789. t.Fatalf("test %d, disk write sequence wrong:\ngot %x exp %x\n", i, got, exp)
  790. }
  791. if got, exp := callbackSponge.Sum(nil), tc.expCallbackSeqHash; !bytes.Equal(got, exp) {
  792. t.Fatalf("test %d, call back sequence wrong:\ngot: %x exp %x\n", i, got, exp)
  793. }
  794. }
  795. }
  796. func TestCommitSequenceStackTrie(t *testing.T) {
  797. for count := 1; count < 200; count++ {
  798. prng := rand.New(rand.NewSource(int64(count)))
  799. // This spongeDb is used to check the sequence of disk-db-writes
  800. s := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "a"}
  801. db := NewDatabase(s)
  802. trie := NewEmpty(db)
  803. // Another sponge is used for the stacktrie commits
  804. stackTrieSponge := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "b"}
  805. stTrie := NewStackTrie(stackTrieSponge)
  806. // Fill the trie with elements
  807. for i := 0; i < count; i++ {
  808. // For the stack trie, we need to do inserts in proper order
  809. key := make([]byte, 32)
  810. binary.BigEndian.PutUint64(key, uint64(i))
  811. var val []byte
  812. // 50% short elements, 50% large elements
  813. if prng.Intn(2) == 0 {
  814. val = make([]byte, 1+prng.Intn(32))
  815. } else {
  816. val = make([]byte, 1+prng.Intn(1024))
  817. }
  818. prng.Read(val)
  819. trie.TryUpdate(key, val)
  820. stTrie.TryUpdate(key, val)
  821. }
  822. // Flush trie -> database
  823. root, nodes, _ := trie.Commit(false)
  824. // Flush memdb -> disk (sponge)
  825. db.Update(NewWithNodeSet(nodes))
  826. db.Commit(root, false, nil)
  827. // And flush stacktrie -> disk
  828. stRoot, err := stTrie.Commit()
  829. if err != nil {
  830. t.Fatalf("Failed to commit stack trie %v", err)
  831. }
  832. if stRoot != root {
  833. t.Fatalf("root wrong, got %x exp %x", stRoot, root)
  834. }
  835. if got, exp := stackTrieSponge.sponge.Sum(nil), s.sponge.Sum(nil); !bytes.Equal(got, exp) {
  836. // Show the journal
  837. t.Logf("Expected:")
  838. for i, v := range s.journal {
  839. t.Logf("op %d: %v", i, v)
  840. }
  841. t.Logf("Stacktrie:")
  842. for i, v := range stackTrieSponge.journal {
  843. t.Logf("op %d: %v", i, v)
  844. }
  845. t.Fatalf("test %d, disk write sequence wrong:\ngot %x exp %x\n", count, got, exp)
  846. }
  847. }
  848. }
  849. // TestCommitSequenceSmallRoot tests that a trie which is essentially only a
  850. // small (<32 byte) shortnode with an included value is properly committed to a
  851. // database.
  852. // This case might not matter, since in practice, all keys are 32 bytes, which means
  853. // that even a small trie which contains a leaf will have an extension making it
  854. // not fit into 32 bytes, rlp-encoded. However, it's still the correct thing to do.
  855. func TestCommitSequenceSmallRoot(t *testing.T) {
  856. s := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "a"}
  857. db := NewDatabase(s)
  858. trie := NewEmpty(db)
  859. // Another sponge is used for the stacktrie commits
  860. stackTrieSponge := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "b"}
  861. stTrie := NewStackTrie(stackTrieSponge)
  862. // Add a single small-element to the trie(s)
  863. key := make([]byte, 5)
  864. key[0] = 1
  865. trie.TryUpdate(key, []byte{0x1})
  866. stTrie.TryUpdate(key, []byte{0x1})
  867. // Flush trie -> database
  868. root, nodes, _ := trie.Commit(false)
  869. // Flush memdb -> disk (sponge)
  870. db.Update(NewWithNodeSet(nodes))
  871. db.Commit(root, false, nil)
  872. // And flush stacktrie -> disk
  873. stRoot, err := stTrie.Commit()
  874. if err != nil {
  875. t.Fatalf("Failed to commit stack trie %v", err)
  876. }
  877. if stRoot != root {
  878. t.Fatalf("root wrong, got %x exp %x", stRoot, root)
  879. }
  880. t.Logf("root: %x\n", stRoot)
  881. if got, exp := stackTrieSponge.sponge.Sum(nil), s.sponge.Sum(nil); !bytes.Equal(got, exp) {
  882. t.Fatalf("test, disk write sequence wrong:\ngot %x exp %x\n", got, exp)
  883. }
  884. }
  885. // BenchmarkCommitAfterHashFixedSize benchmarks the Commit (after Hash) of a fixed number of updates to a trie.
  886. // This benchmark is meant to capture the difference on efficiency of small versus large changes. Typically,
  887. // storage tries are small (a couple of entries), whereas the full post-block account trie update is large (a couple
  888. // of thousand entries)
  889. func BenchmarkHashFixedSize(b *testing.B) {
  890. b.Run("10", func(b *testing.B) {
  891. b.StopTimer()
  892. acc, add := makeAccounts(20)
  893. for i := 0; i < b.N; i++ {
  894. benchmarkHashFixedSize(b, acc, add)
  895. }
  896. })
  897. b.Run("100", func(b *testing.B) {
  898. b.StopTimer()
  899. acc, add := makeAccounts(100)
  900. for i := 0; i < b.N; i++ {
  901. benchmarkHashFixedSize(b, acc, add)
  902. }
  903. })
  904. b.Run("1K", func(b *testing.B) {
  905. b.StopTimer()
  906. acc, add := makeAccounts(1000)
  907. for i := 0; i < b.N; i++ {
  908. benchmarkHashFixedSize(b, acc, add)
  909. }
  910. })
  911. b.Run("10K", func(b *testing.B) {
  912. b.StopTimer()
  913. acc, add := makeAccounts(10000)
  914. for i := 0; i < b.N; i++ {
  915. benchmarkHashFixedSize(b, acc, add)
  916. }
  917. })
  918. b.Run("100K", func(b *testing.B) {
  919. b.StopTimer()
  920. acc, add := makeAccounts(100000)
  921. for i := 0; i < b.N; i++ {
  922. benchmarkHashFixedSize(b, acc, add)
  923. }
  924. })
  925. }
  926. func benchmarkHashFixedSize(b *testing.B, addresses [][20]byte, accounts [][]byte) {
  927. b.ReportAllocs()
  928. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  929. for i := 0; i < len(addresses); i++ {
  930. trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
  931. }
  932. // Insert the accounts into the trie and hash it
  933. b.StartTimer()
  934. trie.Hash()
  935. b.StopTimer()
  936. }
  937. func BenchmarkCommitAfterHashFixedSize(b *testing.B) {
  938. b.Run("10", func(b *testing.B) {
  939. b.StopTimer()
  940. acc, add := makeAccounts(20)
  941. for i := 0; i < b.N; i++ {
  942. benchmarkCommitAfterHashFixedSize(b, acc, add)
  943. }
  944. })
  945. b.Run("100", func(b *testing.B) {
  946. b.StopTimer()
  947. acc, add := makeAccounts(100)
  948. for i := 0; i < b.N; i++ {
  949. benchmarkCommitAfterHashFixedSize(b, acc, add)
  950. }
  951. })
  952. b.Run("1K", func(b *testing.B) {
  953. b.StopTimer()
  954. acc, add := makeAccounts(1000)
  955. for i := 0; i < b.N; i++ {
  956. benchmarkCommitAfterHashFixedSize(b, acc, add)
  957. }
  958. })
  959. b.Run("10K", func(b *testing.B) {
  960. b.StopTimer()
  961. acc, add := makeAccounts(10000)
  962. for i := 0; i < b.N; i++ {
  963. benchmarkCommitAfterHashFixedSize(b, acc, add)
  964. }
  965. })
  966. b.Run("100K", func(b *testing.B) {
  967. b.StopTimer()
  968. acc, add := makeAccounts(100000)
  969. for i := 0; i < b.N; i++ {
  970. benchmarkCommitAfterHashFixedSize(b, acc, add)
  971. }
  972. })
  973. }
  974. func benchmarkCommitAfterHashFixedSize(b *testing.B, addresses [][20]byte, accounts [][]byte) {
  975. b.ReportAllocs()
  976. trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  977. for i := 0; i < len(addresses); i++ {
  978. trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
  979. }
  980. // Insert the accounts into the trie and hash it
  981. trie.Hash()
  982. b.StartTimer()
  983. trie.Commit(false)
  984. b.StopTimer()
  985. }
  986. func BenchmarkDerefRootFixedSize(b *testing.B) {
  987. b.Run("10", func(b *testing.B) {
  988. b.StopTimer()
  989. acc, add := makeAccounts(20)
  990. for i := 0; i < b.N; i++ {
  991. benchmarkDerefRootFixedSize(b, acc, add)
  992. }
  993. })
  994. b.Run("100", func(b *testing.B) {
  995. b.StopTimer()
  996. acc, add := makeAccounts(100)
  997. for i := 0; i < b.N; i++ {
  998. benchmarkDerefRootFixedSize(b, acc, add)
  999. }
  1000. })
  1001. b.Run("1K", func(b *testing.B) {
  1002. b.StopTimer()
  1003. acc, add := makeAccounts(1000)
  1004. for i := 0; i < b.N; i++ {
  1005. benchmarkDerefRootFixedSize(b, acc, add)
  1006. }
  1007. })
  1008. b.Run("10K", func(b *testing.B) {
  1009. b.StopTimer()
  1010. acc, add := makeAccounts(10000)
  1011. for i := 0; i < b.N; i++ {
  1012. benchmarkDerefRootFixedSize(b, acc, add)
  1013. }
  1014. })
  1015. b.Run("100K", func(b *testing.B) {
  1016. b.StopTimer()
  1017. acc, add := makeAccounts(100000)
  1018. for i := 0; i < b.N; i++ {
  1019. benchmarkDerefRootFixedSize(b, acc, add)
  1020. }
  1021. })
  1022. }
  1023. func benchmarkDerefRootFixedSize(b *testing.B, addresses [][20]byte, accounts [][]byte) {
  1024. b.ReportAllocs()
  1025. triedb := NewDatabase(rawdb.NewMemoryDatabase())
  1026. trie := NewEmpty(triedb)
  1027. for i := 0; i < len(addresses); i++ {
  1028. trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
  1029. }
  1030. h := trie.Hash()
  1031. _, nodes, _ := trie.Commit(false)
  1032. triedb.Update(NewWithNodeSet(nodes))
  1033. b.StartTimer()
  1034. triedb.Dereference(h)
  1035. b.StopTimer()
  1036. }
  1037. func getString(trie *Trie, k string) []byte {
  1038. return trie.Get([]byte(k))
  1039. }
  1040. func updateString(trie *Trie, k, v string) {
  1041. trie.Update([]byte(k), []byte(v))
  1042. }
  1043. func deleteString(trie *Trie, k string) {
  1044. trie.Delete([]byte(k))
  1045. }
  1046. func TestDecodeNode(t *testing.T) {
  1047. t.Parallel()
  1048. var (
  1049. hash = make([]byte, 20)
  1050. elems = make([]byte, 20)
  1051. )
  1052. for i := 0; i < 5000000; i++ {
  1053. rand.Read(hash)
  1054. rand.Read(elems)
  1055. decodeNode(hash, elems)
  1056. }
  1057. }