Skip to content

Instantly share code, notes, and snippets.

@lukechampine
Created April 4, 2017 20:09
Show Gist options
  • Save lukechampine/a75f2819f565b0b0d8b0d36cfbb2c1f4 to your computer and use it in GitHub Desktop.
Save lukechampine/a75f2819f565b0b0d8b0d36cfbb2c1f4 to your computer and use it in GitHub Desktop.
Helper for exploring patterns in the Sia blockchain
package main
import (
"encoding/json"
"io/ioutil"
"log"
"os"
"github.com/NebulousLabs/Sia/encoding"
"github.com/NebulousLabs/Sia/persist"
"github.com/NebulousLabs/Sia/types"
"github.com/NebulousLabs/bolt"
)
// Modify this function to return whatever you're interested in
func blockFn(height types.BlockHeight, b types.Block) float64 {
return float64(len(encoding.Marshal(b)))
}
func openDB(filename string) (*persist.BoltDatabase, error) {
return persist.OpenDatabase(persist.Metadata{
Header: "Consensus Set Database",
Version: "0.5.0",
}, filename)
}
func forEachBlock(db *persist.BoltDatabase, fn func(types.BlockHeight, types.Block) float64) ([]float64, error) {
// read all ids
var ids []types.BlockID
err := db.View(func(tx *bolt.Tx) error {
// get current height
var currentHeight types.BlockHeight
err := encoding.Unmarshal(tx.Bucket([]byte("BlockHeight")).Get([]byte("BlockHeight")), &currentHeight)
if err != nil {
return err
}
ids = make([]types.BlockID, currentHeight+1)
return tx.Bucket([]byte("BlockPath")).ForEach(func(k, v []byte) error {
var height types.BlockHeight
var id types.BlockID
if err := encoding.Unmarshal(k, &height); err != nil {
return err
}
if err := encoding.Unmarshal(v, &id); err != nil {
return err
}
ids[height] = id
return nil
})
})
if err != nil {
return nil, err
}
points := make([]float64, len(ids))
// lookup each block in order
err = db.View(func(tx *bolt.Tx) error {
for height, id := range ids {
if id == (types.BlockID{}) {
log.Fatal("missing id at height", height)
}
var block types.Block
if err := encoding.Unmarshal(tx.Bucket([]byte("BlockMap")).Get(encoding.Marshal(id)), &block); err != nil {
return err
}
points[height] = blockFn(types.BlockHeight(height), block)
}
return nil
})
if err != nil {
return nil, err
}
return points, nil
}
func main() {
db, err := openDB(os.Args[1])
if err != nil {
log.Fatal(err)
}
points, err := forEachBlock(db, blockFn)
if err != nil {
log.Fatal(err)
}
b, err := json.Marshal(points)
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile("data.json", b, 0666)
if err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment