Skip to content

Commit

Permalink
Merge pull request #3538 from onflow/supun/export-invalid-caps
Browse files Browse the repository at this point in the history
Add support for exporting unmigrated path capabilities
  • Loading branch information
SupunS authored Aug 17, 2024
2 parents 4d6993b + 2dbecfb commit 0ff758d
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 20 deletions.
25 changes: 16 additions & 9 deletions encoding/json/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,10 @@ type jsonTypeValue struct {
}

type jsonCapabilityValue struct {
BorrowType jsonValue `json:"borrowType"`
Address string `json:"address"`
ID string `json:"id"`
BorrowType jsonValue `json:"borrowType"`
Address string `json:"address"`
ID string `json:"id"`
DeprecatedPath jsonValue `json:"path,omitempty"` // Deprecated
}

type jsonFunctionValue struct {
Expand Down Expand Up @@ -981,13 +982,19 @@ func prepareTypeValue(typeValue cadence.TypeValue) jsonValue {
}

func prepareCapability(capability cadence.Capability) jsonValue {
capabilityJson := jsonCapabilityValue{
ID: encodeUInt(uint64(capability.ID)),
Address: encodeBytes(capability.Address.Bytes()),
BorrowType: PrepareType(capability.BorrowType, TypePreparationResults{}),
}

if capability.DeprecatedPath != nil {
capabilityJson.DeprecatedPath = preparePath(*capability.DeprecatedPath)
}

return jsonValueObject{
Type: capabilityTypeStr,
Value: jsonCapabilityValue{
ID: encodeUInt(uint64(capability.ID)),
Address: encodeBytes(capability.Address.Bytes()),
BorrowType: PrepareType(capability.BorrowType, TypePreparationResults{}),
},
Type: capabilityTypeStr,
Value: capabilityJson,
}
}

Expand Down
59 changes: 48 additions & 11 deletions encoding/json/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2781,15 +2781,18 @@ func TestEncodeCapability(t *testing.T) {

t.Parallel()

testEncodeAndDecode(
t,
cadence.NewCapability(
6,
cadence.BytesToAddress([]byte{1, 2, 3, 4, 5}),
cadence.IntType,
),
// language=json
`
t.Run("valid capability", func(t *testing.T) {
t.Parallel()

testEncodeAndDecode(
t,
cadence.NewCapability(
6,
cadence.BytesToAddress([]byte{1, 2, 3, 4, 5}),
cadence.IntType,
),
// language=json
`
{
"type": "Capability",
"value": {
Expand All @@ -2801,7 +2804,41 @@ func TestEncodeCapability(t *testing.T) {
}
}
`,
)
)
})

t.Run("deprecated path capability", func(t *testing.T) {
t.Parallel()

testEncode(
t,
cadence.NewDeprecatedPathCapability( //nolint:staticcheck
cadence.BytesToAddress([]byte{1, 2, 3, 4, 5}),
cadence.MustNewPath(common.PathDomainPublic, "foo"),
cadence.AnyResourceType,
),
// language=json
`
{
"type": "Capability",
"value": {
"path": {
"type": "Path",
"value": {
"domain": "public",
"identifier": "foo"
}
},
"borrowType": {
"kind": "AnyResource"
},
"address": "0x0000000102030405",
"id": "0"
}
}
`,
)
})
}

func TestDecodeCapability(t *testing.T) {
Expand Down Expand Up @@ -2833,7 +2870,7 @@ func TestDecodeCapability(t *testing.T) {
)
})

t.Run("with backwards compatibility on a deprecated Path Capabliity", func(t *testing.T) {
t.Run("with backwards compatibility on a deprecated Path Capability", func(t *testing.T) {
t.Parallel()

testDecode(
Expand Down
25 changes: 25 additions & 0 deletions runtime/convertValues.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ func exportValueWithInterpreter(
return exportTypeValue(v, inter), nil
case *interpreter.IDCapabilityValue:
return exportCapabilityValue(v, inter)
case *interpreter.PathCapabilityValue: //nolint:staticcheck
return exportPathCapabilityValue(v, inter)
case *interpreter.EphemeralReferenceValue:
// Break recursion through references
if _, ok := seenReferences[v]; ok {
Expand Down Expand Up @@ -707,6 +709,29 @@ func exportCapabilityValue(
), nil
}

func exportPathCapabilityValue(
v *interpreter.PathCapabilityValue, //nolint:staticcheck
inter *interpreter.Interpreter,
) (cadence.Capability, error) {
borrowType := inter.MustConvertStaticToSemaType(v.BorrowType)
exportedBorrowType := ExportMeteredType(inter, borrowType, map[sema.TypeID]cadence.Type{})

capability := cadence.NewMeteredCapability(
inter,
cadence.NewMeteredUInt64(inter, uint64(interpreter.InvalidCapabilityID)),
cadence.NewMeteredAddress(inter, v.Address),
exportedBorrowType,
)

path, err := exportPathValue(inter, v.Path)
if err != nil {
return cadence.Capability{}, err
}
capability.DeprecatedPath = &path

return capability, nil
}

// exportEvent converts a runtime event to its native Go representation.
func exportEvent(
gauge common.MemoryGauge,
Expand Down
16 changes: 16 additions & 0 deletions runtime/convertValues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,22 @@ func TestRuntimeExportValue(t *testing.T) {
},
invalid: true,
},
{
label: "path capability",
value: &interpreter.PathCapabilityValue{ //nolint:staticcheck
BorrowType: interpreter.PrimitiveStaticTypeAnyResource,
Path: interpreter.PathValue{
Domain: common.PathDomainStorage,
Identifier: "foo",
},
Address: interpreter.AddressValue{0x1},
},
expected: cadence.NewDeprecatedPathCapability( //nolint:staticcheck
cadence.Address{0x1},
cadence.MustNewPath(common.PathDomainStorage, "foo"),
cadence.AnyResourceType,
),
},
} {
test(tt)
}
Expand Down

0 comments on commit 0ff758d

Please sign in to comment.