-
Notifications
You must be signed in to change notification settings - Fork 183
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
Infer the missing borrow type for storage capabilities #6314
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,15 +3,16 @@ | |
import ( | ||
"context" | ||
_ "embed" | ||
"fmt" | ||
|
||
"github.com/rs/zerolog" | ||
|
||
"github.com/onflow/cadence/migrations/capcons" | ||
"github.com/onflow/cadence/migrations/statictypes" | ||
"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/flow-go/cmd/util/ledger/reporters" | ||
"github.com/onflow/flow-go/cmd/util/ledger/util" | ||
|
@@ -235,6 +236,8 @@ | |
log zerolog.Logger | ||
} | ||
|
||
var _ AccountBasedMigration = &IssueStorageCapConMigration{} | ||
|
||
const issueStorageCapConMigrationReporterName = "cadence-storage-capcon-issue-migration" | ||
|
||
func NewIssueStorageCapConMigration( | ||
|
@@ -328,13 +331,12 @@ | |
m.verboseErrorOutput, | ||
) | ||
|
||
capcons.IssueAccountCapabilities( | ||
migrationRuntime.Interpreter, | ||
m.issueAccountCapabilities( | ||
migrationRuntime, | ||
reporter, | ||
address, | ||
accountCapabilities, | ||
handler, | ||
m.mapping, | ||
) | ||
|
||
return nil | ||
|
@@ -345,7 +347,71 @@ | |
return nil | ||
} | ||
|
||
var _ AccountBasedMigration = &IssueStorageCapConMigration{} | ||
func (m *IssueStorageCapConMigration) issueAccountCapabilities( | ||
migrationRuntime *InterpreterMigrationRuntime, | ||
reporter capcons.StorageCapabilityMigrationReporter, | ||
address common.Address, | ||
capabilities *capcons.AccountCapabilities, | ||
handler stdlib.CapabilityControllerIssueHandler, | ||
) { | ||
|
||
storageMap := migrationRuntime.Storage.GetStorageMap( | ||
address, | ||
common.PathDomainStorage.Identifier(), | ||
false, | ||
) | ||
|
||
inter := migrationRuntime.Interpreter | ||
|
||
for _, capability := range capabilities.Capabilities { | ||
addressPath := interpreter.AddressPath{ | ||
Address: address, | ||
Path: capability.Path, | ||
} | ||
|
||
borrowStaticType := capability.BorrowType | ||
path := capability.Path.Identifier | ||
|
||
if borrowStaticType == nil { | ||
reporter.MissingBorrowType(address, addressPath) | ||
|
||
// If the borrow type is missing, treat it as `AnyStruct` or `AnyResource`. | ||
// To determine whether it is a resource, read the target path. | ||
Comment on lines
+378
to
+379
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The capability has direct access to the storage path, without any borrow type "restriction", so theoretically the capability could be borrowed with any type. Inferring to
The first issue is more problematic than the latter. Maybe we should just infer a more specific type, based on the stored value at the time of migration. This would make 2) worse, but would at least fix 1) |
||
value := storageMap.ReadValue(nil, interpreter.StringStorageMapKey(path)) | ||
|
||
assumedBorrowType := interpreter.PrimitiveStaticTypeAnyStruct | ||
if value.IsResourceKinded(inter) { | ||
assumedBorrowType = interpreter.PrimitiveStaticTypeAnyResource | ||
} | ||
|
||
borrowStaticType = interpreter.NewReferenceStaticType( | ||
nil, | ||
interpreter.UnauthorizedAccess, | ||
assumedBorrowType, | ||
) | ||
} | ||
|
||
borrowType := inter.MustConvertStaticToSemaType(borrowStaticType).(*sema.ReferenceType) | ||
|
||
capabilityID, _ := stdlib.IssueStorageCapabilityController( | ||
inter, | ||
interpreter.EmptyLocationRange, | ||
handler, | ||
address, | ||
borrowType, | ||
capability.Path, | ||
) | ||
|
||
m.mapping.Record(addressPath, capabilityID, borrowType) | ||
|
||
reporter.IssuedStorageCapabilityController( | ||
address, | ||
addressPath, | ||
borrowStaticType.(*interpreter.ReferenceStaticType), | ||
capabilityID, | ||
) | ||
} | ||
} | ||
|
||
func NewCadence1ValueMigrations( | ||
log zerolog.Logger, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method was copied over and modified from Cadence side. Need to access the storage, etc. so having it here makes more sense.
The old method can be removed from cadence (tech-debt).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might need to re-incorporate the logic from onflow/cadence#3516 once it's merged, or move the changes here to Cadence.