webapi: Display decoded fee tx, not just raw bytes
When searching for a ticket in the admin interface, use GetRawTransaction RPC to get the decoded transaction and display it as formatted JSON.
This commit is contained in:
parent
4dc2cc4d8d
commit
a88c261cb1
11
rpc/dcrd.go
11
rpc/dcrd.go
@ -150,6 +150,17 @@ func (c *DcrdRPC) GetRawTransaction(txHash string) (*dcrdtypes.TxRawResult, erro
|
|||||||
return &resp, nil
|
return &resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeRawTransaction uses decoderawtransaction RPC to decode raw transaction bytes.
|
||||||
|
func (c *DcrdRPC) DecodeRawTransaction(txHex string) (*dcrdtypes.TxRawDecodeResult, error) {
|
||||||
|
var resp dcrdtypes.TxRawDecodeResult
|
||||||
|
err := c.Call(c.ctx, "decoderawtransaction", &resp, txHex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SendRawTransaction uses sendrawtransaction RPC to broadcast a transaction to
|
// SendRawTransaction uses sendrawtransaction RPC to broadcast a transaction to
|
||||||
// the network. It ignores errors caused by duplicate transactions.
|
// the network. It ignores errors caused by duplicate transactions.
|
||||||
func (c *DcrdRPC) SendRawTransaction(txHex string) error {
|
func (c *DcrdRPC) SendRawTransaction(txHex string) error {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
package webapi
|
package webapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/decred/vspd/database"
|
"github.com/decred/vspd/database"
|
||||||
@ -41,6 +42,7 @@ type searchResult struct {
|
|||||||
Hash string
|
Hash string
|
||||||
Found bool
|
Found bool
|
||||||
Ticket database.Ticket
|
Ticket database.Ticket
|
||||||
|
FeeTxDecoded string
|
||||||
AltSignAddrData *database.AltSignAddrData
|
AltSignAddrData *database.AltSignAddrData
|
||||||
VoteChanges map[uint32]database.VoteChangeRecord
|
VoteChanges map[uint32]database.VoteChangeRecord
|
||||||
MaxVoteChanges int
|
MaxVoteChanges int
|
||||||
@ -176,11 +178,42 @@ func (s *Server) ticketSearch(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode the fee tx so it can be displayed human-readable. Fee tx hex may
|
||||||
|
// be null because it is removed from the DB if the tx is already mined and
|
||||||
|
// confirmed.
|
||||||
|
var feeTxDecoded string
|
||||||
|
if ticket.FeeTxHex != "" {
|
||||||
|
dcrdClient := c.MustGet(dcrdKey).(*rpc.DcrdRPC)
|
||||||
|
dcrdErr := c.MustGet(dcrdErrorKey)
|
||||||
|
if dcrdErr != nil {
|
||||||
|
s.log.Errorf("Could not get dcrd client: %v", dcrdErr.(error))
|
||||||
|
c.String(http.StatusInternalServerError, "Could not get dcrd client")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := dcrdClient.DecodeRawTransaction(ticket.FeeTxHex)
|
||||||
|
if err != nil {
|
||||||
|
s.log.Errorf("dcrd.DecodeRawTransaction error: %w", err)
|
||||||
|
c.String(http.StatusInternalServerError, "Error decoding fee transaction")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
decoded, err := json.Marshal(resp)
|
||||||
|
if err != nil {
|
||||||
|
s.log.Errorf("Unmarshal fee tx error: %w", err)
|
||||||
|
c.String(http.StatusInternalServerError, "Error unmarshalling fee tx")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
feeTxDecoded = string(decoded)
|
||||||
|
}
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "admin.html", gin.H{
|
c.HTML(http.StatusOK, "admin.html", gin.H{
|
||||||
"SearchResult": searchResult{
|
"SearchResult": searchResult{
|
||||||
Hash: hash,
|
Hash: hash,
|
||||||
Found: found,
|
Found: found,
|
||||||
Ticket: ticket,
|
Ticket: ticket,
|
||||||
|
FeeTxDecoded: feeTxDecoded,
|
||||||
AltSignAddrData: altSignAddrData,
|
AltSignAddrData: altSignAddrData,
|
||||||
VoteChanges: voteChanges,
|
VoteChanges: voteChanges,
|
||||||
MaxVoteChanges: s.cfg.MaxVoteChangeRecords,
|
MaxVoteChanges: s.cfg.MaxVoteChangeRecords,
|
||||||
|
|||||||
@ -158,6 +158,11 @@ footer .code {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ticket-table .small-text {
|
||||||
|
padding: 10px 16px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
#ticket-table pre {
|
#ticket-table pre {
|
||||||
color: #3D5873;
|
color: #3D5873;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|||||||
@ -75,7 +75,22 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Fee Tx</th>
|
<th>Fee Tx</th>
|
||||||
<td>{{ .Ticket.FeeTxHex }}</td>
|
<td>
|
||||||
|
{{ if .Ticket.FeeTxHex }}
|
||||||
|
<details>
|
||||||
|
<summary>Raw Bytes</summary>
|
||||||
|
<div class="small-text">
|
||||||
|
{{ .Ticket.FeeTxHex }}
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>Decoded</summary>
|
||||||
|
<div class="small-text">
|
||||||
|
<pre>{{ indentJSON .FeeTxDecoded }}</pre>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
{{ end }}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Fee Tx Status</th>
|
<th>Fee Tx Status</th>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user