github.com/ethereum/go-ethereum@v1.16.1/triedb/pathdb/layertree_test.go (about) 1 // Copyright 2024 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 17 package pathdb 18 19 import ( 20 "errors" 21 "testing" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/core/rawdb" 25 "github.com/ethereum/go-ethereum/trie/trienode" 26 ) 27 28 func newTestLayerTree() *layerTree { 29 db := New(rawdb.NewMemoryDatabase(), nil, false) 30 l := newDiskLayer(common.Hash{0x1}, 0, db, nil, nil, newBuffer(0, nil, nil, 0), nil) 31 t := newLayerTree(l) 32 return t 33 } 34 35 func TestLayerCap(t *testing.T) { 36 var cases = []struct { 37 init func() *layerTree 38 head common.Hash 39 layers int 40 base common.Hash 41 snapshot map[common.Hash]struct{} 42 }{ 43 { 44 // Chain: 45 // C1->C2->C3->C4 (HEAD) 46 init: func() *layerTree { 47 tr := newTestLayerTree() 48 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 49 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 50 tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 51 return tr 52 }, 53 // Chain: 54 // C2->C3->C4 (HEAD) 55 head: common.Hash{0x4}, 56 layers: 2, 57 base: common.Hash{0x2}, 58 snapshot: map[common.Hash]struct{}{ 59 common.Hash{0x2}: {}, 60 common.Hash{0x3}: {}, 61 common.Hash{0x4}: {}, 62 }, 63 }, 64 { 65 // Chain: 66 // C1->C2->C3->C4 (HEAD) 67 init: func() *layerTree { 68 tr := newTestLayerTree() 69 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 70 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 71 tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 72 return tr 73 }, 74 // Chain: 75 // C3->C4 (HEAD) 76 head: common.Hash{0x4}, 77 layers: 1, 78 base: common.Hash{0x3}, 79 snapshot: map[common.Hash]struct{}{ 80 common.Hash{0x3}: {}, 81 common.Hash{0x4}: {}, 82 }, 83 }, 84 { 85 // Chain: 86 // C1->C2->C3->C4 (HEAD) 87 init: func() *layerTree { 88 tr := newTestLayerTree() 89 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 90 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 91 tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 92 return tr 93 }, 94 // Chain: 95 // C4 (HEAD) 96 head: common.Hash{0x4}, 97 layers: 0, 98 base: common.Hash{0x4}, 99 snapshot: map[common.Hash]struct{}{ 100 common.Hash{0x4}: {}, 101 }, 102 }, 103 { 104 // Chain: 105 // C1->C2->C3->C4 (HEAD) 106 // ->C2'->C3'->C4' 107 init: func() *layerTree { 108 tr := newTestLayerTree() 109 tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 110 tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 111 tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 112 tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 113 tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 114 tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 115 return tr 116 }, 117 // Chain: 118 // C2->C3->C4 (HEAD) 119 head: common.Hash{0x4a}, 120 layers: 2, 121 base: common.Hash{0x2a}, 122 snapshot: map[common.Hash]struct{}{ 123 common.Hash{0x4a}: {}, 124 common.Hash{0x3a}: {}, 125 common.Hash{0x2a}: {}, 126 }, 127 }, 128 { 129 // Chain: 130 // C1->C2->C3->C4 (HEAD) 131 // ->C2'->C3'->C4' 132 init: func() *layerTree { 133 tr := newTestLayerTree() 134 tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 135 tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 136 tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 137 tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 138 tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 139 tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 140 return tr 141 }, 142 // Chain: 143 // C3->C4 (HEAD) 144 head: common.Hash{0x4a}, 145 layers: 1, 146 base: common.Hash{0x3a}, 147 snapshot: map[common.Hash]struct{}{ 148 common.Hash{0x4a}: {}, 149 common.Hash{0x3a}: {}, 150 }, 151 }, 152 { 153 // Chain: 154 // C1->C2->C3->C4 (HEAD) 155 // ->C3'->C4' 156 init: func() *layerTree { 157 tr := newTestLayerTree() 158 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 159 tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 160 tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 161 tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 162 tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 163 return tr 164 }, 165 // Chain: 166 // C2->C3->C4 (HEAD) 167 // ->C3'->C4' 168 head: common.Hash{0x4a}, 169 layers: 2, 170 base: common.Hash{0x2}, 171 snapshot: map[common.Hash]struct{}{ 172 common.Hash{0x4a}: {}, 173 common.Hash{0x3a}: {}, 174 common.Hash{0x4b}: {}, 175 common.Hash{0x3b}: {}, 176 common.Hash{0x2}: {}, 177 }, 178 }, 179 } 180 for _, c := range cases { 181 tr := c.init() 182 if err := tr.cap(c.head, c.layers); err != nil { 183 t.Fatalf("Failed to cap the layer tree %v", err) 184 } 185 if tr.bottom().root != c.base { 186 t.Fatalf("Unexpected bottom layer tree root, want %v, got %v", c.base, tr.bottom().root) 187 } 188 if len(c.snapshot) != len(tr.layers) { 189 t.Fatalf("Unexpected layer tree size, want %v, got %v", len(c.snapshot), len(tr.layers)) 190 } 191 for h := range tr.layers { 192 if _, ok := c.snapshot[h]; !ok { 193 t.Fatalf("Unexpected layer %v", h) 194 } 195 } 196 } 197 } 198 199 func TestBaseLayer(t *testing.T) { 200 tr := newTestLayerTree() 201 202 var cases = []struct { 203 op func() 204 base common.Hash 205 }{ 206 // Chain: 207 // C1 (HEAD) 208 { 209 func() {}, 210 common.Hash{0x1}, 211 }, 212 // Chain: 213 // C1->C2->C3 (HEAD) 214 { 215 func() { 216 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 217 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 218 }, 219 common.Hash{0x1}, 220 }, 221 // Chain: 222 // C3 (HEAD) 223 { 224 func() { 225 tr.cap(common.Hash{0x3}, 0) 226 }, 227 common.Hash{0x3}, 228 }, 229 // Chain: 230 // C4->C5->C6 (HEAD) 231 { 232 func() { 233 tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 234 tr.add(common.Hash{0x5}, common.Hash{0x4}, 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 235 tr.add(common.Hash{0x6}, common.Hash{0x5}, 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 236 tr.cap(common.Hash{0x6}, 2) 237 }, 238 common.Hash{0x4}, 239 }, 240 } 241 for _, c := range cases { 242 c.op() 243 if tr.base.rootHash() != c.base { 244 t.Fatalf("Unexpected base root, want %v, got: %v", c.base, tr.base.rootHash()) 245 } 246 } 247 } 248 249 func TestDescendant(t *testing.T) { 250 var cases = []struct { 251 init func() *layerTree 252 snapshotA map[common.Hash]map[common.Hash]struct{} 253 op func(tr *layerTree) 254 snapshotB map[common.Hash]map[common.Hash]struct{} 255 }{ 256 { 257 // Chain: 258 // C1->C2 (HEAD) 259 init: func() *layerTree { 260 tr := newTestLayerTree() 261 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 262 return tr 263 }, 264 snapshotA: map[common.Hash]map[common.Hash]struct{}{ 265 common.Hash{0x1}: { 266 common.Hash{0x2}: {}, 267 }, 268 }, 269 // Chain: 270 // C1->C2->C3 (HEAD) 271 op: func(tr *layerTree) { 272 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 273 }, 274 snapshotB: map[common.Hash]map[common.Hash]struct{}{ 275 common.Hash{0x1}: { 276 common.Hash{0x2}: {}, 277 common.Hash{0x3}: {}, 278 }, 279 common.Hash{0x2}: { 280 common.Hash{0x3}: {}, 281 }, 282 }, 283 }, 284 { 285 // Chain: 286 // C1->C2->C3->C4 (HEAD) 287 init: func() *layerTree { 288 tr := newTestLayerTree() 289 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 290 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 291 tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 292 return tr 293 }, 294 snapshotA: map[common.Hash]map[common.Hash]struct{}{ 295 common.Hash{0x1}: { 296 common.Hash{0x2}: {}, 297 common.Hash{0x3}: {}, 298 common.Hash{0x4}: {}, 299 }, 300 common.Hash{0x2}: { 301 common.Hash{0x3}: {}, 302 common.Hash{0x4}: {}, 303 }, 304 common.Hash{0x3}: { 305 common.Hash{0x4}: {}, 306 }, 307 }, 308 // Chain: 309 // C2->C3->C4 (HEAD) 310 op: func(tr *layerTree) { 311 tr.cap(common.Hash{0x4}, 2) 312 }, 313 snapshotB: map[common.Hash]map[common.Hash]struct{}{ 314 common.Hash{0x2}: { 315 common.Hash{0x3}: {}, 316 common.Hash{0x4}: {}, 317 }, 318 common.Hash{0x3}: { 319 common.Hash{0x4}: {}, 320 }, 321 }, 322 }, 323 { 324 // Chain: 325 // C1->C2->C3->C4 (HEAD) 326 init: func() *layerTree { 327 tr := newTestLayerTree() 328 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 329 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 330 tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 331 return tr 332 }, 333 snapshotA: map[common.Hash]map[common.Hash]struct{}{ 334 common.Hash{0x1}: { 335 common.Hash{0x2}: {}, 336 common.Hash{0x3}: {}, 337 common.Hash{0x4}: {}, 338 }, 339 common.Hash{0x2}: { 340 common.Hash{0x3}: {}, 341 common.Hash{0x4}: {}, 342 }, 343 common.Hash{0x3}: { 344 common.Hash{0x4}: {}, 345 }, 346 }, 347 // Chain: 348 // C3->C4 (HEAD) 349 op: func(tr *layerTree) { 350 tr.cap(common.Hash{0x4}, 1) 351 }, 352 snapshotB: map[common.Hash]map[common.Hash]struct{}{ 353 common.Hash{0x3}: { 354 common.Hash{0x4}: {}, 355 }, 356 }, 357 }, 358 { 359 // Chain: 360 // C1->C2->C3->C4 (HEAD) 361 init: func() *layerTree { 362 tr := newTestLayerTree() 363 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 364 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 365 tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 366 return tr 367 }, 368 snapshotA: map[common.Hash]map[common.Hash]struct{}{ 369 common.Hash{0x1}: { 370 common.Hash{0x2}: {}, 371 common.Hash{0x3}: {}, 372 common.Hash{0x4}: {}, 373 }, 374 common.Hash{0x2}: { 375 common.Hash{0x3}: {}, 376 common.Hash{0x4}: {}, 377 }, 378 common.Hash{0x3}: { 379 common.Hash{0x4}: {}, 380 }, 381 }, 382 // Chain: 383 // C4 (HEAD) 384 op: func(tr *layerTree) { 385 tr.cap(common.Hash{0x4}, 0) 386 }, 387 snapshotB: map[common.Hash]map[common.Hash]struct{}{}, 388 }, 389 { 390 // Chain: 391 // C1->C2->C3->C4 (HEAD) 392 // ->C2'->C3'->C4' 393 init: func() *layerTree { 394 tr := newTestLayerTree() 395 tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 396 tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 397 tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 398 tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 399 tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 400 tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 401 return tr 402 }, 403 snapshotA: map[common.Hash]map[common.Hash]struct{}{ 404 common.Hash{0x1}: { 405 common.Hash{0x2a}: {}, 406 common.Hash{0x3a}: {}, 407 common.Hash{0x4a}: {}, 408 common.Hash{0x2b}: {}, 409 common.Hash{0x3b}: {}, 410 common.Hash{0x4b}: {}, 411 }, 412 common.Hash{0x2a}: { 413 common.Hash{0x3a}: {}, 414 common.Hash{0x4a}: {}, 415 }, 416 common.Hash{0x3a}: { 417 common.Hash{0x4a}: {}, 418 }, 419 common.Hash{0x2b}: { 420 common.Hash{0x3b}: {}, 421 common.Hash{0x4b}: {}, 422 }, 423 common.Hash{0x3b}: { 424 common.Hash{0x4b}: {}, 425 }, 426 }, 427 // Chain: 428 // C2->C3->C4 (HEAD) 429 op: func(tr *layerTree) { 430 tr.cap(common.Hash{0x4a}, 2) 431 }, 432 snapshotB: map[common.Hash]map[common.Hash]struct{}{ 433 common.Hash{0x2a}: { 434 common.Hash{0x3a}: {}, 435 common.Hash{0x4a}: {}, 436 }, 437 common.Hash{0x3a}: { 438 common.Hash{0x4a}: {}, 439 }, 440 }, 441 }, 442 { 443 // Chain: 444 // C1->C2->C3->C4 (HEAD) 445 // ->C2'->C3'->C4' 446 init: func() *layerTree { 447 tr := newTestLayerTree() 448 tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 449 tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 450 tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 451 tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 452 tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 453 tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 454 return tr 455 }, 456 snapshotA: map[common.Hash]map[common.Hash]struct{}{ 457 common.Hash{0x1}: { 458 common.Hash{0x2a}: {}, 459 common.Hash{0x3a}: {}, 460 common.Hash{0x4a}: {}, 461 common.Hash{0x2b}: {}, 462 common.Hash{0x3b}: {}, 463 common.Hash{0x4b}: {}, 464 }, 465 common.Hash{0x2a}: { 466 common.Hash{0x3a}: {}, 467 common.Hash{0x4a}: {}, 468 }, 469 common.Hash{0x3a}: { 470 common.Hash{0x4a}: {}, 471 }, 472 common.Hash{0x2b}: { 473 common.Hash{0x3b}: {}, 474 common.Hash{0x4b}: {}, 475 }, 476 common.Hash{0x3b}: { 477 common.Hash{0x4b}: {}, 478 }, 479 }, 480 // Chain: 481 // C3->C4 (HEAD) 482 op: func(tr *layerTree) { 483 tr.cap(common.Hash{0x4a}, 1) 484 }, 485 snapshotB: map[common.Hash]map[common.Hash]struct{}{ 486 common.Hash{0x3a}: { 487 common.Hash{0x4a}: {}, 488 }, 489 }, 490 }, 491 { 492 // Chain: 493 // C1->C2->C3->C4 (HEAD) 494 // ->C3'->C4' 495 init: func() *layerTree { 496 tr := newTestLayerTree() 497 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 498 tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 499 tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 500 tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 501 tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) 502 return tr 503 }, 504 snapshotA: map[common.Hash]map[common.Hash]struct{}{ 505 common.Hash{0x1}: { 506 common.Hash{0x2}: {}, 507 common.Hash{0x3a}: {}, 508 common.Hash{0x4a}: {}, 509 common.Hash{0x3b}: {}, 510 common.Hash{0x4b}: {}, 511 }, 512 common.Hash{0x2}: { 513 common.Hash{0x3a}: {}, 514 common.Hash{0x4a}: {}, 515 common.Hash{0x3b}: {}, 516 common.Hash{0x4b}: {}, 517 }, 518 common.Hash{0x3a}: { 519 common.Hash{0x4a}: {}, 520 }, 521 common.Hash{0x3b}: { 522 common.Hash{0x4b}: {}, 523 }, 524 }, 525 // Chain: 526 // C2->C3->C4 (HEAD) 527 // ->C3'->C4' 528 op: func(tr *layerTree) { 529 tr.cap(common.Hash{0x4a}, 2) 530 }, 531 snapshotB: map[common.Hash]map[common.Hash]struct{}{ 532 common.Hash{0x2}: { 533 common.Hash{0x3a}: {}, 534 common.Hash{0x4a}: {}, 535 common.Hash{0x3b}: {}, 536 common.Hash{0x4b}: {}, 537 }, 538 common.Hash{0x3a}: { 539 common.Hash{0x4a}: {}, 540 }, 541 common.Hash{0x3b}: { 542 common.Hash{0x4b}: {}, 543 }, 544 }, 545 }, 546 } 547 check := func(setA, setB map[common.Hash]map[common.Hash]struct{}) bool { 548 if len(setA) != len(setB) { 549 return false 550 } 551 for h, subA := range setA { 552 subB, ok := setB[h] 553 if !ok { 554 return false 555 } 556 if len(subA) != len(subB) { 557 return false 558 } 559 for hh := range subA { 560 if _, ok := subB[hh]; !ok { 561 return false 562 } 563 } 564 } 565 return true 566 } 567 for _, c := range cases { 568 tr := c.init() 569 if !check(c.snapshotA, tr.descendants) { 570 t.Fatalf("Unexpected descendants") 571 } 572 c.op(tr) 573 if !check(c.snapshotB, tr.descendants) { 574 t.Fatalf("Unexpected descendants") 575 } 576 } 577 } 578 579 func TestAccountLookup(t *testing.T) { 580 // Chain: 581 // C1->C2->C3->C4 (HEAD) 582 tr := newTestLayerTree() // base = 0x1 583 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), 584 NewStateSetWithOrigin(randomAccountSet("0xa"), nil, nil, nil, false)) 585 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), 586 NewStateSetWithOrigin(randomAccountSet("0xb"), nil, nil, nil, false)) 587 tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), 588 NewStateSetWithOrigin(randomAccountSet("0xa", "0xc"), nil, nil, nil, false)) 589 590 var cases = []struct { 591 account common.Hash 592 state common.Hash 593 expect common.Hash 594 }{ 595 { 596 // unknown account 597 common.HexToHash("0xd"), common.Hash{0x4}, common.Hash{0x1}, 598 }, 599 /* 600 lookup account from the top 601 */ 602 { 603 common.HexToHash("0xa"), common.Hash{0x4}, common.Hash{0x4}, 604 }, 605 { 606 common.HexToHash("0xb"), common.Hash{0x4}, common.Hash{0x3}, 607 }, 608 { 609 common.HexToHash("0xc"), common.Hash{0x4}, common.Hash{0x4}, 610 }, 611 /* 612 lookup account from the middle 613 */ 614 { 615 common.HexToHash("0xa"), common.Hash{0x3}, common.Hash{0x2}, 616 }, 617 { 618 common.HexToHash("0xb"), common.Hash{0x3}, common.Hash{0x3}, 619 }, 620 { 621 common.HexToHash("0xc"), common.Hash{0x3}, common.Hash{0x1}, // not found 622 }, 623 { 624 common.HexToHash("0xa"), common.Hash{0x2}, common.Hash{0x2}, 625 }, 626 { 627 common.HexToHash("0xb"), common.Hash{0x2}, common.Hash{0x1}, // not found 628 }, 629 { 630 common.HexToHash("0xc"), common.Hash{0x2}, common.Hash{0x1}, // not found 631 }, 632 /* 633 lookup account from the bottom 634 */ 635 { 636 common.HexToHash("0xa"), common.Hash{0x1}, common.Hash{0x1}, // not found 637 }, 638 { 639 common.HexToHash("0xb"), common.Hash{0x1}, common.Hash{0x1}, // not found 640 }, 641 { 642 common.HexToHash("0xc"), common.Hash{0x1}, common.Hash{0x1}, // not found 643 }, 644 } 645 for i, c := range cases { 646 l, err := tr.lookupAccount(c.account, c.state) 647 if err != nil { 648 t.Fatalf("%d: %v", i, err) 649 } 650 if l.rootHash() != c.expect { 651 t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash()) 652 } 653 } 654 655 // Chain: 656 // C3->C4 (HEAD) 657 tr.cap(common.Hash{0x4}, 1) 658 659 cases2 := []struct { 660 account common.Hash 661 state common.Hash 662 expect common.Hash 663 expectErr error 664 }{ 665 { 666 // unknown account 667 common.HexToHash("0xd"), common.Hash{0x4}, common.Hash{0x3}, nil, 668 }, 669 /* 670 lookup account from the top 671 */ 672 { 673 common.HexToHash("0xa"), common.Hash{0x4}, common.Hash{0x4}, nil, 674 }, 675 { 676 common.HexToHash("0xb"), common.Hash{0x4}, common.Hash{0x3}, nil, 677 }, 678 { 679 common.HexToHash("0xc"), common.Hash{0x4}, common.Hash{0x4}, nil, 680 }, 681 /* 682 lookup account from the bottom 683 */ 684 { 685 common.HexToHash("0xa"), common.Hash{0x3}, common.Hash{0x3}, nil, 686 }, 687 { 688 common.HexToHash("0xb"), common.Hash{0x3}, common.Hash{0x3}, nil, 689 }, 690 { 691 common.HexToHash("0xc"), common.Hash{0x3}, common.Hash{0x3}, nil, // not found 692 }, 693 /* 694 stale states 695 */ 696 { 697 common.HexToHash("0xa"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, 698 }, 699 { 700 common.HexToHash("0xb"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, 701 }, 702 { 703 common.HexToHash("0xc"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, 704 }, 705 { 706 common.HexToHash("0xa"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, 707 }, 708 { 709 common.HexToHash("0xb"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, 710 }, 711 { 712 common.HexToHash("0xc"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, 713 }, 714 } 715 for i, c := range cases2 { 716 l, err := tr.lookupAccount(c.account, c.state) 717 if c.expectErr != nil { 718 if !errors.Is(err, c.expectErr) { 719 t.Fatalf("%d: unexpected error, want %v, got %v", i, c.expectErr, err) 720 } 721 } 722 if c.expectErr == nil { 723 if err != nil { 724 t.Fatalf("%d: %v", i, err) 725 } 726 if l.rootHash() != c.expect { 727 t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash()) 728 } 729 } 730 } 731 } 732 733 func TestStorageLookup(t *testing.T) { 734 // Chain: 735 // C1->C2->C3->C4 (HEAD) 736 tr := newTestLayerTree() // base = 0x1 737 tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), 738 NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x1"}}, nil), nil, nil, false)) 739 tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), 740 NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x2"}}, nil), nil, nil, false)) 741 tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), 742 NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x1", "0x3"}}, nil), nil, nil, false)) 743 744 var cases = []struct { 745 storage common.Hash 746 state common.Hash 747 expect common.Hash 748 }{ 749 { 750 // unknown storage slot 751 common.HexToHash("0x4"), common.Hash{0x4}, common.Hash{0x1}, 752 }, 753 /* 754 lookup storage slot from the top 755 */ 756 { 757 common.HexToHash("0x1"), common.Hash{0x4}, common.Hash{0x4}, 758 }, 759 { 760 common.HexToHash("0x2"), common.Hash{0x4}, common.Hash{0x3}, 761 }, 762 { 763 common.HexToHash("0x3"), common.Hash{0x4}, common.Hash{0x4}, 764 }, 765 /* 766 lookup storage slot from the middle 767 */ 768 { 769 common.HexToHash("0x1"), common.Hash{0x3}, common.Hash{0x2}, 770 }, 771 { 772 common.HexToHash("0x2"), common.Hash{0x3}, common.Hash{0x3}, 773 }, 774 { 775 common.HexToHash("0x3"), common.Hash{0x3}, common.Hash{0x1}, // not found 776 }, 777 { 778 common.HexToHash("0x1"), common.Hash{0x2}, common.Hash{0x2}, 779 }, 780 { 781 common.HexToHash("0x2"), common.Hash{0x2}, common.Hash{0x1}, // not found 782 }, 783 { 784 common.HexToHash("0x3"), common.Hash{0x2}, common.Hash{0x1}, // not found 785 }, 786 /* 787 lookup storage slot from the bottom 788 */ 789 { 790 common.HexToHash("0x1"), common.Hash{0x1}, common.Hash{0x1}, // not found 791 }, 792 { 793 common.HexToHash("0x2"), common.Hash{0x1}, common.Hash{0x1}, // not found 794 }, 795 { 796 common.HexToHash("0x3"), common.Hash{0x1}, common.Hash{0x1}, // not found 797 }, 798 } 799 for i, c := range cases { 800 l, err := tr.lookupStorage(common.HexToHash("0xa"), c.storage, c.state) 801 if err != nil { 802 t.Fatalf("%d: %v", i, err) 803 } 804 if l.rootHash() != c.expect { 805 t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash()) 806 } 807 } 808 809 // Chain: 810 // C3->C4 (HEAD) 811 tr.cap(common.Hash{0x4}, 1) 812 813 cases2 := []struct { 814 storage common.Hash 815 state common.Hash 816 expect common.Hash 817 expectErr error 818 }{ 819 { 820 // unknown storage slot 821 common.HexToHash("0x4"), common.Hash{0x4}, common.Hash{0x3}, nil, 822 }, 823 /* 824 lookup account from the top 825 */ 826 { 827 common.HexToHash("0x1"), common.Hash{0x4}, common.Hash{0x4}, nil, 828 }, 829 { 830 common.HexToHash("0x2"), common.Hash{0x4}, common.Hash{0x3}, nil, 831 }, 832 { 833 common.HexToHash("0x3"), common.Hash{0x4}, common.Hash{0x4}, nil, 834 }, 835 /* 836 lookup account from the bottom 837 */ 838 { 839 common.HexToHash("0x1"), common.Hash{0x3}, common.Hash{0x3}, nil, 840 }, 841 { 842 common.HexToHash("0x2"), common.Hash{0x3}, common.Hash{0x3}, nil, 843 }, 844 { 845 common.HexToHash("0x3"), common.Hash{0x3}, common.Hash{0x3}, nil, // not found 846 }, 847 /* 848 stale states 849 */ 850 { 851 common.HexToHash("0x1"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, 852 }, 853 { 854 common.HexToHash("0x2"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, 855 }, 856 { 857 common.HexToHash("0x3"), common.Hash{0x2}, common.Hash{}, errSnapshotStale, 858 }, 859 { 860 common.HexToHash("0x1"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, 861 }, 862 { 863 common.HexToHash("0x2"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, 864 }, 865 { 866 common.HexToHash("0x3"), common.Hash{0x1}, common.Hash{}, errSnapshotStale, 867 }, 868 } 869 for i, c := range cases2 { 870 l, err := tr.lookupStorage(common.HexToHash("0xa"), c.storage, c.state) 871 if c.expectErr != nil { 872 if !errors.Is(err, c.expectErr) { 873 t.Fatalf("%d: unexpected error, want %v, got %v", i, c.expectErr, err) 874 } 875 } 876 if c.expectErr == nil { 877 if err != nil { 878 t.Fatalf("%d: %v", i, err) 879 } 880 if l.rootHash() != c.expect { 881 t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash()) 882 } 883 } 884 } 885 }