Skip to content

Commit

Permalink
Merge pull request #3125 from onflow/bastian/3119-convert-untyped-pat…
Browse files Browse the repository at this point in the history
…h-capabilities
  • Loading branch information
turbolent authored Feb 22, 2024
2 parents 78fa376 + 3e6a1d1 commit 07dafce
Show file tree
Hide file tree
Showing 4 changed files with 300 additions and 31 deletions.
12 changes: 9 additions & 3 deletions migrations/capcons/capabilitymigration.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ type CapabilityMigrationReporter interface {
// CapabilityValueMigration migrates all path capabilities to ID capabilities,
// using the path to ID capability controller mapping generated by LinkValueMigration.
type CapabilityValueMigration struct {
CapabilityIDs *CapabilityIDMapping
Reporter CapabilityMigrationReporter
CapabilityMapping *CapabilityMapping
Reporter CapabilityMigrationReporter
}

var _ migrations.ValueMigration = &CapabilityValueMigration{}
Expand Down Expand Up @@ -75,7 +75,7 @@ func (m *CapabilityValueMigration) Migrate(
oldCapability := value

capabilityAddressPath := oldCapability.AddressPath()
capabilityID, ok := m.CapabilityIDs.Get(capabilityAddressPath)
capabilityID, controllerBorrowType, ok := m.CapabilityMapping.Get(capabilityAddressPath)
if !ok {
if reporter != nil {
reporter.MissingCapabilityID(
Expand All @@ -88,6 +88,12 @@ func (m *CapabilityValueMigration) Migrate(

oldBorrowType := oldCapability.BorrowType

// Convert untyped path capability value to typed ID capability value
// by using capability controller's borrow type
if oldBorrowType == nil {
oldBorrowType = interpreter.ConvertSemaToStaticType(nil, controllerBorrowType)
}

newBorrowType, ok := oldBorrowType.(*interpreter.ReferenceStaticType)
if !ok {
panic(errors.NewUnexpectedError("unexpected non-reference borrow type: %T", oldBorrowType))
Expand Down
4 changes: 2 additions & 2 deletions migrations/capcons/linkmigration.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type LinkMigrationReporter interface {

// LinkValueMigration migrates all links to capability controllers.
type LinkValueMigration struct {
CapabilityIDs *CapabilityIDMapping
CapabilityMapping *CapabilityMapping
AccountIDGenerator stdlib.AccountIDGenerator
Reporter LinkMigrationReporter
}
Expand Down Expand Up @@ -184,7 +184,7 @@ func (m *LinkValueMigration) Migrate(
// Record new capability ID in source path mapping.
// The mapping is used later for migrating path capabilities to ID capabilities,
// see CapabilityMigration.
m.CapabilityIDs.Record(addressPath, capabilityID)
m.CapabilityMapping.Record(addressPath, capabilityID, borrowType)

if reporter != nil {
reporter.MigratedLink(addressPath, capabilityID)
Expand Down
47 changes: 31 additions & 16 deletions migrations/capcons/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,46 @@ import (
"sync"

"github.com/onflow/cadence/runtime/interpreter"
"github.com/onflow/cadence/runtime/sema"
)

type CapabilityIDMapping struct {
// CapabilityIDs' maps common.Address to map[interpreter.PathValue]interpreter.UInt64Value
capabilityIDs sync.Map
type CapabilityEntry struct {
CapabilityID interpreter.UInt64Value
BorrowType *sema.ReferenceType
}

func (m *CapabilityIDMapping) Record(addressPath interpreter.AddressPath, capabilityID interpreter.UInt64Value) {
var accountCapabilityIDs map[interpreter.PathValue]interpreter.UInt64Value
rawAccountCapabilityIDs, ok := m.capabilityIDs.Load(addressPath.Address)
type CapabilityEntryMap map[interpreter.PathValue]CapabilityEntry

type CapabilityMapping struct {
// capabilityEntries maps common.Address to CapabilityEntryMap
capabilityEntries sync.Map
}

func (m *CapabilityMapping) Record(
addressPath interpreter.AddressPath,
capabilityID interpreter.UInt64Value,
borrowType *sema.ReferenceType,
) {
var capabilityEntryMap CapabilityEntryMap
rawCapabilityEntryMap, ok := m.capabilityEntries.Load(addressPath.Address)
if ok {
accountCapabilityIDs = rawAccountCapabilityIDs.(map[interpreter.PathValue]interpreter.UInt64Value)
capabilityEntryMap = rawCapabilityEntryMap.(CapabilityEntryMap)
} else {
accountCapabilityIDs = map[interpreter.PathValue]interpreter.UInt64Value{}
m.capabilityIDs.Store(addressPath.Address, accountCapabilityIDs)
capabilityEntryMap = CapabilityEntryMap{}
m.capabilityEntries.Store(addressPath.Address, capabilityEntryMap)
}
capabilityEntryMap[addressPath.Path] = CapabilityEntry{
CapabilityID: capabilityID,
BorrowType: borrowType,
}
accountCapabilityIDs[addressPath.Path] = capabilityID
}

func (m *CapabilityIDMapping) Get(addressPath interpreter.AddressPath) (interpreter.UInt64Value, bool) {
rawAccountCapabilityIDs, ok := m.capabilityIDs.Load(addressPath.Address)
func (m *CapabilityMapping) Get(addressPath interpreter.AddressPath) (interpreter.UInt64Value, sema.Type, bool) {
rawCapabilityEntryMap, ok := m.capabilityEntries.Load(addressPath.Address)
if !ok {
return 0, false
return 0, nil, false
}
accountCapabilityIDs := rawAccountCapabilityIDs.(map[interpreter.PathValue]interpreter.UInt64Value)
capabilityID, ok := accountCapabilityIDs[addressPath.Path]
return capabilityID, ok
capabilityEntryMap := rawCapabilityEntryMap.(CapabilityEntryMap)
capabilityEntry, ok := capabilityEntryMap[addressPath.Path]
return capabilityEntry.CapabilityID, capabilityEntry.BorrowType, ok
}
Loading

0 comments on commit 07dafce

Please sign in to comment.