diff --git a/cmd/lotus-chainwatch/site/block.html b/cmd/lotus-chainwatch/site/block.html new file mode 100644 index 000000000..b9aa09c32 --- /dev/null +++ b/cmd/lotus-chainwatch/site/block.html @@ -0,0 +1,61 @@ + + + + Lotus ChainWatch + + + +{{$cid := param "cid"}} + +
+
+
+ Lotus ChainWatch - Wallets +
+
+
+
+
Miner: {{index (strings "blocks" "miner" "cid=?" $cid) 0}}
+
Parents:
+
+ {{range strings "block_parents" "parent" "block=?" $cid}} + {{$parent := .}} + {{. | substr 54 62}} + {{end}} +
+
Messages:
+ + {{range strings "block_messages" "message" "block=?" $cid}} + {{$msg := .}} + + + + + + + {{$rec := qstrs `select r.exit, r.gas_used from messages + inner join block_messages bm on messages.cid = bm.message + inner join blocks b on bm.block = b.cid + inner join block_parents bp on b.cid = bp.parent + inner join blocks chd on bp.block = chd.cid + inner join receipts r on messages.cid = r.msg and chd.parentStateRoot = r.state + where messages.cid=? and b.cid=?` 2 $msg $cid}} + + + + {{end}} +
{{$msg | substr 54 62}} + {{$from := qstr "select \"from\" from messages where cid=?" $msg}} + {{$nonce := qstr "select nonce from messages where cid=?" $msg}} + {{$from}} (N:{{$nonce}}) + -> + {{$to := qstr "select \"to\" from messages where cid=?" $msg}} + {{$to}} + + Method:{{qstr "select method from messages where cid=?" $msg}} + exit:{{index $rec 0}}gasUsed:{{index $rec 1}}
+
+
+
+ + \ No newline at end of file diff --git a/cmd/lotus-chainwatch/site/blocks.html b/cmd/lotus-chainwatch/site/blocks.html new file mode 100644 index 000000000..6e38d9e2d --- /dev/null +++ b/cmd/lotus-chainwatch/site/blocks.html @@ -0,0 +1,43 @@ + + + + Lotus ChainWatch + + + +{{$start := param "start" | parseInt}} + +
+
+
+ Lotus ChainWatch - Wallets +
+
+
+
+ + {{range pageDown $start 50}} + + + + + + {{end}} +
+ {{$h := .}} + {{$h}}; + + {{qstr `select count(distinct block_messages.message) from block_messages + inner join blocks b on block_messages.block = b.cid + where b.height = ?` $h}} Msgs + + {{range strings "blocks" "cid" "height = ?" $h}} + {{. | substr 54 62}} + {{end}} +
+ Next 50 +
+
+
+ + diff --git a/cmd/lotus-chainwatch/site/index.html b/cmd/lotus-chainwatch/site/index.html index 1a1c2813a..315ba5705 100644 --- a/cmd/lotus-chainwatch/site/index.html +++ b/cmd/lotus-chainwatch/site/index.html @@ -26,6 +26,11 @@ {{count "id_address_map" "id != address"}} Keys; E% FIL in wallets; F% FIL in miners; M% in market; %G Other actors; %H FIL it treasury +
+ {{$maxH := queryNum "select max(height) from blocks inner join blocks_synced bs on blocks.cid = bs.cid"}} + + {{count "blocks"}} Blocks; Current Height: {{$maxH}}; +
diff --git a/cmd/lotus-chainwatch/site/key.html b/cmd/lotus-chainwatch/site/key.html index 697838ed2..7ae65b13f 100644 --- a/cmd/lotus-chainwatch/site/key.html +++ b/cmd/lotus-chainwatch/site/key.html @@ -24,9 +24,9 @@ {{ range messages "`from` = ? or `to` = ?" $wallet $wallet $wallet}} {{ if eq .From.String $wallet }} - To{{.To.String}} + To{{.To.String}} {{else}} - From{{.From.String}} + From{{.From.String}} {{end}} {{.Nonce}} {{.Value}} diff --git a/cmd/lotus-chainwatch/site/keys.html b/cmd/lotus-chainwatch/site/keys.html index adf96adb1..01ba3d241 100644 --- a/cmd/lotus-chainwatch/site/keys.html +++ b/cmd/lotus-chainwatch/site/keys.html @@ -14,7 +14,12 @@
{{range strings "id_address_map" "address" "address != id"}} -
{{.}}
+ {{$addr := .}} +
+ {{$addr}} + {{qstr "select count(distinct cid) from messages where \"from\"=?" $addr}} outmsgs; + {{qstr "select count(distinct cid) from messages where \"to\"=?" $addr}} inmsgs +
{{end}}
diff --git a/cmd/lotus-chainwatch/site/main.css b/cmd/lotus-chainwatch/site/main.css index 820625360..cc9da2f35 100644 --- a/cmd/lotus-chainwatch/site/main.css +++ b/cmd/lotus-chainwatch/site/main.css @@ -6,6 +6,10 @@ body { margin: 0; } +b { + color: #aff; +} + .Index { width: 100vw; height: 100vh; diff --git a/cmd/lotus-chainwatch/templates.go b/cmd/lotus-chainwatch/templates.go index 02e85d6b0..c255e8399 100644 --- a/cmd/lotus-chainwatch/templates.go +++ b/cmd/lotus-chainwatch/templates.go @@ -6,6 +6,7 @@ import ( "net/http" "os" "path/filepath" + "strconv" rice "github.com/GeertJohan/go.rice" "github.com/ipfs/go-cid" @@ -42,8 +43,15 @@ func newHandler(api api.FullNode, st *storage) (*handler, error) { "queryNum": h.queryNum, "sizeStr": sizeStr, "strings": h.strings, + "qstr": h.qstr, + "qstrs": h.qstrs, "messages": h.messages, + "pageDown": pageDown, + "parseInt": func(s string) (int, error) {i, e := strconv.ParseInt(s, 10, 64); return int(i), e}, + "substr": func(i, j int, s string,) string {return s[i:j]}, + "sub": func(a, b int) int {return a - b}, // TODO: really not builtin? + "param": func(string) string { return "" }, // replaced in request handler } @@ -193,7 +201,7 @@ func (h *handler) strings(table string, col string, filter string, args ...inter if len(filter) > 0 { filter = " where " + filter } - log.Info("strings qstr ", "select "+col+" from "+table+filter) + log.Info("strings qstr ", "select "+col+" from "+table+filter, args) rws, err := h.st.db.Query("select "+col+" from "+table+filter, args...) if err != nil { return nil, err @@ -209,6 +217,33 @@ func (h *handler) strings(table string, col string, filter string, args ...inter return } +func (h *handler) qstr(q string, p ...interface{}) (string, error) { + // explicitly not caring about sql injection too much, this doesn't take user input + + r, err := h.qstrs(q, 1, p...) + if err != nil { + return "", err + } + return r[0], nil +} + +func (h *handler) qstrs(q string, n int, p ...interface{}) ([]string, error) { + // explicitly not caring about sql injection too much, this doesn't take user input + + c := make([]string, n) + ia := make([]interface{}, n) + for i := range c { + ia[i] = &c[i] + } + err := h.st.db.QueryRow(q, p...).Scan(ia...) + if err != nil { + log.Error("qnum ", q, p, err) + return nil, err + } + + return c, nil +} + func (h *handler) messages(filter string, args ...interface{}) (out []types.Message, err error) { if len(filter) > 0 { filter = " where " + filter @@ -250,4 +285,13 @@ func (h *handler) messages(filter string, args ...interface{}) (out []types.Mess return } +func pageDown(base, n int) []int { + out := make([]int, n) + for i := range out { + out[i] = base - i + } + + return out +} + var _ http.Handler = &handler{}