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

Improve and fix static types and their ID and string functions #2756

Merged
merged 24 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8e2492b
make CompositeStaticType a pointer type
turbolent Aug 30, 2023
52a7026
make InterfaceStaticType a pointer type
turbolent Aug 30, 2023
6abe32a
make CapabilityStaticType a pointer type
turbolent Aug 30, 2023
dcf26d3
make ConstantSizedStaticType a pointer type
turbolent Aug 30, 2023
ded9101
make DictionaryStaticType a pointer type
turbolent Aug 30, 2023
25c6ce3
make VariableSizedStaticType a pointer type
turbolent Aug 30, 2023
b21688f
make OptionalStaticType a pointer type
turbolent Aug 30, 2023
0eab597
make ReferenceStaticType a pointer type
turbolent Aug 30, 2023
c672a74
delegate StaticType.String to StaticType.MeteredString to avoid re-im…
turbolent Aug 30, 2023
6e4023c
improve metering of static type strings
turbolent Aug 30, 2023
0367e39
don't cache potentially complex type IDs
turbolent Aug 30, 2023
97055b6
remove unused code
turbolent Aug 30, 2023
8468bc2
clean up ID/String/QualifiedString for restricted type, authorization…
turbolent Aug 30, 2023
70886de
remove unnecessary code
turbolent Aug 30, 2023
d7bb1f0
adjust and improve checker tests
turbolent Aug 30, 2023
a578898
change argument order to match static type
turbolent Aug 30, 2023
4abf980
expose entitlement set access type ID formatting
turbolent Aug 30, 2023
a5e40d9
improve type IDs and strings of authorizations, intersection types, a…
turbolent Aug 30, 2023
682bc0f
improve authorizations
turbolent Aug 30, 2023
85484a1
generalize formatting functions
turbolent Aug 31, 2023
703bb14
use sema's type ID formatting functions to ensure consistency, remove…
turbolent Aug 31, 2023
743d93a
test IDs of intersection types, reference type, and authorizations
turbolent Aug 31, 2023
dc70745
Merge branch 'feature/stable-cadence' into bastian/improve-static-types
turbolent Sep 1, 2023
9c733bb
remove unused field
turbolent Sep 1, 2023
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
32 changes: 16 additions & 16 deletions encoding/ccf/ccf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6125,8 +6125,8 @@ func TestEncodeEvent(t *testing.T) {
require.NoError(t, err)
assert.Equal(
t,
cadence.ValueWithCachedTypeID(tc.val),
cadence.ValueWithCachedTypeID(decodedVal),
tc.val,
decodedVal,
)
})
}
Expand Down Expand Up @@ -8295,8 +8295,8 @@ func TestEncodeType(t *testing.T) {
require.NoError(t, err)
assert.Equal(
t,
cadence.ValueWithCachedTypeID(val),
cadence.ValueWithCachedTypeID(decodedVal),
val,
decodedVal,
)
})

Expand Down Expand Up @@ -11571,8 +11571,8 @@ func testDecode(t *testing.T, actualCBOR []byte, expectedVal cadence.Value) {
require.NoError(t, err)
assert.Equal(
t,
cadence.ValueWithCachedTypeID(expectedVal),
cadence.ValueWithCachedTypeID(decodedVal),
expectedVal,
decodedVal,
)
}

Expand Down Expand Up @@ -12853,8 +12853,8 @@ func TestDeployedEvents(t *testing.T) {
// Since event encoding doesn't sort fields, make sure that input event is identical to decoded event.
require.Equal(
t,
cadence.ValueWithCachedTypeID(tc.event),
cadence.ValueWithCachedTypeID(decodedEvent),
tc.event,
decodedEvent,
)
})
}
Expand Down Expand Up @@ -14616,8 +14616,8 @@ func TestSortOptions(t *testing.T) {
require.NoError(t, err)
assert.Equal(
t,
cadence.ValueWithCachedTypeID(expectedVal),
cadence.ValueWithCachedTypeID(decodedVal),
expectedVal,
decodedVal,
)

// Decode value enforcing sorting of composite fields should return error.
Expand Down Expand Up @@ -14805,8 +14805,8 @@ func TestSortOptions(t *testing.T) {
require.NoError(t, err)
assert.Equal(
t,
cadence.ValueWithCachedTypeID(expectedVal),
cadence.ValueWithCachedTypeID(decodedVal),
expectedVal,
decodedVal,
)

// Decode value without enforcing sorting should return no error.
Expand Down Expand Up @@ -14994,8 +14994,8 @@ func TestSortOptions(t *testing.T) {
require.NoError(t, err)
assert.Equal(
t,
cadence.ValueWithCachedTypeID(expectedVal),
cadence.ValueWithCachedTypeID(decodedVal),
expectedVal,
decodedVal,
)

// Decode value without enforcing sorting should return no error.
Expand Down Expand Up @@ -15183,8 +15183,8 @@ func TestSortOptions(t *testing.T) {
require.NoError(t, err)
assert.Equal(
t,
cadence.ValueWithCachedTypeID(expectedVal),
cadence.ValueWithCachedTypeID(decodedVal),
expectedVal,
decodedVal,
)

// Decode value without enforcing sorting should return no error.
Expand Down
22 changes: 11 additions & 11 deletions encoding/ccf/decode_typedef.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (d *Decoder) decodeTypeDef(
) {
tagNum, err := d.dec.DecodeTagNumber()
if err != nil {
return ccfTypeID(0), cadenceTypeID(""), nil, err
return ccfTypeID(0), "", nil, err
}

switch tagNum {
Expand Down Expand Up @@ -296,7 +296,7 @@ func (d *Decoder) decodeTypeDef(

default:
return ccfTypeID(0),
cadenceTypeID(""),
"",
nil,
fmt.Errorf("unsupported type definition with CBOR tag number %d", tagNum)
}
Expand Down Expand Up @@ -329,32 +329,32 @@ func (d *Decoder) decodeCompositeType(
// Decode array head of length 3.
err := decodeCBORArrayWithKnownSize(d.dec, 3)
if err != nil {
return ccfTypeID(0), cadenceTypeID(""), nil, err
return ccfTypeID(0), "", nil, err
}

// element 0: id
ccfID, err := d.decodeCCFTypeID()
if err != nil {
return ccfTypeID(0), cadenceTypeID(""), nil, err
return ccfTypeID(0), "", nil, err
}

// "Valid CCF Encoding Requirements" in CCF specs:
//
// "composite-type.id MUST be unique in ccf-typedef-message or ccf-typedef-and-value-message."
if types.has(ccfID) {
return ccfTypeID(0), cadenceTypeID(""), nil, fmt.Errorf("found duplicate CCF type ID %d in composite-type", ccfID)
return ccfTypeID(0), "", nil, fmt.Errorf("found duplicate CCF type ID %d in composite-type", ccfID)
}

// element 1: cadence-type-id
cadenceID, location, identifier, err := d.decodeCadenceTypeID()
if err != nil {
return ccfTypeID(0), cadenceTypeID(""), nil, err
return ccfTypeID(0), "", nil, err
}

// element 2: fields
rawField, err := d.dec.DecodeRawBytes()
if err != nil {
return ccfTypeID(0), cadenceTypeID(""), nil, err
return ccfTypeID(0), "", nil, err
}

// The return value can be ignored, because its non-existence was already checked above
Expand Down Expand Up @@ -476,26 +476,26 @@ func (d *Decoder) decodeInterfaceType(
// Decode array head of length 2.
err := decodeCBORArrayWithKnownSize(d.dec, 2)
if err != nil {
return ccfTypeID(0), cadenceTypeID(""), nil, err
return ccfTypeID(0), "", nil, err
}

// element 0: id
ccfID, err := d.decodeCCFTypeID()
if err != nil {
return ccfTypeID(0), cadenceTypeID(""), nil, err
return ccfTypeID(0), "", nil, err
}

// "Valid CCF Encoding Requirements" in CCF specs:
//
// "composite-type.id MUST be unique in ccf-typedef-message or ccf-typedef-and-value-message."
if types.has(ccfID) {
return ccfTypeID(0), cadenceTypeID(""), nil, fmt.Errorf("found duplicate CCF type ID %d in interface-type", ccfID)
return ccfTypeID(0), "", nil, fmt.Errorf("found duplicate CCF type ID %d in interface-type", ccfID)
}

// element 1: cadence-type-id
cadenceID, location, identifier, err := d.decodeCadenceTypeID()
if err != nil {
return ccfTypeID(0), cadenceTypeID(""), nil, err
return ccfTypeID(0), "", nil, err
}

// The return value can be ignored, because its non-existence was already checked above
Expand Down
4 changes: 2 additions & 2 deletions encoding/json/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3288,8 +3288,8 @@ func testDecode(t *testing.T, actualJSON string, expectedVal cadence.Value, opti

assert.Equal(
t,
cadence.ValueWithCachedTypeID(expectedVal),
cadence.ValueWithCachedTypeID(decodedVal),
expectedVal,
decodedVal,
)
}

Expand Down
24 changes: 2 additions & 22 deletions runtime/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -881,13 +881,7 @@ var SignAlgoType = ExportedBuiltinType(sema.SignatureAlgorithmType).(*cadence.En
var HashAlgoType = ExportedBuiltinType(sema.HashAlgorithmType).(*cadence.EnumType)

func ExportedBuiltinType(internalType sema.Type) cadence.Type {
typ := ExportType(internalType, map[sema.TypeID]cadence.Type{})

// These types are re-used across tests.
// Hence, cache the ID always to avoid any non-determinism.
typ = cadence.TypeWithCachedTypeID(typ)

return typ
return ExportType(internalType, map[sema.TypeID]cadence.Type{})
}

func newBytesValue(bytes []byte) cadence.Array {
Expand Down Expand Up @@ -921,7 +915,7 @@ func accountKeyExportedValue(
panic(err)
}

value := cadence.Struct{
return cadence.Struct{
StructType: AccountKeyType,
Fields: []cadence.Value{
// Key index
Expand Down Expand Up @@ -951,8 +945,6 @@ func accountKeyExportedValue(
cadence.NewBool(isRevoked),
},
}

return cadence.ValueWithCachedTypeID(value)
}

func getAccountKeyTestRuntimeInterface(storage *testAccountKeyStorage) *testRuntimeInterface {
Expand Down Expand Up @@ -1115,10 +1107,6 @@ func (test accountKeyTestCase) executeScript(
},
)

if err == nil {
value = cadence.ValueWithCachedTypeID(value)
}

return value, err
}

Expand Down Expand Up @@ -1155,10 +1143,6 @@ func TestRuntimePublicKey(t *testing.T) {
},
)

if err == nil {
value = cadence.ValueWithCachedTypeID(value)
}

return value, err
}

Expand Down Expand Up @@ -1197,7 +1181,6 @@ func TestRuntimePublicKey(t *testing.T) {
},
}

expected = cadence.ValueWithCachedTypeID(expected)
assert.Equal(t, expected, value)
})

Expand Down Expand Up @@ -1463,8 +1446,6 @@ func TestRuntimePublicKey(t *testing.T) {
},
}

expected = cadence.ValueWithCachedTypeID(expected)

assert.Equal(t, expected, value)
})

Expand Down Expand Up @@ -1505,7 +1486,6 @@ func TestRuntimePublicKey(t *testing.T) {
},
}

expected = cadence.ValueWithCachedTypeID(expected)
assert.Equal(t, expected, value)
})

Expand Down
10 changes: 6 additions & 4 deletions runtime/common/metering.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,12 @@ var (

// Static types string representations

VariableSizedStaticTypeStringMemoryUsage = NewRawStringMemoryUsage(2) // []
DictionaryStaticTypeStringMemoryUsage = NewRawStringMemoryUsage(4) // {: }
OptionalStaticTypeStringMemoryUsage = NewRawStringMemoryUsage(1) // ?
CapabilityStaticTypeStringMemoryUsage = NewRawStringMemoryUsage(12) // Capability<>
VariableSizedStaticTypeStringMemoryUsage = NewRawStringMemoryUsage(2) // []
DictionaryStaticTypeStringMemoryUsage = NewRawStringMemoryUsage(4) // {: }
OptionalStaticTypeStringMemoryUsage = NewRawStringMemoryUsage(1) // ?
CapabilityStaticTypeStringMemoryUsage = NewRawStringMemoryUsage(12) // Capability<>
IntersectionStaticTypeStringMemoryUsage = NewRawStringMemoryUsage(2) // {}
IntersectionStaticTypeSeparatorStringMemoryUsage = NewRawStringMemoryUsage(2) // ,
)

func UseMemory(gauge MemoryGauge, usage MemoryUsage) {
Expand Down
34 changes: 0 additions & 34 deletions runtime/common/orderedmap/orderedmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
package orderedmap

import (
"sort"

"golang.org/x/exp/maps"

"github.com/onflow/cadence/runtime/common/list"
)

Expand Down Expand Up @@ -233,36 +229,6 @@ func (om *OrderedMap[K, V]) ForAllKeys(predicate func(key K) bool) bool {
return true
}

// MapKeys returns a new ordered map whose keys are mapped according to
// the provided mapping function between
func MapKeys[T OrderedMap[K, V], K comparable, V any, H comparable](om *OrderedMap[K, V], f func(K) H) *OrderedMap[H, V] {
mapped := New[OrderedMap[H, V]](om.Len())

om.Foreach(func(key K, value V) {
mapped.Set(f(key), value)
})

return mapped
}

// SortByKeys returns a new ordered map whose insertion order is sorted according to
// the provided comparison function between keys
func (om *OrderedMap[K, V]) SortByKey(compare func(K, K) bool) *OrderedMap[K, V] {
sorted := New[OrderedMap[K, V]](om.Len())
// non-deterministic order is okay here because the result is immediately sorted
keys := maps.Keys(om.pairs) //nolint:forbidigo
sort.Slice(keys, func(i, j int) bool {
return compare(keys[i], keys[j])
})

for _, key := range keys {
value, _ := om.Get(key)
sorted.Set(key, value)
}

return sorted
}

// ForAnyKey iterates over the keys of the map, and returns whether the provided
// predicate is true for any of them
func (om *OrderedMap[K, V]) ForAnyKey(predicate func(key K) bool) bool {
Expand Down
10 changes: 5 additions & 5 deletions runtime/convertTypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ func exportAuthorization(
})
return cadence.EntitlementSetAuthorization{
Entitlements: entitlements,
Kind: cadence.EntitlementSetKind(access.SetKind),
Kind: access.SetKind,
}
}
panic(fmt.Sprintf("cannot export authorization with access %T", access))
Expand Down Expand Up @@ -619,15 +619,15 @@ func exportCapabilityType(
)
}

func importInterfaceType(memoryGauge common.MemoryGauge, t cadence.InterfaceType) interpreter.InterfaceStaticType {
func importInterfaceType(memoryGauge common.MemoryGauge, t cadence.InterfaceType) *interpreter.InterfaceStaticType {
return interpreter.NewInterfaceStaticTypeComputeTypeID(
memoryGauge,
t.InterfaceTypeLocation(),
t.InterfaceTypeQualifiedIdentifier(),
)
}

func importCompositeType(memoryGauge common.MemoryGauge, t cadence.CompositeType) interpreter.CompositeStaticType {
func importCompositeType(memoryGauge common.MemoryGauge, t cadence.CompositeType) *interpreter.CompositeStaticType {
return interpreter.NewCompositeStaticTypeComputeTypeID(
memoryGauge,
t.CompositeTypeLocation(),
Expand All @@ -646,7 +646,7 @@ func importAuthorization(memoryGauge common.MemoryGauge, auth cadence.Authorizat
memoryGauge,
func() []common.TypeID { return auth.Entitlements },
len(auth.Entitlements),
sema.EntitlementSetKind(auth.Kind),
auth.Kind,
)
}
panic(fmt.Sprintf("cannot import authorization of type %T", auth))
Expand Down Expand Up @@ -712,7 +712,7 @@ func ImportType(memoryGauge common.MemoryGauge, t cadence.Type) interpreter.Stat
)

case *cadence.IntersectionType:
types := make([]interpreter.InterfaceStaticType, 0, len(t.Types))
types := make([]*interpreter.InterfaceStaticType, 0, len(t.Types))
for _, typ := range t.Types {
intf, ok := typ.(cadence.InterfaceType)
if !ok {
Expand Down
2 changes: 1 addition & 1 deletion runtime/convertValues.go
Original file line number Diff line number Diff line change
Expand Up @@ -1245,7 +1245,7 @@ func (i valueImporter) importDictionaryValue(
keysAndValues[pairIndex*2+1] = value
}

var dictionaryStaticType interpreter.DictionaryStaticType
var dictionaryStaticType *interpreter.DictionaryStaticType
if dictionaryType != nil {
dictionaryStaticType = interpreter.ConvertSemaDictionaryTypeToStaticDictionaryType(inter, dictionaryType)
} else {
Expand Down
Loading