github.com/onflow/atree@v0.6.0/map_debug.go (about) 1 /* 2 * Atree - Scalable Arrays and Ordered Maps 3 * 4 * Copyright 2021 Dapper Labs, Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package atree 20 21 import ( 22 "bytes" 23 "errors" 24 "fmt" 25 "reflect" 26 "sort" 27 "strings" 28 29 "github.com/fxamacker/cbor/v2" 30 ) 31 32 type MapStats struct { 33 Levels uint64 34 ElementCount uint64 35 MetaDataSlabCount uint64 36 DataSlabCount uint64 37 CollisionDataSlabCount uint64 38 StorableSlabCount uint64 39 } 40 41 func (s *MapStats) SlabCount() uint64 { 42 return s.DataSlabCount + s.MetaDataSlabCount + s.CollisionDataSlabCount + s.StorableSlabCount 43 } 44 45 // GetMapStats returns stats about the map slabs. 46 func GetMapStats(m *OrderedMap) (MapStats, error) { 47 level := uint64(0) 48 metaDataSlabCount := uint64(0) 49 dataSlabCount := uint64(0) 50 collisionDataSlabCount := uint64(0) 51 storableDataSlabCount := uint64(0) 52 53 nextLevelIDs := []StorageID{m.StorageID()} 54 55 for len(nextLevelIDs) > 0 { 56 57 ids := nextLevelIDs 58 59 nextLevelIDs = []StorageID(nil) 60 61 for _, id := range ids { 62 63 slab, err := getMapSlab(m.Storage, id) 64 if err != nil { 65 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 66 return MapStats{}, err 67 } 68 69 if slab.IsData() { 70 dataSlabCount++ 71 72 leaf := slab.(*MapDataSlab) 73 elementGroups := []elements{leaf.elements} 74 75 for len(elementGroups) > 0 { 76 77 var nestedElementGroups []elements 78 79 for i := 0; i < len(elementGroups); i++ { 80 81 elems := elementGroups[i] 82 83 for j := 0; j < int(elems.Count()); j++ { 84 elem, err := elems.Element(j) 85 if err != nil { 86 // Don't need to wrap error as external error because err is already categorized by elements.Element(). 87 return MapStats{}, err 88 } 89 90 if group, ok := elem.(elementGroup); ok { 91 if !group.Inline() { 92 collisionDataSlabCount++ 93 } 94 95 nested, err := group.Elements(m.Storage) 96 if err != nil { 97 // Don't need to wrap error as external error because err is already categorized by elementGroup.Elements(). 98 return MapStats{}, err 99 } 100 nestedElementGroups = append(nestedElementGroups, nested) 101 102 } else { 103 e := elem.(*singleElement) 104 if _, ok := e.key.(StorageIDStorable); ok { 105 storableDataSlabCount++ 106 } 107 if _, ok := e.value.(StorageIDStorable); ok { 108 storableDataSlabCount++ 109 } 110 } 111 } 112 } 113 elementGroups = nestedElementGroups 114 } 115 } else { 116 metaDataSlabCount++ 117 118 for _, storable := range slab.ChildStorables() { 119 id, ok := storable.(StorageIDStorable) 120 if !ok { 121 return MapStats{}, NewFatalError(fmt.Errorf("metadata slab's child storables are not of type StorageIDStorable")) 122 } 123 nextLevelIDs = append(nextLevelIDs, StorageID(id)) 124 } 125 } 126 } 127 128 level++ 129 } 130 131 return MapStats{ 132 Levels: level, 133 ElementCount: m.Count(), 134 MetaDataSlabCount: metaDataSlabCount, 135 DataSlabCount: dataSlabCount, 136 CollisionDataSlabCount: collisionDataSlabCount, 137 StorableSlabCount: storableDataSlabCount, 138 }, nil 139 } 140 141 func PrintMap(m *OrderedMap) { 142 dumps, err := DumpMapSlabs(m) 143 if err != nil { 144 fmt.Println(err) 145 return 146 } 147 fmt.Println(strings.Join(dumps, "\n")) 148 } 149 150 func DumpMapSlabs(m *OrderedMap) ([]string, error) { 151 var dumps []string 152 153 nextLevelIDs := []StorageID{m.StorageID()} 154 155 var overflowIDs []StorageID 156 var collisionSlabIDs []StorageID 157 158 level := 0 159 for len(nextLevelIDs) > 0 { 160 161 ids := nextLevelIDs 162 163 nextLevelIDs = []StorageID(nil) 164 165 for _, id := range ids { 166 167 slab, err := getMapSlab(m.Storage, id) 168 if err != nil { 169 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 170 return nil, err 171 } 172 173 if slab.IsData() { 174 dataSlab := slab.(*MapDataSlab) 175 dumps = append(dumps, fmt.Sprintf("level %d, %s", level+1, dataSlab)) 176 177 for i := 0; i < int(dataSlab.elements.Count()); i++ { 178 elem, err := dataSlab.elements.Element(i) 179 if err != nil { 180 // Don't need to wrap error as external error because err is already categorized by elements.Element(). 181 return nil, err 182 } 183 if group, ok := elem.(elementGroup); ok { 184 if !group.Inline() { 185 extSlab := group.(*externalCollisionGroup) 186 collisionSlabIDs = append(collisionSlabIDs, extSlab.id) 187 } 188 } 189 } 190 191 childStorables := dataSlab.ChildStorables() 192 for _, e := range childStorables { 193 if id, ok := e.(StorageIDStorable); ok { 194 overflowIDs = append(overflowIDs, StorageID(id)) 195 } 196 } 197 198 } else { 199 meta := slab.(*MapMetaDataSlab) 200 dumps = append(dumps, fmt.Sprintf("level %d, %s", level+1, meta)) 201 202 for _, storable := range slab.ChildStorables() { 203 id, ok := storable.(StorageIDStorable) 204 if !ok { 205 return nil, NewFatalError(errors.New("metadata slab's child storables are not of type StorageIDStorable")) 206 } 207 nextLevelIDs = append(nextLevelIDs, StorageID(id)) 208 } 209 } 210 } 211 212 level++ 213 } 214 215 for _, id := range collisionSlabIDs { 216 slab, err := getMapSlab(m.Storage, id) 217 if err != nil { 218 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 219 return nil, err 220 } 221 dumps = append(dumps, fmt.Sprintf("collision: %s", slab.String())) 222 } 223 224 // overflowIDs include collisionSlabIDs 225 for _, id := range overflowIDs { 226 found := false 227 for _, cid := range collisionSlabIDs { 228 if id == cid { 229 found = true 230 break 231 } 232 } 233 if found { 234 continue 235 } 236 slab, found, err := m.Storage.Retrieve(id) 237 if err != nil { 238 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 239 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to retrieve slab %s", id)) 240 } 241 if !found { 242 return nil, NewSlabNotFoundErrorf(id, "slab not found during map slab dump") 243 } 244 dumps = append(dumps, fmt.Sprintf("overflow: %s", slab)) 245 } 246 247 return dumps, nil 248 } 249 250 func ValidMap(m *OrderedMap, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInputProvider) error { 251 252 extraData := m.root.ExtraData() 253 if extraData == nil { 254 return NewFatalError(fmt.Errorf("root slab %d doesn't have extra data", m.root.ID())) 255 } 256 257 // Verify that extra data has correct type information 258 if typeInfo != nil && !tic(extraData.TypeInfo, typeInfo) { 259 return NewFatalError( 260 fmt.Errorf( 261 "root slab %d type information %v, want %v", 262 m.root.ID(), 263 extraData.TypeInfo, 264 typeInfo, 265 )) 266 } 267 268 // Verify that extra data has seed 269 if extraData.Seed == 0 { 270 return NewFatalError(fmt.Errorf("root slab %d seed is uninitialized", m.root.ID())) 271 } 272 273 computedCount, dataSlabIDs, nextDataSlabIDs, firstKeys, err := validMapSlab( 274 m.Storage, m.digesterBuilder, tic, hip, m.root.ID(), 0, nil, []StorageID{}, []StorageID{}, []Digest{}) 275 if err != nil { 276 // Don't need to wrap error as external error because err is already categorized by validMapSlab(). 277 return err 278 } 279 280 // Verify that extra data has correct count 281 if computedCount != extraData.Count { 282 return NewFatalError( 283 fmt.Errorf( 284 "root slab %d count %d is wrong, want %d", 285 m.root.ID(), 286 extraData.Count, 287 computedCount, 288 )) 289 } 290 291 // Verify next data slab ids 292 if !reflect.DeepEqual(dataSlabIDs[1:], nextDataSlabIDs) { 293 return NewFatalError(fmt.Errorf("chained next data slab ids %v are wrong, want %v", 294 nextDataSlabIDs, dataSlabIDs[1:])) 295 } 296 297 // Verify data slabs' first keys are sorted 298 if !sort.SliceIsSorted(firstKeys, func(i, j int) bool { 299 return firstKeys[i] < firstKeys[j] 300 }) { 301 return NewFatalError(fmt.Errorf("chained first keys %v are not sorted", firstKeys)) 302 } 303 304 // Verify data slabs' first keys are unique 305 if len(firstKeys) > 1 { 306 prev := firstKeys[0] 307 for _, d := range firstKeys[1:] { 308 if prev == d { 309 return NewFatalError(fmt.Errorf("chained first keys %v are not unique", firstKeys)) 310 } 311 prev = d 312 } 313 } 314 315 return nil 316 } 317 318 func validMapSlab( 319 storage SlabStorage, 320 digesterBuilder DigesterBuilder, 321 tic TypeInfoComparator, 322 hip HashInputProvider, 323 id StorageID, 324 level int, 325 headerFromParentSlab *MapSlabHeader, 326 dataSlabIDs []StorageID, 327 nextDataSlabIDs []StorageID, 328 firstKeys []Digest, 329 ) ( 330 elementCount uint64, 331 _dataSlabIDs []StorageID, 332 _nextDataSlabIDs []StorageID, 333 _firstKeys []Digest, 334 err error, 335 ) { 336 337 slab, err := getMapSlab(storage, id) 338 if err != nil { 339 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 340 return 0, nil, nil, nil, err 341 } 342 343 if level > 0 { 344 // Verify that non-root slab doesn't have extra data. 345 if slab.ExtraData() != nil { 346 return 0, nil, nil, nil, NewFatalError(fmt.Errorf("non-root slab %d has extra data", id)) 347 } 348 349 // Verify that non-root slab doesn't underflow 350 if underflowSize, underflow := slab.IsUnderflow(); underflow { 351 return 0, nil, nil, nil, NewFatalError(fmt.Errorf("slab %d underflows by %d bytes", id, underflowSize)) 352 } 353 354 } 355 356 // Verify that slab doesn't overflow 357 if slab.IsFull() { 358 return 0, nil, nil, nil, NewFatalError(fmt.Errorf("slab %d overflows", id)) 359 } 360 361 // Verify that header is in sync with header from parent slab 362 if headerFromParentSlab != nil { 363 if !reflect.DeepEqual(*headerFromParentSlab, slab.Header()) { 364 return 0, nil, nil, nil, NewFatalError( 365 fmt.Errorf("slab %d header %+v is different from header %+v from parent slab", 366 id, slab.Header(), headerFromParentSlab)) 367 } 368 } 369 370 if slab.IsData() { 371 372 dataSlab, ok := slab.(*MapDataSlab) 373 if !ok { 374 return 0, nil, nil, nil, NewFatalError(fmt.Errorf("slab %d is not MapDataSlab", id)) 375 } 376 377 // Verify data slab's elements 378 elementCount, elementSize, err := validMapElements(storage, digesterBuilder, tic, hip, id, dataSlab.elements, 0, nil) 379 if err != nil { 380 // Don't need to wrap error as external error because err is already categorized by validMapElements(). 381 return 0, nil, nil, nil, err 382 } 383 384 // Verify slab's first key 385 if dataSlab.elements.firstKey() != dataSlab.header.firstKey { 386 return 0, nil, nil, nil, NewFatalError( 387 fmt.Errorf("data slab %d header first key %d is wrong, want %d", 388 id, dataSlab.header.firstKey, dataSlab.elements.firstKey())) 389 } 390 391 // Verify that aggregated element size + slab prefix is the same as header.size 392 computedSize := uint32(mapDataSlabPrefixSize) 393 if level == 0 { 394 computedSize = uint32(mapRootDataSlabPrefixSize) 395 } 396 computedSize += elementSize 397 398 if computedSize != dataSlab.header.size { 399 return 0, nil, nil, nil, NewFatalError( 400 fmt.Errorf("data slab %d header size %d is wrong, want %d", 401 id, dataSlab.header.size, computedSize)) 402 } 403 404 // Verify any size flag 405 if dataSlab.anySize { 406 return 0, nil, nil, nil, NewFatalError( 407 fmt.Errorf("data slab %d anySize %t is wrong, want false", 408 id, dataSlab.anySize)) 409 } 410 411 // Verify collision group flag 412 if dataSlab.collisionGroup { 413 return 0, nil, nil, nil, NewFatalError( 414 fmt.Errorf("data slab %d collisionGroup %t is wrong, want false", 415 id, dataSlab.collisionGroup)) 416 } 417 418 dataSlabIDs = append(dataSlabIDs, id) 419 420 if dataSlab.next != StorageIDUndefined { 421 nextDataSlabIDs = append(nextDataSlabIDs, dataSlab.next) 422 } 423 424 firstKeys = append(firstKeys, dataSlab.header.firstKey) 425 426 return elementCount, dataSlabIDs, nextDataSlabIDs, firstKeys, nil 427 } 428 429 meta, ok := slab.(*MapMetaDataSlab) 430 if !ok { 431 return 0, nil, nil, nil, NewFatalError(fmt.Errorf("slab %d is not MapMetaDataSlab", id)) 432 } 433 434 if level == 0 { 435 // Verify that root slab has more than one child slabs 436 if len(meta.childrenHeaders) < 2 { 437 return 0, nil, nil, nil, NewFatalError( 438 fmt.Errorf("root metadata slab %d has %d children, want at least 2 children ", 439 id, len(meta.childrenHeaders))) 440 } 441 } 442 443 elementCount = 0 444 for _, h := range meta.childrenHeaders { 445 // Verify child slabs 446 count := uint64(0) 447 count, dataSlabIDs, nextDataSlabIDs, firstKeys, err = 448 validMapSlab(storage, digesterBuilder, tic, hip, h.id, level+1, &h, dataSlabIDs, nextDataSlabIDs, firstKeys) 449 if err != nil { 450 // Don't need to wrap error as external error because err is already categorized by validMapSlab(). 451 return 0, nil, nil, nil, err 452 } 453 454 elementCount += count 455 } 456 457 // Verify slab header first key 458 if meta.childrenHeaders[0].firstKey != meta.header.firstKey { 459 return 0, nil, nil, nil, NewFatalError( 460 fmt.Errorf("metadata slab %d header first key %d is wrong, want %d", 461 id, meta.header.firstKey, meta.childrenHeaders[0].firstKey)) 462 } 463 464 // Verify that child slab's first keys are sorted. 465 sortedHKey := sort.SliceIsSorted(meta.childrenHeaders, func(i, j int) bool { 466 return meta.childrenHeaders[i].firstKey < meta.childrenHeaders[j].firstKey 467 }) 468 if !sortedHKey { 469 return 0, nil, nil, nil, NewFatalError(fmt.Errorf("metadata slab %d child slab's first key isn't sorted %+v", id, meta.childrenHeaders)) 470 } 471 472 // Verify that child slab's first keys are unique. 473 if len(meta.childrenHeaders) > 1 { 474 prev := meta.childrenHeaders[0].firstKey 475 for _, h := range meta.childrenHeaders[1:] { 476 if prev == h.firstKey { 477 return 0, nil, nil, nil, NewFatalError( 478 fmt.Errorf("metadata slab %d child header first key isn't unique %v", 479 id, meta.childrenHeaders)) 480 } 481 prev = h.firstKey 482 } 483 } 484 485 // Verify slab header's size 486 computedSize := uint32(len(meta.childrenHeaders)*mapSlabHeaderSize) + mapMetaDataSlabPrefixSize 487 if computedSize != meta.header.size { 488 return 0, nil, nil, nil, NewFatalError( 489 fmt.Errorf("metadata slab %d header size %d is wrong, want %d", 490 id, meta.header.size, computedSize)) 491 } 492 493 return elementCount, dataSlabIDs, nextDataSlabIDs, firstKeys, nil 494 } 495 496 func validMapElements( 497 storage SlabStorage, 498 db DigesterBuilder, 499 tic TypeInfoComparator, 500 hip HashInputProvider, 501 id StorageID, 502 elements elements, 503 digestLevel uint, 504 hkeyPrefixes []Digest, 505 ) ( 506 elementCount uint64, 507 elementSize uint32, 508 err error, 509 ) { 510 511 switch elems := elements.(type) { 512 case *hkeyElements: 513 return validMapHkeyElements(storage, db, tic, hip, id, elems, digestLevel, hkeyPrefixes) 514 case *singleElements: 515 return validMapSingleElements(storage, db, tic, hip, id, elems, digestLevel, hkeyPrefixes) 516 default: 517 return 0, 0, NewFatalError(fmt.Errorf("slab %d has unknown elements type %T at digest level %d", id, elements, digestLevel)) 518 } 519 } 520 521 func validMapHkeyElements( 522 storage SlabStorage, 523 db DigesterBuilder, 524 tic TypeInfoComparator, 525 hip HashInputProvider, 526 id StorageID, 527 elements *hkeyElements, 528 digestLevel uint, 529 hkeyPrefixes []Digest, 530 ) ( 531 elementCount uint64, 532 elementSize uint32, 533 err error, 534 ) { 535 536 // Verify element's level 537 if digestLevel != elements.level { 538 return 0, 0, NewFatalError( 539 fmt.Errorf("data slab %d elements digest level %d is wrong, want %d", 540 id, elements.level, digestLevel)) 541 } 542 543 // Verify number of hkeys is the same as number of elements 544 if len(elements.hkeys) != len(elements.elems) { 545 return 0, 0, NewFatalError( 546 fmt.Errorf("data slab %d hkeys count %d is wrong, want %d", 547 id, len(elements.hkeys), len(elements.elems))) 548 } 549 550 // Verify hkeys are sorted 551 if !sort.SliceIsSorted(elements.hkeys, func(i, j int) bool { 552 return elements.hkeys[i] < elements.hkeys[j] 553 }) { 554 return 0, 0, NewFatalError(fmt.Errorf("data slab %d hkeys is not sorted %v", id, elements.hkeys)) 555 } 556 557 // Verify hkeys are unique 558 if len(elements.hkeys) > 1 { 559 prev := elements.hkeys[0] 560 for _, d := range elements.hkeys[1:] { 561 if prev == d { 562 return 0, 0, NewFatalError(fmt.Errorf("data slab %d hkeys is not unique %v", id, elements.hkeys)) 563 } 564 prev = d 565 } 566 } 567 568 elementSize = uint32(hkeyElementsPrefixSize) 569 570 for i := 0; i < len(elements.elems); i++ { 571 e := elements.elems[i] 572 573 elementSize += digestSize 574 575 // Verify element size is <= inline size 576 if digestLevel == 0 { 577 if e.Size() > uint32(maxInlineMapElementSize) { 578 return 0, 0, NewFatalError( 579 fmt.Errorf("data slab %d element %s size %d is too large, want < %d", 580 id, e, e.Size(), maxInlineMapElementSize)) 581 } 582 } 583 584 if group, ok := e.(elementGroup); ok { 585 586 ge, err := group.Elements(storage) 587 if err != nil { 588 // Don't need to wrap error as external error because err is already categorized by elementGroup.Elements(). 589 return 0, 0, err 590 } 591 592 hkeys := make([]Digest, len(hkeyPrefixes)+1) 593 copy(hkeys, hkeyPrefixes) 594 hkeys[len(hkeys)-1] = elements.hkeys[i] 595 596 count, size, err := validMapElements(storage, db, tic, hip, id, ge, digestLevel+1, hkeys) 597 if err != nil { 598 // Don't need to wrap error as external error because err is already categorized by validMapElement(). 599 return 0, 0, err 600 } 601 602 if _, ok := e.(*inlineCollisionGroup); ok { 603 size += inlineCollisionGroupPrefixSize 604 } else { 605 size = externalCollisionGroupPrefixSize + 2 + 1 + 16 606 } 607 608 // Verify element group size 609 if size != e.Size() { 610 return 0, 0, NewFatalError(fmt.Errorf("data slab %d element %s size %d is wrong, want %d", id, e, e.Size(), size)) 611 } 612 613 elementSize += e.Size() 614 615 elementCount += count 616 617 } else { 618 619 se, ok := e.(*singleElement) 620 if !ok { 621 return 0, 0, NewFatalError(fmt.Errorf("data slab %d element type %T is wrong, want *singleElement", id, e)) 622 } 623 624 hkeys := make([]Digest, len(hkeyPrefixes)+1) 625 copy(hkeys, hkeyPrefixes) 626 hkeys[len(hkeys)-1] = elements.hkeys[i] 627 628 // Verify element 629 computedSize, maxDigestLevel, err := validSingleElement(storage, db, tic, hip, se, hkeys) 630 if err != nil { 631 // Don't need to wrap error as external error because err is already categorized by validSingleElement(). 632 return 0, 0, fmt.Errorf("data slab %d: %w", id, err) 633 } 634 635 // Verify digest level 636 if digestLevel >= maxDigestLevel { 637 return 0, 0, NewFatalError( 638 fmt.Errorf("data slab %d, hkey elements %s: digest level %d is wrong, want < %d", 639 id, elements, digestLevel, maxDigestLevel)) 640 } 641 642 elementSize += computedSize 643 644 elementCount++ 645 } 646 } 647 648 // Verify elements size 649 if elementSize != elements.Size() { 650 return 0, 0, NewFatalError(fmt.Errorf("data slab %d elements size %d is wrong, want %d", id, elements.Size(), elementSize)) 651 } 652 653 return elementCount, elementSize, nil 654 } 655 656 func validMapSingleElements( 657 storage SlabStorage, 658 db DigesterBuilder, 659 tic TypeInfoComparator, 660 hip HashInputProvider, 661 id StorageID, 662 elements *singleElements, 663 digestLevel uint, 664 hkeyPrefixes []Digest, 665 ) ( 666 elementCount uint64, 667 elementSize uint32, 668 err error, 669 ) { 670 671 // Verify elements' level 672 if digestLevel != elements.level { 673 return 0, 0, NewFatalError( 674 fmt.Errorf("data slab %d elements level %d is wrong, want %d", 675 id, elements.level, digestLevel)) 676 } 677 678 elementSize = singleElementsPrefixSize 679 680 for _, e := range elements.elems { 681 682 // Verify element 683 computedSize, maxDigestLevel, err := validSingleElement(storage, db, tic, hip, e, hkeyPrefixes) 684 if err != nil { 685 // Don't need to wrap error as external error because err is already categorized by validSingleElement(). 686 return 0, 0, fmt.Errorf("data slab %d: %w", id, err) 687 } 688 689 // Verify element size is <= inline size 690 if e.Size() > uint32(maxInlineMapElementSize) { 691 return 0, 0, NewFatalError( 692 fmt.Errorf("data slab %d element %s size %d is too large, want < %d", 693 id, e, e.Size(), maxInlineMapElementSize)) 694 } 695 696 // Verify digest level 697 if digestLevel != maxDigestLevel { 698 return 0, 0, NewFatalError( 699 fmt.Errorf("data slab %d single elements %s digest level %d is wrong, want %d", 700 id, elements, digestLevel, maxDigestLevel)) 701 } 702 703 elementSize += computedSize 704 } 705 706 // Verify elements size 707 if elementSize != elements.Size() { 708 return 0, 0, NewFatalError(fmt.Errorf("slab %d elements size %d is wrong, want %d", id, elements.Size(), elementSize)) 709 } 710 711 return uint64(len(elements.elems)), elementSize, nil 712 } 713 714 func validSingleElement( 715 storage SlabStorage, 716 db DigesterBuilder, 717 tic TypeInfoComparator, 718 hip HashInputProvider, 719 e *singleElement, 720 digests []Digest, 721 ) ( 722 size uint32, 723 digestMaxLevel uint, 724 err error, 725 ) { 726 727 // Verify key pointer 728 if _, keyPointer := e.key.(StorageIDStorable); e.keyPointer != keyPointer { 729 return 0, 0, NewFatalError(fmt.Errorf("element %s keyPointer %t is wrong, want %t", e, e.keyPointer, keyPointer)) 730 } 731 732 // Verify key 733 kv, err := e.key.StoredValue(storage) 734 if err != nil { 735 // Wrap err as external error (if needed) because err is returned by Stroable interface. 736 return 0, 0, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("element %s key can't be converted to value", e)) 737 } 738 739 err = ValidValue(kv, nil, tic, hip) 740 if err != nil { 741 // Don't need to wrap error as external error because err is already categorized by ValidValue(). 742 return 0, 0, fmt.Errorf("element %s key isn't valid: %w", e, err) 743 } 744 745 // Verify value pointer 746 if _, valuePointer := e.value.(StorageIDStorable); e.valuePointer != valuePointer { 747 return 0, 0, NewFatalError(fmt.Errorf("element %s valuePointer %t is wrong, want %t", e, e.valuePointer, valuePointer)) 748 } 749 750 // Verify value 751 vv, err := e.value.StoredValue(storage) 752 if err != nil { 753 // Wrap err as external error (if needed) because err is returned by Stroable interface. 754 return 0, 0, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("element %s value can't be converted to value", e)) 755 } 756 757 err = ValidValue(vv, nil, tic, hip) 758 if err != nil { 759 // Don't need to wrap error as external error because err is already categorized by ValidValue(). 760 return 0, 0, fmt.Errorf("element %s value isn't valid: %w", e, err) 761 } 762 763 // Verify size 764 computedSize := singleElementPrefixSize + e.key.ByteSize() + e.value.ByteSize() 765 if computedSize != e.Size() { 766 return 0, 0, NewFatalError(fmt.Errorf("element %s size %d is wrong, want %d", e, e.Size(), computedSize)) 767 } 768 769 // Verify digest 770 digest, err := db.Digest(hip, kv) 771 if err != nil { 772 // Wrap err as external error (if needed) because err is returned by DigesterBuilder interface. 773 return 0, 0, wrapErrorfAsExternalErrorIfNeeded(err, "failed to create digester") 774 } 775 776 computedDigests, err := digest.DigestPrefix(digest.Levels()) 777 if err != nil { 778 // Wrap err as external error (if needed) because err is returned by Digester interface. 779 return 0, 0, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate digest prefix up to level %d", digest.Levels())) 780 } 781 782 if !reflect.DeepEqual(digests, computedDigests[:len(digests)]) { 783 return 0, 0, NewFatalError(fmt.Errorf("element %s digest %v is wrong, want %v", e, digests, computedDigests)) 784 } 785 786 return computedSize, digest.Levels(), nil 787 } 788 789 func ValidValue(value Value, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInputProvider) error { 790 switch v := value.(type) { 791 case *Array: 792 return ValidArray(v, typeInfo, tic, hip) 793 case *OrderedMap: 794 return ValidMap(v, typeInfo, tic, hip) 795 } 796 return nil 797 } 798 799 // ValidMapSerialization traverses ordered map tree and verifies serialization 800 // by encoding, decoding, and re-encoding slabs. 801 // It compares in-memory objects of original slab with decoded slab. 802 // It also compares encoded data of original slab with encoded data of decoded slab. 803 func ValidMapSerialization( 804 m *OrderedMap, 805 cborDecMode cbor.DecMode, 806 cborEncMode cbor.EncMode, 807 decodeStorable StorableDecoder, 808 decodeTypeInfo TypeInfoDecoder, 809 compare StorableComparator, 810 ) error { 811 return validMapSlabSerialization( 812 m.Storage, 813 m.root.ID(), 814 cborDecMode, 815 cborEncMode, 816 decodeStorable, 817 decodeTypeInfo, 818 compare, 819 ) 820 } 821 822 func validMapSlabSerialization( 823 storage SlabStorage, 824 id StorageID, 825 cborDecMode cbor.DecMode, 826 cborEncMode cbor.EncMode, 827 decodeStorable StorableDecoder, 828 decodeTypeInfo TypeInfoDecoder, 829 compare StorableComparator, 830 ) error { 831 832 slab, err := getMapSlab(storage, id) 833 if err != nil { 834 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 835 return err 836 } 837 838 // Encode slab 839 data, err := Encode(slab, cborEncMode) 840 if err != nil { 841 // Don't need to wrap error as external error because err is already categorized by Encode(). 842 return err 843 } 844 845 // Decode encoded slab 846 decodedSlab, err := DecodeSlab(id, data, cborDecMode, decodeStorable, decodeTypeInfo) 847 if err != nil { 848 // Don't need to wrap error as external error because err is already categorized by DecodeSlab(). 849 return err 850 } 851 852 // Re-encode decoded slab 853 dataFromDecodedSlab, err := Encode(decodedSlab, cborEncMode) 854 if err != nil { 855 // Don't need to wrap error as external error because err is already categorized by Encode(). 856 return err 857 } 858 859 // Extra check: encoded data size == header.size 860 encodedExtraDataSize, err := getEncodedMapExtraDataSize(slab.ExtraData(), cborEncMode) 861 if err != nil { 862 // Don't need to wrap error as external error because err is already categorized by getEncodedMapExtraDataSize(). 863 return err 864 } 865 866 // Need to exclude extra data size from encoded data size. 867 encodedSlabSize := uint32(len(data) - encodedExtraDataSize) 868 if slab.Header().size != encodedSlabSize { 869 return NewFatalError( 870 fmt.Errorf("slab %d encoded size %d != header.size %d (encoded extra data size %d)", 871 id, encodedSlabSize, slab.Header().size, encodedExtraDataSize)) 872 } 873 874 // Compare encoded data of original slab with encoded data of decoded slab 875 if !bytes.Equal(data, dataFromDecodedSlab) { 876 return NewFatalError( 877 fmt.Errorf("slab %d encoded data is different from decoded slab's encoded data, got %v, want %v", 878 id, dataFromDecodedSlab, data)) 879 } 880 881 if slab.IsData() { 882 dataSlab, ok := slab.(*MapDataSlab) 883 if !ok { 884 return NewFatalError(fmt.Errorf("slab %d is not MapDataSlab", id)) 885 } 886 887 decodedDataSlab, ok := decodedSlab.(*MapDataSlab) 888 if !ok { 889 return NewFatalError(fmt.Errorf("decoded slab %d is not MapDataSlab", id)) 890 } 891 892 // Compare slabs 893 err = mapDataSlabEqual( 894 dataSlab, 895 decodedDataSlab, 896 storage, 897 cborDecMode, 898 cborEncMode, 899 decodeStorable, 900 decodeTypeInfo, 901 compare, 902 ) 903 if err != nil { 904 // Don't need to wrap error as external error because err is already categorized by mapDataSlabEqual(). 905 return fmt.Errorf("data slab %d round-trip serialization failed: %w", id, err) 906 } 907 908 return nil 909 } 910 911 metaSlab, ok := slab.(*MapMetaDataSlab) 912 if !ok { 913 return NewFatalError(fmt.Errorf("slab %d is not MapMetaDataSlab", id)) 914 } 915 916 decodedMetaSlab, ok := decodedSlab.(*MapMetaDataSlab) 917 if !ok { 918 return NewFatalError(fmt.Errorf("decoded slab %d is not MapMetaDataSlab", id)) 919 } 920 921 // Compare slabs 922 err = mapMetaDataSlabEqual(metaSlab, decodedMetaSlab) 923 if err != nil { 924 // Don't need to wrap error as external error because err is already categorized by mapMetaDataSlabEqual(). 925 return fmt.Errorf("metadata slab %d round-trip serialization failed: %w", id, err) 926 } 927 928 for _, h := range metaSlab.childrenHeaders { 929 // Verify child slabs 930 err = validMapSlabSerialization( 931 storage, 932 h.id, 933 cborDecMode, 934 cborEncMode, 935 decodeStorable, 936 decodeTypeInfo, 937 compare, 938 ) 939 if err != nil { 940 // Don't need to wrap error as external error because err is already categorized by validMapSlabSerialization(). 941 return err 942 } 943 } 944 945 return nil 946 } 947 948 func mapDataSlabEqual( 949 expected *MapDataSlab, 950 actual *MapDataSlab, 951 storage SlabStorage, 952 cborDecMode cbor.DecMode, 953 cborEncMode cbor.EncMode, 954 decodeStorable StorableDecoder, 955 decodeTypeInfo TypeInfoDecoder, 956 compare StorableComparator, 957 ) error { 958 959 // Compare extra data 960 err := mapExtraDataEqual(expected.extraData, actual.extraData) 961 if err != nil { 962 // Don't need to wrap error as external error because err is already categorized by mapExtraDataEqual(). 963 return err 964 } 965 966 // Compare next 967 if expected.next != actual.next { 968 return NewFatalError(fmt.Errorf("next %d is wrong, want %d", actual.next, expected.next)) 969 } 970 971 // Compare anySize flag 972 if expected.anySize != actual.anySize { 973 return NewFatalError(fmt.Errorf("anySize %t is wrong, want %t", actual.anySize, expected.anySize)) 974 } 975 976 // Compare collisionGroup flag 977 if expected.collisionGroup != actual.collisionGroup { 978 return NewFatalError(fmt.Errorf("collisionGroup %t is wrong, want %t", actual.collisionGroup, expected.collisionGroup)) 979 } 980 981 // Compare header 982 if !reflect.DeepEqual(expected.header, actual.header) { 983 return NewFatalError(fmt.Errorf("header %+v is wrong, want %+v", actual.header, expected.header)) 984 } 985 986 // Compare elements 987 err = mapElementsEqual( 988 expected.elements, 989 actual.elements, 990 storage, 991 cborDecMode, 992 cborEncMode, 993 decodeStorable, 994 decodeTypeInfo, 995 compare, 996 ) 997 if err != nil { 998 // Don't need to wrap error as external error because err is already categorized by mapElementsEqual(). 999 return err 1000 } 1001 1002 return nil 1003 } 1004 1005 func mapElementsEqual( 1006 expected elements, 1007 actual elements, 1008 storage SlabStorage, 1009 cborDecMode cbor.DecMode, 1010 cborEncMode cbor.EncMode, 1011 decodeStorable StorableDecoder, 1012 decodeTypeInfo TypeInfoDecoder, 1013 compare StorableComparator, 1014 ) error { 1015 switch expectedElems := expected.(type) { 1016 1017 case *hkeyElements: 1018 actualElems, ok := actual.(*hkeyElements) 1019 if !ok { 1020 return NewFatalError(fmt.Errorf("elements type %T is wrong, want %T", actual, expected)) 1021 } 1022 return mapHkeyElementsEqual( 1023 expectedElems, 1024 actualElems, 1025 storage, 1026 cborDecMode, 1027 cborEncMode, 1028 decodeStorable, 1029 decodeTypeInfo, 1030 compare, 1031 ) 1032 1033 case *singleElements: 1034 actualElems, ok := actual.(*singleElements) 1035 if !ok { 1036 return NewFatalError(fmt.Errorf("elements type %T is wrong, want %T", actual, expected)) 1037 } 1038 return mapSingleElementsEqual( 1039 expectedElems, 1040 actualElems, 1041 storage, 1042 cborDecMode, 1043 cborEncMode, 1044 decodeStorable, 1045 decodeTypeInfo, 1046 compare, 1047 ) 1048 1049 } 1050 1051 return nil 1052 } 1053 1054 func mapHkeyElementsEqual( 1055 expected *hkeyElements, 1056 actual *hkeyElements, 1057 storage SlabStorage, 1058 cborDecMode cbor.DecMode, 1059 cborEncMode cbor.EncMode, 1060 decodeStorable StorableDecoder, 1061 decodeTypeInfo TypeInfoDecoder, 1062 compare StorableComparator, 1063 ) error { 1064 1065 if expected.level != actual.level { 1066 return NewFatalError(fmt.Errorf("hkeyElements level %d is wrong, want %d", actual.level, expected.level)) 1067 } 1068 1069 if expected.size != actual.size { 1070 return NewFatalError(fmt.Errorf("hkeyElements size %d is wrong, want %d", actual.size, expected.size)) 1071 } 1072 1073 if len(expected.hkeys) == 0 { 1074 if len(actual.hkeys) != 0 { 1075 return NewFatalError(fmt.Errorf("hkeyElements hkeys %v is wrong, want %v", actual.hkeys, expected.hkeys)) 1076 } 1077 } else { 1078 if !reflect.DeepEqual(expected.hkeys, actual.hkeys) { 1079 return NewFatalError(fmt.Errorf("hkeyElements hkeys %v is wrong, want %v", actual.hkeys, expected.hkeys)) 1080 } 1081 } 1082 1083 if len(expected.elems) != len(actual.elems) { 1084 return NewFatalError(fmt.Errorf("hkeyElements elems len %d is wrong, want %d", len(actual.elems), len(expected.elems))) 1085 } 1086 1087 for i := 0; i < len(expected.elems); i++ { 1088 expectedEle := expected.elems[i] 1089 actualEle := actual.elems[i] 1090 1091 err := mapElementEqual( 1092 expectedEle, 1093 actualEle, 1094 storage, 1095 cborDecMode, 1096 cborEncMode, 1097 decodeStorable, 1098 decodeTypeInfo, 1099 compare, 1100 ) 1101 if err != nil { 1102 // Don't need to wrap error as external error because err is already categorized by mapElementEqual(). 1103 return err 1104 } 1105 } 1106 1107 return nil 1108 } 1109 1110 func mapSingleElementsEqual( 1111 expected *singleElements, 1112 actual *singleElements, 1113 storage SlabStorage, 1114 cborDecMode cbor.DecMode, 1115 cborEncMode cbor.EncMode, 1116 decodeStorable StorableDecoder, 1117 decodeTypeInfo TypeInfoDecoder, 1118 compare StorableComparator, 1119 ) error { 1120 1121 if expected.level != actual.level { 1122 return NewFatalError(fmt.Errorf("singleElements level %d is wrong, want %d", actual.level, expected.level)) 1123 } 1124 1125 if expected.size != actual.size { 1126 return NewFatalError(fmt.Errorf("singleElements size %d is wrong, want %d", actual.size, expected.size)) 1127 } 1128 1129 if len(expected.elems) != len(actual.elems) { 1130 return NewFatalError(fmt.Errorf("singleElements elems len %d is wrong, want %d", len(actual.elems), len(expected.elems))) 1131 } 1132 1133 for i := 0; i < len(expected.elems); i++ { 1134 expectedElem := expected.elems[i] 1135 actualElem := actual.elems[i] 1136 1137 err := mapSingleElementEqual( 1138 expectedElem, 1139 actualElem, 1140 storage, 1141 cborDecMode, 1142 cborEncMode, 1143 decodeStorable, 1144 decodeTypeInfo, 1145 compare, 1146 ) 1147 if err != nil { 1148 // Don't need to wrap error as external error because err is already categorized by mapSingleElementEqual(). 1149 return err 1150 } 1151 } 1152 1153 return nil 1154 } 1155 1156 func mapElementEqual( 1157 expected element, 1158 actual element, 1159 storage SlabStorage, 1160 cborDecMode cbor.DecMode, 1161 cborEncMode cbor.EncMode, 1162 decodeStorable StorableDecoder, 1163 decodeTypeInfo TypeInfoDecoder, 1164 compare StorableComparator, 1165 ) error { 1166 switch expectedElem := expected.(type) { 1167 1168 case *singleElement: 1169 actualElem, ok := actual.(*singleElement) 1170 if !ok { 1171 return NewFatalError(fmt.Errorf("elements type %T is wrong, want %T", actual, expected)) 1172 } 1173 return mapSingleElementEqual( 1174 expectedElem, 1175 actualElem, 1176 storage, 1177 cborDecMode, 1178 cborEncMode, 1179 decodeStorable, 1180 decodeTypeInfo, 1181 compare, 1182 ) 1183 1184 case *inlineCollisionGroup: 1185 actualElem, ok := actual.(*inlineCollisionGroup) 1186 if !ok { 1187 return NewFatalError(fmt.Errorf("elements type %T is wrong, want %T", actual, expected)) 1188 } 1189 return mapElementsEqual( 1190 expectedElem.elements, 1191 actualElem.elements, 1192 storage, 1193 cborDecMode, 1194 cborEncMode, 1195 decodeStorable, 1196 decodeTypeInfo, 1197 compare, 1198 ) 1199 1200 case *externalCollisionGroup: 1201 actualElem, ok := actual.(*externalCollisionGroup) 1202 if !ok { 1203 return NewFatalError(fmt.Errorf("elements type %T is wrong, want %T", actual, expected)) 1204 } 1205 return mapExternalCollisionElementsEqual( 1206 expectedElem, 1207 actualElem, 1208 storage, 1209 cborDecMode, 1210 cborEncMode, 1211 decodeStorable, 1212 decodeTypeInfo, 1213 compare, 1214 ) 1215 1216 } 1217 1218 return nil 1219 } 1220 1221 func mapExternalCollisionElementsEqual( 1222 expected *externalCollisionGroup, 1223 actual *externalCollisionGroup, 1224 storage SlabStorage, 1225 cborDecMode cbor.DecMode, 1226 cborEncMode cbor.EncMode, 1227 decodeStorable StorableDecoder, 1228 decodeTypeInfo TypeInfoDecoder, 1229 compare StorableComparator, 1230 ) error { 1231 1232 if expected.size != actual.size { 1233 return NewFatalError(fmt.Errorf("externalCollisionGroup size %d is wrong, want %d", actual.size, expected.size)) 1234 } 1235 1236 if expected.id != actual.id { 1237 return NewFatalError(fmt.Errorf("externalCollisionGroup id %d is wrong, want %d", actual.id, expected.id)) 1238 } 1239 1240 // Compare external collision slab 1241 err := validMapSlabSerialization( 1242 storage, 1243 expected.id, 1244 cborDecMode, 1245 cborEncMode, 1246 decodeStorable, 1247 decodeTypeInfo, 1248 compare, 1249 ) 1250 if err != nil { 1251 // Don't need to wrap error as external error because err is already categorized by validMapSlabSerialization(). 1252 return err 1253 } 1254 1255 return nil 1256 } 1257 1258 func mapSingleElementEqual( 1259 expected *singleElement, 1260 actual *singleElement, 1261 storage SlabStorage, 1262 cborDecMode cbor.DecMode, 1263 cborEncMode cbor.EncMode, 1264 decodeStorable StorableDecoder, 1265 decodeTypeInfo TypeInfoDecoder, 1266 compare StorableComparator, 1267 ) error { 1268 1269 if expected.size != actual.size { 1270 return NewFatalError(fmt.Errorf("singleElement size %d is wrong, want %d", actual.size, expected.size)) 1271 } 1272 1273 if expected.keyPointer != actual.keyPointer { 1274 return NewFatalError(fmt.Errorf("singleElement keyPointer %t is wrong, want %t", actual.keyPointer, expected.keyPointer)) 1275 } 1276 1277 if expected.valuePointer != actual.valuePointer { 1278 return NewFatalError(fmt.Errorf("singleElement valuePointer %t is wrong, want %t", actual.valuePointer, expected.valuePointer)) 1279 } 1280 1281 if !compare(expected.key, actual.key) { 1282 return NewFatalError(fmt.Errorf("singleElement key %v is wrong, want %v", actual.key, expected.key)) 1283 } 1284 1285 // Compare key stored in a separate slab 1286 if idStorable, ok := expected.key.(StorageIDStorable); ok { 1287 1288 v, err := idStorable.StoredValue(storage) 1289 if err != nil { 1290 // Don't need to wrap error as external error because err is already categorized by StorageIDStorable.StoredValue(). 1291 return err 1292 } 1293 1294 err = ValidValueSerialization( 1295 v, 1296 cborDecMode, 1297 cborEncMode, 1298 decodeStorable, 1299 decodeTypeInfo, 1300 compare, 1301 ) 1302 if err != nil { 1303 // Don't need to wrap error as external error because err is already categorized by ValidValueSerialization(). 1304 return err 1305 } 1306 } 1307 1308 if !compare(expected.value, actual.value) { 1309 return NewFatalError(fmt.Errorf("singleElement value %v is wrong, want %v", actual.value, expected.value)) 1310 } 1311 1312 // Compare value stored in a separate slab 1313 if idStorable, ok := expected.value.(StorageIDStorable); ok { 1314 1315 v, err := idStorable.StoredValue(storage) 1316 if err != nil { 1317 // Don't need to wrap error as external error because err is already categorized by StorageIDStorable.StoredValue(). 1318 return err 1319 } 1320 1321 err = ValidValueSerialization( 1322 v, 1323 cborDecMode, 1324 cborEncMode, 1325 decodeStorable, 1326 decodeTypeInfo, 1327 compare, 1328 ) 1329 if err != nil { 1330 // Don't need to wrap error as external error because err is already categorized by ValidValueSerialization(). 1331 return err 1332 } 1333 } 1334 1335 return nil 1336 } 1337 1338 func mapMetaDataSlabEqual(expected, actual *MapMetaDataSlab) error { 1339 1340 // Compare extra data 1341 err := mapExtraDataEqual(expected.extraData, actual.extraData) 1342 if err != nil { 1343 // Don't need to wrap error as external error because err is already categorized by mapExtraDataEqual(). 1344 return err 1345 } 1346 1347 // Compare header 1348 if !reflect.DeepEqual(expected.header, actual.header) { 1349 return NewFatalError(fmt.Errorf("header %+v is wrong, want %+v", actual.header, expected.header)) 1350 } 1351 1352 // Compare childrenHeaders 1353 if !reflect.DeepEqual(expected.childrenHeaders, actual.childrenHeaders) { 1354 return NewFatalError(fmt.Errorf("childrenHeaders %+v is wrong, want %+v", actual.childrenHeaders, expected.childrenHeaders)) 1355 } 1356 1357 return nil 1358 } 1359 1360 func mapExtraDataEqual(expected, actual *MapExtraData) error { 1361 1362 if (expected == nil) && (actual == nil) { 1363 return nil 1364 } 1365 1366 if (expected == nil) != (actual == nil) { 1367 return NewFatalError(fmt.Errorf("has extra data is %t, want %t", actual == nil, expected == nil)) 1368 } 1369 1370 if !reflect.DeepEqual(*expected, *actual) { 1371 return NewFatalError(fmt.Errorf("extra data %+v is wrong, want %+v", *actual, *expected)) 1372 } 1373 1374 return nil 1375 } 1376 1377 func getEncodedMapExtraDataSize(extraData *MapExtraData, cborEncMode cbor.EncMode) (int, error) { 1378 if extraData == nil { 1379 return 0, nil 1380 } 1381 1382 var buf bytes.Buffer 1383 enc := NewEncoder(&buf, cborEncMode) 1384 1385 err := extraData.Encode(enc, byte(0), byte(0)) 1386 if err != nil { 1387 // Don't need to wrap error as external error because err is already categorized by MapExtraData.Encode(). 1388 return 0, err 1389 } 1390 1391 return len(buf.Bytes()), nil 1392 }