Skip to content

Instantly share code, notes, and snippets.

@bluesign
Created October 19, 2021 09:18
Show Gist options
  • Save bluesign/df24b31a61bf4cd11f88efb6edd78925 to your computer and use it in GitHub Desktop.
Save bluesign/df24b31a61bf4cd11f88efb6edd78925 to your computer and use it in GitHub Desktop.
Enumerate Storage on persistent emulator
package main
import (
"bytes"
"encoding/binary"
"encoding/hex"
"fmt"
"log"
"strings"
"github.com/cheynewallace/tabby"
badger "github.com/dgraph-io/badger/v2"
"github.com/onflow/cadence/runtime/interpreter"
)
func main() {
db, err := badger.Open(badger.DefaultOptions("./flowdb").WithLoggingLevel(badger.ERROR).WithBypassLockGuard(true))
if err != nil {
log.Fatal(err)
}
defer db.Close()
txn := db.NewTransaction(false)
defer txn.Discard()
iopt := badger.DefaultIteratorOptions
iopt.Prefix = []byte("")
iopt.PrefetchValues = false
iopt.Reverse = true
iopt.AllVersions = false
it := txn.NewIterator(iopt)
defer it.Close()
seen := make(map[string]struct{})
t := tabby.New()
t.AddHeader("Address", "Location", "Content", "Block Height")
for it.Rewind(); it.Valid(); it.Next() {
item := it.Item()
key := item.Key()
location := bytes.Index(key, []byte("ledger_value_by_block_height_register_id"))
if location > -1 {
addressBytes := key[location+41 : location+41+16]
address := string(addressBytes)
locationBytes := key[location+41+17:]
location := string(locationBytes)
parts := strings.Split(location, "/")
if len(parts) < 2 {
continue
}
ledgerValueKey := strings.Split(parts[1], "-")
registerIdBytes, _ := hex.DecodeString(ledgerValueKey[0])
blockHeightBytes, _ := hex.DecodeString(ledgerValueKey[1])
blockHeight := binary.BigEndian.Uint64(blockHeightBytes[8:])
sepLocation := bytes.Index(registerIdBytes, []byte{31})
if sepLocation < 0 {
continue
}
registerIdBytes[sepLocation] = '/'
name := string(registerIdBytes)
if !strings.Contains(name, "storage") {
continue
}
_, ok := seen[fmt.Sprintf("%s_%s", address, name)]
if ok {
continue
}
seen[fmt.Sprintf("%s_%s", address, name)] = struct{}{}
item.Value(func(val []byte) error {
decoded, _ := interpreter.DecodeValue(val[5:], nil, nil, 4, nil)
t.AddLine(address, name, decoded.RecursiveString(interpreter.SeenReferences{}), blockHeight)
return nil
})
}
}
t.Print()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment