Skip to content

Commit

Permalink
Merge pull request #3138 from onflow/bastian/fix-empty-intersection-t…
Browse files Browse the repository at this point in the history
…ype-migration
  • Loading branch information
turbolent authored Mar 4, 2024
2 parents f605ce8 + 574c0df commit 7eccaf4
Show file tree
Hide file tree
Showing 14 changed files with 592 additions and 144 deletions.
8 changes: 6 additions & 2 deletions migrations/entitlements/migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ func TestConvertToEntitledType(t *testing.T) {
nil,
sema.UnauthorizedAccess,
sema.NewIntersectionType(
nil,
nil,
[]*sema.InterfaceType{
interfaceTypeInheriting,
Expand All @@ -541,6 +542,7 @@ func TestConvertToEntitledType(t *testing.T) {
nil,
eFAndGAccess,
sema.NewIntersectionType(
nil,
nil,
[]*sema.InterfaceType{
interfaceTypeInheriting,
Expand All @@ -556,6 +558,7 @@ func TestConvertToEntitledType(t *testing.T) {
sema.NewOptionalType(
nil,
sema.NewIntersectionType(
nil,
nil,
[]*sema.InterfaceType{
interfaceTypeInheriting,
Expand All @@ -570,6 +573,7 @@ func TestConvertToEntitledType(t *testing.T) {
sema.NewOptionalType(
nil,
sema.NewIntersectionType(
nil,
nil,
[]*sema.InterfaceType{
interfaceTypeInheriting,
Expand Down Expand Up @@ -1313,7 +1317,7 @@ func TestConvertToEntitledValue(t *testing.T) {
},
}

test := func(testCase testCase, valueGenerator valueGenerator, typeGenerator typeGenerator) {
test := func(t *testing.T, testCase testCase, valueGenerator valueGenerator, typeGenerator typeGenerator) {

input := valueGenerator.wrap(typeGenerator.wrap(testCase.Input))
if input == nil {
Expand Down Expand Up @@ -1346,7 +1350,7 @@ func TestConvertToEntitledValue(t *testing.T) {
for _, typeGenerator := range typeGenerators {
t.Run(typeGenerator.name, func(t *testing.T) {

test(testCase, valueGenerator, typeGenerator)
test(t, testCase, valueGenerator, typeGenerator)
})
}
})
Expand Down
217 changes: 203 additions & 14 deletions migrations/migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/onflow/cadence/runtime"
"github.com/onflow/cadence/runtime/common"
"github.com/onflow/cadence/runtime/interpreter"
"github.com/onflow/cadence/runtime/sema"
"github.com/onflow/cadence/runtime/stdlib"
. "github.com/onflow/cadence/runtime/tests/runtime_utils"
"github.com/onflow/cadence/runtime/tests/utils"
Expand All @@ -42,10 +43,10 @@ type testReporter struct {
interpreter.StorageKey
interpreter.StorageMapKey
}][]string
errored map[struct {
errors map[struct {
interpreter.StorageKey
interpreter.StorageMapKey
}][]string
}][]error
}

var _ Reporter = &testReporter{}
Expand All @@ -56,10 +57,10 @@ func newTestReporter() *testReporter {
interpreter.StorageKey
interpreter.StorageMapKey
}][]string{},
errored: map[struct {
errors: map[struct {
interpreter.StorageKey
interpreter.StorageMapKey
}][]string{},
}][]error{},
}
}

Expand All @@ -85,8 +86,8 @@ func (t *testReporter) Migrated(
func (t *testReporter) Error(
storageKey interpreter.StorageKey,
storageMapKey interpreter.StorageMapKey,
migration string,
_ error,
_ string,
err error,
) {
key := struct {
interpreter.StorageKey
Expand All @@ -96,9 +97,9 @@ func (t *testReporter) Error(
StorageMapKey: storageMapKey,
}

t.errored[key] = append(
t.errored[key],
migration,
t.errors[key] = append(
t.errors[key],
err,
)
}

Expand Down Expand Up @@ -702,18 +703,18 @@ func TestMigrationError(t *testing.T) {
map[struct {
interpreter.StorageKey
interpreter.StorageMapKey
}][]string{
}][]error{
{
StorageKey: interpreter.StorageKey{
Address: account,
Key: pathDomain.Identifier(),
},
StorageMapKey: interpreter.StringStorageMapKey("int8_value"),
}: {
"testInt8Migration",
errors.New("error occurred while migrating int8"),
},
},
reporter.errored,
reporter.errors,
)
}

Expand Down Expand Up @@ -806,7 +807,7 @@ func TestCapConMigration(t *testing.T) {

// Assert

assert.Len(t, reporter.errored, 0)
assert.Len(t, reporter.errors, 0)
assert.Len(t, reporter.migrated, 2)

storageMap = storage.GetStorageMap(
Expand Down Expand Up @@ -921,7 +922,7 @@ func TestContractMigration(t *testing.T) {

// Assert

assert.Len(t, reporter.errored, 0)
assert.Len(t, reporter.errors, 0)
assert.Len(t, reporter.migrated, 1)

value, err := rt.ExecuteScript(
Expand All @@ -947,3 +948,191 @@ func TestContractMigration(t *testing.T) {
value,
)
}

// testCompositeValueMigration

type testCompositeValueMigration struct {
}

var _ ValueMigration = testCompositeValueMigration{}

func (testCompositeValueMigration) Name() string {
return "testCompositeValueMigration"
}

func (m testCompositeValueMigration) Migrate(
_ interpreter.StorageKey,
_ interpreter.StorageMapKey,
value interpreter.Value,
inter *interpreter.Interpreter,
) (
interpreter.Value,
error,
) {
compositeValue, ok := value.(*interpreter.CompositeValue)
if !ok {
return nil, nil
}

return interpreter.NewCompositeValue(
inter,
emptyLocationRange,
utils.TestLocation,
"S2",
common.CompositeKindStructure,
nil,
common.Address(compositeValue.StorageAddress()),
), nil
}

func TestEmptyIntersectionTypeMigration(t *testing.T) {

t.Parallel()

testAddress := common.MustBytesToAddress([]byte{0x1})

rt := NewTestInterpreterRuntime()

runtimeInterface := &TestRuntimeInterface{
Storage: NewTestLedger(nil, nil),
}

// Prepare

storage, inter, err := rt.Storage(runtime.Context{
Location: utils.TestLocation,
Interface: runtimeInterface,
})
require.NoError(t, err)

storageMap := storage.GetStorageMap(
testAddress,
common.PathDomainStorage.Identifier(),
true,
)

elaboration := sema.NewElaboration(nil)

const s1QualifiedIdentifier = "S1"
const s2QualifiedIdentifier = "S2"

elaboration.SetCompositeType(
utils.TestLocation.TypeID(nil, s1QualifiedIdentifier),
&sema.CompositeType{
Location: utils.TestLocation,
Members: &sema.StringMemberOrderedMap{},
Identifier: s1QualifiedIdentifier,
Kind: common.CompositeKindStructure,
},
)

elaboration.SetCompositeType(
utils.TestLocation.TypeID(nil, s2QualifiedIdentifier),
&sema.CompositeType{
Location: utils.TestLocation,
Members: &sema.StringMemberOrderedMap{},
Identifier: s2QualifiedIdentifier,
Kind: common.CompositeKindStructure,
},
)

compositeValue := interpreter.NewCompositeValue(
inter,
emptyLocationRange,
utils.TestLocation,
s1QualifiedIdentifier,
common.CompositeKindStructure,
nil,
testAddress,
)

inter.Program = &interpreter.Program{
Elaboration: elaboration,
}

// NOTE: create an empty intersection type with a legacy type: AnyStruct{}
emptyIntersectionType := interpreter.NewIntersectionStaticType(
nil,
nil,
)
emptyIntersectionType.LegacyType = interpreter.PrimitiveStaticTypeAnyStruct

storageMapKey := interpreter.StringStorageMapKey("test")

dictionaryKey := interpreter.NewUnmeteredStringValue("foo")

dictionaryValue := interpreter.NewDictionaryValueWithAddress(
inter,
emptyLocationRange,
interpreter.NewDictionaryStaticType(
nil,
interpreter.PrimitiveStaticTypeString,
emptyIntersectionType,
),
testAddress,
)

dictionaryValue.Insert(
inter,
emptyLocationRange,
dictionaryKey,
compositeValue,
)

storageMap.WriteValue(
inter,
storageMapKey,
dictionaryValue,
)

// Migrate

reporter := newTestReporter()

migration := NewStorageMigration(inter, storage)

migration.Migrate(
&AddressSliceIterator{
Addresses: []common.Address{
testAddress,
},
},
migration.NewValueMigrationsPathMigrator(
reporter,
testCompositeValueMigration{},
),
)

err = migration.Commit()
require.NoError(t, err)

// Assert

assert.Len(t, reporter.errors, 0)
assert.Len(t, reporter.migrated, 1)

storageMap = storage.GetStorageMap(
testAddress,
common.PathDomainStorage.Identifier(),
false,
)

assert.Equal(t, uint64(1), storageMap.Count())

migratedValue := storageMap.ReadValue(nil, storageMapKey)

require.IsType(t, &interpreter.DictionaryValue{}, migratedValue)
migratedDictionaryValue := migratedValue.(*interpreter.DictionaryValue)

migratedChildValue, ok := migratedDictionaryValue.Get(inter, emptyLocationRange, dictionaryKey)
require.True(t, ok)

require.IsType(t, &interpreter.CompositeValue{}, migratedChildValue)
migratedCompositeValue := migratedChildValue.(*interpreter.CompositeValue)

require.Equal(
t,
s2QualifiedIdentifier,
migratedCompositeValue.QualifiedIdentifier,
)
}
14 changes: 5 additions & 9 deletions runtime/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3321,7 +3321,7 @@ func lookupEntitlement(interpreter *Interpreter, typeID string) (*sema.Entitleme
return nil, err
}

typ, err := interpreter.getEntitlement(common.TypeID(typeID))
typ, err := interpreter.GetEntitlementType(common.TypeID(typeID))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -4473,7 +4473,7 @@ func (interpreter *Interpreter) authAccountCheckFunction(addressValue AddressVal
)
}

func (interpreter *Interpreter) getEntitlement(typeID common.TypeID) (*sema.EntitlementType, error) {
func (interpreter *Interpreter) GetEntitlementType(typeID common.TypeID) (*sema.EntitlementType, error) {
location, qualifiedIdentifier, err := common.DecodeTypeID(interpreter, string(typeID))
if err != nil {
return nil, err
Expand Down Expand Up @@ -4507,7 +4507,7 @@ func (interpreter *Interpreter) getEntitlement(typeID common.TypeID) (*sema.Enti
return ty, nil
}

func (interpreter *Interpreter) getEntitlementMapType(typeID common.TypeID) (*sema.EntitlementMapType, error) {
func (interpreter *Interpreter) GetEntitlementMapType(typeID common.TypeID) (*sema.EntitlementMapType, error) {
location, qualifiedIdentifier, err := common.DecodeTypeID(interpreter, string(typeID))
if err != nil {
return nil, err
Expand Down Expand Up @@ -4546,10 +4546,7 @@ func (interpreter *Interpreter) ConvertStaticToSemaType(staticType StaticType) (
return ConvertStaticToSemaType(
config.MemoryGauge,
staticType,
interpreter.GetInterfaceType,
interpreter.GetCompositeType,
interpreter.getEntitlement,
interpreter.getEntitlementMapType,
interpreter,
)
}

Expand All @@ -4569,8 +4566,7 @@ func (interpreter *Interpreter) MustConvertStaticAuthorizationToSemaAccess(auth
access, err := ConvertStaticAuthorizationToSemaAccess(
interpreter,
auth,
interpreter.getEntitlement,
interpreter.getEntitlementMapType,
interpreter,
)
if err != nil {
panic(err)
Expand Down
Loading

0 comments on commit 7eccaf4

Please sign in to comment.