From 674e15d9e9ad3fc1fc1b5b7160de468aa183dbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 15 Dec 2023 10:51:19 -0800 Subject: [PATCH 1/5] make supported types explicit --- migrations/account_type/migration.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/migrations/account_type/migration.go b/migrations/account_type/migration.go index b3b0502410..908a9fdd3f 100644 --- a/migrations/account_type/migration.go +++ b/migrations/account_type/migration.go @@ -21,6 +21,7 @@ package account_type import ( "github.com/onflow/cadence/migrations" "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/errors" "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" ) @@ -112,11 +113,15 @@ func maybeConvertAccountType(staticType interpreter.StaticType) interpreter.Stat case *interpreter.IntersectionStaticType: // No need to convert `staticType.Types` as they can only be interfaces. - convertedLegacyType := maybeConvertAccountType(staticType.LegacyType) - if convertedLegacyType != nil { - intersectionType := interpreter.NewIntersectionStaticType(nil, staticType.Types) - intersectionType.LegacyType = convertedLegacyType - return intersectionType + + legacyType := staticType.LegacyType + if legacyType != nil { + convertedLegacyType := maybeConvertAccountType(legacyType) + if convertedLegacyType != nil { + intersectionType := interpreter.NewIntersectionStaticType(nil, staticType.Types) + intersectionType.LegacyType = convertedLegacyType + return intersectionType + } } case *interpreter.OptionalStaticType: @@ -155,7 +160,7 @@ func maybeConvertAccountType(staticType interpreter.StaticType) interpreter.Stat // Ignore the wrapper, and continue with the inner type. return maybeConvertAccountType(staticType.PrimitiveStaticType) - default: + case interpreter.PrimitiveStaticType: // Is it safe to do so? switch staticType { case interpreter.PrimitiveStaticTypePublicAccount: //nolint:staticcheck @@ -187,6 +192,9 @@ func maybeConvertAccountType(staticType interpreter.StaticType) interpreter.Stat case interpreter.PrimitiveStaticTypeAccountKey: //nolint:staticcheck return interpreter.AccountKeyStaticType } + + default: + panic(errors.NewUnreachableError()) } return nil From fc69d49edc40afd1e65d736211b39562b6bdd710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 15 Dec 2023 10:51:41 -0800 Subject: [PATCH 2/5] FunctionStaticType.ReturnType only needs a memory gauge, not a full interpreter --- runtime/interpreter/statictype.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/interpreter/statictype.go b/runtime/interpreter/statictype.go index 975ecbd29d..16bd43345e 100644 --- a/runtime/interpreter/statictype.go +++ b/runtime/interpreter/statictype.go @@ -1218,10 +1218,10 @@ func NewFunctionStaticType( } } -func (t FunctionStaticType) ReturnType(interpreter *Interpreter) StaticType { +func (t FunctionStaticType) ReturnType(gauge common.MemoryGauge) StaticType { var returnType StaticType if t.Type.ReturnTypeAnnotation.Type != nil { - returnType = ConvertSemaToStaticType(interpreter, t.Type.ReturnTypeAnnotation.Type) + returnType = ConvertSemaToStaticType(gauge, t.Type.ReturnTypeAnnotation.Type) } return returnType From 501d06c92862127984e46fd539d4446ff861bfcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 15 Dec 2023 10:52:06 -0800 Subject: [PATCH 3/5] report useful errors when a program logs or emits events, but handlers are not provided --- runtime/tests/runtime_utils/testinterface.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime/tests/runtime_utils/testinterface.go b/runtime/tests/runtime_utils/testinterface.go index f51db54a11..412a8b56b8 100644 --- a/runtime/tests/runtime_utils/testinterface.go +++ b/runtime/tests/runtime_utils/testinterface.go @@ -317,11 +317,17 @@ func (i *TestRuntimeInterface) GetSigningAccounts() ([]runtime.Address, error) { } func (i *TestRuntimeInterface) ProgramLog(message string) error { + if i.OnProgramLog == nil { + panic("must specify TestRuntimeInterface.OnProgramLog") + } i.OnProgramLog(message) return nil } func (i *TestRuntimeInterface) EmitEvent(event cadence.Event) error { + if i.OnEmitEvent == nil { + panic("must specify TestRuntimeInterface.OnEmitEvent") + } return i.OnEmitEvent(event) } From e6fc3f5e707e9fa1be3fe2ccff45e91281a79a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 15 Dec 2023 12:17:32 -0800 Subject: [PATCH 4/5] make it explicit that migration is not expected --- migrations/account_type/migration_test.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/migrations/account_type/migration_test.go b/migrations/account_type/migration_test.go index 349ef70e5a..c5469cf04c 100644 --- a/migrations/account_type/migration_test.go +++ b/migrations/account_type/migration_test.go @@ -137,21 +137,24 @@ func TestTypeValueMigration(t *testing.T) { expectedType: interpreter.NewOptionalStaticType(nil, unauthorizedAccountReferenceType), }, "optional_string": { - storedType: interpreter.NewOptionalStaticType(nil, stringType), + storedType: interpreter.NewOptionalStaticType(nil, stringType), + expectedType: nil, }, "constant_sized_account_array": { storedType: interpreter.NewConstantSizedStaticType(nil, publicAccountType, 3), expectedType: interpreter.NewConstantSizedStaticType(nil, unauthorizedAccountReferenceType, 3), }, "constant_sized_string_array": { - storedType: interpreter.NewConstantSizedStaticType(nil, stringType, 3), + storedType: interpreter.NewConstantSizedStaticType(nil, stringType, 3), + expectedType: nil, }, "variable_sized_account_array": { storedType: interpreter.NewVariableSizedStaticType(nil, authAccountType), expectedType: interpreter.NewVariableSizedStaticType(nil, authAccountReferenceType), }, "variable_sized_string_array": { - storedType: interpreter.NewVariableSizedStaticType(nil, stringType), + storedType: interpreter.NewVariableSizedStaticType(nil, stringType), + expectedType: nil, }, "dictionary_with_account_type_value": { storedType: interpreter.NewDictionaryStaticType( @@ -195,6 +198,7 @@ func TestTypeValueMigration(t *testing.T) { stringType, stringType, ), + expectedType: nil, }, "capability": { storedType: interpreter.NewCapabilityStaticType( @@ -211,6 +215,7 @@ func TestTypeValueMigration(t *testing.T) { nil, stringType, ), + expectedType: nil, }, "intersection": { storedType: interpreter.NewIntersectionStaticType( @@ -228,12 +233,14 @@ func TestTypeValueMigration(t *testing.T) { ), }, ), + expectedType: nil, }, "empty intersection": { storedType: interpreter.NewIntersectionStaticType( nil, []*interpreter.InterfaceStaticType{}, ), + expectedType: nil, }, "intersection_with_legacy_type": { storedType: &interpreter.IntersectionStaticType{ @@ -307,6 +314,7 @@ func TestTypeValueMigration(t *testing.T) { "Bar", ), ), + expectedType: nil, }, "composite": { storedType: interpreter.NewCompositeStaticType( @@ -319,6 +327,7 @@ func TestTypeValueMigration(t *testing.T) { "Bar", ), ), + expectedType: nil, }, } From f5c41c9e5412ae2b1114ae918acd62bee5e676a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 15 Dec 2023 12:22:23 -0800 Subject: [PATCH 5/5] fix qualified identifiers --- migrations/account_type/migration_test.go | 32 ++++++++++++++--------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/migrations/account_type/migration_test.go b/migrations/account_type/migration_test.go index c5469cf04c..38f6571a33 100644 --- a/migrations/account_type/migration_test.go +++ b/migrations/account_type/migration_test.go @@ -78,6 +78,9 @@ func TestTypeValueMigration(t *testing.T) { const authAccountType = interpreter.PrimitiveStaticTypeAuthAccount //nolint:staticcheck const stringType = interpreter.PrimitiveStaticTypeString + const fooBarQualifiedIdentifier = "Foo.Bar" + fooAddressLocation := common.NewAddressLocation(nil, account, "Foo") + type testCase struct { storedType interpreter.StaticType expectedType interpreter.StaticType @@ -224,11 +227,11 @@ func TestTypeValueMigration(t *testing.T) { interpreter.NewInterfaceStaticType( nil, nil, - "Bar", + fooBarQualifiedIdentifier, common.NewTypeIDFromQualifiedName( nil, - common.NewAddressLocation(nil, account, "Foo"), - "Bar", + fooAddressLocation, + fooBarQualifiedIdentifier, ), ), }, @@ -307,11 +310,11 @@ func TestTypeValueMigration(t *testing.T) { storedType: interpreter.NewInterfaceStaticType( nil, nil, - "Bar", + fooBarQualifiedIdentifier, common.NewTypeIDFromQualifiedName( nil, - common.NewAddressLocation(nil, account, "Foo"), - "Bar", + fooAddressLocation, + fooBarQualifiedIdentifier, ), ), expectedType: nil, @@ -320,11 +323,11 @@ func TestTypeValueMigration(t *testing.T) { storedType: interpreter.NewCompositeStaticType( nil, nil, - "Bar", + fooBarQualifiedIdentifier, common.NewTypeIDFromQualifiedName( nil, - common.NewAddressLocation(nil, account, "Foo"), - "Bar", + fooAddressLocation, + fooBarQualifiedIdentifier, ), ), expectedType: nil, @@ -475,6 +478,9 @@ func TestNestedTypeValueMigration(t *testing.T) { ) require.NoError(t, err) + fooAddressLocation := common.NewAddressLocation(nil, account, "Foo") + const fooBarQualifiedIdentifier = "Foo.Bar" + testCases := map[string]testCase{ "account_some_value": { storedValue: interpreter.NewUnmeteredSomeValueNonCopying(storedAccountTypeValue), @@ -632,8 +638,8 @@ func TestNestedTypeValueMigration(t *testing.T) { storedValue: interpreter.NewCompositeValue( inter, interpreter.EmptyLocationRange, - common.NewAddressLocation(nil, common.Address{0x42}, "Foo"), - "Bar", + fooAddressLocation, + fooBarQualifiedIdentifier, common.CompositeKindResource, []interpreter.CompositeField{ interpreter.NewUnmeteredCompositeField("field1", storedAccountTypeValue), @@ -644,8 +650,8 @@ func TestNestedTypeValueMigration(t *testing.T) { expectedValue: interpreter.NewCompositeValue( inter, interpreter.EmptyLocationRange, - common.NewAddressLocation(nil, common.Address{0x42}, "Foo"), - "Bar", + fooAddressLocation, + fooBarQualifiedIdentifier, common.CompositeKindResource, []interpreter.CompositeField{ interpreter.NewUnmeteredCompositeField("field1", expectedAccountTypeValue),