Skip to content

Commit

Permalink
Validate address of inlined array/map in tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fxamacker committed Sep 22, 2023
1 parent 27aa4cb commit 5d8ff98
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 28 deletions.
24 changes: 18 additions & 6 deletions array_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,16 @@ func DumpArraySlabs(a *Array) ([]string, error) {

type TypeInfoComparator func(TypeInfo, TypeInfo) bool

func ValidArray(a *Array, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInputProvider) error {
func ValidArray(a *Array, address Address, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInputProvider) error {

// Verify array address
if address != a.Address() {
return NewFatalError(fmt.Errorf("array address %v, got %v", address, a.Address()))
}

if address != a.root.Header().slabID.address {
return NewFatalError(fmt.Errorf("array root slab address %v, got %v", address, a.root.Header().slabID.address))
}

// Verify array value ID
err := validArrayValueID(a)
Expand Down Expand Up @@ -199,7 +208,7 @@ func ValidArray(a *Array, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInp

// Verify array root slab
computedCount, dataSlabIDs, nextDataSlabIDs, err :=
validArraySlab(tic, hip, a.Storage, a.root, 0, nil, []SlabID{}, []SlabID{})
validArraySlab(address, tic, hip, a.Storage, a.root, 0, nil, []SlabID{}, []SlabID{})
if err != nil {
// Don't need to wrap error as external error because err is already categorized by validArraySlab().
return err
Expand All @@ -220,6 +229,7 @@ func ValidArray(a *Array, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInp
}

func validArraySlab(
address Address,
tic TypeInfoComparator,
hip HashInputProvider,
storage SlabStorage,
Expand Down Expand Up @@ -265,17 +275,18 @@ func validArraySlab(

switch slab := slab.(type) {
case *ArrayDataSlab:
return validArrayDataSlab(tic, hip, storage, slab, level, dataSlabIDs, nextDataSlabIDs)
return validArrayDataSlab(address, tic, hip, storage, slab, level, dataSlabIDs, nextDataSlabIDs)

case *ArrayMetaDataSlab:
return validArrayMetaDataSlab(tic, hip, storage, slab, level, dataSlabIDs, nextDataSlabIDs)
return validArrayMetaDataSlab(address, tic, hip, storage, slab, level, dataSlabIDs, nextDataSlabIDs)

default:
return 0, nil, nil, NewFatalError(fmt.Errorf("ArraySlab is either *ArrayDataSlab or *ArrayMetaDataSlab, got %T", slab))
}
}

func validArrayDataSlab(
address Address,
tic TypeInfoComparator,
hip HashInputProvider,
storage SlabStorage,
Expand Down Expand Up @@ -348,7 +359,7 @@ func validArrayDataSlab(
id, e,
))
}
err = ValidValue(v, nil, tic, hip)
err = ValidValue(v, address, nil, tic, hip)
if err != nil {
// Don't need to wrap error as external error because err is already categorized by ValidValue().
return 0, nil, nil, fmt.Errorf(
Expand All @@ -362,6 +373,7 @@ func validArrayDataSlab(
}

func validArrayMetaDataSlab(
address Address,
tic TypeInfoComparator,
hip HashInputProvider,
storage SlabStorage,
Expand Down Expand Up @@ -416,7 +428,7 @@ func validArrayMetaDataSlab(
// Verify child slabs
var count uint32
count, dataSlabIDs, nextDataSlabIDs, err =
validArraySlab(tic, hip, storage, childSlab, level+1, &h, dataSlabIDs, nextDataSlabIDs)
validArraySlab(address, tic, hip, storage, childSlab, level+1, &h, dataSlabIDs, nextDataSlabIDs)
if err != nil {
// Don't need to wrap error as external error because err is already categorized by validArraySlab().
return 0, nil, nil, err
Expand Down
6 changes: 3 additions & 3 deletions array_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func verifyArray(
require.Equal(t, len(values), i)

// Verify in-memory slabs
err = ValidArray(array, typeInfo, typeInfoComparator, hashInputProvider)
err = ValidArray(array, address, typeInfo, typeInfoComparator, hashInputProvider)
if err != nil {
PrintArray(array)
}
Expand Down Expand Up @@ -4628,7 +4628,7 @@ func TestSlabSizeWhenResettingMutableStorable(t *testing.T) {
expectedArrayRootDataSlabSize := arrayRootDataSlabPrefixSize + initialStorableSize*arraySize
require.Equal(t, uint32(expectedArrayRootDataSlabSize), array.root.ByteSize())

err = ValidArray(array, typeInfo, typeInfoComparator, hashInputProvider)
err = ValidArray(array, address, typeInfo, typeInfoComparator, hashInputProvider)
require.NoError(t, err)

for i := uint64(0); i < arraySize; i++ {
Expand All @@ -4645,7 +4645,7 @@ func TestSlabSizeWhenResettingMutableStorable(t *testing.T) {
expectedArrayRootDataSlabSize = arrayRootDataSlabPrefixSize + mutatedStorableSize*arraySize
require.Equal(t, uint32(expectedArrayRootDataSlabSize), array.root.ByteSize())

err = ValidArray(array, typeInfo, typeInfoComparator, hashInputProvider)
err = ValidArray(array, address, typeInfo, typeInfoComparator, hashInputProvider)
require.NoError(t, err)
}

Expand Down
48 changes: 32 additions & 16 deletions map_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,16 @@ func DumpMapSlabs(m *OrderedMap) ([]string, error) {
return dumps, nil
}

func ValidMap(m *OrderedMap, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInputProvider) error {
func ValidMap(m *OrderedMap, address Address, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInputProvider) error {

// Verify map address
if address != m.Address() {
return NewFatalError(fmt.Errorf("map address %v, got %v", address, m.Address()))
}

if address != m.root.Header().slabID.address {
return NewFatalError(fmt.Errorf("map root slab address %v, got %v", address, m.root.Header().slabID.address))
}

// Verify map value ID
err := validMapValueID(m)
Expand Down Expand Up @@ -282,7 +291,7 @@ func ValidMap(m *OrderedMap, typeInfo TypeInfo, tic TypeInfoComparator, hip Hash
}

computedCount, dataSlabIDs, nextDataSlabIDs, firstKeys, err := validMapSlab(
m.Storage, m.digesterBuilder, tic, hip, m.root, 0, nil, []SlabID{}, []SlabID{}, []Digest{})
address, m.Storage, m.digesterBuilder, tic, hip, m.root, 0, nil, []SlabID{}, []SlabID{}, []Digest{})
if err != nil {
// Don't need to wrap error as external error because err is already categorized by validMapSlab().
return err
Expand Down Expand Up @@ -327,6 +336,7 @@ func ValidMap(m *OrderedMap, typeInfo TypeInfo, tic TypeInfoComparator, hip Hash
}

func validMapSlab(
address Address,
storage SlabStorage,
digesterBuilder DigesterBuilder,
tic TypeInfoComparator,
Expand Down Expand Up @@ -376,17 +386,18 @@ func validMapSlab(

switch slab := slab.(type) {
case *MapDataSlab:
return validMapDataSlab(storage, digesterBuilder, tic, hip, slab, level, dataSlabIDs, nextDataSlabIDs, firstKeys)
return validMapDataSlab(address, storage, digesterBuilder, tic, hip, slab, level, dataSlabIDs, nextDataSlabIDs, firstKeys)

case *MapMetaDataSlab:
return validMapMetaDataSlab(storage, digesterBuilder, tic, hip, slab, level, dataSlabIDs, nextDataSlabIDs, firstKeys)
return validMapMetaDataSlab(address, storage, digesterBuilder, tic, hip, slab, level, dataSlabIDs, nextDataSlabIDs, firstKeys)

default:
return 0, nil, nil, nil, NewFatalError(fmt.Errorf("MapSlab is either *MapDataSlab or *MapMetaDataSlab, got %T", slab))
}
}

func validMapDataSlab(
address Address,
storage SlabStorage,
digesterBuilder DigesterBuilder,
tic TypeInfoComparator,
Expand All @@ -410,7 +421,7 @@ func validMapDataSlab(
}

// Verify data slab's elements
elementCount, elementSize, err := validMapElements(storage, digesterBuilder, tic, hip, id, dataSlab.elements, 0, nil)
elementCount, elementSize, err := validMapElements(address, storage, digesterBuilder, tic, hip, id, dataSlab.elements, 0, nil)
if err != nil {
// Don't need to wrap error as external error because err is already categorized by validMapElements().
return 0, nil, nil, nil, err
Expand Down Expand Up @@ -470,6 +481,7 @@ func validMapDataSlab(
}

func validMapMetaDataSlab(
address Address,
storage SlabStorage,
digesterBuilder DigesterBuilder,
tic TypeInfoComparator,
Expand Down Expand Up @@ -518,7 +530,7 @@ func validMapMetaDataSlab(
// Verify child slabs
count := uint64(0)
count, dataSlabIDs, nextDataSlabIDs, firstKeys, err =
validMapSlab(storage, digesterBuilder, tic, hip, childSlab, level+1, &h, dataSlabIDs, nextDataSlabIDs, firstKeys)
validMapSlab(address, storage, digesterBuilder, tic, hip, childSlab, level+1, &h, dataSlabIDs, nextDataSlabIDs, firstKeys)
if err != nil {
// Don't need to wrap error as external error because err is already categorized by validMapSlab().
return 0, nil, nil, nil, err
Expand Down Expand Up @@ -567,6 +579,7 @@ func validMapMetaDataSlab(
}

func validMapElements(
address Address,
storage SlabStorage,
db DigesterBuilder,
tic TypeInfoComparator,
Expand All @@ -583,15 +596,16 @@ func validMapElements(

switch elems := elements.(type) {
case *hkeyElements:
return validMapHkeyElements(storage, db, tic, hip, id, elems, digestLevel, hkeyPrefixes)
return validMapHkeyElements(address, storage, db, tic, hip, id, elems, digestLevel, hkeyPrefixes)
case *singleElements:
return validMapSingleElements(storage, db, tic, hip, id, elems, digestLevel, hkeyPrefixes)
return validMapSingleElements(address, storage, db, tic, hip, id, elems, digestLevel, hkeyPrefixes)
default:
return 0, 0, NewFatalError(fmt.Errorf("slab %d has unknown elements type %T at digest level %d", id, elements, digestLevel))
}
}

func validMapHkeyElements(
address Address,
storage SlabStorage,
db DigesterBuilder,
tic TypeInfoComparator,
Expand Down Expand Up @@ -666,7 +680,7 @@ func validMapHkeyElements(
copy(hkeys, hkeyPrefixes)
hkeys[len(hkeys)-1] = elements.hkeys[i]

count, size, err := validMapElements(storage, db, tic, hip, id, ge, digestLevel+1, hkeys)
count, size, err := validMapElements(address, storage, db, tic, hip, id, ge, digestLevel+1, hkeys)
if err != nil {
// Don't need to wrap error as external error because err is already categorized by validMapElement().
return 0, 0, err
Expand Down Expand Up @@ -699,7 +713,7 @@ func validMapHkeyElements(
hkeys[len(hkeys)-1] = elements.hkeys[i]

// Verify element
computedSize, maxDigestLevel, err := validSingleElement(storage, db, tic, hip, se, hkeys)
computedSize, maxDigestLevel, err := validSingleElement(address, storage, db, tic, hip, se, hkeys)
if err != nil {
// Don't need to wrap error as external error because err is already categorized by validSingleElement().
return 0, 0, fmt.Errorf("data slab %d: %w", id, err)
Expand Down Expand Up @@ -727,6 +741,7 @@ func validMapHkeyElements(
}

func validMapSingleElements(
address Address,
storage SlabStorage,
db DigesterBuilder,
tic TypeInfoComparator,
Expand All @@ -753,7 +768,7 @@ func validMapSingleElements(
for _, e := range elements.elems {

// Verify element
computedSize, maxDigestLevel, err := validSingleElement(storage, db, tic, hip, e, hkeyPrefixes)
computedSize, maxDigestLevel, err := validSingleElement(address, storage, db, tic, hip, e, hkeyPrefixes)
if err != nil {
// Don't need to wrap error as external error because err is already categorized by validSingleElement().
return 0, 0, fmt.Errorf("data slab %d: %w", id, err)
Expand Down Expand Up @@ -785,6 +800,7 @@ func validMapSingleElements(
}

func validSingleElement(
address Address,
storage SlabStorage,
db DigesterBuilder,
tic TypeInfoComparator,
Expand Down Expand Up @@ -822,7 +838,7 @@ func validSingleElement(
return 0, 0, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("element %s key can't be converted to value", e))
}

err = ValidValue(kv, nil, tic, hip)
err = ValidValue(kv, address, nil, tic, hip)
if err != nil {
// Don't need to wrap error as external error because err is already categorized by ValidValue().
return 0, 0, fmt.Errorf("element %s key isn't valid: %w", e, err)
Expand All @@ -835,7 +851,7 @@ func validSingleElement(
return 0, 0, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("element %s value can't be converted to value", e))
}

err = ValidValue(vv, nil, tic, hip)
err = ValidValue(vv, address, nil, tic, hip)
if err != nil {
// Don't need to wrap error as external error because err is already categorized by ValidValue().
return 0, 0, fmt.Errorf("element %s value isn't valid: %w", e, err)
Expand Down Expand Up @@ -867,12 +883,12 @@ func validSingleElement(
return computedSize, digest.Levels(), nil
}

func ValidValue(value Value, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInputProvider) error {
func ValidValue(value Value, address Address, typeInfo TypeInfo, tic TypeInfoComparator, hip HashInputProvider) error {
switch v := value.(type) {
case *Array:
return ValidArray(v, typeInfo, tic, hip)
return ValidArray(v, address, typeInfo, tic, hip)
case *OrderedMap:
return ValidMap(v, typeInfo, tic, hip)
return ValidMap(v, address, typeInfo, tic, hip)
}
return nil
}
Expand Down
6 changes: 3 additions & 3 deletions map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func verifyMap(
}

// Verify in-memory slabs
err = ValidMap(m, typeInfo, typeInfoComparator, hashInputProvider)
err = ValidMap(m, address, typeInfo, typeInfoComparator, hashInputProvider)
if err != nil {
PrintMap(m)
}
Expand Down Expand Up @@ -10696,7 +10696,7 @@ func TestSlabSizeWhenResettingMutableStorableInMap(t *testing.T) {
expectedMapRootDataSlabSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + expectedElementSize*mapSize
require.Equal(t, expectedMapRootDataSlabSize, m.root.ByteSize())

err = ValidMap(m, typeInfo, typeInfoComparator, hashInputProvider)
err = ValidMap(m, address, typeInfo, typeInfoComparator, hashInputProvider)
require.NoError(t, err)

// Reset mutable values after changing its storable size
Expand All @@ -10714,7 +10714,7 @@ func TestSlabSizeWhenResettingMutableStorableInMap(t *testing.T) {
expectedMapRootDataSlabSize = mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + expectedElementSize*mapSize
require.Equal(t, expectedMapRootDataSlabSize, m.root.ByteSize())

err = ValidMap(m, typeInfo, typeInfoComparator, hashInputProvider)
err = ValidMap(m, address, typeInfo, typeInfoComparator, hashInputProvider)
require.NoError(t, err)
}

Expand Down

0 comments on commit 5d8ff98

Please sign in to comment.