diff --git a/cmd/decode-state-values/main.go b/cmd/decode-state-values/main.go index b6f781258f..5c61e11ba0 100644 --- a/cmd/decode-state-values/main.go +++ b/cmd/decode-state-values/main.go @@ -234,7 +234,7 @@ type interpreterStorage struct { var _ interpreter.Storage = &interpreterStorage{} -func (i interpreterStorage) GetStorageMap(_ *interpreter.Interpreter, _ common.Address, _ string, _ bool) *interpreter.DomainStorageMap { +func (i interpreterStorage) GetStorageMap(_ *interpreter.Interpreter, _ common.Address, _ common.StorageDomain, _ bool) *interpreter.DomainStorageMap { panic("unexpected GetStorageMap call") } diff --git a/common/pathdomain.go b/common/pathdomain.go index 943301dc4c..ea9e5609c8 100644 --- a/common/pathdomain.go +++ b/common/pathdomain.go @@ -70,3 +70,18 @@ func (i PathDomain) Identifier() string { panic(errors.NewUnreachableError()) } + +func (i PathDomain) StorageDomain() StorageDomain { + switch i { + case PathDomainStorage: + return StorageDomainPathStorage + + case PathDomainPrivate: + return StorageDomainPathPrivate + + case PathDomainPublic: + return StorageDomainPathPublic + } + + panic(errors.NewUnreachableError()) +} diff --git a/common/storagedomain.go b/common/storagedomain.go new file mode 100644 index 0000000000..108196cdac --- /dev/null +++ b/common/storagedomain.go @@ -0,0 +1,132 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Flow Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package common + +import ( + "fmt" + + "github.com/onflow/cadence/errors" +) + +type StorageDomain uint8 + +const ( + StorageDomainUnknown StorageDomain = iota + + StorageDomainPathStorage + + StorageDomainPathPrivate + + StorageDomainPathPublic + + StorageDomainContract + + StorageDomainInbox + + // StorageDomainCapabilityController is the storage domain which stores + // capability controllers by capability ID + StorageDomainCapabilityController + + // StorageDomainCapabilityControllerTag is the storage domain which stores + // capability controller tags by capability ID + StorageDomainCapabilityControllerTag + + // StorageDomainPathCapability is the storage domain which stores + // capability ID dictionaries (sets) by storage path identifier + StorageDomainPathCapability + + // StorageDomainAccountCapability is the storage domain which + // records active account capability controller IDs + StorageDomainAccountCapability +) + +var AllStorageDomains = []StorageDomain{ + StorageDomainPathStorage, + StorageDomainPathPrivate, + StorageDomainPathPublic, + StorageDomainContract, + StorageDomainInbox, + StorageDomainCapabilityController, + StorageDomainCapabilityControllerTag, + StorageDomainPathCapability, + StorageDomainAccountCapability, +} + +var AllStorageDomainsByIdentifier = map[string]StorageDomain{} + +var allStorageDomainsSet = map[StorageDomain]struct{}{} + +func init() { + for _, domain := range AllStorageDomains { + identifier := domain.Identifier() + AllStorageDomainsByIdentifier[identifier] = domain + + allStorageDomainsSet[domain] = struct{}{} + } +} + +func StorageDomainFromIdentifier(domain string) (StorageDomain, bool) { + result, ok := AllStorageDomainsByIdentifier[domain] + if !ok { + return StorageDomainUnknown, false + } + return result, true +} + +func StorageDomainFromUint64(i uint64) (StorageDomain, error) { + d := StorageDomain(i) + _, exists := allStorageDomainsSet[d] + if !exists { + return StorageDomainUnknown, fmt.Errorf("failed to convert %d to StorageDomain", i) + } + return d, nil +} + +func (d StorageDomain) Identifier() string { + switch d { + case StorageDomainPathStorage: + return PathDomainStorage.Identifier() + + case StorageDomainPathPrivate: + return PathDomainPrivate.Identifier() + + case StorageDomainPathPublic: + return PathDomainPublic.Identifier() + + case StorageDomainContract: + return "contract" + + case StorageDomainInbox: + return "inbox" + + case StorageDomainCapabilityController: + return "cap_con" + + case StorageDomainCapabilityControllerTag: + return "cap_tag" + + case StorageDomainPathCapability: + return "path_cap" + + case StorageDomainAccountCapability: + return "acc_cap" + } + + panic(errors.NewUnreachableError()) +} diff --git a/interpreter/account_storagemap.go b/interpreter/account_storagemap.go index 67a51c1c35..7498ae14c1 100644 --- a/interpreter/account_storagemap.go +++ b/interpreter/account_storagemap.go @@ -75,8 +75,8 @@ func NewAccountStorageMapWithRootID( } // DomainExists returns true if the given domain exists in the account storage map. -func (s *AccountStorageMap) DomainExists(domain string) bool { - key := StringStorageMapKey(domain) +func (s *AccountStorageMap) DomainExists(domain common.StorageDomain) bool { + key := StringStorageMapKey(domain.Identifier()) exists, err := s.orderedMap.Has( key.AtreeValueCompare, @@ -96,10 +96,10 @@ func (s *AccountStorageMap) DomainExists(domain string) bool { func (s *AccountStorageMap) GetDomain( gauge common.MemoryGauge, interpreter *Interpreter, - domain string, + domain common.StorageDomain, createIfNotExists bool, ) *DomainStorageMap { - key := StringStorageMapKey(domain) + key := StringStorageMapKey(domain.Identifier()) storedValue, err := s.orderedMap.Get( key.AtreeValueCompare, @@ -129,13 +129,13 @@ func (s *AccountStorageMap) GetDomain( func (s *AccountStorageMap) NewDomain( gauge common.MemoryGauge, interpreter *Interpreter, - domain string, + domain common.StorageDomain, ) *DomainStorageMap { interpreter.recordStorageMutation() domainStorageMap := NewDomainStorageMap(gauge, s.orderedMap.Storage, s.orderedMap.Address()) - key := StringStorageMapKey(domain) + key := StringStorageMapKey(domain.Identifier()) existingStorable, err := s.orderedMap.Set( key.AtreeValueCompare, @@ -149,7 +149,8 @@ func (s *AccountStorageMap) NewDomain( if existingStorable != nil { panic(errors.NewUnexpectedError( "account %x domain %s should not exist", - s.orderedMap.Address(), domain, + s.orderedMap.Address(), + domain.Identifier(), )) } @@ -162,7 +163,7 @@ func (s *AccountStorageMap) NewDomain( // Returns true if domain storage map previously existed at the given domain. func (s *AccountStorageMap) WriteDomain( interpreter *Interpreter, - domain string, + domain common.StorageDomain, storageMap *DomainStorageMap, ) (existed bool) { if storageMap == nil { @@ -175,12 +176,12 @@ func (s *AccountStorageMap) WriteDomain( // If the given domain already stores a domain storage map, it is overwritten. func (s *AccountStorageMap) setDomain( interpreter *Interpreter, - domain string, + domain common.StorageDomain, storageMap *DomainStorageMap, ) (existed bool) { interpreter.recordStorageMutation() - key := StringStorageMapKey(domain) + key := StringStorageMapKey(domain.Identifier()) existingValueStorable, err := s.orderedMap.Set( key.AtreeValueCompare, @@ -214,10 +215,10 @@ func (s *AccountStorageMap) setDomain( } // removeDomain removes domain storage map with given domain in account storage map, if it exists. -func (s *AccountStorageMap) removeDomain(interpreter *Interpreter, domain string) (existed bool) { +func (s *AccountStorageMap) removeDomain(interpreter *Interpreter, domain common.StorageDomain) (existed bool) { interpreter.recordStorageMutation() - key := StringStorageMapKey(domain) + key := StringStorageMapKey(domain.Identifier()) existingKeyStorable, existingValueStorable, err := s.orderedMap.Remove( key.AtreeValueCompare, @@ -268,8 +269,8 @@ func (s *AccountStorageMap) Count() uint64 { } // Domains returns a set of domains in account storage map -func (s *AccountStorageMap) Domains() map[string]struct{} { - domains := make(map[string]struct{}) +func (s *AccountStorageMap) Domains() map[common.StorageDomain]struct{} { + domains := make(map[common.StorageDomain]struct{}) iterator := s.Iterator() @@ -314,15 +315,15 @@ type AccountStorageMapIterator struct { } // Next returns the next domain and domain storage map. -// If there is no more domain, ("", nil) is returned. -func (i *AccountStorageMapIterator) Next() (string, *DomainStorageMap) { +// If there is no more domain, (common.StorageDomainUnknown, nil) is returned. +func (i *AccountStorageMapIterator) Next() (common.StorageDomain, *DomainStorageMap) { k, v, err := i.mapIterator.Next() if err != nil { panic(errors.NewExternalError(err)) } if k == nil || v == nil { - return "", nil + return common.StorageDomainUnknown, nil } key := convertKeyToDomain(k) @@ -332,10 +333,14 @@ func (i *AccountStorageMapIterator) Next() (string, *DomainStorageMap) { return key, value } -func convertKeyToDomain(v atree.Value) string { +func convertKeyToDomain(v atree.Value) common.StorageDomain { key, ok := v.(StringAtreeValue) if !ok { panic(errors.NewUnexpectedError("domain key type %T isn't expected", key)) } - return string(key) + domain, found := common.StorageDomainFromIdentifier(string(key)) + if !found { + panic(errors.NewUnexpectedError("domain key %s isn't expected", key)) + } + return domain } diff --git a/interpreter/account_storagemap_test.go b/interpreter/account_storagemap_test.go index cdc6fc868c..b926f2724b 100644 --- a/interpreter/account_storagemap_test.go +++ b/interpreter/account_storagemap_test.go @@ -49,7 +49,7 @@ func TestAccountStorageMapDomainExists(t *testing.T) { require.NotNil(t, accountStorageMap) require.Equal(t, uint64(0), accountStorageMap.Count()) - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { exist := accountStorageMap.DomainExists(domain) require.False(t, exist) } @@ -75,13 +75,13 @@ func TestAccountStorageMapDomainExists(t *testing.T) { atreeStorageValidationEnabled, ) - existingDomains := []string{common.PathDomainStorage.Identifier()} + existingDomains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} const count = 10 accountStorageMap, _ := createAccountStorageMap(storage, inter, address, existingDomains, count, random) // Check if domain exists - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { exist := accountStorageMap.DomainExists(domain) require.Equal(t, slices.Contains(existingDomains, domain), exist) } @@ -115,7 +115,7 @@ func TestAccountStorageMapGetDomain(t *testing.T) { require.NotNil(t, accountStorageMap) require.Equal(t, uint64(0), accountStorageMap.Count()) - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { const createIfNotExists = false storagemap := accountStorageMap.GetDomain(nil, inter, domain, createIfNotExists) require.Nil(t, storagemap) @@ -142,12 +142,12 @@ func TestAccountStorageMapGetDomain(t *testing.T) { atreeStorageValidationEnabled, ) - existingDomains := []string{common.PathDomainStorage.Identifier()} + existingDomains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} const count = 10 accountStorageMap, accountValues := createAccountStorageMap(storage, inter, address, existingDomains, count, random) - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { const createIfNotExists = false domainStoragemap := accountStorageMap.GetDomain(nil, inter, domain, createIfNotExists) require.Equal(t, slices.Contains(existingDomains, domain), domainStoragemap != nil) @@ -188,7 +188,7 @@ func TestAccountStorageMapCreateDomain(t *testing.T) { require.NotNil(t, accountStorageMap) require.Equal(t, uint64(0), accountStorageMap.Count()) - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { const createIfNotExists = true domainStoragemap := accountStorageMap.GetDomain(nil, inter, domain, createIfNotExists) require.NotNil(t, domainStoragemap) @@ -220,12 +220,12 @@ func TestAccountStorageMapCreateDomain(t *testing.T) { atreeStorageValidationEnabled, ) - existingDomains := []string{common.PathDomainStorage.Identifier()} + existingDomains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} const count = 10 accountStorageMap, accountValues := createAccountStorageMap(storage, inter, address, existingDomains, count, random) - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { const createIfNotExists = true domainStoragemap := accountStorageMap.GetDomain(nil, inter, domain, createIfNotExists) require.NotNil(t, domainStoragemap) @@ -272,7 +272,7 @@ func TestAccountStorageMapSetAndUpdateDomain(t *testing.T) { require.Equal(t, uint64(0), accountStorageMap.Count()) const count = 10 - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { domainStorageMap := interpreter.NewDomainStorageMap(nil, storage, atree.Address(address)) domainValues := writeRandomValuesToDomainStorageMap(inter, domainStorageMap, count, random) @@ -306,12 +306,12 @@ func TestAccountStorageMapSetAndUpdateDomain(t *testing.T) { atreeStorageValidationEnabled, ) - existingDomains := []string{common.PathDomainStorage.Identifier()} + existingDomains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} const count = 10 accountStorageMap, accountValues := createAccountStorageMap(storage, inter, address, existingDomains, count, random) - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { domainStorageMap := interpreter.NewDomainStorageMap(nil, storage, atree.Address(address)) domainValues := writeRandomValuesToDomainStorageMap(inter, domainStorageMap, count, random) @@ -355,7 +355,7 @@ func TestAccountStorageMapRemoveDomain(t *testing.T) { require.NotNil(t, accountStorageMap) require.Equal(t, uint64(0), accountStorageMap.Count()) - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { existed := accountStorageMap.WriteDomain(inter, domain, nil) require.False(t, existed) } @@ -383,12 +383,12 @@ func TestAccountStorageMapRemoveDomain(t *testing.T) { atreeStorageValidationEnabled, ) - existingDomains := []string{common.PathDomainStorage.Identifier()} + existingDomains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} const count = 10 accountStorageMap, accountValues := createAccountStorageMap(storage, inter, address, existingDomains, count, random) - for _, domain := range runtime.AccountDomains { + for _, domain := range common.AllStorageDomains { existed := accountStorageMap.WriteDomain(inter, domain, nil) require.Equal(t, slices.Contains(existingDomains, domain), existed) @@ -461,9 +461,9 @@ func TestAccountStorageMapIterator(t *testing.T) { atreeStorageValidationEnabled, ) - existingDomains := []string{ - common.PathDomainStorage.Identifier(), - common.PathDomainPublic.Identifier(), + existingDomains := []common.StorageDomain{ + common.PathDomainStorage.StorageDomain(), + common.PathDomainPublic.StorageDomain(), } const count = 10 @@ -474,7 +474,7 @@ func TestAccountStorageMapIterator(t *testing.T) { domainCount := 0 for { domain, domainStorageMap := iterator.Next() - if domain == "" { + if domain == common.StorageDomainUnknown { break } @@ -488,7 +488,7 @@ func TestAccountStorageMapIterator(t *testing.T) { // Test calling Next() after iterator reaches the end. domain, domainStorageMap := iterator.Next() - require.True(t, domain == "") + require.Equal(t, common.StorageDomainUnknown, domain) require.Nil(t, domainStorageMap) require.Equal(t, len(existingDomains), domainCount) @@ -530,10 +530,10 @@ func TestAccountStorageMapDomains(t *testing.T) { const atreeStorageValidationEnabled = false inter := NewTestInterpreterWithStorageAndAtreeValidationConfig(t, storage, atreeValueValidationEnabled, atreeStorageValidationEnabled) - existingDomains := []string{ - common.PathDomainStorage.Identifier(), - common.PathDomainPublic.Identifier(), - common.PathDomainPrivate.Identifier(), + existingDomains := []common.StorageDomain{ + common.PathDomainStorage.StorageDomain(), + common.PathDomainPublic.StorageDomain(), + common.PathDomainPrivate.StorageDomain(), } const count = 10 @@ -590,10 +590,10 @@ func TestAccountStorageMapLoadFromRootSlabID(t *testing.T) { }) t.Run("non-empty", func(t *testing.T) { - existingDomains := []string{ - common.PathDomainStorage.Identifier(), - common.PathDomainPublic.Identifier(), - common.PathDomainPrivate.Identifier(), + existingDomains := []common.StorageDomain{ + common.PathDomainStorage.StorageDomain(), + common.PathDomainPublic.StorageDomain(), + common.PathDomainPrivate.StorageDomain(), } init := func() (atree.SlabID, accountStorageMapValues, map[string][]byte, map[string]uint64) { @@ -636,14 +636,14 @@ func TestAccountStorageMapLoadFromRootSlabID(t *testing.T) { type ( domainStorageMapValues map[interpreter.StorageMapKey]interpreter.Value - accountStorageMapValues map[string]domainStorageMapValues + accountStorageMapValues map[common.StorageDomain]domainStorageMapValues ) func createAccountStorageMap( storage atree.SlabStorage, inter *interpreter.Interpreter, address common.Address, - domains []string, + domains []common.StorageDomain, count int, random *rand.Rand, ) (*interpreter.AccountStorageMap, accountStorageMapValues) { @@ -710,7 +710,7 @@ func checkAccountStorageMapData( iter := accountStorageMap.Iterator() for { domain, domainStorageMap := iter.Next() - if domain == "" { + if domain == common.StorageDomainUnknown { break } diff --git a/interpreter/account_test.go b/interpreter/account_test.go index a003477a56..595d0d7352 100644 --- a/interpreter/account_test.go +++ b/interpreter/account_test.go @@ -492,7 +492,7 @@ func testAccountWithErrorHandler( } storageKey := storageKey{ address: storageMapKey.Address, - domain: storageMapKey.Key, + domain: storageMapKey.Domain.Identifier(), key: key, } accountValues[storageKey] = value diff --git a/interpreter/encode.go b/interpreter/encode.go index 02a86e5819..a4b409a41b 100644 --- a/interpreter/encode.go +++ b/interpreter/encode.go @@ -1684,10 +1684,6 @@ func (c compositeTypeInfo) IsComposite() bool { return true } -func (c compositeTypeInfo) Identifier() string { - return string(c.location.TypeID(nil, c.qualifiedIdentifier)) -} - func (c compositeTypeInfo) Copy() atree.TypeInfo { // Return c as is because c is a value type. return c @@ -1741,10 +1737,6 @@ func (e EmptyTypeInfo) IsComposite() bool { return false } -func (e EmptyTypeInfo) Identifier() string { - return "" -} - func (e EmptyTypeInfo) Copy() atree.TypeInfo { return e } diff --git a/interpreter/interpreter.go b/interpreter/interpreter.go index 9fdbf1d135..7b8abb0d78 100644 --- a/interpreter/interpreter.go +++ b/interpreter/interpreter.go @@ -237,7 +237,7 @@ func (c TypeCodes) Merge(codes TypeCodes) { type Storage interface { atree.SlabStorage - GetStorageMap(inter *Interpreter, address common.Address, domain string, createIfNotExists bool) *DomainStorageMap + GetStorageMap(inter *Interpreter, address common.Address, domain common.StorageDomain, createIfNotExists bool) *DomainStorageMap CheckHealth() error } @@ -967,7 +967,7 @@ func (interpreter *Interpreter) declareSelfVariable(value Value, locationRange L } func (interpreter *Interpreter) visitAssignment( - transferOperation ast.TransferOperation, + _ ast.TransferOperation, targetGetterSetter getterSetter, targetType sema.Type, valueExpression ast.Expression, valueType sema.Type, position ast.HasPosition, @@ -1271,7 +1271,7 @@ func (declarationInterpreter *Interpreter) declareNonEnumCompositeValue( functions.Set(resourceDefaultDestroyEventName(compositeType), destroyEventConstructor) } - applyDefaultFunctions := func(ty *sema.InterfaceType, code WrapperCode) { + applyDefaultFunctions := func(_ *sema.InterfaceType, code WrapperCode) { // Apply default functions, if conforming type does not provide the function @@ -2678,7 +2678,7 @@ func (interpreter *Interpreter) NewSubInterpreter( func (interpreter *Interpreter) StoredValueExists( storageAddress common.Address, - domain string, + domain common.StorageDomain, identifier StorageMapKey, ) bool { accountStorage := interpreter.Storage().GetStorageMap(interpreter, storageAddress, domain, false) @@ -2690,7 +2690,7 @@ func (interpreter *Interpreter) StoredValueExists( func (interpreter *Interpreter) ReadStored( storageAddress common.Address, - domain string, + domain common.StorageDomain, identifier StorageMapKey, ) Value { accountStorage := interpreter.Storage().GetStorageMap(interpreter, storageAddress, domain, false) @@ -2702,7 +2702,7 @@ func (interpreter *Interpreter) ReadStored( func (interpreter *Interpreter) WriteStored( storageAddress common.Address, - domain string, + domain common.StorageDomain, key StorageMapKey, value Value, ) (existed bool) { @@ -4069,7 +4069,7 @@ func (interpreter *Interpreter) IsSubTypeOfSemaType(staticSubType StaticType, su } func (interpreter *Interpreter) domainPaths(address common.Address, domain common.PathDomain) []Value { - storageMap := interpreter.Storage().GetStorageMap(interpreter, address, domain.Identifier(), false) + storageMap := interpreter.Storage().GetStorageMap(interpreter, address, domain.StorageDomain(), false) if storageMap == nil { return []Value{} } @@ -4164,7 +4164,7 @@ func (interpreter *Interpreter) newStorageIterationFunction( parameterTypes := fnType.ParameterTypes() returnType := fnType.ReturnTypeAnnotation.Type - storageMap := config.Storage.GetStorageMap(interpreter, address, domain.Identifier(), false) + storageMap := config.Storage.GetStorageMap(interpreter, address, domain.StorageDomain(), false) if storageMap == nil { // if nothing is stored, no iteration is required return Void @@ -4327,7 +4327,7 @@ func (interpreter *Interpreter) authAccountSaveFunction( panic(errors.NewUnreachableError()) } - domain := path.Domain.Identifier() + domain := path.Domain.StorageDomain() identifier := path.Identifier // Prevent an overwrite @@ -4390,7 +4390,7 @@ func (interpreter *Interpreter) authAccountTypeFunction( panic(errors.NewUnreachableError()) } - domain := path.Domain.Identifier() + domain := path.Domain.StorageDomain() identifier := path.Identifier storageMapKey := StringStorageMapKey(identifier) @@ -4448,7 +4448,7 @@ func (interpreter *Interpreter) authAccountReadFunction( panic(errors.NewUnreachableError()) } - domain := path.Domain.Identifier() + domain := path.Domain.StorageDomain() identifier := path.Identifier storageMapKey := StringStorageMapKey(identifier) @@ -4589,7 +4589,7 @@ func (interpreter *Interpreter) authAccountCheckFunction( panic(errors.NewUnreachableError()) } - domain := path.Domain.Identifier() + domain := path.Domain.StorageDomain() identifier := path.Identifier storageMapKey := StringStorageMapKey(identifier) diff --git a/interpreter/misc_test.go b/interpreter/misc_test.go index e00d00f525..f81454cbfc 100644 --- a/interpreter/misc_test.go +++ b/interpreter/misc_test.go @@ -5349,7 +5349,7 @@ func TestInterpretReferenceFailableDowncasting(t *testing.T) { true, // r is standalone. ) - domain := storagePath.Domain.Identifier() + domain := storagePath.Domain.StorageDomain() storageMap := storage.GetStorageMap(inter, storageAddress, domain, true) storageMapKey := interpreter.StringStorageMapKey(storagePath.Identifier) storageMap.WriteValue(inter, storageMapKey, r) diff --git a/interpreter/statictype.go b/interpreter/statictype.go index 1b80201088..c2de979eea 100644 --- a/interpreter/statictype.go +++ b/interpreter/statictype.go @@ -252,10 +252,6 @@ func (t *VariableSizedStaticType) Copy() atree.TypeInfo { return t } -func (t *VariableSizedStaticType) Identifier() string { - return string(t.ID()) -} - func (*VariableSizedStaticType) isStaticType() {} func (*VariableSizedStaticType) elementSize() uint { @@ -382,10 +378,6 @@ func (t *ConstantSizedStaticType) Copy() atree.TypeInfo { return t } -func (t *ConstantSizedStaticType) Identifier() string { - return string(t.ID()) -} - func (*ConstantSizedStaticType) isStaticType() {} func (*ConstantSizedStaticType) elementSize() uint { @@ -464,10 +456,6 @@ func (t *DictionaryStaticType) Copy() atree.TypeInfo { return t } -func (t *DictionaryStaticType) Identifier() string { - return string(t.ID()) -} - func (*DictionaryStaticType) isStaticType() {} func (*DictionaryStaticType) elementSize() uint { diff --git a/interpreter/storage.go b/interpreter/storage.go index 992a039e69..e89417af39 100644 --- a/interpreter/storage.go +++ b/interpreter/storage.go @@ -101,6 +101,23 @@ func ConvertStoredValue(gauge common.MemoryGauge, value atree.Value) (Value, err } } +type StorageDomainKey struct { + Domain common.StorageDomain + Address common.Address +} + +func NewStorageDomainKey( + memoryGauge common.MemoryGauge, + address common.Address, + domain common.StorageDomain, +) StorageDomainKey { + common.UseMemory(memoryGauge, common.StorageKeyMemoryUsage) + return StorageDomainKey{ + Address: address, + Domain: domain, + } +} + type StorageKey struct { Key string Address common.Address @@ -130,7 +147,7 @@ func (k StorageKey) IsLess(o StorageKey) bool { // InMemoryStorage type InMemoryStorage struct { *atree.BasicSlabStorage - StorageMaps map[StorageKey]*DomainStorageMap + StorageMaps map[StorageDomainKey]*DomainStorageMap memoryGauge common.MemoryGauge } @@ -158,7 +175,7 @@ func NewInMemoryStorage(memoryGauge common.MemoryGauge) InMemoryStorage { return InMemoryStorage{ BasicSlabStorage: slabStorage, - StorageMaps: make(map[StorageKey]*DomainStorageMap), + StorageMaps: make(map[StorageDomainKey]*DomainStorageMap), memoryGauge: memoryGauge, } } @@ -166,12 +183,12 @@ func NewInMemoryStorage(memoryGauge common.MemoryGauge) InMemoryStorage { func (i InMemoryStorage) GetStorageMap( _ *Interpreter, address common.Address, - domain string, + domain common.StorageDomain, createIfNotExists bool, ) ( storageMap *DomainStorageMap, ) { - key := NewStorageKey(i.memoryGauge, address, domain) + key := NewStorageDomainKey(i.memoryGauge, address, domain) storageMap = i.StorageMaps[key] if storageMap == nil && createIfNotExists { storageMap = NewDomainStorageMap(i.memoryGauge, i, atree.Address(address)) diff --git a/interpreter/storage_test.go b/interpreter/storage_test.go index 16fd679a19..147385e051 100644 --- a/interpreter/storage_test.go +++ b/interpreter/storage_test.go @@ -524,7 +524,7 @@ func TestStorageOverwriteAndRemove(t *testing.T) { const storageMapKey = StringStorageMapKey("test") - storageMap := storage.GetStorageMap(inter, address, "storage", true) + storageMap := storage.GetStorageMap(inter, address, common.StorageDomainPathStorage, true) storageMap.WriteValue(inter, storageMapKey, array1) // Overwriting delete any existing child slabs diff --git a/interpreter/stringatreevalue_test.go b/interpreter/stringatreevalue_test.go index 366b59b1ee..bbeccd9414 100644 --- a/interpreter/stringatreevalue_test.go +++ b/interpreter/stringatreevalue_test.go @@ -48,7 +48,7 @@ func TestLargeStringAtreeValueInSeparateSlab(t *testing.T) { storageMap := storage.GetStorageMap( inter, common.MustBytesToAddress([]byte{0x1}), - common.PathDomainStorage.Identifier(), + common.PathDomainStorage.StorageDomain(), true, ) diff --git a/interpreter/value_composite.go b/interpreter/value_composite.go index d11311d543..cf460d466d 100644 --- a/interpreter/value_composite.go +++ b/interpreter/value_composite.go @@ -1658,7 +1658,7 @@ func (v *CompositeValue) getBaseValue( return NewEphemeralReferenceValue(interpreter, functionAuthorization, v.base, baseType, locationRange) } -func (v *CompositeValue) setBaseValue(interpreter *Interpreter, base *CompositeValue) { +func (v *CompositeValue) setBaseValue(_ *Interpreter, base *CompositeValue) { v.base = base } diff --git a/interpreter/value_storage_reference.go b/interpreter/value_storage_reference.go index 741fd4ae18..906edc5819 100644 --- a/interpreter/value_storage_reference.go +++ b/interpreter/value_storage_reference.go @@ -123,7 +123,7 @@ func (*StorageReferenceValue) IsImportable(_ *Interpreter, _ LocationRange) bool func (v *StorageReferenceValue) dereference(interpreter *Interpreter, locationRange LocationRange) (*Value, error) { address := v.TargetStorageAddress - domain := v.TargetPath.Domain.Identifier() + domain := v.TargetPath.Domain.StorageDomain() identifier := v.TargetPath.Identifier storageMapKey := StringStorageMapKey(identifier) diff --git a/interpreter/value_test.go b/interpreter/value_test.go index 26cfac8621..09f1e233d7 100644 --- a/interpreter/value_test.go +++ b/interpreter/value_test.go @@ -3806,7 +3806,7 @@ func TestValue_ConformsToStaticType(t *testing.T) { ) require.NoError(t, err) - storageMap := storage.GetStorageMap(inter, testAddress, "storage", true) + storageMap := storage.GetStorageMap(inter, testAddress, common.StorageDomainPathStorage, true) storageMap.WriteValue(inter, StringStorageMapKey("test"), TrueValue) value := valueFactory(inter) diff --git a/runtime/capabilitycontrollers_test.go b/runtime/capabilitycontrollers_test.go index d00fb18dae..feae867007 100644 --- a/runtime/capabilitycontrollers_test.go +++ b/runtime/capabilitycontrollers_test.go @@ -3256,7 +3256,7 @@ func TestRuntimeCapabilityControllers(t *testing.T) { storageMap := storage.GetStorageMap( nil, common.MustBytesToAddress([]byte{0x1}), - stdlib.PathCapabilityStorageDomain, + common.StorageDomainPathCapability, false, ) require.Zero(t, storageMap.Count()) @@ -3846,7 +3846,7 @@ func TestRuntimeCapabilitiesGetBackwardCompatibility(t *testing.T) { publicStorageMap := storage.GetStorageMap( inter, testAddress, - common.PathDomainPublic.Identifier(), + common.PathDomainPublic.StorageDomain(), true, ) @@ -3954,7 +3954,7 @@ func TestRuntimeCapabilitiesPublishBackwardCompatibility(t *testing.T) { publicStorageMap := storage.GetStorageMap( inter, testAddress, - common.PathDomainStorage.Identifier(), + common.PathDomainStorage.StorageDomain(), true, ) @@ -4045,7 +4045,7 @@ func TestRuntimeCapabilitiesUnpublishBackwardCompatibility(t *testing.T) { publicStorageMap := storage.GetStorageMap( inter, testAddress, - common.PathDomainPublic.Identifier(), + common.PathDomainPublic.StorageDomain(), true, ) diff --git a/runtime/contract_test.go b/runtime/contract_test.go index a009906aa0..05a91e1b85 100644 --- a/runtime/contract_test.go +++ b/runtime/contract_test.go @@ -223,7 +223,7 @@ func TestRuntimeContract(t *testing.T) { getContractValueExists := func() bool { storageMap := NewStorage(storage, nil). - GetStorageMap(inter, signerAddress, StorageDomainContract, false) + GetStorageMap(inter, signerAddress, common.StorageDomainContract, false) if storageMap == nil { return false } diff --git a/runtime/environment.go b/runtime/environment.go index 1806f18698..1ab7ee9b6a 100644 --- a/runtime/environment.go +++ b/runtime/environment.go @@ -1109,7 +1109,7 @@ func (e *interpreterEnvironment) loadContract( storageMap := e.storage.GetStorageMap( inter, addressLocation.Address, - StorageDomainContract, + common.StorageDomainContract, false, ) if storageMap != nil { diff --git a/runtime/ft_test.go b/runtime/ft_test.go index 3e37164cf7..56846cf2f5 100644 --- a/runtime/ft_test.go +++ b/runtime/ft_test.go @@ -1086,7 +1086,7 @@ func TestRuntimeBrokenFungibleTokenRecovery(t *testing.T) { contractStorage := storage.GetStorageMap( inter, contractsAddress, - StorageDomainContract, + common.StorageDomainContract, true, ) contractStorage.SetValue( @@ -1122,7 +1122,7 @@ func TestRuntimeBrokenFungibleTokenRecovery(t *testing.T) { userStorage := storage.GetStorageMap( inter, userAddress, - common.PathDomainStorage.Identifier(), + common.PathDomainStorage.StorageDomain(), true, ) const storagePathIdentifier = "exampleTokenVault" diff --git a/runtime/migrate_domain_registers.go b/runtime/migrate_domain_registers.go index 2298e99e38..e51bf81887 100644 --- a/runtime/migrate_domain_registers.go +++ b/runtime/migrate_domain_registers.go @@ -33,7 +33,7 @@ type GetDomainStorageMapFunc func( ledger atree.Ledger, storage atree.SlabStorage, address common.Address, - domain string, + domain common.StorageDomain, ) (*interpreter.DomainStorageMap, error) type DomainRegisterMigration struct { @@ -152,7 +152,7 @@ func (m *DomainRegisterMigration) migrateDomains( var accountStorageMap *interpreter.AccountStorageMap - for _, domain := range AccountDomains { + for _, domain := range common.AllStorageDomains { domainStorageMap, err := m.getDomainStorageMap(m.ledger, m.storage, address, domain) if err != nil { @@ -173,7 +173,9 @@ func (m *DomainRegisterMigration) migrateDomains( if existed { // This shouldn't happen because we are inserting domain storage map into empty account storage map. return nil, errors.NewUnexpectedError( - "failed to migrate domain %s for account %x: domain already exists in account storage map", domain, address, + "failed to migrate domain %s for account %x: domain already exists in account storage map", + domain.Identifier(), + address, ) } @@ -182,7 +184,7 @@ func (m *DomainRegisterMigration) migrateDomains( // NOTE: removing non-existent domain registers is no-op. err = m.ledger.SetValue( address[:], - []byte(domain), + []byte(domain.Identifier()), nil) }) if err != nil { diff --git a/runtime/migrate_domain_registers_test.go b/runtime/migrate_domain_registers_test.go index 28769c9e14..2c18879dbe 100644 --- a/runtime/migrate_domain_registers_test.go +++ b/runtime/migrate_domain_registers_test.go @@ -119,14 +119,14 @@ func TestMigrateDomainRegisters(t *testing.T) { { address: address1, domains: []domainInfo{ - {domain: common.PathDomainStorage.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, - {domain: common.PathDomainPrivate.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainStorage.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainPrivate.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, }, }, { address: address2, domains: []domainInfo{ - {domain: common.PathDomainPublic.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainPublic.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, }, }, } @@ -178,14 +178,14 @@ func TestMigrateDomainRegisters(t *testing.T) { { address: address1, domains: []domainInfo{ - {domain: common.PathDomainStorage.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, - {domain: common.PathDomainPrivate.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainStorage.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainPrivate.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, }, }, { address: address2, domains: []domainInfo{ - {domain: common.PathDomainPublic.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainPublic.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, }, }, } @@ -217,13 +217,13 @@ func TestMigrateDomainRegisters(t *testing.T) { { address: address1, domains: []domainInfo{ - {domain: common.PathDomainStorage.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainStorage.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, }, }, { address: address2, domains: []domainInfo{ - {domain: common.PathDomainPublic.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainPublic.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, }, }, } @@ -250,13 +250,13 @@ func TestMigrateDomainRegisters(t *testing.T) { { address: address1, domains: []domainInfo{ - {domain: common.PathDomainStorage.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainStorage.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, }, }, { address: address2, domains: []domainInfo{ - {domain: common.PathDomainPublic.Identifier(), domainStorageMapCount: 10, maxDepth: 3}, + {domain: common.PathDomainPublic.StorageDomain(), domainStorageMapCount: 10, maxDepth: 3}, }, }, } @@ -281,7 +281,7 @@ func TestMigrateDomainRegisters(t *testing.T) { } type domainInfo struct { - domain string + domain common.StorageDomain domainStorageMapCount int maxDepth int } @@ -339,7 +339,7 @@ func newTestLedgerWithUnmigratedAccounts( // Write domain register domainStorageMapValueID := domainStorageMap.ValueID() - err := ledger.SetValue(address[:], []byte(domain), domainStorageMapValueID[8:]) + err := ledger.SetValue(address[:], []byte(domain.Identifier()), domainStorageMapValueID[8:]) require.NoError(tb, err) vid := domainStorageMap.ValueID() diff --git a/runtime/runtime.go b/runtime/runtime.go index e385f2c0c7..c6277c55ae 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -612,7 +612,7 @@ func (r *interpreterRuntime) ReadStored( pathValue := valueImporter{inter: inter}.importPathValue(path) - domain := pathValue.Domain.Identifier() + domain := pathValue.Domain.StorageDomain() identifier := pathValue.Identifier storageMapKey := interpreter.StringStorageMapKey(identifier) diff --git a/runtime/runtime_memory_metering_test.go b/runtime/runtime_memory_metering_test.go index 669b6152c1..09dc1d8069 100644 --- a/runtime/runtime_memory_metering_test.go +++ b/runtime/runtime_memory_metering_test.go @@ -930,7 +930,7 @@ func TestRuntimeMemoryMeteringErrors(t *testing.T) { type memoryMeter map[common.MemoryKind]uint64 - runtimeInterface := func(meter memoryMeter) *TestRuntimeInterface { + runtimeInterface := func(memoryMeter) *TestRuntimeInterface { return &TestRuntimeInterface{ OnMeterMemory: func(usage common.MemoryUsage) error { if usage.Kind == common.MemoryKindStringValue || diff --git a/runtime/sharedstate_test.go b/runtime/sharedstate_test.go index f1d0ad703e..287f03519c 100644 --- a/runtime/sharedstate_test.go +++ b/runtime/sharedstate_test.go @@ -28,7 +28,6 @@ import ( "github.com/onflow/cadence/common" "github.com/onflow/cadence/interpreter" . "github.com/onflow/cadence/runtime" - "github.com/onflow/cadence/stdlib" . "github.com/onflow/cadence/test_utils/runtime_utils" ) @@ -222,7 +221,7 @@ func TestRuntimeSharedState(t *testing.T) { // Read returns no value. { owner: signerAddress[:], - key: []byte(StorageDomainContract), + key: []byte(common.StorageDomainContract.Identifier()), }, // Read all available domain registers to check if it is a new account // Read returns no value. @@ -240,27 +239,27 @@ func TestRuntimeSharedState(t *testing.T) { }, { owner: signerAddress[:], - key: []byte(StorageDomainContract), + key: []byte(common.StorageDomainContract.Identifier()), }, { owner: signerAddress[:], - key: []byte(stdlib.InboxStorageDomain), + key: []byte(common.StorageDomainInbox.Identifier()), }, { owner: signerAddress[:], - key: []byte(stdlib.CapabilityControllerStorageDomain), + key: []byte(common.StorageDomainCapabilityController.Identifier()), }, { owner: signerAddress[:], - key: []byte(stdlib.CapabilityControllerTagStorageDomain), + key: []byte(common.StorageDomainCapabilityControllerTag.Identifier()), }, { owner: signerAddress[:], - key: []byte(stdlib.PathCapabilityStorageDomain), + key: []byte(common.StorageDomainPathCapability.Identifier()), }, { owner: signerAddress[:], - key: []byte(stdlib.AccountCapabilityStorageDomain), + key: []byte(common.StorageDomainAccountCapability.Identifier()), }, // Read account domain register { diff --git a/runtime/storage.go b/runtime/storage.go index d2559818ad..253aeabe60 100644 --- a/runtime/storage.go +++ b/runtime/storage.go @@ -30,12 +30,10 @@ import ( "github.com/onflow/cadence/common/orderedmap" "github.com/onflow/cadence/errors" "github.com/onflow/cadence/interpreter" - "github.com/onflow/cadence/stdlib" ) const ( - StorageDomainContract = "contract" - AccountStorageKey = "stored" + AccountStorageKey = "stored" ) type Storage struct { @@ -55,7 +53,7 @@ type Storage struct { // cachedDomainStorageMaps is a cache of domain storage maps. // Key is StorageKey{address, domain} and value is domain storage map. - cachedDomainStorageMaps map[interpreter.StorageKey]*interpreter.DomainStorageMap + cachedDomainStorageMaps map[interpreter.StorageDomainKey]*interpreter.DomainStorageMap // contractUpdates is a cache of contract updates. // Key is StorageKey{contract_address, contract_name} and value is contract composite value. @@ -102,7 +100,7 @@ func NewStorage(ledger atree.Ledger, memoryGauge common.MemoryGauge) *Storage { Ledger: ledger, PersistentSlabStorage: persistentSlabStorage, cachedAccountStorageMaps: map[interpreter.StorageKey]*interpreter.AccountStorageMap{}, - cachedDomainStorageMaps: map[interpreter.StorageKey]*interpreter.DomainStorageMap{}, + cachedDomainStorageMaps: map[interpreter.StorageDomainKey]*interpreter.DomainStorageMap{}, memoryGauge: memoryGauge, } } @@ -113,7 +111,7 @@ const storageIndexLength = 8 func (s *Storage) GetStorageMap( inter *interpreter.Interpreter, address common.Address, - domain string, + domain common.StorageDomain, createIfNotExists bool, ) ( storageMap *interpreter.DomainStorageMap, @@ -178,7 +176,7 @@ func (s *Storage) GetStorageMap( // Get cached domain storage map if it exists. - domainStorageKey := interpreter.NewStorageKey(s.memoryGauge, address, domain) + domainStorageKey := interpreter.NewStorageDomainKey(s.memoryGauge, address, domain) if domainStorageMap := s.cachedDomainStorageMaps[domainStorageKey]; domainStorageMap != nil { return domainStorageMap @@ -218,14 +216,6 @@ func (s *Storage) GetStorageMap( if domainStorageMap != nil { // This is a unmigrated account with given domain register. - // Sanity check that domain is among expected domains. - if _, exist := accountDomainsSet[domain]; !exist { - // TODO: maybe also log unexpected domain. - panic(errors.NewUnexpectedError( - "unexpected domain %s exists for account %s", domain, address.String(), - )) - } - // Cache domain storage map s.cachedDomainStorageMaps[domainStorageKey] = domainStorageMap @@ -324,9 +314,12 @@ func getDomainStorageMapFromLegacyDomainRegister( ledger atree.Ledger, storage atree.SlabStorage, address common.Address, - domain string, + domain common.StorageDomain, ) (*interpreter.DomainStorageMap, error) { - domainStorageSlabIndex, domainRegisterExists, err := getSlabIndexFromRegisterValue(ledger, address, []byte(domain)) + domainStorageSlabIndex, domainRegisterExists, err := getSlabIndexFromRegisterValue( + ledger, + address, + []byte(domain.Identifier())) if err != nil { return nil, err } @@ -362,8 +355,11 @@ func (s *Storage) isUnmigratedAccount(address common.Address) (bool, error) { } // Check most frequently used domains first, such as storage, public, private. - for _, domain := range AccountDomains { - _, domainExists, err := getSlabIndexFromRegisterValue(s.Ledger, address, []byte(domain)) + for _, domain := range common.AllStorageDomains { + _, domainExists, err := getSlabIndexFromRegisterValue( + s.Ledger, + address, + []byte(domain.Identifier())) if err != nil { return false, err } @@ -470,7 +466,7 @@ func (s *Storage) writeContractUpdate( key interpreter.StorageKey, contractValue *interpreter.CompositeValue, ) { - storageMap := s.GetStorageMap(inter, key.Address, StorageDomainContract, true) + storageMap := s.GetStorageMap(inter, key.Address, common.StorageDomainContract, true) // NOTE: pass nil instead of allocating a Value-typed interface that points to nil storageMapKey := interpreter.StringStorageMapKey(key.Key) if contractValue == nil { @@ -571,9 +567,9 @@ func (s *Storage) migrateAccounts(inter *interpreter.Interpreter) error { ledger atree.Ledger, storage atree.SlabStorage, address common.Address, - domain string, + domain common.StorageDomain, ) (*interpreter.DomainStorageMap, error) { - domainStorageKey := interpreter.NewStorageKey(s.memoryGauge, address, domain) + domainStorageKey := interpreter.NewStorageDomainKey(s.memoryGauge, address, domain) // Get cached domain storage map if available. domainStorageMap := s.cachedDomainStorageMaps[domainStorageKey] @@ -726,23 +722,3 @@ func (UnreferencedRootSlabsError) IsInternalError() {} func (e UnreferencedRootSlabsError) Error() string { return fmt.Sprintf("slabs not referenced: %s", e.UnreferencedRootSlabIDs) } - -var AccountDomains = []string{ - common.PathDomainStorage.Identifier(), - common.PathDomainPrivate.Identifier(), - common.PathDomainPublic.Identifier(), - StorageDomainContract, - stdlib.InboxStorageDomain, - stdlib.CapabilityControllerStorageDomain, - stdlib.CapabilityControllerTagStorageDomain, - stdlib.PathCapabilityStorageDomain, - stdlib.AccountCapabilityStorageDomain, -} - -var accountDomainsSet = func() map[string]struct{} { - m := make(map[string]struct{}) - for _, domain := range AccountDomains { - m[domain] = struct{}{} - } - return m -}() diff --git a/runtime/storage_test.go b/runtime/storage_test.go index 55090be2be..5c1299df9f 100644 --- a/runtime/storage_test.go +++ b/runtime/storage_test.go @@ -39,7 +39,6 @@ import ( "github.com/onflow/cadence/encoding/json" "github.com/onflow/cadence/interpreter" . "github.com/onflow/cadence/runtime" - "github.com/onflow/cadence/stdlib" . "github.com/onflow/cadence/test_utils/common_utils" . "github.com/onflow/cadence/test_utils/interpreter_utils" . "github.com/onflow/cadence/test_utils/runtime_utils" @@ -57,15 +56,16 @@ func withWritesToStorage( inter := NewTestInterpreter(tb) - address := common.MustBytesToAddress([]byte{0x1}) - for i := 0; i < count; i++ { randomIndex := random.Uint32() + var address common.Address + random.Read(address[:]) + storageKey := interpreter.StorageKey{ Address: address, - Key: fmt.Sprintf("%d", randomIndex), + Key: AccountStorageKey, } var slabIndex atree.SlabIndex @@ -3110,7 +3110,7 @@ func TestRuntimeStorageInternalAccess(t *testing.T) { }) require.NoError(t, err) - storageMap := storage.GetStorageMap(inter, address, common.PathDomainStorage.Identifier(), false) + storageMap := storage.GetStorageMap(inter, address, common.PathDomainStorage.StorageDomain(), false) require.NotNil(t, storageMap) // Read first @@ -6242,7 +6242,7 @@ func TestRuntimeStorageReferenceAccess(t *testing.T) { type ( domainStorageMapValues map[interpreter.StorageMapKey]interpreter.Value - accountStorageMapValues map[string]domainStorageMapValues + accountStorageMapValues map[common.StorageDomain]domainStorageMapValues ) func TestRuntimeStorageForNewAccount(t *testing.T) { @@ -6264,7 +6264,7 @@ func TestRuntimeStorageForNewAccount(t *testing.T) { inter := NewTestInterpreterWithStorage(t, storage) - domain := common.PathDomainStorage.Identifier() + domain := common.PathDomainStorage.StorageDomain() // Get non-existent domain storage map const createIfNotExists = false @@ -6293,13 +6293,13 @@ func TestRuntimeStorageForNewAccount(t *testing.T) { // migration: no migraiton for new account. createDomainTestCases := []struct { name string - newDomains []string + newDomains []common.StorageDomain domainStorageMapCount int inlined bool }{ - {name: "empty domain storage map", newDomains: []string{common.PathDomainStorage.Identifier()}, domainStorageMapCount: 0, inlined: true}, - {name: "small domain storage map", newDomains: []string{common.PathDomainStorage.Identifier()}, domainStorageMapCount: 10, inlined: true}, - {name: "large domain storage map", newDomains: []string{common.PathDomainStorage.Identifier()}, domainStorageMapCount: 20, inlined: false}, + {name: "empty domain storage map", newDomains: []common.StorageDomain{common.PathDomainStorage.StorageDomain()}, domainStorageMapCount: 0, inlined: true}, + {name: "small domain storage map", newDomains: []common.StorageDomain{common.PathDomainStorage.StorageDomain()}, domainStorageMapCount: 10, inlined: true}, + {name: "large domain storage map", newDomains: []common.StorageDomain{common.PathDomainStorage.StorageDomain()}, domainStorageMapCount: 20, inlined: false}, } for _, tc := range createDomainTestCases { @@ -6395,9 +6395,9 @@ func TestRuntimeStorageForNewAccount(t *testing.T) { accountValues := make(accountStorageMapValues) - domains := []string{ - common.PathDomainStorage.Identifier(), - common.PathDomainPublic.Identifier(), + domains := []common.StorageDomain{ + common.PathDomainStorage.StorageDomain(), + common.PathDomainPublic.StorageDomain(), } // Create empty domain storage map and commit @@ -6517,7 +6517,7 @@ func TestRuntimeStorageForMigratedAccount(t *testing.T) { onRead LedgerOnRead, onWrite LedgerOnWrite, address common.Address, - domains []string, + domains []common.StorageDomain, domainStorageMapCount int, ) (TestLedger, accountStorageMapValues) { ledger := NewTestLedger(nil, nil) @@ -6539,11 +6539,11 @@ func TestRuntimeStorageForMigratedAccount(t *testing.T) { // post-condition: no change // migration: none t.Run("read non-existent domain storage map", func(t *testing.T) { - existingDomains := []string{ - common.PathDomainStorage.Identifier(), + existingDomains := []common.StorageDomain{ + common.PathDomainStorage.StorageDomain(), } - nonexistentDomain := common.PathDomainPublic.Identifier() + nonexistentDomain := common.PathDomainPublic.StorageDomain() var writeCount int @@ -6588,7 +6588,7 @@ func TestRuntimeStorageForMigratedAccount(t *testing.T) { for _, tc := range readExistingDomainTestCases { t.Run("read existing domain storage map "+tc.name, func(t *testing.T) { - existingDomains := []string{common.PathDomainStorage.Identifier()} + existingDomains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} var writeCount int @@ -6640,33 +6640,33 @@ func TestRuntimeStorageForMigratedAccount(t *testing.T) { // - account storage map with new domain storage map. createDomainTestCases := []struct { name string - existingDomains []string - newDomains []string + existingDomains []common.StorageDomain + newDomains []common.StorageDomain existingDomainStorageMapCount int newDomainStorageMapCount int isNewDomainStorageMapInlined bool }{ { name: "empty domain storage map", - existingDomains: []string{common.PathDomainStorage.Identifier()}, + existingDomains: []common.StorageDomain{common.PathDomainStorage.StorageDomain()}, existingDomainStorageMapCount: 5, - newDomains: []string{common.PathDomainPublic.Identifier()}, + newDomains: []common.StorageDomain{common.PathDomainPublic.StorageDomain()}, newDomainStorageMapCount: 0, isNewDomainStorageMapInlined: true, }, { name: "small domain storage map", - existingDomains: []string{common.PathDomainStorage.Identifier()}, + existingDomains: []common.StorageDomain{common.PathDomainStorage.StorageDomain()}, existingDomainStorageMapCount: 5, - newDomains: []string{common.PathDomainPublic.Identifier()}, + newDomains: []common.StorageDomain{common.PathDomainPublic.StorageDomain()}, newDomainStorageMapCount: 10, isNewDomainStorageMapInlined: true, }, { name: "large domain storage map", - existingDomains: []string{common.PathDomainStorage.Identifier()}, + existingDomains: []common.StorageDomain{common.PathDomainStorage.StorageDomain()}, existingDomainStorageMapCount: 5, - newDomains: []string{common.PathDomainPublic.Identifier()}, + newDomains: []common.StorageDomain{common.PathDomainPublic.StorageDomain()}, newDomainStorageMapCount: 20, isNewDomainStorageMapInlined: false, }, @@ -6759,7 +6759,7 @@ func TestRuntimeStorageForMigratedAccount(t *testing.T) { var writeEntries []OwnerKeyValue - existingDomains := []string{common.PathDomainStorage.Identifier()} + existingDomains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} const existingDomainStorageMapCount = 5 // Create storage with account storage map @@ -6849,9 +6849,9 @@ func TestRuntimeStorageForMigratedAccount(t *testing.T) { // - read domain storage map and commit t.Run("read, commit, update, commit, remove, commit", func(t *testing.T) { - domains := []string{ - common.PathDomainStorage.Identifier(), - common.PathDomainPublic.Identifier(), + domains := []common.StorageDomain{ + common.PathDomainStorage.StorageDomain(), + common.PathDomainPublic.StorageDomain(), } const domainStorageMapCount = 5 @@ -6997,7 +6997,7 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { onRead LedgerOnRead, onWrite LedgerOnWrite, address common.Address, - domains []string, + domains []common.StorageDomain, domainStorageMapCount int, ) (TestLedger, accountStorageMapValues) { ledger := NewTestLedger(nil, nil) @@ -7017,7 +7017,7 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { // Write domain register domainStorageMapValueID := domainStorageMap.ValueID() - err := ledger.SetValue(address[:], []byte(domain), domainStorageMapValueID[8:]) + err := ledger.SetValue(address[:], []byte(domain.Identifier()), domainStorageMapValueID[8:]) require.NoError(t, err) // Write elements to to domain storage map @@ -7048,8 +7048,8 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { // post-condition: no change // migration: none because only read ops. t.Run("read non-existent domain storage map", func(t *testing.T) { - existingDomains := []string{ - common.PathDomainStorage.Identifier(), + existingDomains := []common.StorageDomain{ + common.PathDomainStorage.StorageDomain(), } var writeCount int @@ -7068,7 +7068,7 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { // Get non-existent domain storage map const createIfNotExists = false - nonexistingDomain := common.PathDomainPublic.Identifier() + nonexistingDomain := common.PathDomainPublic.StorageDomain() domainStorageMap := storage.GetStorageMap(inter, address, nonexistingDomain, createIfNotExists) require.Nil(t, domainStorageMap) @@ -7098,7 +7098,7 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { var writeCount int - existingDomains := []string{common.PathDomainStorage.Identifier()} + existingDomains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} const existingDomainStorageMapCount = 5 // Create storage with existing domain storage map @@ -7152,33 +7152,33 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { // migration: yes createDomainTestCases := []struct { name string - existingDomains []string - newDomains []string + existingDomains []common.StorageDomain + newDomains []common.StorageDomain existingDomainStorageMapCount int newDomainStorageMapCount int isNewDomainStorageMapInlined bool }{ { name: "empty domain storage map", - existingDomains: []string{common.PathDomainStorage.Identifier()}, + existingDomains: []common.StorageDomain{common.PathDomainStorage.StorageDomain()}, existingDomainStorageMapCount: 5, - newDomains: []string{common.PathDomainPublic.Identifier()}, + newDomains: []common.StorageDomain{common.PathDomainPublic.StorageDomain()}, newDomainStorageMapCount: 0, isNewDomainStorageMapInlined: true, }, { name: "small domain storage map", - existingDomains: []string{common.PathDomainStorage.Identifier()}, + existingDomains: []common.StorageDomain{common.PathDomainStorage.StorageDomain()}, existingDomainStorageMapCount: 5, - newDomains: []string{common.PathDomainPublic.Identifier()}, + newDomains: []common.StorageDomain{common.PathDomainPublic.StorageDomain()}, newDomainStorageMapCount: 10, isNewDomainStorageMapInlined: true, }, { name: "large domain storage map", - existingDomains: []string{common.PathDomainStorage.Identifier()}, + existingDomains: []common.StorageDomain{common.PathDomainStorage.StorageDomain()}, existingDomainStorageMapCount: 5, - newDomains: []string{common.PathDomainPublic.Identifier()}, + newDomains: []common.StorageDomain{common.PathDomainPublic.StorageDomain()}, newDomainStorageMapCount: 20, isNewDomainStorageMapInlined: false, }, @@ -7232,7 +7232,7 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { require.True(t, len(writeEntries) > 1+len(tc.existingDomains)+len(tc.newDomains)) i := 0 - for _, domain := range AccountDomains { + for _, domain := range common.AllStorageDomains { if slices.Contains(tc.existingDomains, domain) || slices.Contains(tc.newDomains, domain) { @@ -7240,7 +7240,7 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { // Existing and new domain registers are removed. // Removing new (non-existent) domain registers is no-op. require.Equal(t, address[:], writeEntries[i].Owner) - require.Equal(t, []byte(domain), writeEntries[i].Key) + require.Equal(t, []byte(domain.Identifier()), writeEntries[i].Key) require.True(t, len(writeEntries[i].Value) == 0) i++ @@ -7277,7 +7277,7 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { var writeEntries []OwnerKeyValue - domains := []string{common.PathDomainStorage.Identifier()} + domains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} const existingDomainStorageMapCount = 5 // Create storage with existing domain storage maps @@ -7386,7 +7386,7 @@ func TestRuntimeStorageForUnmigratedAccount(t *testing.T) { var writeEntries []OwnerKeyValue - domains := []string{common.PathDomainStorage.Identifier()} + domains := []common.StorageDomain{common.PathDomainStorage.StorageDomain()} const domainStorageMapCount = 5 // Create storage with existing account storage map @@ -7602,10 +7602,10 @@ func TestRuntimeStorageDomainStorageMapInlinedState(t *testing.T) { inter := NewTestInterpreterWithStorage(t, storage) - domains := []string{ - common.PathDomainStorage.Identifier(), - common.PathDomainPublic.Identifier(), - common.PathDomainPrivate.Identifier(), + domains := []common.StorageDomain{ + common.PathDomainStorage.StorageDomain(), + common.PathDomainPublic.StorageDomain(), + common.PathDomainPrivate.StorageDomain(), } const domainStorageMapCount = 500 @@ -7724,10 +7724,10 @@ func TestRuntimeStorageLargeDomainValues(t *testing.T) { inter := NewTestInterpreterWithStorage(t, storage) - domains := []string{ - common.PathDomainStorage.Identifier(), - common.PathDomainPublic.Identifier(), - common.PathDomainPrivate.Identifier(), + domains := []common.StorageDomain{ + common.PathDomainStorage.StorageDomain(), + common.PathDomainPublic.StorageDomain(), + common.PathDomainPrivate.StorageDomain(), } const domainStorageMapCount = 5 @@ -7843,9 +7843,9 @@ func TestDomainRegisterMigrationForLargeAccount(t *testing.T) { { address: address, domains: []domainInfo{ - {domain: common.PathDomainStorage.Identifier(), domainStorageMapCount: 100, maxDepth: 3}, - {domain: common.PathDomainPublic.Identifier(), domainStorageMapCount: 100, maxDepth: 3}, - {domain: common.PathDomainPrivate.Identifier(), domainStorageMapCount: 100, maxDepth: 3}, + {domain: common.PathDomainStorage.StorageDomain(), domainStorageMapCount: 100, maxDepth: 3}, + {domain: common.PathDomainPublic.StorageDomain(), domainStorageMapCount: 100, maxDepth: 3}, + {domain: common.PathDomainPrivate.StorageDomain(), domainStorageMapCount: 100, maxDepth: 3}, }, }, } @@ -7864,7 +7864,7 @@ func TestDomainRegisterMigrationForLargeAccount(t *testing.T) { // Create new domain storage map const createIfNotExists = true - domain := stdlib.InboxStorageDomain + domain := common.StorageDomainInbox domainStorageMap := storage.GetStorageMap(inter, address, domain, createIfNotExists) require.NotNil(t, domainStorageMap) @@ -7911,7 +7911,7 @@ func createAndWriteAccountStorageMap( storage *Storage, inter *interpreter.Interpreter, address common.Address, - domains []string, + domains []common.StorageDomain, count int, random *rand.Rand, ) accountStorageMapValues { @@ -7996,7 +7996,7 @@ func checkAccountStorageMapData( iter := accountStorageMap.Iterator() for { domain, domainStorageMap := iter.Next() - if domain == "" { + if domain == common.StorageDomainUnknown { break } diff --git a/stdlib/account.go b/stdlib/account.go index 4ce0f6d65c..b3a785bf39 100644 --- a/stdlib/account.go +++ b/stdlib/account.go @@ -938,8 +938,6 @@ func newAccountKeysRevokeFunction( } } -const InboxStorageDomain = "inbox" - func newAccountInboxPublishFunction( inter *interpreter.Interpreter, handler EventEmitter, @@ -996,7 +994,7 @@ func newAccountInboxPublishFunction( inter.WriteStored( provider, - InboxStorageDomain, + common.StorageDomainInbox, storageMapKey, publishedValue, ) @@ -1029,7 +1027,7 @@ func newAccountInboxUnpublishFunction( storageMapKey := interpreter.StringStorageMapKey(nameValue.Str) - readValue := inter.ReadStored(provider, InboxStorageDomain, storageMapKey) + readValue := inter.ReadStored(provider, common.StorageDomainInbox, storageMapKey) if readValue == nil { return interpreter.Nil } @@ -1065,7 +1063,7 @@ func newAccountInboxUnpublishFunction( inter.WriteStored( provider, - InboxStorageDomain, + common.StorageDomainInbox, storageMapKey, nil, ) @@ -1114,7 +1112,7 @@ func newAccountInboxClaimFunction( storageMapKey := interpreter.StringStorageMapKey(nameValue.Str) - readValue := inter.ReadStored(providerAddress, InboxStorageDomain, storageMapKey) + readValue := inter.ReadStored(providerAddress, common.StorageDomainInbox, storageMapKey) if readValue == nil { return interpreter.Nil } @@ -1155,7 +1153,7 @@ func newAccountInboxClaimFunction( inter.WriteStored( providerAddress, - InboxStorageDomain, + common.StorageDomainInbox, storageMapKey, nil, ) @@ -2983,10 +2981,6 @@ func IssueAccountCapabilityController( return capabilityIDValue } -// CapabilityControllerStorageDomain is the storage domain which stores -// capability controllers by capability ID -const CapabilityControllerStorageDomain = "cap_con" - // storeCapabilityController stores a capability controller in the account's capability ID to controller storage map func storeCapabilityController( inter *interpreter.Interpreter, @@ -2998,7 +2992,7 @@ func storeCapabilityController( existed := inter.WriteStored( address, - CapabilityControllerStorageDomain, + common.StorageDomainCapabilityController, storageMapKey, controller, ) @@ -3017,7 +3011,7 @@ func removeCapabilityController( existed := inter.WriteStored( address, - CapabilityControllerStorageDomain, + common.StorageDomainCapabilityController, storageMapKey, nil, ) @@ -3045,7 +3039,7 @@ func getCapabilityController( readValue := inter.ReadStored( address, - CapabilityControllerStorageDomain, + common.StorageDomainCapabilityController, storageMapKey, ) if readValue == nil { @@ -3225,10 +3219,6 @@ var capabilityIDSetStaticType = &interpreter.DictionaryStaticType{ ValueType: interpreter.NilStaticType, } -// PathCapabilityStorageDomain is the storage domain which stores -// capability ID dictionaries (sets) by storage path identifier -const PathCapabilityStorageDomain = "path_cap" - func recordStorageCapabilityController( inter *interpreter.Interpreter, locationRange interpreter.LocationRange, @@ -3255,7 +3245,7 @@ func recordStorageCapabilityController( storageMap := inter.Storage().GetStorageMap( inter, address, - PathCapabilityStorageDomain, + common.StorageDomainPathCapability, true, ) @@ -3298,7 +3288,7 @@ func getPathCapabilityIDSet( storageMap := inter.Storage().GetStorageMap( inter, address, - PathCapabilityStorageDomain, + common.StorageDomainPathCapability, false, ) if storageMap == nil { @@ -3349,7 +3339,7 @@ func unrecordStorageCapabilityController( storageMap := inter.Storage().GetStorageMap( inter, address, - PathCapabilityStorageDomain, + common.StorageDomainPathCapability, true, ) if storageMap == nil { @@ -3400,10 +3390,6 @@ func getStorageCapabilityControllerIDsIterator( return } -// AccountCapabilityStorageDomain is the storage domain which -// records active account capability controller IDs -const AccountCapabilityStorageDomain = "acc_cap" - func recordAccountCapabilityController( inter *interpreter.Interpreter, locationRange interpreter.LocationRange, @@ -3422,7 +3408,7 @@ func recordAccountCapabilityController( storageMap := inter.Storage().GetStorageMap( inter, address, - AccountCapabilityStorageDomain, + common.StorageDomainAccountCapability, true, ) @@ -3450,7 +3436,7 @@ func unrecordAccountCapabilityController( storageMap := inter.Storage().GetStorageMap( inter, address, - AccountCapabilityStorageDomain, + common.StorageDomainAccountCapability, true, ) @@ -3470,7 +3456,7 @@ func getAccountCapabilityControllerIDsIterator( storageMap := inter.Storage().GetStorageMap( inter, address, - AccountCapabilityStorageDomain, + common.StorageDomainAccountCapability, false, ) if storageMap == nil { @@ -3537,7 +3523,7 @@ func newAccountCapabilitiesPublishFunction( panic(errors.NewUnreachableError()) } - domain := pathValue.Domain.Identifier() + domain := pathValue.Domain.StorageDomain() identifier := pathValue.Identifier capabilityType, ok := capabilityValue.StaticType(inter).(*interpreter.CapabilityStaticType) @@ -3656,7 +3642,7 @@ func newAccountCapabilitiesUnpublishFunction( panic(errors.NewUnreachableError()) } - domain := pathValue.Domain.Identifier() + domain := pathValue.Domain.StorageDomain() identifier := pathValue.Identifier // Read/remove capability @@ -3930,7 +3916,7 @@ func newAccountCapabilitiesGetFunction( panic(errors.NewUnreachableError()) } - domain := pathValue.Domain.Identifier() + domain := pathValue.Domain.StorageDomain() identifier := pathValue.Identifier // Get borrow type type argument @@ -4115,7 +4101,7 @@ func newAccountCapabilitiesExistsFunction( panic(errors.NewUnreachableError()) } - domain := pathValue.Domain.Identifier() + domain := pathValue.Domain.StorageDomain() identifier := pathValue.Identifier // Read stored capability, if any @@ -4433,10 +4419,6 @@ func newAccountCapabilityControllerDeleteFunction( } } -// CapabilityControllerTagStorageDomain is the storage domain which stores -// capability controller tags by capability ID -const CapabilityControllerTagStorageDomain = "cap_tag" - func getCapabilityControllerTag( inter *interpreter.Interpreter, address common.Address, @@ -4445,7 +4427,7 @@ func getCapabilityControllerTag( value := inter.ReadStored( address, - CapabilityControllerTagStorageDomain, + common.StorageDomainCapabilityControllerTag, interpreter.Uint64StorageMapKey(capabilityID), ) if value == nil { @@ -4507,7 +4489,7 @@ func setCapabilityControllerTag( inter.WriteStored( address, - CapabilityControllerTagStorageDomain, + common.StorageDomainCapabilityControllerTag, interpreter.Uint64StorageMapKey(capabilityID), value, ) diff --git a/stdlib/account_test.go b/stdlib/account_test.go index 2429663cc2..2218655c86 100644 --- a/stdlib/account_test.go +++ b/stdlib/account_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/onflow/cadence/common" "github.com/onflow/cadence/sema" . "github.com/onflow/cadence/test_utils/common_utils" ) @@ -33,11 +34,11 @@ func TestSemaCheckPathLiteralForInternalStorageDomains(t *testing.T) { t.Parallel() internalStorageDomains := []string{ - InboxStorageDomain, - AccountCapabilityStorageDomain, - CapabilityControllerStorageDomain, - PathCapabilityStorageDomain, - CapabilityControllerTagStorageDomain, + common.StorageDomainInbox.Identifier(), + common.StorageDomainAccountCapability.Identifier(), + common.StorageDomainCapabilityController.Identifier(), + common.StorageDomainPathCapability.Identifier(), + common.StorageDomainCapabilityControllerTag.Identifier(), } test := func(domain string) {