Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update atree register inlining v1.0 branch #3454

Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
aeef038
Merge pull request #3437 from onflow/release/v1.0.0-preview.35
turbolent Jun 24, 2024
60db132
add migrations data for 2024-06-26
zhangchiqing Jun 27, 2024
77565e2
Merge pull request #3439 from onflow/leo/migrations_data-2024-06-26
SupunS Jun 27, 2024
1c1db28
turn commit hash into pseudo version
turbolent Jun 27, 2024
c0fa37d
Merge pull request #3440 from onflow/bastian/improve-update-tool-6
turbolent Jun 27, 2024
f0f1ff2
get the repos default branch, don't assume it's master
turbolent Jun 27, 2024
79878f5
improve handling of non-v0/1 major versions
turbolent Jun 27, 2024
92c8ee8
Merge pull request #3441 from onflow/bastian/improve-update-Tool-7
turbolent Jun 27, 2024
b17ca98
ignore draft releases
turbolent Jun 28, 2024
f43e799
Merge branch 'master' into bastian/improve-update-Tool-7
turbolent Jun 28, 2024
03341f1
Merge pull request #3442 from onflow/bastian/improve-update-Tool-7
turbolent Jun 28, 2024
7380e47
add tests for existing borrowing
turbolent Jun 28, 2024
da6e662
add root block info for migration net
zhangchiqing Jun 29, 2024
3d4874a
Merge pull request #3443 from onflow/leo/add-root-block-info
turbolent Jun 29, 2024
588ea76
Remove mention of feature branch
chasefleming Jul 1, 2024
1965f93
Merge pull request #3444 from onflow/cf/remove-feature-branch
turbolent Jul 2, 2024
ce94b54
fix toConstantSized: always return optional
turbolent Jul 2, 2024
bb69a7c
improve toVariableSized
turbolent Jul 2, 2024
93cc80a
improve tests
turbolent Jul 2, 2024
736227f
simplify subtyping
turbolent Jul 2, 2024
24f7c3b
allow borrowing with subtype, but ensure valid access/auth
turbolent Jul 3, 2024
7833360
Update runtime/stdlib/account.go
turbolent Jul 4, 2024
5fcde32
add 2024-07-03 staged contracts report
zhangchiqing Jul 4, 2024
12be5dc
Merge pull request #3450 from onflow/leo/add-staged-contracts-report-…
turbolent Jul 4, 2024
95bf3d9
add root block info for migration 2024-07-03
zhangchiqing Jul 4, 2024
be2d8ff
Merge pull request #3451 from onflow/leo/add-root-block-id-for-migrat…
turbolent Jul 4, 2024
76bd6db
Merge pull request #3446 from onflow/bastian/3445-fix-toconstantsized
turbolent Jul 8, 2024
2a5e3c4
Merge pull request #3449 from onflow/bastian/3080-improve-capabilitiy…
turbolent Jul 8, 2024
5979bf0
Merge pull request #3447 from onflow/bastian/simplify-subtyping
turbolent Jul 8, 2024
38f634c
Merge branch 'master' into bastian/update-atree-register-inlining-v1.0-7
turbolent Jul 8, 2024
c45e331
tidy
turbolent Jul 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
882 changes: 445 additions & 437 deletions migrations_data/staged-contracts-report-2024-06-12T13-03-00Z-testnet.md

Large diffs are not rendered by default.

894 changes: 451 additions & 443 deletions migrations_data/staged-contracts-report-2024-06-19T12-31-00Z-testnet.md

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

137 changes: 124 additions & 13 deletions runtime/capabilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,20 @@ func TestRuntimeCapability_borrowAndCheck(t *testing.T) {
entitlement X

access(all)
resource R {
resource interface RI {}

access(all)
resource R: RI {

access(all)
let foo: Int

access(X)
let bar: Int

init() {
self.foo = 42
self.bar = 21
}
}

Expand Down Expand Up @@ -128,6 +135,12 @@ func TestRuntimeCapability_borrowAndCheck(t *testing.T) {

let noCap = self.account.capabilities.storage.issue<&R>(/storage/nonExistentTarget)
self.account.capabilities.publish(noCap, at: /public/nonExistentTarget)

let unentitledRICap = self.account.capabilities.storage.issue<&{RI}>(/storage/r)
self.account.capabilities.publish(unentitledRICap, at: /public/unentitledRI)

let entitledRICap = self.account.capabilities.storage.issue<auth(X) &{RI}>(/storage/r)
self.account.capabilities.publish(entitledRICap, at: /public/entitledRI)
}

access(all)
Expand Down Expand Up @@ -252,15 +265,51 @@ func TestRuntimeCapability_borrowAndCheck(t *testing.T) {

access(all)
fun testSwap(): Int {
let ref = self.account.capabilities.get<&R>(/public/r).borrow()!
let ref = self.account.capabilities.get<&R>(/public/r).borrow()!

let r <- self.account.storage.load<@R>(from: /storage/r)
destroy r
let r <- self.account.storage.load<@R>(from: /storage/r)
destroy r

let r2 <- create R2()
self.account.storage.save(<-r2, to: /storage/r)
let r2 <- create R2()
self.account.storage.save(<-r2, to: /storage/r)

return ref.foo
return ref.foo
}

access(all)
fun testRI() {
// Borrow /public/unentitledRI.
// - All unentitled borrows should succeed (as &{RI} / as &R)
// - All entitled borrows should fail (as &{RI} / as &R)

let unentitledRI1 = self.account.capabilities.get<&{RI}>(/public/unentitledRI).borrow()
assert(unentitledRI1 != nil, message: "unentitledRI1 should not be nil")

let entitledRI1 = self.account.capabilities.get<auth(X) &{RI}>(/public/unentitledRI).borrow()
assert(entitledRI1 == nil, message: "entitledRI1 should be nil")

let unentitledR1 = self.account.capabilities.get<&R>(/public/unentitledRI).borrow()
assert(unentitledR1 != nil, message: "unentitledR1 should not be nil")

let entitledR1 = self.account.capabilities.get<auth(X) &R>(/public/unentitledRI).borrow()
assert(entitledR1 == nil, message: "entitledR1 should be nil")

// Borrow /public/entitledRI.
// All borrows should succeed:
// - As &{RI} / as &R
// - Unentitled / entitled

let unentitledRI2 = self.account.capabilities.get<&{RI}>(/public/entitledRI).borrow()
assert(unentitledRI2 != nil, message: "unentitledRI2 should not be nil")

let entitledRI2 = self.account.capabilities.get<auth(X) &{RI}>(/public/entitledRI).borrow()
assert(entitledRI2 != nil, message: "entitledRI2 should not be nil")

let unentitledR2 = self.account.capabilities.get<&R>(/public/entitledRI).borrow()
assert(unentitledR2 != nil, message: "unentitledR2 should not be nil")

let entitledR2 = self.account.capabilities.get<auth(X) &R>(/public/entitledRI).borrow()
assert(entitledR2 != nil, message: "entitledR2 should not be nil")
}
}
`
Expand Down Expand Up @@ -327,6 +376,12 @@ func TestRuntimeCapability_borrowAndCheck(t *testing.T) {

require.ErrorAs(t, err, &interpreter.DereferenceError{})
})

t.Run("testRI", func(t *testing.T) {

_, err := invoke("testRI")
require.NoError(t, err)
})
})

t.Run("struct", func(t *testing.T) {
Expand All @@ -347,13 +402,20 @@ func TestRuntimeCapability_borrowAndCheck(t *testing.T) {
entitlement X

access(all)
struct S {
struct interface SI {}

access(all)
struct S: SI {

access(all)
let foo: Int

access(X)
let bar: Int

init() {
self.foo = 42
self.bar = 21
}
}

Expand Down Expand Up @@ -395,6 +457,12 @@ func TestRuntimeCapability_borrowAndCheck(t *testing.T) {

let noCap = self.account.capabilities.storage.issue<&S>(/storage/nonExistentTarget)
self.account.capabilities.publish(noCap, at: /public/nonExistentTarget)

let unentitledSICap = self.account.capabilities.storage.issue<&{SI}>(/storage/s)
self.account.capabilities.publish(unentitledSICap, at: /public/unentitledSI)

let entitledSICap = self.account.capabilities.storage.issue<auth(X) &{SI}>(/storage/s)
self.account.capabilities.publish(entitledSICap, at: /public/entitledSI)
}

access(all)
Expand Down Expand Up @@ -519,14 +587,51 @@ func TestRuntimeCapability_borrowAndCheck(t *testing.T) {

access(all)
fun testSwap(): Int {
let ref = self.account.capabilities.get<&S>(/public/s).borrow()!
let ref = self.account.capabilities.get<&S>(/public/s).borrow()!

self.account.storage.load<S>(from: /storage/s)

let s2 = S2()
self.account.storage.save(s2, to: /storage/s)

return ref.foo
}

access(all)
fun testSI() {

self.account.storage.load<S>(from: /storage/s)
// Borrow /public/unentitledSI.
// - All unentitled borrows should succeed (as &{SI} / as &S)
// - All entitled borrows should fail (as &{SI} / as &S)

let s2 = S2()
self.account.storage.save(s2, to: /storage/s)
let unentitledSI1 = self.account.capabilities.get<&{SI}>(/public/unentitledSI).borrow()
assert(unentitledSI1 != nil, message: "unentitledSI1 should not be nil")

return ref.foo
let entitledSI1 = self.account.capabilities.get<auth(X) &{SI}>(/public/unentitledSI).borrow()
assert(entitledSI1 == nil, message: "entitledSI1 should be nil")

let unentitledS1 = self.account.capabilities.get<&S>(/public/unentitledSI).borrow()
assert(unentitledS1 != nil, message: "unentitledS1 should not be nil")

let entitledS1 = self.account.capabilities.get<auth(X) &S>(/public/unentitledSI).borrow()
assert(entitledS1 == nil, message: "entitledS1 should be nil")

// Borrow /public/entitledSI.
// All borrows should succeed:
// - As &{SI} / as &S
// - Unentitled / entitled

let unentitledSI2 = self.account.capabilities.get<&{SI}>(/public/entitledSI).borrow()
assert(unentitledSI2 != nil, message: "unentitledSI2 should not be nil")

let entitledSI2 = self.account.capabilities.get<auth(X) &{SI}>(/public/entitledSI).borrow()
assert(entitledSI2 != nil, message: "entitledSI2 should not be nil")

let unentitledS2 = self.account.capabilities.get<&S>(/public/entitledSI).borrow()
assert(unentitledS2 != nil, message: "unentitledS2 should not be nil")

let entitledS2 = self.account.capabilities.get<auth(X) &S>(/public/entitledSI).borrow()
assert(entitledS2 != nil, message: "entitledS2 should not be nil")
}
}
`
Expand Down Expand Up @@ -593,6 +698,12 @@ func TestRuntimeCapability_borrowAndCheck(t *testing.T) {

require.ErrorAs(t, err, &interpreter.DereferenceError{})
})

t.Run("testSI", func(t *testing.T) {

_, err := invoke("testSI")
require.NoError(t, err)
})
})

t.Run("account", func(t *testing.T) {
Expand Down
30 changes: 11 additions & 19 deletions runtime/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -1792,7 +1792,7 @@ func (interpreter *Interpreter) VisitEnumCaseDeclaration(_ *ast.EnumCaseDeclarat
panic(errors.NewUnreachableError())
}

func (interpreter *Interpreter) substituteMappedEntitlements(ty sema.Type) sema.Type {
func (interpreter *Interpreter) SubstituteMappedEntitlements(ty sema.Type) sema.Type {
if interpreter.SharedState.currentEntitlementMappedValue == nil {
return ty
}
Expand Down Expand Up @@ -1831,7 +1831,7 @@ func (interpreter *Interpreter) transferAndConvert(
true, // value is standalone.
)

targetType = interpreter.substituteMappedEntitlements(targetType)
targetType = interpreter.SubstituteMappedEntitlements(targetType)

result := interpreter.ConvertAndBox(
locationRange,
Expand Down Expand Up @@ -3998,39 +3998,31 @@ func (interpreter *Interpreter) IsSubType(subType StaticType, superType StaticTy
return interpreter.IsSubTypeOfSemaType(subType, semaType)
}

func (interpreter *Interpreter) IsSubTypeOfSemaType(subType StaticType, superType sema.Type) bool {
func (interpreter *Interpreter) IsSubTypeOfSemaType(staticSubType StaticType, superType sema.Type) bool {
if superType == sema.AnyType {
return true
}

switch subType := subType.(type) {
// Optimization: Implement subtyping for common cases directly,
// without converting the subtype to a sema type.

switch staticSubType := staticSubType.(type) {
case *OptionalStaticType:
if superType, ok := superType.(*sema.OptionalType); ok {
return interpreter.IsSubTypeOfSemaType(subType.Type, superType.Type)
return interpreter.IsSubTypeOfSemaType(staticSubType.Type, superType.Type)
}

switch superType {
case sema.AnyStructType, sema.AnyResourceType:
return interpreter.IsSubTypeOfSemaType(subType.Type, superType)
}

case *ReferenceStaticType:
if superType, ok := superType.(*sema.ReferenceType); ok {

// First, check that the static type of the referenced value
// is a subtype of the super type

return subType.ReferencedType != nil &&
interpreter.IsSubTypeOfSemaType(subType.ReferencedType, superType.Type) &&
superType.Authorization.PermitsAccess(interpreter.MustConvertStaticAuthorizationToSemaAccess(subType.Authorization))
return interpreter.IsSubTypeOfSemaType(staticSubType.Type, superType)
}

return superType == sema.AnyStructType
}

semaType := interpreter.MustConvertStaticToSemaType(subType)
semaSubType := interpreter.MustConvertStaticToSemaType(staticSubType)

return sema.IsSubType(semaType, superType)
return sema.IsSubType(semaSubType, superType)
}

func (interpreter *Interpreter) domainPaths(address common.Address, domain common.PathDomain) []Value {
Expand Down
4 changes: 2 additions & 2 deletions runtime/interpreter/interpreter_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -1312,7 +1312,7 @@ func (interpreter *Interpreter) VisitCastingExpression(expression *ast.CastingEx
}

castingExpressionTypes := interpreter.Program.Elaboration.CastingExpressionTypes(expression)
expectedType := interpreter.substituteMappedEntitlements(castingExpressionTypes.TargetType)
expectedType := interpreter.SubstituteMappedEntitlements(castingExpressionTypes.TargetType)

switch expression.Operation {
case ast.OperationFailableCast, ast.OperationForceCast:
Expand All @@ -1325,7 +1325,7 @@ func (interpreter *Interpreter) VisitCastingExpression(expression *ast.CastingEx
// thus this is the only place where it becomes necessary to "instantiate" the result of a map to its
// concrete outputs. In other places (e.g. interface conformance checks) we want to leave maps generic,
// so we don't substitute them.
valueSemaType := interpreter.substituteMappedEntitlements(interpreter.MustSemaTypeOfValue(value))
valueSemaType := interpreter.SubstituteMappedEntitlements(interpreter.MustSemaTypeOfValue(value))
valueStaticType := ConvertSemaToStaticType(interpreter, valueSemaType)
isSubType := interpreter.IsSubTypeOfSemaType(valueStaticType, expectedType)

Expand Down
Loading
Loading