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

Sync feature/combine-domain-payloads branch with master #3676

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion cmd/decode-state-values/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

Expand Down
15 changes: 15 additions & 0 deletions common/pathdomain.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
132 changes: 132 additions & 0 deletions common/storagedomain.go
Original file line number Diff line number Diff line change
@@ -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())
}
43 changes: 24 additions & 19 deletions interpreter/account_storagemap.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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(),
))
}

Expand All @@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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)
Expand All @@ -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
}
Loading
Loading