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