2019-11-18 20:11:43 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"hash/crc32"
|
|
|
|
"strconv"
|
|
|
|
|
2019-11-19 12:57:16 +00:00
|
|
|
"github.com/ipfs/go-cid"
|
2019-11-18 20:11:43 +00:00
|
|
|
"gopkg.in/urfave/cli.v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
var dotCmd = &cli.Command{
|
2019-12-06 00:27:32 +00:00
|
|
|
Name: "dot",
|
|
|
|
Usage: "generate dot graphs",
|
2019-12-05 11:12:08 +00:00
|
|
|
ArgsUsage: "<minHeight> <toseeHeight>",
|
2019-11-18 20:11:43 +00:00
|
|
|
Action: func(cctx *cli.Context) error {
|
2019-12-05 11:58:19 +00:00
|
|
|
st, err := openStorage(cctx.String("db"))
|
2019-11-18 20:11:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
minH, err := strconv.ParseInt(cctx.Args().Get(0), 10, 32)
|
2020-06-02 14:29:39 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-11-18 20:11:43 +00:00
|
|
|
tosee, err := strconv.ParseInt(cctx.Args().Get(1), 10, 32)
|
2020-06-02 14:29:39 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-11-18 20:11:43 +00:00
|
|
|
maxH := minH + tosee
|
|
|
|
|
2019-12-18 17:40:05 +00:00
|
|
|
res, err := st.db.Query(`select block, parent, b.miner, b.height, p.height from block_parents
|
|
|
|
inner join blocks b on block_parents.block = b.cid
|
|
|
|
inner join blocks p on block_parents.parent = p.cid
|
2020-01-08 14:08:34 +00:00
|
|
|
where b.height > $1 and b.height < $2`, minH, maxH)
|
2019-12-18 17:40:05 +00:00
|
|
|
|
2019-11-18 20:11:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println("digraph D {")
|
|
|
|
|
2019-12-11 22:17:44 +00:00
|
|
|
hl := st.hasList()
|
|
|
|
|
2019-11-18 20:11:43 +00:00
|
|
|
for res.Next() {
|
2019-11-18 21:39:07 +00:00
|
|
|
var block, parent, miner string
|
2019-12-18 17:40:05 +00:00
|
|
|
var height, ph uint64
|
|
|
|
if err := res.Scan(&block, &parent, &miner, &height, &ph); err != nil {
|
2019-11-19 12:57:16 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
bc, err := cid.Parse(block)
|
|
|
|
if err != nil {
|
2019-11-18 20:11:43 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-12-11 22:17:44 +00:00
|
|
|
_, has := hl[bc]
|
2019-11-19 12:57:16 +00:00
|
|
|
|
|
|
|
col := crc32.Checksum([]byte(miner), crc32.MakeTable(crc32.Castagnoli))&0xc0c0c0c0 + 0x30303030
|
|
|
|
|
|
|
|
hasstr := ""
|
|
|
|
if !has {
|
2019-12-18 17:40:05 +00:00
|
|
|
//col = 0xffffffff
|
2019-11-19 12:57:16 +00:00
|
|
|
hasstr = " UNSYNCED"
|
|
|
|
}
|
2019-11-18 20:11:43 +00:00
|
|
|
|
2019-12-18 17:40:05 +00:00
|
|
|
nulls := height - ph - 1
|
|
|
|
for i := uint64(0); i < nulls; i++ {
|
2019-12-19 15:50:18 +00:00
|
|
|
name := block + "NP" + fmt.Sprint(i)
|
2019-12-18 17:40:05 +00:00
|
|
|
|
|
|
|
fmt.Printf("%s [label = \"NULL:%d\", fillcolor = \"#ffddff\", style=filled, forcelabels=true]\n%s -> %s\n",
|
2019-12-19 15:50:18 +00:00
|
|
|
name, height-nulls+i, name, parent)
|
2019-12-18 17:40:05 +00:00
|
|
|
|
|
|
|
parent = name
|
|
|
|
}
|
|
|
|
|
2019-11-19 12:57:16 +00:00
|
|
|
fmt.Printf("%s [label = \"%s:%d%s\", fillcolor = \"#%06x\", style=filled, forcelabels=true]\n%s -> %s\n", block, miner, height, hasstr, col, block, parent)
|
2019-11-18 20:11:43 +00:00
|
|
|
}
|
|
|
|
if res.Err() != nil {
|
|
|
|
return res.Err()
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println("}")
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
2019-11-18 21:39:07 +00:00
|
|
|
}
|