Skip to content

Commit

Permalink
webapi: Add missed tickets to admin page.
Browse files Browse the repository at this point in the history
A new tab on the admin page displays a list of all tickets which were
registered with the VSP but missed their votes. Clicking on the ticket
hash redirects to the Ticket Search tab with the details of the missed
ticket displayed.
  • Loading branch information
jholdstock authored Sep 26, 2023
1 parent d960898 commit a254e94
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 11 deletions.
14 changes: 14 additions & 0 deletions database/ticket.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package database

import (
"fmt"
"sort"
"time"

bolt "go.etcd.io/bbolt"
Expand Down Expand Up @@ -116,6 +117,12 @@ func (t TicketList) EarliestPurchaseHeight() int64 {
return oldestHeight
}

func (t TicketList) SortByPurchaseHeight() {
sort.Slice(t, func(i, j int) bool {
return t[i].PurchaseHeight > t[j].PurchaseHeight
})
}

func (t *Ticket) FeeExpired() bool {
now := time.Now()
return now.After(time.Unix(t.FeeExpiration, 0))
Expand Down Expand Up @@ -385,6 +392,13 @@ func (vdb *VspDatabase) GetMissingPurchaseHeight() (TicketList, error) {
})
}

// GetMissedTickets returns all tickets which have outcome == missed.
func (vdb *VspDatabase) GetMissedTickets() (TicketList, error) {
return vdb.filterTickets(func(t *bolt.Bucket) bool {
return TicketOutcome(t.Get(outcomeK)) == Missed
})
}

// filterTickets accepts a filter function and returns all tickets from the
// database which match the filter.
func (vdb *VspDatabase) filterTickets(filter func(*bolt.Bucket) bool) (TicketList, error) {
Expand Down
36 changes: 28 additions & 8 deletions internal/webapi/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,21 @@ func (w *WebAPI) statusJSON(c *gin.Context) {
func (w *WebAPI) adminPage(c *gin.Context) {
cacheData := c.MustGet(cacheKey).(cacheData)

missed, err := w.db.GetMissedTickets()
if err != nil {
w.log.Errorf("db.GetMissedTickets error: %v", err)
c.String(http.StatusInternalServerError, "Error getting missed tickets from db")
return
}

missed.SortByPurchaseHeight()

c.HTML(http.StatusOK, "admin.html", gin.H{
"WebApiCache": cacheData,
"WebApiCfg": w.cfg,
"WalletStatus": w.walletStatus(c),
"DcrdStatus": w.dcrdStatus(c),
"WebApiCache": cacheData,
"WebApiCfg": w.cfg,
"WalletStatus": w.walletStatus(c),
"DcrdStatus": w.dcrdStatus(c),
"MissedTickets": missed,
})
}

Expand Down Expand Up @@ -212,6 +222,15 @@ func (w *WebAPI) ticketSearch(c *gin.Context) {
feeTxDecoded = string(decoded)
}

missed, err := w.db.GetMissedTickets()
if err != nil {
w.log.Errorf("db.GetMissedTickets error: %v", err)
c.String(http.StatusInternalServerError, "Error getting missed tickets from db")
return
}

missed.SortByPurchaseHeight()

c.HTML(http.StatusOK, "admin.html", gin.H{
"SearchResult": searchResult{
Hash: hash,
Expand All @@ -222,10 +241,11 @@ func (w *WebAPI) ticketSearch(c *gin.Context) {
VoteChanges: voteChanges,
MaxVoteChanges: w.cfg.MaxVoteChangeRecords,
},
"WebApiCache": cacheData,
"WebApiCfg": w.cfg,
"WalletStatus": w.walletStatus(c),
"DcrdStatus": w.dcrdStatus(c),
"WebApiCache": cacheData,
"WebApiCfg": w.cfg,
"WalletStatus": w.walletStatus(c),
"DcrdStatus": w.dcrdStatus(c),
"MissedTickets": missed,
})
}

Expand Down
13 changes: 13 additions & 0 deletions internal/webapi/formatting.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,16 @@ func atomsToDCR(atoms int64) string {
func float32ToPercent(input float32) string {
return fmt.Sprintf("%.2f%%", input*100)
}

// pluralize suffixes the provided noun with "s" if n is not 1, then
// concatenates n and noun with a space between them. For example:
//
// (0, "biscuit") will return "0 biscuits"
// (1, "biscuit") will return "1 biscuit"
// (3, "biscuit") will return "3 biscuits"
func pluralize(n int, noun string) string {
if n != 1 {
noun += "s"
}
return fmt.Sprintf("%d %s", n, noun)
}
8 changes: 7 additions & 1 deletion internal/webapi/public/css/vspd.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ footer .code {
}
}

.btn {
.btn-primary, .btn-secondary {
outline: 0;
-webkit-box-shadow: 1px 3px 14px 0px rgba(0,0,0,0.19);
box-shadow: 1px 3px 14px 0px rgba(0,0,0,0.19);
Expand Down Expand Up @@ -206,6 +206,12 @@ footer .code {
padding-left: 40px;
}

table.missed-tickets th,
table.missed-tickets td {
border: 1px solid #edeff1;
vertical-align: middle;
text-align: center;
}

.tabset > input {
display:block; /* "enable" hidden elements in IE/edge */
Expand Down
36 changes: 34 additions & 2 deletions internal/webapi/templates/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,18 @@ <h1>Admin Panel</h1>
id="tabset_1_4"
hidden
>
<input
type="radio"
name="tabset_1"
id="tabset_1_5"
hidden
>
<ul>
<li><label for="tabset_1_1">VSP Status</label></li>
<li><label for="tabset_1_2">Ticket Search</label></li>
<li><label for="tabset_1_3">Database</label></li>
<li><label for="tabset_1_4">Logout</label></li>
<li><label for="tabset_1_3">Missed Tickets</label></li>
<li><label for="tabset_1_4">Database</label></li>
<li><label for="tabset_1_5">Logout</label></li>
</ul>

<div>
Expand Down Expand Up @@ -190,6 +197,31 @@ <h1>Voting Wallets</h1>
{{ end }}
</section>

<section>
<h1>{{ pluralize (len .MissedTickets) "Missed Ticket" }}</h1>
{{ with .MissedTickets }}
<table class="missed-tickets mx-auto">
<thead>
<th>Purchase Height</th>
<th>Ticket Hash</th>
</thead>
<tbody>
{{ range . }}
<tr>
<td>{{ .PurchaseHeight }}</td>
<td>
<form action="/admin/ticket" method="post">
<input type="hidden" name="hash" value="{{ .Hash }}">
<button class="btn btn-link p-0 code" type="submit">{{ .Hash }}</button>
</form>
</td>
</tr>
{{ end }}
</tbody>
</table>
{{ end}}
</section>

<section>
<p>Database size: {{ .WebApiCache.DatabaseSize }}</p>
<a class="btn btn-primary" href="/admin/backup" download>Download Backup</a>
Expand Down
1 change: 1 addition & 0 deletions internal/webapi/webapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ func (w *WebAPI) router(cookieSecret []byte, dcrd rpc.DcrdConnect, wallets rpc.W
"atomsToDCR": atomsToDCR,
"float32ToPercent": float32ToPercent,
"comma": humanize.Comma,
"pluralize": pluralize,
})

router.LoadHTMLGlob("internal/webapi/templates/*.html")
Expand Down

0 comments on commit a254e94

Please sign in to comment.