Skip to content

Commit

Permalink
Update to new Atree API
Browse files Browse the repository at this point in the history
This commit updates Cadence to use new Atree API
- Array.SlabID()
- OrderedMap.SlabID()
- SlabID
- SlabIndex
- etc.

For more info, see Atree PRs:
- onflow/atree#322
- onflow/atree#323
- onflow/atree#324
  • Loading branch information
fxamacker committed Jul 7, 2023
1 parent 1442291 commit a4c5f8a
Show file tree
Hide file tree
Showing 19 changed files with 225 additions and 239 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c
github.com/go-test/deep v1.1.0
github.com/leanovate/gopter v0.2.9
github.com/onflow/atree v0.6.1-0.20230629205511-5b7b45a566a9
github.com/onflow/atree v0.6.1-0.20230706233410-78f997992600
github.com/rivo/uniseg v0.4.4
github.com/schollz/progressbar/v3 v3.13.1
github.com/stretchr/testify v1.8.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3px
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/onflow/atree v0.6.1-0.20230629205511-5b7b45a566a9 h1:mffWKRKGrBq5NhCWplOox33eW+gf2lcgjvdI8aeCjGk=
github.com/onflow/atree v0.6.1-0.20230629205511-5b7b45a566a9/go.mod h1:7YNAyCd5JENq+NzH+fR1ABUZVzbSq9dkt0+5fZH3L2A=
github.com/onflow/atree v0.6.1-0.20230706233410-78f997992600 h1:OOnC8buJso6dSZ6W+RGQDnJW9UTh7HfEGyS/ivXJ7NI=
github.com/onflow/atree v0.6.1-0.20230706233410-78f997992600/go.mod h1:7YNAyCd5JENq+NzH+fR1ABUZVzbSq9dkt0+5fZH3L2A=
github.com/pkg/term v1.2.0-beta.2 h1:L3y/h2jkuBVFdWiJvNfYfKmzcCnILw7mJWm2JQuMppw=
github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down
78 changes: 41 additions & 37 deletions runtime/cmd/decode-state-values/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,26 @@ func isSlabStorageKey(key string) bool {
return len(key) == slabKeyLength && key[0] == '$'
}

func storageKeySlabStorageID(address atree.Address, key string) atree.StorageID {
func storageKeyToSlabID(address atree.Address, key string) atree.SlabID {
if !isSlabStorageKey(key) {
return atree.StorageIDUndefined
return atree.SlabIDUndefined
}
var result atree.StorageID
result.Address = address
copy(result.Index[:], key[1:])
return result

var index atree.SlabIndex
copy(index[:], key[1:])

return atree.NewSlabID(address, index)
}

func decodeStorable(decoder *cbor.StreamDecoder, storableSlabStorageID atree.StorageID) (atree.Storable, error) {
func decodeStorable(decoder *cbor.StreamDecoder, storableSlabStorageID atree.SlabID) (atree.Storable, error) {
return interpreter.DecodeStorable(decoder, storableSlabStorageID, nil)
}

func decodeTypeInfo(decoder *cbor.StreamDecoder) (atree.TypeInfo, error) {
return interpreter.DecodeTypeInfo(decoder, nil)
}

func decodeSlab(id atree.StorageID, data []byte) (atree.Slab, error) {
func decodeSlab(id atree.SlabID, data []byte) (atree.Slab, error) {
return atree.DecodeSlab(
id,
data,
Expand All @@ -108,11 +109,17 @@ func decodeSlab(id atree.StorageID, data []byte) (atree.Slab, error) {
)
}

func storageIDStorageKey(id atree.StorageID) storageKey {
func slabIDToStorageKey(id atree.SlabID) storageKey {
var b [16]byte
_, err := id.ToRawBytes(b[:])
if err != nil {
panic(err)
}

return storageKey{
string(id.Address[:]),
string(b[:8]),
"",
"$" + string(id.Index[:]),
"$" + string(b[8:]),
}
}

Expand All @@ -122,8 +129,8 @@ type slabStorage struct{}

var _ atree.SlabStorage = &slabStorage{}

func (s *slabStorage) Retrieve(id atree.StorageID) (atree.Slab, bool, error) {
data, ok := storage[storageIDStorageKey(id)]
func (s *slabStorage) Retrieve(id atree.SlabID) (atree.Slab, bool, error) {
data, ok := storage[slabIDToStorageKey(id)]
if !ok {
return nil, false, nil
}
Expand All @@ -136,22 +143,22 @@ func (s *slabStorage) Retrieve(id atree.StorageID) (atree.Slab, bool, error) {
return slab, true, nil
}

func (s *slabStorage) Store(_ atree.StorageID, _ atree.Slab) error {
func (s *slabStorage) Store(_ atree.SlabID, _ atree.Slab) error {
panic("unexpected Store call")
}

func (s *slabStorage) Remove(_ atree.StorageID) error {
func (s *slabStorage) Remove(_ atree.SlabID) error {
panic("unexpected Remove call")
}

func (s *slabStorage) GenerateStorageID(_ atree.Address) (atree.StorageID, error) {
func (s *slabStorage) GenerateSlabID(_ atree.Address) (atree.SlabID, error) {
panic("unexpected GenerateStorageID call")
}

func (s *slabStorage) SlabIterator() (atree.SlabIterator, error) {
var slabs []struct {
storageKey
atree.StorageID
atree.SlabID
}

// NOTE: iteration over map is safe,
Expand All @@ -161,50 +168,50 @@ func (s *slabStorage) SlabIterator() (atree.SlabIterator, error) {

var address atree.Address
copy(address[:], key[0])
storageID := storageKeySlabStorageID(address, key[2])
if storageID == atree.StorageIDUndefined {
slabID := storageKeyToSlabID(address, key[2])
if slabID == atree.SlabIDUndefined {
continue
}

slabs = append(slabs, struct {
storageKey
atree.StorageID
atree.SlabID
}{
StorageID: storageID,
SlabID: slabID,
storageKey: key,
})
}

sort.Slice(slabs, func(i, j int) bool {
a := slabs[i]
b := slabs[j]
return a.StorageID.Compare(b.StorageID) < 0
return a.SlabID.Compare(b.SlabID) < 0
})

var i int

bar := progressbar.Default(int64(len(slabs)))

return func() (atree.StorageID, atree.Slab) {
return func() (atree.SlabID, atree.Slab) {
if i >= len(slabs) {
_ = bar.Close()
return atree.StorageIDUndefined, nil
return atree.SlabIDUndefined, nil
}

slabEntry := slabs[i]
i++

_ = bar.Add(1)

storageID := slabEntry.StorageID
slabID := slabEntry.SlabID
data := storage[slabEntry.storageKey]

slab, err := decodeSlab(storageID, data)
slab, err := decodeSlab(slabID, data)
if err != nil {
log.Fatalf("failed to decode slab @ %s", storageID)
log.Fatalf("failed to decode slab @ %s", slabID)
}

return storageID, slab
return slabID, slab
}, nil
}

Expand Down Expand Up @@ -308,20 +315,17 @@ func loadStorageKey(

if !*checkSlabsFlag {

var storageIndex atree.StorageIndex
var slabIndex atree.SlabIndex
// Skip '$' prefix
copy(storageIndex[:], key[1:])
copy(slabIndex[:], key[1:])

storageID := atree.StorageID{
Address: address,
Index: storageIndex,
}
slabID := atree.NewSlabID(address, slabIndex)

_, err := decodeSlab(storageID, data)
_, err := decodeSlab(slabID, data)
if err != nil {
log.Printf(
"Failed to decode slab @ %s: %s (size: %d)",
storageID, err, len(data),
slabID, err, len(data),
)
return err
}
Expand All @@ -339,7 +343,7 @@ func loadStorageKey(

reader := bytes.NewReader(data)
decoder := interpreter.CBORDecMode.NewStreamDecoder(reader)
storable, err := interpreter.DecodeStorable(decoder, atree.StorageIDUndefined, nil)
storable, err := interpreter.DecodeStorable(decoder, atree.SlabIDUndefined, nil)
if err != nil {
log.Printf(
"Failed to decode storable @ 0x%x %s: %s (data: %x)\n",
Expand Down
4 changes: 2 additions & 2 deletions runtime/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ type Interface interface {
SetValue(owner, key, value []byte) (err error)
// ValueExists returns true if the given key exists in the storage, owned by the given account.
ValueExists(owner, key []byte) (exists bool, err error)
// AllocateStorageIndex allocates a new storage index under the given account.
AllocateStorageIndex(owner []byte) (atree.StorageIndex, error)
// AllocateSlabIndex allocates a new slab index under the given account.
AllocateSlabIndex(owner []byte) (atree.SlabIndex, error)
// CreateAccount creates a new account.
CreateAccount(payer Address) (address Address, err error)
// AddEncodedAccountKey appends an encoded key to an account.
Expand Down
22 changes: 11 additions & 11 deletions runtime/interpreter/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,24 +117,24 @@ func decodeInt64(d StorableDecoder) (int64, error) {

func DecodeStorable(
decoder *cbor.StreamDecoder,
slabStorageID atree.StorageID,
slabID atree.SlabID,
memoryGauge common.MemoryGauge,
) (
atree.Storable,
error,
) {
return NewStorableDecoder(decoder, slabStorageID, memoryGauge).decodeStorable()
return NewStorableDecoder(decoder, slabID, memoryGauge).decodeStorable()
}

func NewStorableDecoder(
decoder *cbor.StreamDecoder,
slabStorageID atree.StorageID,
slabID atree.SlabID,
memoryGauge common.MemoryGauge,
) StorableDecoder {
return StorableDecoder{
decoder: decoder,
memoryGauge: memoryGauge,
slabStorageID: slabStorageID,
decoder: decoder,
memoryGauge: memoryGauge,
slabID: slabID,
TypeDecoder: NewTypeDecoder(
decoder,
memoryGauge,
Expand All @@ -144,9 +144,9 @@ func NewStorableDecoder(

type StorableDecoder struct {
TypeDecoder
memoryGauge common.MemoryGauge
decoder *cbor.StreamDecoder
slabStorageID atree.StorageID
memoryGauge common.MemoryGauge
decoder *cbor.StreamDecoder
slabID atree.SlabID
}

func (d StorableDecoder) decodeStorable() (atree.Storable, error) {
Expand Down Expand Up @@ -200,8 +200,8 @@ func (d StorableDecoder) decodeStorable() (atree.Storable, error) {

switch num {

case atree.CBORTagStorageID:
return atree.DecodeStorageIDStorable(d.decoder)
case atree.CBORTagSlabID:
return atree.DecodeSlabIDStorable(d.decoder)

case CBORTagVoidValue:
err := d.decoder.Skip()
Expand Down
2 changes: 1 addition & 1 deletion runtime/interpreter/deepcopyremove_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func TestValueDeepCopyAndDeepRemove(t *testing.T) {

count := 0
for id := range storage.Slabs {
if id.Address != (atree.Address{}) {
if !id.HasTempAddress() {
count++
}
}
Expand Down
Loading

0 comments on commit a4c5f8a

Please sign in to comment.