Skip to content

Commit

Permalink
Merge pull request #3141 from onflow/supun/fix-static-type-migration
Browse files Browse the repository at this point in the history
Migrate static types of arrays and dictionaries
  • Loading branch information
SupunS authored Feb 28, 2024
2 parents 2dd12d3 + 621b611 commit 08a4868
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 1 deletion.
80 changes: 80 additions & 0 deletions migrations/statictypes/account_type_migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,46 @@ func TestMigratingValuesWithAccountStaticType(t *testing.T) {
require.NoError(t, err)

testCases := map[string]testCase{
"dictionary_value": {
storedValue: interpreter.NewDictionaryValue(
inter,
locationRange,
interpreter.NewDictionaryStaticType(
nil,
interpreter.PrimitiveStaticTypeString,
interpreter.PrimitiveStaticTypePublicAccount, //nolint:staticcheck
),
),
expectedValue: interpreter.NewDictionaryValue(
inter,
locationRange,
interpreter.NewDictionaryStaticType(
nil,
interpreter.PrimitiveStaticTypeString,
unauthorizedAccountReferenceType,
),
),
},
"array_value": {
storedValue: interpreter.NewArrayValue(
inter,
locationRange,
interpreter.NewVariableSizedStaticType(
nil,
interpreter.PrimitiveStaticTypePublicAccount, //nolint:staticcheck
),
common.Address{},
),
expectedValue: interpreter.NewArrayValue(
inter,
locationRange,
interpreter.NewVariableSizedStaticType(
nil,
unauthorizedAccountReferenceType,
),
common.Address{},
),
},
"account_capability_value": {
storedValue: interpreter.NewUnmeteredCapabilityValue(
123,
Expand Down Expand Up @@ -955,6 +995,46 @@ func TestMigratingValuesWithAccountStaticType(t *testing.T) {
BorrowType: unauthorizedAccountReferenceType,
},
},
"capability_dictionary": {
storedValue: interpreter.NewDictionaryValue(
inter,
locationRange,
interpreter.NewDictionaryStaticType(
nil,
interpreter.PrimitiveStaticTypeString,
interpreter.NewCapabilityStaticType(
nil,
interpreter.PrimitiveStaticTypePublicAccount, //nolint:staticcheck
),
),
interpreter.NewUnmeteredStringValue("key"),
interpreter.NewCapabilityValue(
nil,
interpreter.NewUnmeteredUInt64Value(1234),
interpreter.NewAddressValue(nil, common.Address{}),
interpreter.PrimitiveStaticTypePublicAccount, //nolint:staticcheck
),
),
expectedValue: interpreter.NewDictionaryValue(
inter,
locationRange,
interpreter.NewDictionaryStaticType(
nil,
interpreter.PrimitiveStaticTypeString,
interpreter.NewCapabilityStaticType(
nil,
unauthorizedAccountReferenceType,
),
),
interpreter.NewUnmeteredStringValue("key"),
interpreter.NewCapabilityValue(
nil,
interpreter.NewUnmeteredUInt64Value(1234),
interpreter.NewAddressValue(nil, common.Address{}),
unauthorizedAccountReferenceType,
),
),
},
}

// Store values
Expand Down
47 changes: 46 additions & 1 deletion migrations/statictypes/statictype_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (m *StaticTypeMigration) Migrate(
_ interpreter.StorageKey,
_ interpreter.StorageMapKey,
value interpreter.Value,
_ *interpreter.Interpreter,
inter *interpreter.Interpreter,
) (newValue interpreter.Value, err error) {
switch value := value.(type) {
case interpreter.TypeValue:
Expand Down Expand Up @@ -129,6 +129,51 @@ func (m *StaticTypeMigration) Migrate(
value.CapabilityID,
value.TargetPath,
), nil

case *interpreter.ArrayValue:
convertedElementType := m.maybeConvertStaticType(value.Type, nil)
if convertedElementType == nil {
return
}

iterator := value.Iterator(inter, interpreter.EmptyLocationRange)

return interpreter.NewArrayValueWithIterator(
inter,
convertedElementType.(interpreter.ArrayStaticType),
value.GetOwner(),
uint64(value.Count()),
func() interpreter.Value {
return iterator.Next(inter, interpreter.EmptyLocationRange)
},
), nil

case *interpreter.DictionaryValue:
convertedElementType := m.maybeConvertStaticType(value.Type, nil)
if convertedElementType == nil {
return
}

var keysAndValues []interpreter.Value

iterator := value.Iterator()
for {
keyValue, value := iterator.Next(inter)
if keyValue == nil {
break
}

keysAndValues = append(keysAndValues, keyValue)
keysAndValues = append(keysAndValues, value)
}

return interpreter.NewDictionaryValueWithAddress(
inter,
interpreter.EmptyLocationRange,
convertedElementType.(*interpreter.DictionaryStaticType),
value.GetOwner(),
keysAndValues...,
), nil
}

return
Expand Down

0 comments on commit 08a4868

Please sign in to comment.