Created
April 4, 2017 20:09
-
-
Save lukechampine/a75f2819f565b0b0d8b0d36cfbb2c1f4 to your computer and use it in GitHub Desktop.
Helper for exploring patterns in the Sia blockchain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")), ¤tHeight) | |
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