Skip to content

Commit

Permalink
Merge pull request #3158 from onflow/bastian/use-settype-in-migrations
Browse files Browse the repository at this point in the history
Improve static type and entitlements migrations: Update array/dictionary type directly
  • Loading branch information
turbolent authored Mar 8, 2024
2 parents 32e81b0 + 0d6f45a commit e165153
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 211 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/kr/pretty v0.3.1
github.com/leanovate/gopter v0.2.9
github.com/logrusorgru/aurora/v4 v4.0.0
github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f
github.com/onflow/atree v0.6.1-0.20240308163425-dc825c20b1a2
github.com/rivo/uniseg v0.4.4
github.com/schollz/progressbar/v3 v3.13.1
github.com/stretchr/testify v1.8.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvr
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f h1:Z8/PgTqOgOg02MTRpTBYO2k16FE6z4wEOtaC2WBR9Xo=
github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM=
github.com/onflow/atree v0.6.1-0.20240308163425-dc825c20b1a2 h1:jJLDswfAVB0bHCu1y1FPdKukPcTNmN+jYEX9S9phbv0=
github.com/onflow/atree v0.6.1-0.20240308163425-dc825c20b1a2/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM=
github.com/onflow/crypto v0.25.0 h1:BeWbLsh3ZD13Ej+Uky6kg1PL1ZIVBDVX+2MVBNwqddg=
github.com/onflow/crypto v0.25.0/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
Expand Down
12 changes: 4 additions & 8 deletions migrations/entitlements/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,9 @@ func ConvertValueToEntitlements(
return nil, nil
}

return v.NewWithType(
inter,
interpreter.EmptyLocationRange,
v.SetType(
entitledElementType.(interpreter.ArrayStaticType),
), nil
)

case *interpreter.DictionaryValue:
elementType := v.Type
Expand All @@ -259,11 +257,9 @@ func ConvertValueToEntitlements(
return nil, nil
}

return v.NewWithType(
inter,
interpreter.EmptyLocationRange,
v.SetType(
entitledElementType.(*interpreter.DictionaryStaticType),
), nil
)

case *interpreter.IDCapabilityValue:
borrowType := v.BorrowType
Expand Down
4 changes: 2 additions & 2 deletions migrations/migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1151,15 +1151,15 @@ func (testContainerMigration) Migrate(
interpreter.PrimitiveStaticTypeAnyStruct,
)

return value.NewWithType(inter, emptyLocationRange, newType), nil
value.SetType(newType)

case *interpreter.ArrayValue:

newType := interpreter.NewVariableSizedStaticType(nil,
interpreter.PrimitiveStaticTypeAnyStruct,
)

return value.NewWithType(inter, emptyLocationRange, newType), nil
value.SetType(newType)

case *interpreter.CompositeValue:
if value.QualifiedIdentifier == "Inner" {
Expand Down
12 changes: 4 additions & 8 deletions migrations/statictypes/statictype_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,23 +136,19 @@ func (m *StaticTypeMigration) Migrate(
return
}

return value.NewWithType(
inter,
interpreter.EmptyLocationRange,
value.SetType(
convertedElementType.(interpreter.ArrayStaticType),
), nil
)

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

return value.NewWithType(
inter,
interpreter.EmptyLocationRange,
value.SetType(
convertedElementType.(*interpreter.DictionaryStaticType),
), nil
)
}

return
Expand Down
120 changes: 13 additions & 107 deletions runtime/interpreter/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -3518,55 +3518,12 @@ func (v *ArrayValue) ToConstantSized(
)
}

func (v *ArrayValue) NewWithType(
inter *Interpreter,
locationRange LocationRange,
newType ArrayStaticType,
) *ArrayValue {

newArray := NewArrayValue(
inter,
locationRange,
newType,
v.GetOwner(),
)

storage := inter.Storage()

count := v.Count()

for index := 0; index < count; index++ {

storable := v.RemoveWithoutTransfer(
inter,
locationRange,
// NOTE: always removing first element,
// until original array is empty
0,
)

if storable == nil {
panic(errors.NewUnreachableError())
}

if v.Count() != count-index-1 {
panic(errors.NewUnreachableError())
}

newValue, err := storable.StoredValue(storage)
if err != nil {
panic(err)
}

newArray.InsertWithoutTransfer(
inter,
locationRange,
index,
newValue,
)
func (v *ArrayValue) SetType(staticType ArrayStaticType) {
v.Type = staticType
err := v.array.SetType(staticType)
if err != nil {
panic(errors.NewExternalError(err))
}

return newArray
}

// NumberValue
Expand Down Expand Up @@ -18667,65 +18624,6 @@ func newDictionaryValueFromAtreeMap(
}
}

func (v *DictionaryValue) NewWithType(
inter *Interpreter,
locationRange LocationRange,
newType *DictionaryStaticType,
) *DictionaryValue {

newDictionary := NewDictionaryValueWithAddress(
inter,
locationRange,
newType,
v.GetOwner(),
)

var keys []atree.Value

iterator := v.Iterator()

for {
key := iterator.NextKeyUnconverted()
if key == nil {
break
}

keys = append(keys, key)
}

storage := inter.Storage()

for _, key := range keys {
existingKeyStorable, existingValueStorable := v.RemoveWithoutTransfer(
inter,
locationRange,
key,
)
if existingKeyStorable == nil || existingValueStorable == nil {
panic(errors.NewUnreachableError())
}

newKey, err := existingKeyStorable.StoredValue(storage)
if err != nil {
panic(err)
}

newValue, err := existingValueStorable.StoredValue(storage)
if err != nil {
panic(err)
}

newDictionary.InsertWithoutTransfer(
inter,
locationRange,
newKey,
newValue,
)
}

return newDictionary
}

var _ Value = &DictionaryValue{}
var _ atree.Value = &DictionaryValue{}
var _ EquatableValue = &DictionaryValue{}
Expand Down Expand Up @@ -19903,6 +19801,14 @@ func (v *DictionaryValue) IsResourceKinded(interpreter *Interpreter) bool {
return *v.isResourceKinded
}

func (v *DictionaryValue) SetType(staticType *DictionaryStaticType) {
v.Type = staticType
err := v.dictionary.SetType(staticType)
if err != nil {
panic(errors.NewExternalError(err))
}
}

// OptionalValue

type OptionalValue interface {
Expand Down
83 changes: 0 additions & 83 deletions runtime/interpreter/value_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4187,86 +4187,3 @@ func TestValue_ConformsToStaticType(t *testing.T) {
})

}

func TestDictionaryValue_NewWithType(t *testing.T) {

t.Parallel()

inter := newTestInterpreter(t)

address := common.Address{0x1}

newDictionaryValue := func(dictionaryType *DictionaryStaticType) *DictionaryValue {
return NewDictionaryValueWithAddress(
inter,
EmptyLocationRange,
dictionaryType,
address,
NewUnmeteredStringValue("a"),
NewUnmeteredIntValueFromInt64(1),
NewUnmeteredStringValue("b"),
NewUnmeteredIntValueFromInt64(2),
NewUnmeteredStringValue("c"),
NewUnmeteredIntValueFromInt64(3),
)
}

oldType := &DictionaryStaticType{
KeyType: PrimitiveStaticTypeString,
ValueType: PrimitiveStaticTypeAnyStruct,
}

newType := &DictionaryStaticType{
KeyType: PrimitiveStaticTypeString,
ValueType: PrimitiveStaticTypeInt,
}

require.True(t,
newDictionaryValue(oldType).
NewWithType(inter, EmptyLocationRange, newType).
Equal(
inter,
EmptyLocationRange,
newDictionaryValue(newType),
),
)
}

func TestArrayValue_NewWithType(t *testing.T) {

t.Parallel()

inter := newTestInterpreter(t)

address := common.Address{0x1}

newArrayValue := func(arrayType ArrayStaticType) *ArrayValue {
return NewArrayValue(
inter,
EmptyLocationRange,
arrayType,
address,
NewUnmeteredStringValue("a"),
NewUnmeteredStringValue("b"),
NewUnmeteredStringValue("c"),
)
}

oldType := &VariableSizedStaticType{
Type: PrimitiveStaticTypeAnyStruct,
}

newType := &VariableSizedStaticType{
Type: PrimitiveStaticTypeString,
}

require.True(t,
newArrayValue(oldType).
NewWithType(inter, EmptyLocationRange, newType).
Equal(
inter,
EmptyLocationRange,
newArrayValue(newType),
),
)
}

0 comments on commit e165153

Please sign in to comment.