Skip to content

Commit

Permalink
Merge pull request #3676 from onflow/fxamacker/sync-feature-branch-co…
Browse files Browse the repository at this point in the history
…mbine-domain-payloads

Sync `feature/combine-domain-payloads` branch with master
  • Loading branch information
fxamacker authored Nov 12, 2024
2 parents b13fdba + 7660d65 commit cc95223
Show file tree
Hide file tree
Showing 29 changed files with 385 additions and 276 deletions.
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

0 comments on commit cc95223

Please sign in to comment.