Wallet consistency checks & setting ticket outcome
This commit is contained in:
parent
8c3cab7942
commit
9d503e67ae
@ -27,6 +27,8 @@ var (
|
|||||||
type NotificationHandler struct{}
|
type NotificationHandler struct{}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// consistencyInterval is the time period between wallet consistency checks.
|
||||||
|
consistencyInterval = 30 * time.Minute
|
||||||
// requiredConfs is the number of confirmations required to consider a
|
// requiredConfs is the number of confirmations required to consider a
|
||||||
// ticket purchase or a fee transaction to be final.
|
// ticket purchase or a fee transaction to be final.
|
||||||
requiredConfs = 6
|
requiredConfs = 6
|
||||||
@ -69,7 +71,7 @@ func blockConnected() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1/3: Update the database with any tickets which now have 6+
|
// Step 1/4: Update the database with any tickets which now have 6+
|
||||||
// confirmations.
|
// confirmations.
|
||||||
|
|
||||||
unconfirmed, err := db.GetUnconfirmedTickets()
|
unconfirmed, err := db.GetUnconfirmedTickets()
|
||||||
@ -106,15 +108,16 @@ func blockConnected() {
|
|||||||
ticket.Confirmed = true
|
ticket.Confirmed = true
|
||||||
err = db.UpdateTicket(ticket)
|
err = db.UpdateTicket(ticket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s: db.UpdateTicket error (ticketHash=%s): %v", funcName, ticket.Hash, err)
|
log.Errorf("%s: db.UpdateTicket error, failed to set ticket as confirmed (ticketHash=%s): %v",
|
||||||
|
funcName, ticket.Hash, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("%s: Ticket confirmed (ticketHash=%s)", funcName, ticket.Hash)
|
log.Infof("%s: Ticket confirmed (ticketHash=%s)", funcName, ticket.Hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2/3: Broadcast fee tx for tickets which are confirmed.
|
// Step 2/4: Broadcast fee tx for tickets which are confirmed.
|
||||||
|
|
||||||
pending, err := db.GetPendingFees()
|
pending, err := db.GetPendingFees()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -128,36 +131,28 @@ func blockConnected() {
|
|||||||
funcName, ticket.Hash, err)
|
funcName, ticket.Hash, err)
|
||||||
ticket.FeeTxStatus = database.FeeError
|
ticket.FeeTxStatus = database.FeeError
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("%s: Fee tx broadcast for ticket (ticketHash=%s, feeHash=%s)",
|
log.Infof("%s: Fee tx broadcast for ticket (ticketHash=%s, feeHash=%s)",
|
||||||
funcName, ticket.Hash, ticket.FeeTxHash)
|
funcName, ticket.Hash, ticket.FeeTxHash)
|
||||||
ticket.FeeTxStatus = database.FeeBroadcast
|
ticket.FeeTxStatus = database.FeeBroadcast
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.UpdateTicket(ticket)
|
err = db.UpdateTicket(ticket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s: db.UpdateTicket error (ticketHash=%s): %v", funcName, ticket.Hash, err)
|
log.Errorf("%s: db.UpdateTicket error, failed to set fee tx as broadcast (ticketHash=%s): %v",
|
||||||
|
funcName, ticket.Hash, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3/3: Add tickets with confirmed fees to voting wallets.
|
// Step 3/4: Add tickets with confirmed fees to voting wallets.
|
||||||
|
|
||||||
unconfirmedFees, err := db.GetUnconfirmedFees()
|
unconfirmedFees, err := db.GetUnconfirmedFees()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s: db.GetUnconfirmedFees error: %v", funcName, err)
|
log.Errorf("%s: db.GetUnconfirmedFees error: %v", funcName, err)
|
||||||
// If this fails, there is nothing more we can do. Return.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are no confirmed fees, there is nothing more to do. Return.
|
|
||||||
if len(unconfirmedFees) == 0 {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
walletClients, failedConnections := walletRPC.Clients(ctx, netParams)
|
walletClients, failedConnections := walletRPC.Clients(ctx, netParams)
|
||||||
if len(walletClients) == 0 {
|
if len(walletClients) == 0 {
|
||||||
// If no wallet clients, there is nothing more we can do. Return.
|
|
||||||
log.Errorf("%s: Could not connect to any wallets", funcName)
|
log.Errorf("%s: Could not connect to any wallets", funcName)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if len(failedConnections) > 0 {
|
if len(failedConnections) > 0 {
|
||||||
log.Errorf("%s: Failed to connect to %d wallet(s), proceeding with only %d",
|
log.Errorf("%s: Failed to connect to %d wallet(s), proceeding with only %d",
|
||||||
@ -178,10 +173,11 @@ func blockConnected() {
|
|||||||
ticket.FeeTxStatus = database.FeeConfirmed
|
ticket.FeeTxStatus = database.FeeConfirmed
|
||||||
err = db.UpdateTicket(ticket)
|
err = db.UpdateTicket(ticket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s: db.UpdateTicket error (ticketHash=%s): %v", funcName, ticket.Hash, err)
|
log.Errorf("%s: db.UpdateTicket error, failed to set fee tx as confirmed (ticketHash=%s): %v",
|
||||||
return
|
funcName, ticket.Hash, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
log.Debugf("%s: Fee tx confirmed (ticketHash=%s)", funcName, ticket.Hash)
|
log.Infof("%s: Fee tx confirmed (ticketHash=%s)", funcName, ticket.Hash)
|
||||||
|
|
||||||
// Add ticket to the voting wallet.
|
// Add ticket to the voting wallet.
|
||||||
|
|
||||||
@ -208,11 +204,63 @@ func blockConnected() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Debugf("%s: Ticket added to voting wallet (wallet=%s, ticketHash=%s)",
|
log.Infof("%s: Ticket added to voting wallet (wallet=%s, ticketHash=%s)",
|
||||||
funcName, walletClient.String(), ticket.Hash)
|
funcName, walletClient.String(), ticket.Hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 4/4: Set ticket outcome in database if any tickets are voted/revoked.
|
||||||
|
|
||||||
|
// Ticket status needs to be checked on every wallet. This is because only
|
||||||
|
// one of the voting wallets will actually succeed in voting/revoking
|
||||||
|
// tickets (the others will get errors like "tx already exists"). Only the
|
||||||
|
// successful wallet will have the most up-to-date ticket status, the others
|
||||||
|
// will be outdated.
|
||||||
|
for _, walletClient := range walletClients {
|
||||||
|
dbTickets, err := db.GetVotableTickets()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: db.GetVotableTickets failed: %v", funcName, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ticketInfo, err := walletClient.TicketInfo()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: dcrwallet.TicketInfo failed (wallet=%s): %v",
|
||||||
|
funcName, walletClient.String(), err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dbTicket := range dbTickets {
|
||||||
|
tInfo, ok := ticketInfo[dbTicket.Hash]
|
||||||
|
if !ok {
|
||||||
|
log.Warnf("%s: TicketInfo response did not include expected ticket (wallet=%s, ticketHash=%s)",
|
||||||
|
funcName, walletClient.String(), dbTicket.Hash)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch tInfo.Status {
|
||||||
|
case "revoked":
|
||||||
|
dbTicket.Outcome = database.Revoked
|
||||||
|
case "voted":
|
||||||
|
dbTicket.Outcome = database.Voted
|
||||||
|
default:
|
||||||
|
// Skip to next ticket.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.UpdateTicket(dbTicket)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: db.UpdateTicket error, failed to set ticket outcome (ticketHash=%s): %v",
|
||||||
|
funcName, dbTicket.Hash, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("%s: Ticket no longer votable: outcome=%s, ticketHash=%s", funcName,
|
||||||
|
dbTicket.Outcome, dbTicket.Hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NotificationHandler) Close() error {
|
func (n *NotificationHandler) Close() error {
|
||||||
@ -260,6 +308,24 @@ func Start(c context.Context, wg *sync.WaitGroup, vdb *database.VspDatabase, drp
|
|||||||
// while vspd was shut down.
|
// while vspd was shut down.
|
||||||
blockConnected()
|
blockConnected()
|
||||||
|
|
||||||
|
// Run voting wallet consistency check now to ensure all wallets are up to
|
||||||
|
// date.
|
||||||
|
checkWalletConsistency()
|
||||||
|
|
||||||
|
// Run voting wallet consistency check periodically.
|
||||||
|
go func() {
|
||||||
|
ticker := time.NewTicker(consistencyInterval)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
ticker.Stop()
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
checkWalletConsistency()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// Loop forever attempting to create a connection to the dcrd server for
|
// Loop forever attempting to create a connection to the dcrd server for
|
||||||
// notifications.
|
// notifications.
|
||||||
go func() {
|
go func() {
|
||||||
@ -280,3 +346,145 @@ func Start(c context.Context, wg *sync.WaitGroup, vdb *database.VspDatabase, drp
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkWalletConsistency will retrieve all votable tickets from the database
|
||||||
|
// and ensure they are all added to voting wallets with the correct vote
|
||||||
|
// choices.
|
||||||
|
func checkWalletConsistency() {
|
||||||
|
|
||||||
|
funcName := "checkWalletConsistency"
|
||||||
|
|
||||||
|
log.Info("Checking voting wallet consistency")
|
||||||
|
|
||||||
|
dcrdClient, err := dcrdRPC.Client(ctx, netParams)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: %v", funcName, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
walletClients, failedConnections := walletRPC.Clients(ctx, netParams)
|
||||||
|
if len(walletClients) == 0 {
|
||||||
|
log.Errorf("%s: Could not connect to any wallets", funcName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(failedConnections) > 0 {
|
||||||
|
log.Errorf("%s: Failed to connect to %d wallet(s), proceeding with only %d",
|
||||||
|
funcName, len(failedConnections), len(walletClients))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1/2: Check all tickets are added to all voting wallets.
|
||||||
|
|
||||||
|
votableTickets, err := db.GetVotableTickets()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: db.GetVotableTickets failed: %v", funcName, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over each wallet and add any missing tickets.
|
||||||
|
for _, walletClient := range walletClients {
|
||||||
|
// Get all tickets the wallet is aware of.
|
||||||
|
walletTickets, err := walletClient.TicketInfo()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: dcrwallet.TicketInfo failed (wallet=%s): %v",
|
||||||
|
funcName, walletClient.String(), err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If missing tickets are added, set a flag and keep track of the
|
||||||
|
// earliest purchase height.
|
||||||
|
var added bool
|
||||||
|
var minHeight int64
|
||||||
|
for _, dbTicket := range votableTickets {
|
||||||
|
// If wallet already knows this ticket, skip to the next one.
|
||||||
|
_, exists := walletTickets[dbTicket.Hash]
|
||||||
|
if exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("%s: Adding missing ticket (wallet=%s, ticketHash=%s)",
|
||||||
|
funcName, walletClient.String(), dbTicket.Hash)
|
||||||
|
|
||||||
|
rawTicket, err := dcrdClient.GetRawTransaction(dbTicket.Hash)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: dcrd.GetRawTransaction error: %v", funcName, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = walletClient.AddTicketForVoting(dbTicket.VotingWIF, rawTicket.BlockHash, rawTicket.Hex)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: dcrwallet.AddTicketForVoting error (wallet=%s, ticketHash=%s): %v",
|
||||||
|
funcName, walletClient.String(), dbTicket.Hash, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
added = true
|
||||||
|
if minHeight == 0 || minHeight > rawTicket.BlockHeight {
|
||||||
|
minHeight = rawTicket.BlockHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a rescan if any missing tickets were added to this wallet.
|
||||||
|
if added {
|
||||||
|
log.Infof("%s: Performing a rescan on wallet %s (fromHeight=%d)",
|
||||||
|
funcName, walletClient.String(), minHeight)
|
||||||
|
err = walletClient.RescanFrom(minHeight)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: dcrwallet.RescanFrom failed (wallet=%s): %v",
|
||||||
|
funcName, walletClient.String(), err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2/2: Ensure vote choices are set correctly for all tickets on
|
||||||
|
// all wallets.
|
||||||
|
|
||||||
|
for _, walletClient := range walletClients {
|
||||||
|
// Get all tickets the wallet is aware of.
|
||||||
|
walletTickets, err := walletClient.TicketInfo()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: dcrwallet.TicketInfo failed (wallet=%s): %v",
|
||||||
|
funcName, walletClient.String(), err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dbTicket := range votableTickets {
|
||||||
|
// All tickets should be added to all wallets at this point, so log
|
||||||
|
// a warning if any are still missing.
|
||||||
|
walletTicket, exists := walletTickets[dbTicket.Hash]
|
||||||
|
if !exists {
|
||||||
|
log.Warnf("%s: Ticket missing from voting wallet (wallet=%s, ticketHash=%s)",
|
||||||
|
funcName, walletClient.String, dbTicket.Hash)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if vote choices match
|
||||||
|
for dbAgenda, dbChoice := range dbTicket.VoteChoices {
|
||||||
|
match := false
|
||||||
|
for _, walletChoice := range walletTicket.Choices {
|
||||||
|
if walletChoice.AgendaID == dbAgenda && walletChoice.ChoiceID == dbChoice {
|
||||||
|
match = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip to next agenda if db and wallet are matching.
|
||||||
|
if match {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("%s: Updating incorrect vote choices (wallet=%s, agenda=%s, ticketHash=%s)",
|
||||||
|
funcName, walletClient.String(), dbAgenda, dbTicket.Hash)
|
||||||
|
|
||||||
|
// If db and wallet are not matching, update wallet with correct
|
||||||
|
// choice.
|
||||||
|
err = walletClient.SetVoteChoice(dbAgenda, dbChoice, dbTicket.Hash)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s: dcrwallet.SetVoteChoice error (wallet=%s, ticketHash=%s): %v",
|
||||||
|
funcName, walletClient.String(), dbTicket.Hash, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -25,6 +25,16 @@ const (
|
|||||||
FeeError FeeStatus = "error"
|
FeeError FeeStatus = "error"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TicketOutcome describes the reason a ticket is no longer votable.
|
||||||
|
type TicketOutcome string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Ticket has been revoked, either because it was missed or it expired.
|
||||||
|
Revoked TicketOutcome = "revoked"
|
||||||
|
// Ticket has already voted.
|
||||||
|
Voted TicketOutcome = "voted"
|
||||||
|
)
|
||||||
|
|
||||||
// Ticket is serialized to json and stored in bbolt db. The json keys are
|
// Ticket is serialized to json and stored in bbolt db. The json keys are
|
||||||
// deliberately kept short because they are duplicated many times in the db.
|
// deliberately kept short because they are duplicated many times in the db.
|
||||||
type Ticket struct {
|
type Ticket struct {
|
||||||
@ -51,6 +61,10 @@ type Ticket struct {
|
|||||||
|
|
||||||
// FeeTxStatus indicates the current state of the fee transaction.
|
// FeeTxStatus indicates the current state of the fee transaction.
|
||||||
FeeTxStatus FeeStatus `json:"fsts"`
|
FeeTxStatus FeeStatus `json:"fsts"`
|
||||||
|
|
||||||
|
// Outcome is set once a ticket is either voted or revoked. An empty outcome
|
||||||
|
// indicates that a ticket is still votable.
|
||||||
|
Outcome TicketOutcome `json:"otcme"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Ticket) FeeExpired() bool {
|
func (t *Ticket) FeeExpired() bool {
|
||||||
@ -170,16 +184,15 @@ func (vdb *VspDatabase) GetTicketByHash(ticketHash string) (Ticket, bool, error)
|
|||||||
return ticket, found, err
|
return ticket, found, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vdb *VspDatabase) CountTickets() (int, int, error) {
|
func (vdb *VspDatabase) CountTickets() (int64, int64, int64, error) {
|
||||||
defer vdb.ticketsMtx.RUnlock()
|
defer vdb.ticketsMtx.RUnlock()
|
||||||
vdb.ticketsMtx.RLock()
|
vdb.ticketsMtx.RLock()
|
||||||
|
|
||||||
var total, feePaid int
|
var voting, voted, revoked int64
|
||||||
err := vdb.db.View(func(tx *bolt.Tx) error {
|
err := vdb.db.View(func(tx *bolt.Tx) error {
|
||||||
ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK)
|
ticketBkt := tx.Bucket(vspBktK).Bucket(ticketBktK)
|
||||||
|
|
||||||
return ticketBkt.ForEach(func(k, v []byte) error {
|
return ticketBkt.ForEach(func(k, v []byte) error {
|
||||||
total++
|
|
||||||
var ticket Ticket
|
var ticket Ticket
|
||||||
err := json.Unmarshal(v, &ticket)
|
err := json.Unmarshal(v, &ticket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -187,14 +200,21 @@ func (vdb *VspDatabase) CountTickets() (int, int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ticket.FeeTxStatus == FeeConfirmed {
|
if ticket.FeeTxStatus == FeeConfirmed {
|
||||||
feePaid++
|
switch ticket.Outcome {
|
||||||
|
case Voted:
|
||||||
|
voted++
|
||||||
|
case Revoked:
|
||||||
|
revoked++
|
||||||
|
default:
|
||||||
|
voting++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return total, feePaid, err
|
return voting, voted, revoked, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUnconfirmedTickets returns tickets which are not yet confirmed.
|
// GetUnconfirmedTickets returns tickets which are not yet confirmed.
|
||||||
@ -229,6 +249,14 @@ func (vdb *VspDatabase) GetUnconfirmedFees() ([]Ticket, error) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetVotableTickets returns tickets with a confirmed fee tx and no outcome (ie.
|
||||||
|
// not expired/voted/missed).
|
||||||
|
func (vdb *VspDatabase) GetVotableTickets() ([]Ticket, error) {
|
||||||
|
return vdb.filterTickets(func(t Ticket) bool {
|
||||||
|
return t.FeeTxStatus == FeeConfirmed && t.Outcome == ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// filterTickets accepts a filter function and returns all tickets from the
|
// filterTickets accepts a filter function and returns all tickets from the
|
||||||
// database which match the filter.
|
// database which match the filter.
|
||||||
//
|
//
|
||||||
|
|||||||
@ -50,7 +50,10 @@ when a VSP is closed will result in an error.
|
|||||||
"feepercentage":3.0,
|
"feepercentage":3.0,
|
||||||
"vspclosed":false,
|
"vspclosed":false,
|
||||||
"network":"testnet3",
|
"network":"testnet3",
|
||||||
"vspdversion":"1.0.0-pre"
|
"vspdversion":"1.0.0-pre",
|
||||||
|
"voting":10,
|
||||||
|
"voted":25,
|
||||||
|
"revoked":3
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
6
go.mod
6
go.mod
@ -3,9 +3,9 @@ module github.com/decred/vspd
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
decred.org/dcrwallet v1.2.3-0.20200519180100-f1aa4c354e05
|
decred.org/dcrwallet v1.2.3-0.20200727154839-096e3bee25f2
|
||||||
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200616182840-3baf1f590cb1
|
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200616182840-3baf1f590cb1
|
||||||
github.com/decred/dcrd/blockchain/v3 v3.0.0-20200311044114-143c1884e4c8
|
github.com/decred/dcrd/blockchain/v3 v3.0.0-20200608124004-b2f67c2dc475
|
||||||
github.com/decred/dcrd/chaincfg/chainhash v1.0.2
|
github.com/decred/dcrd/chaincfg/chainhash v1.0.2
|
||||||
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200616182840-3baf1f590cb1
|
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200616182840-3baf1f590cb1
|
||||||
github.com/decred/dcrd/dcrec v1.0.0
|
github.com/decred/dcrd/dcrec v1.0.0
|
||||||
@ -17,7 +17,7 @@ require (
|
|||||||
github.com/decred/slog v1.0.0
|
github.com/decred/slog v1.0.0
|
||||||
github.com/gin-gonic/gin v1.6.3
|
github.com/gin-gonic/gin v1.6.3
|
||||||
github.com/gorilla/sessions v1.2.0
|
github.com/gorilla/sessions v1.2.0
|
||||||
github.com/jessevdk/go-flags v1.4.0
|
github.com/jessevdk/go-flags v1.4.1-0.20200711081900-c17162fe8fd7
|
||||||
github.com/jrick/bitset v1.0.0
|
github.com/jrick/bitset v1.0.0
|
||||||
github.com/jrick/logrotate v1.0.0
|
github.com/jrick/logrotate v1.0.0
|
||||||
github.com/jrick/wsrpc/v2 v2.3.3
|
github.com/jrick/wsrpc/v2 v2.3.3
|
||||||
|
|||||||
41
go.sum
41
go.sum
@ -1,7 +1,8 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
decred.org/cspp v0.3.0 h1:2AkSsWzA7HIMZImfw0gT82Gdp8OXIM4NsBn7vna22uE=
|
||||||
decred.org/cspp v0.3.0/go.mod h1:UygjYilC94dER3BEU65Zzyoqy9ngJfWCD2rdJqvUs2A=
|
decred.org/cspp v0.3.0/go.mod h1:UygjYilC94dER3BEU65Zzyoqy9ngJfWCD2rdJqvUs2A=
|
||||||
decred.org/dcrwallet v1.2.3-0.20200519180100-f1aa4c354e05 h1:xongFmW2UgEOGu4zQ4VcQFduExKVBa+dC4aLRQLCCnQ=
|
decred.org/dcrwallet v1.2.3-0.20200727154839-096e3bee25f2 h1:iwsnZPdoo1ownS4T2asE3rZAwkDwfufQ+LanREPsFBY=
|
||||||
decred.org/dcrwallet v1.2.3-0.20200519180100-f1aa4c354e05/go.mod h1:V6pzOHJuuWZaUPUZZL2kiyx9Co3lVD0DRqDXJTWA+3c=
|
decred.org/dcrwallet v1.2.3-0.20200727154839-096e3bee25f2/go.mod h1:3cZSQAgJzWXeSKMxWuyAPjxcheBYOB5fwTzD5exhvgs=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
|
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
|
||||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
||||||
@ -20,16 +21,18 @@ github.com/decred/base58 v1.0.1/go.mod h1:H2ENcsJjye1G7CbRa67kV9OFaui0LGr56ntKKo
|
|||||||
github.com/decred/base58 v1.0.2/go.mod h1:pXP9cXCfM2sFLb2viz2FNIdeMWmZDBKG3ZBYbiSM78E=
|
github.com/decred/base58 v1.0.2/go.mod h1:pXP9cXCfM2sFLb2viz2FNIdeMWmZDBKG3ZBYbiSM78E=
|
||||||
github.com/decred/base58 v1.0.3 h1:KGZuh8d1WEMIrK0leQRM47W85KqCAdl2N+uagbctdDI=
|
github.com/decred/base58 v1.0.3 h1:KGZuh8d1WEMIrK0leQRM47W85KqCAdl2N+uagbctdDI=
|
||||||
github.com/decred/base58 v1.0.3/go.mod h1:pXP9cXCfM2sFLb2viz2FNIdeMWmZDBKG3ZBYbiSM78E=
|
github.com/decred/base58 v1.0.3/go.mod h1:pXP9cXCfM2sFLb2viz2FNIdeMWmZDBKG3ZBYbiSM78E=
|
||||||
|
github.com/decred/dcrd/addrmgr v1.1.0 h1:VQkn1qmafZypfN2u7yi7J/girwz4ZDicquo7JzsoxdQ=
|
||||||
github.com/decred/dcrd/addrmgr v1.1.0/go.mod h1:exghL+0+QeVvO4MXezWJ1C2tcpBn3ngfuP6S1R+adB8=
|
github.com/decred/dcrd/addrmgr v1.1.0/go.mod h1:exghL+0+QeVvO4MXezWJ1C2tcpBn3ngfuP6S1R+adB8=
|
||||||
github.com/decred/dcrd/blockchain/stake/v2 v2.0.2/go.mod h1:o2TT/l/YFdrt15waUdlZ3g90zfSwlA0WgQqHV9UGJF4=
|
github.com/decred/dcrd/blockchain/stake/v2 v2.0.2/go.mod h1:o2TT/l/YFdrt15waUdlZ3g90zfSwlA0WgQqHV9UGJF4=
|
||||||
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:aDL94kcVJfaaJP+acWUJrlK7g7xEOqTSiFe6bSN3yRQ=
|
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:aDL94kcVJfaaJP+acWUJrlK7g7xEOqTSiFe6bSN3yRQ=
|
||||||
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200311044114-143c1884e4c8/go.mod h1:4zE60yDWlfCDtmqnyP5o1k1K0oyhNn3Tvqo6F93/+RU=
|
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200608124004-b2f67c2dc475/go.mod h1:4zE60yDWlfCDtmqnyP5o1k1K0oyhNn3Tvqo6F93/+RU=
|
||||||
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:7fg/+PpoT/ecAnA/uvccRQQk7+JZ7gSOgcIHHqqZtIM=
|
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:7fg/+PpoT/ecAnA/uvccRQQk7+JZ7gSOgcIHHqqZtIM=
|
||||||
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:1e94ovQXEcOjIn7BRzkXpswA7pWQXqB2el5l0w0Srf8=
|
github.com/decred/dcrd/blockchain/stake/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:1e94ovQXEcOjIn7BRzkXpswA7pWQXqB2el5l0w0Srf8=
|
||||||
github.com/decred/dcrd/blockchain/standalone v1.1.0 h1:yclvVGEY09Gf8A4GSAo+NCtL1dW2TYJ4OKp4+g0ICI0=
|
github.com/decred/dcrd/blockchain/standalone v1.1.0 h1:yclvVGEY09Gf8A4GSAo+NCtL1dW2TYJ4OKp4+g0ICI0=
|
||||||
github.com/decred/dcrd/blockchain/standalone v1.1.0/go.mod h1:6K8ZgzlWM1Kz2TwXbrtiAvfvIwfAmlzrtpA7CVPCUPE=
|
github.com/decred/dcrd/blockchain/standalone v1.1.0/go.mod h1:6K8ZgzlWM1Kz2TwXbrtiAvfvIwfAmlzrtpA7CVPCUPE=
|
||||||
github.com/decred/dcrd/blockchain/v3 v3.0.0-20200311044114-143c1884e4c8 h1:I3psccIeKb9eld+TNd69SgUOy6940uflH/J3aLM2ctU=
|
github.com/decred/dcrd/blockchain/v3 v3.0.0-20200608124004-b2f67c2dc475 h1:4VxMHgkwn9YTglLQyp7fvuP2/TWqBrvonjaOJComPIs=
|
||||||
github.com/decred/dcrd/blockchain/v3 v3.0.0-20200311044114-143c1884e4c8/go.mod h1:R9rIXU8kEJVC9Z4LAlh9bo9hiT3a+ihys3mCrz4PVao=
|
github.com/decred/dcrd/blockchain/v3 v3.0.0-20200608124004-b2f67c2dc475/go.mod h1:Jh6HF5q9YQHjV+0PHcwCWL7NCYj0LFyjnKlzPFO8/Zc=
|
||||||
|
github.com/decred/dcrd/certgen v1.1.0 h1:lAPE2OLYdYeXDCaji/+KC53j7/s7wF7RVGeQbXK//XA=
|
||||||
github.com/decred/dcrd/certgen v1.1.0/go.mod h1:ivkPLChfjdAgFh7ZQOtl6kJRqVkfrCq67dlq3AbZBQE=
|
github.com/decred/dcrd/certgen v1.1.0/go.mod h1:ivkPLChfjdAgFh7ZQOtl6kJRqVkfrCq67dlq3AbZBQE=
|
||||||
github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU=
|
github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU=
|
||||||
github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60=
|
github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60=
|
||||||
@ -39,10 +42,11 @@ github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200214194519-928737b3e580/go.mod h1:
|
|||||||
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200215015031-3283587e6add/go.mod h1:v4oyBPQ/ZstYCV7+B0y6HogFByW76xTjr+72fOm66Y8=
|
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200215015031-3283587e6add/go.mod h1:v4oyBPQ/ZstYCV7+B0y6HogFByW76xTjr+72fOm66Y8=
|
||||||
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200215023918-6247af01d5e3/go.mod h1:v4oyBPQ/ZstYCV7+B0y6HogFByW76xTjr+72fOm66Y8=
|
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200215023918-6247af01d5e3/go.mod h1:v4oyBPQ/ZstYCV7+B0y6HogFByW76xTjr+72fOm66Y8=
|
||||||
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:v4oyBPQ/ZstYCV7+B0y6HogFByW76xTjr+72fOm66Y8=
|
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:v4oyBPQ/ZstYCV7+B0y6HogFByW76xTjr+72fOm66Y8=
|
||||||
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200311044114-143c1884e4c8/go.mod h1:v4oyBPQ/ZstYCV7+B0y6HogFByW76xTjr+72fOm66Y8=
|
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200608124004-b2f67c2dc475/go.mod h1:OHbKBa6UZZOXCU1Y8f9Ta3O+GShto7nB1O0nuEutKq4=
|
||||||
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:IfBqlTemNgX3Yax/lBBQSxDiVin1IitIXY6zegtXMps=
|
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:IfBqlTemNgX3Yax/lBBQSxDiVin1IitIXY6zegtXMps=
|
||||||
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:OHbKBa6UZZOXCU1Y8f9Ta3O+GShto7nB1O0nuEutKq4=
|
github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:OHbKBa6UZZOXCU1Y8f9Ta3O+GShto7nB1O0nuEutKq4=
|
||||||
github.com/decred/dcrd/connmgr/v3 v3.0.0-20200311044114-143c1884e4c8/go.mod h1:mvIMJsrOEngogmVrq+tdbPIZchHVgGnVBZeNwj1cW6E=
|
github.com/decred/dcrd/connmgr/v3 v3.0.0-20200608124004-b2f67c2dc475 h1:jOEkyTB8KqKrYRNS4PZUs13tf7UbiWspsNYix+eKbis=
|
||||||
|
github.com/decred/dcrd/connmgr/v3 v3.0.0-20200608124004-b2f67c2dc475/go.mod h1:UWFfZ1MbPzBgNA3bRCkF0woOlXkv1EIFEkwD+mdUW5Y=
|
||||||
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
|
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
|
||||||
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
||||||
github.com/decred/dcrd/crypto/ripemd160 v1.0.0 h1:MciTnR4NfBqDFRFjFkrn8WPLP4Vo7t6ww6ghfn6wcXQ=
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.0 h1:MciTnR4NfBqDFRFjFkrn8WPLP4Vo7t6ww6ghfn6wcXQ=
|
||||||
@ -59,8 +63,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200214194519-928737b3e580/go.
|
|||||||
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200215015031-3283587e6add/go.mod h1:Ej0/gOv8NpFfaczyXGndw7eRMJFVhmY2faSeyxztSUw=
|
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200215015031-3283587e6add/go.mod h1:Ej0/gOv8NpFfaczyXGndw7eRMJFVhmY2faSeyxztSUw=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200215023918-6247af01d5e3/go.mod h1:Ej0/gOv8NpFfaczyXGndw7eRMJFVhmY2faSeyxztSUw=
|
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200215023918-6247af01d5e3/go.mod h1:Ej0/gOv8NpFfaczyXGndw7eRMJFVhmY2faSeyxztSUw=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:Ej0/gOv8NpFfaczyXGndw7eRMJFVhmY2faSeyxztSUw=
|
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:Ej0/gOv8NpFfaczyXGndw7eRMJFVhmY2faSeyxztSUw=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200421213827-b60c60ffe98b h1:5/9ZtxOJ2scrLjNte19jKnN2n43WNj01+RGPp/j8L6Q=
|
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200608124004-b2f67c2dc475 h1:N4p2A5SPMXm97Vc8LazxchwudeE5GDs6S0WxwcrRmog=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200421213827-b60c60ffe98b/go.mod h1:J70FGZSbzsjecRTiTzER+3f1KZLNaXkuv+yeFTKoxM8=
|
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200608124004-b2f67c2dc475/go.mod h1:J70FGZSbzsjecRTiTzER+3f1KZLNaXkuv+yeFTKoxM8=
|
||||||
github.com/decred/dcrd/dcrjson/v3 v3.0.1 h1:b9cpplNJG+nutE2jS8K/BtSGIJihEQHhFjFAsvJF/iI=
|
github.com/decred/dcrd/dcrjson/v3 v3.0.1 h1:b9cpplNJG+nutE2jS8K/BtSGIJihEQHhFjFAsvJF/iI=
|
||||||
github.com/decred/dcrd/dcrjson/v3 v3.0.1/go.mod h1:fnTHev/ABGp8IxFudDhjGi9ghLiXRff1qZz/wvq12Mg=
|
github.com/decred/dcrd/dcrjson/v3 v3.0.1/go.mod h1:fnTHev/ABGp8IxFudDhjGi9ghLiXRff1qZz/wvq12Mg=
|
||||||
github.com/decred/dcrd/dcrutil/v2 v2.0.1 h1:aL+c7o7Q66HV1gIif+XkNYo9DeorN3l01Vns8mh0mqs=
|
github.com/decred/dcrd/dcrutil/v2 v2.0.1 h1:aL+c7o7Q66HV1gIif+XkNYo9DeorN3l01Vns8mh0mqs=
|
||||||
@ -68,13 +72,13 @@ github.com/decred/dcrd/dcrutil/v2 v2.0.1/go.mod h1:JdEgF6eh0TTohPeiqDxqDSikTSvAc
|
|||||||
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200215015031-3283587e6add/go.mod h1:CibwaHcCfz1sedFseBYKt+1hSbqnWC4Oe95DM8dAOlA=
|
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200215015031-3283587e6add/go.mod h1:CibwaHcCfz1sedFseBYKt+1hSbqnWC4Oe95DM8dAOlA=
|
||||||
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200215023918-6247af01d5e3/go.mod h1:48ZLpNNrRIYfqYxmvzMgOZrnTZUU3aTJveWtamCkOxo=
|
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200215023918-6247af01d5e3/go.mod h1:48ZLpNNrRIYfqYxmvzMgOZrnTZUU3aTJveWtamCkOxo=
|
||||||
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:jFxEd2LWDLvrWlrIiyx9ZGTQjvoFHZ0OVfBdyIX7jSw=
|
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:jFxEd2LWDLvrWlrIiyx9ZGTQjvoFHZ0OVfBdyIX7jSw=
|
||||||
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200311044114-143c1884e4c8/go.mod h1:/CDBC1SOXKrmihavgXviaTr6eVZSAWKQqEbRmacDxgg=
|
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200608124004-b2f67c2dc475/go.mod h1:WyoYp6FRgNAQL33CdcpvSnKcujH8wMzIRBSMCg64Egw=
|
||||||
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:uiMnZy+YBJt0ZzTXHk0TZgIPTlOGgrIYrRoFET0kUwg=
|
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:uiMnZy+YBJt0ZzTXHk0TZgIPTlOGgrIYrRoFET0kUwg=
|
||||||
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:WyoYp6FRgNAQL33CdcpvSnKcujH8wMzIRBSMCg64Egw=
|
github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:WyoYp6FRgNAQL33CdcpvSnKcujH8wMzIRBSMCg64Egw=
|
||||||
github.com/decred/dcrd/gcs/v2 v2.0.0/go.mod h1:3XjKcrtvB+r2ezhIsyNCLk6dRnXRJVyYmsd1P3SkU3o=
|
github.com/decred/dcrd/gcs/v2 v2.0.0/go.mod h1:3XjKcrtvB+r2ezhIsyNCLk6dRnXRJVyYmsd1P3SkU3o=
|
||||||
github.com/decred/dcrd/gcs/v2 v2.0.2-0.20200312171759-0a8cc56a776e h1:tBOk2P8F9JyRUSp0iRTs4nYEBro1FKBDIbg/UualLWw=
|
github.com/decred/dcrd/gcs/v2 v2.0.2-0.20200608124004-b2f67c2dc475 h1:5Qd0LWsOKVAmZyFRI/enaIsPpD8NsIPSxYwJ7uywMqo=
|
||||||
github.com/decred/dcrd/gcs/v2 v2.0.2-0.20200312171759-0a8cc56a776e/go.mod h1:JJGd1m0DrFgV4J2J8HKNB9YVkM06ewQHT6iINis39Z4=
|
github.com/decred/dcrd/gcs/v2 v2.0.2-0.20200608124004-b2f67c2dc475/go.mod h1:JJGd1m0DrFgV4J2J8HKNB9YVkM06ewQHT6iINis39Z4=
|
||||||
github.com/decred/dcrd/hdkeychain/v3 v3.0.0-20200421213827-b60c60ffe98b/go.mod h1:qKN0WzeSEEZ4fUBsTwKzOPkLP7GqSM6jBUm5Auq9mrM=
|
github.com/decred/dcrd/hdkeychain/v3 v3.0.0-20200608124004-b2f67c2dc475/go.mod h1:OQQKlU+hzvOHVZfUJq1iqQ5IfyycGaSPm1lmqMOyMaQ=
|
||||||
github.com/decred/dcrd/hdkeychain/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:kKZVUO9qWWWq5mJuKy9jiBPUMT6lFyY9MX1xOIaQn5c=
|
github.com/decred/dcrd/hdkeychain/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:kKZVUO9qWWWq5mJuKy9jiBPUMT6lFyY9MX1xOIaQn5c=
|
||||||
github.com/decred/dcrd/hdkeychain/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:OQQKlU+hzvOHVZfUJq1iqQ5IfyycGaSPm1lmqMOyMaQ=
|
github.com/decred/dcrd/hdkeychain/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:OQQKlU+hzvOHVZfUJq1iqQ5IfyycGaSPm1lmqMOyMaQ=
|
||||||
github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.0.0/go.mod h1:c5S+PtQWNIA2aUakgrLhrlopkMadcOv51dWhCEdo49c=
|
github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.0.0/go.mod h1:c5S+PtQWNIA2aUakgrLhrlopkMadcOv51dWhCEdo49c=
|
||||||
@ -83,11 +87,12 @@ github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.0.1-0.20200527025017-6fc98347d984
|
|||||||
github.com/decred/dcrd/txscript/v2 v2.1.0/go.mod h1:XaJAVrZU4NWRx4UEzTiDAs86op1m8GRJLz24SDBKOi0=
|
github.com/decred/dcrd/txscript/v2 v2.1.0/go.mod h1:XaJAVrZU4NWRx4UEzTiDAs86op1m8GRJLz24SDBKOi0=
|
||||||
github.com/decred/dcrd/txscript/v3 v3.0.0-20200215023918-6247af01d5e3/go.mod h1:ATMA8K0SOo+M9Wdbr6dMnAd8qICJi6pXjGLlKsJc99E=
|
github.com/decred/dcrd/txscript/v3 v3.0.0-20200215023918-6247af01d5e3/go.mod h1:ATMA8K0SOo+M9Wdbr6dMnAd8qICJi6pXjGLlKsJc99E=
|
||||||
github.com/decred/dcrd/txscript/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:KsDS7McU1yFaCYR9LCIwk6YnE15YN3wJUDxhKdFqlsc=
|
github.com/decred/dcrd/txscript/v3 v3.0.0-20200215031403-6b2ce76f0986/go.mod h1:KsDS7McU1yFaCYR9LCIwk6YnE15YN3wJUDxhKdFqlsc=
|
||||||
github.com/decred/dcrd/txscript/v3 v3.0.0-20200421213827-b60c60ffe98b/go.mod h1:vrm3R/AesmA9slTf0rFcwhD0SduAJAWxocyaWVi8dM0=
|
github.com/decred/dcrd/txscript/v3 v3.0.0-20200608124004-b2f67c2dc475/go.mod h1:vrm3R/AesmA9slTf0rFcwhD0SduAJAWxocyaWVi8dM0=
|
||||||
github.com/decred/dcrd/txscript/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:ZvPldwEQn42X4Wr2YkaOLNOkKMgtW8hS1mlRHnYfcQc=
|
github.com/decred/dcrd/txscript/v3 v3.0.0-20200616182840-3baf1f590cb1 h1:ZvPldwEQn42X4Wr2YkaOLNOkKMgtW8hS1mlRHnYfcQc=
|
||||||
github.com/decred/dcrd/txscript/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:vrm3R/AesmA9slTf0rFcwhD0SduAJAWxocyaWVi8dM0=
|
github.com/decred/dcrd/txscript/v3 v3.0.0-20200616182840-3baf1f590cb1/go.mod h1:vrm3R/AesmA9slTf0rFcwhD0SduAJAWxocyaWVi8dM0=
|
||||||
github.com/decred/dcrd/wire v1.3.0 h1:X76I2/a8esUmxXmFpJpAvXEi014IA4twgwcOBeIS8lE=
|
github.com/decred/dcrd/wire v1.3.0 h1:X76I2/a8esUmxXmFpJpAvXEi014IA4twgwcOBeIS8lE=
|
||||||
github.com/decred/dcrd/wire v1.3.0/go.mod h1:fnKGlUY2IBuqnpxx5dYRU5Oiq392OBqAuVjRVSkIoXM=
|
github.com/decred/dcrd/wire v1.3.0/go.mod h1:fnKGlUY2IBuqnpxx5dYRU5Oiq392OBqAuVjRVSkIoXM=
|
||||||
|
github.com/decred/go-socks v1.1.0 h1:dnENcc0KIqQo3HSXdgboXAHgqsCIutkqq6ntQjYtm2U=
|
||||||
github.com/decred/go-socks v1.1.0/go.mod h1:sDhHqkZH0X4JjSa02oYOGhcGHYp12FsY1jQ/meV8md0=
|
github.com/decred/go-socks v1.1.0/go.mod h1:sDhHqkZH0X4JjSa02oYOGhcGHYp12FsY1jQ/meV8md0=
|
||||||
github.com/decred/slog v1.0.0 h1:Dl+W8O6/JH6n2xIFN2p3DNjCmjYwvrXsjlSJTQQ4MhE=
|
github.com/decred/slog v1.0.0 h1:Dl+W8O6/JH6n2xIFN2p3DNjCmjYwvrXsjlSJTQQ4MhE=
|
||||||
github.com/decred/slog v1.0.0/go.mod h1:zR98rEZHSnbZ4WHZtO0iqmSZjDLKhkXfrPTZQKtAonQ=
|
github.com/decred/slog v1.0.0/go.mod h1:zR98rEZHSnbZ4WHZtO0iqmSZjDLKhkXfrPTZQKtAonQ=
|
||||||
@ -121,10 +126,14 @@ github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYb
|
|||||||
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/jessevdk/go-flags v1.4.1-0.20200711081900-c17162fe8fd7 h1:Ug59miTxVKVg5Oi2S5uHlKOIV5jBx4Hb2u0jIxxDaSs=
|
||||||
|
github.com/jessevdk/go-flags v1.4.1-0.20200711081900-c17162fe8fd7/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jrick/bitset v1.0.0 h1:Ws0PXV3PwXqWK2n7Vz6idCdrV/9OrBXgHEJi27ZB9Dw=
|
github.com/jrick/bitset v1.0.0 h1:Ws0PXV3PwXqWK2n7Vz6idCdrV/9OrBXgHEJi27ZB9Dw=
|
||||||
github.com/jrick/bitset v1.0.0/go.mod h1:ZOYB5Uvkla7wIEY4FEssPVi3IQXa02arznRaYaAEPe4=
|
github.com/jrick/bitset v1.0.0/go.mod h1:ZOYB5Uvkla7wIEY4FEssPVi3IQXa02arznRaYaAEPe4=
|
||||||
github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=
|
github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=
|
||||||
@ -157,11 +166,11 @@ github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
|||||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
|
||||||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 h1:Sy5bstxEqwwbYs6n0/pBuxKENqOeZUgD45Gp3Q3pqLg=
|
||||||
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
@ -201,9 +210,11 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
|||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
requiredDcrdVersion = "6.1.1"
|
requiredDcrdVersion = "6.1.2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These error codes are defined in dcrd/dcrjson. They are copied here so we
|
// These error codes are defined in dcrd/dcrjson. They are copied here so we
|
||||||
|
|||||||
@ -164,3 +164,24 @@ func (c *WalletRPC) GetBestBlockHeight() (int64, error) {
|
|||||||
}
|
}
|
||||||
return block.Height, nil
|
return block.Height, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *WalletRPC) TicketInfo() (map[string]*wallettypes.TicketInfoResult, error) {
|
||||||
|
var result []*wallettypes.TicketInfoResult
|
||||||
|
err := c.Call(c.ctx, "ticketinfo", &result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// For easier access later on, store the tickets in a map using their hash
|
||||||
|
// as the key.
|
||||||
|
tickets := make(map[string]*wallettypes.TicketInfoResult, len(result))
|
||||||
|
for _, t := range result {
|
||||||
|
tickets[t.Hash] = t
|
||||||
|
}
|
||||||
|
|
||||||
|
return tickets, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *WalletRPC) RescanFrom(fromHeight int64) error {
|
||||||
|
return c.Call(c.ctx, "rescanwallet", nil, fromHeight)
|
||||||
|
}
|
||||||
|
|||||||
@ -131,7 +131,8 @@ func feeAddress(c *gin.Context) {
|
|||||||
|
|
||||||
err = db.UpdateTicket(ticket)
|
err = db.UpdateTicket(ticket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s: db.UpdateTicket failed (ticketHash=%s): %v", funcName, ticket.Hash, err)
|
log.Errorf("%s: db.UpdateTicket error, failed to update fee expiry (ticketHash=%s): %v",
|
||||||
|
funcName, ticket.Hash, err)
|
||||||
sendError(errInternalError, c)
|
sendError(errInternalError, c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,16 +12,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type vspStats struct {
|
type vspStats struct {
|
||||||
PubKey string
|
PubKey string
|
||||||
TotalTickets int
|
Voting int64
|
||||||
FeeConfirmedTickets int
|
Voted int64
|
||||||
VSPFee float64
|
Revoked int64
|
||||||
Network string
|
VSPFee float64
|
||||||
UpdateTime string
|
Network string
|
||||||
SupportEmail string
|
UpdateTime string
|
||||||
VspClosed bool
|
SupportEmail string
|
||||||
Debug bool
|
VspClosed bool
|
||||||
Designation string
|
Debug bool
|
||||||
|
Designation string
|
||||||
}
|
}
|
||||||
|
|
||||||
var statsMtx sync.RWMutex
|
var statsMtx sync.RWMutex
|
||||||
@ -35,7 +36,7 @@ func getVSPStats() *vspStats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateVSPStats(db *database.VspDatabase, cfg Config) error {
|
func updateVSPStats(db *database.VspDatabase, cfg Config) error {
|
||||||
total, feeConfirmed, err := db.CountTickets()
|
voting, voted, revoked, err := db.CountTickets()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -44,16 +45,17 @@ func updateVSPStats(db *database.VspDatabase, cfg Config) error {
|
|||||||
defer statsMtx.Unlock()
|
defer statsMtx.Unlock()
|
||||||
|
|
||||||
stats = &vspStats{
|
stats = &vspStats{
|
||||||
PubKey: base64.StdEncoding.EncodeToString(signPubKey),
|
PubKey: base64.StdEncoding.EncodeToString(signPubKey),
|
||||||
TotalTickets: total,
|
Voting: voting,
|
||||||
FeeConfirmedTickets: feeConfirmed,
|
Voted: voted,
|
||||||
VSPFee: cfg.VSPFee,
|
Revoked: revoked,
|
||||||
Network: cfg.NetParams.Name,
|
VSPFee: cfg.VSPFee,
|
||||||
UpdateTime: time.Now().Format("Mon Jan _2 15:04:05 2006"),
|
Network: cfg.NetParams.Name,
|
||||||
SupportEmail: cfg.SupportEmail,
|
UpdateTime: time.Now().Format("Mon Jan _2 15:04:05 2006"),
|
||||||
VspClosed: cfg.VspClosed,
|
SupportEmail: cfg.SupportEmail,
|
||||||
Debug: cfg.Debug,
|
VspClosed: cfg.VspClosed,
|
||||||
Designation: cfg.Designation,
|
Debug: cfg.Debug,
|
||||||
|
Designation: cfg.Designation,
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -212,7 +212,8 @@ findAddress:
|
|||||||
|
|
||||||
err = db.UpdateTicket(ticket)
|
err = db.UpdateTicket(ticket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s: InsertTicket failed (ticketHash=%s): %v", funcName, ticket.Hash, err)
|
log.Errorf("%s: db.UpdateTicket error, failed to set fee tx (ticketHash=%s): %v",
|
||||||
|
funcName, ticket.Hash, err)
|
||||||
sendError(errInternalError, c)
|
sendError(errInternalError, c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -230,7 +231,8 @@ findAddress:
|
|||||||
|
|
||||||
err = db.UpdateTicket(ticket)
|
err = db.UpdateTicket(ticket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s: db.UpdateTicket failed (ticketHash=%s): %v", funcName, ticket.Hash, err)
|
log.Errorf("%s: db.UpdateTicket error, failed to set fee tx error (ticketHash=%s): %v",
|
||||||
|
funcName, ticket.Hash, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sendErrorWithMsg("could not broadcast fee transaction", errInvalidFeeTx, c)
|
sendErrorWithMsg("could not broadcast fee transaction", errInvalidFeeTx, c)
|
||||||
@ -241,7 +243,8 @@ findAddress:
|
|||||||
|
|
||||||
err = db.UpdateTicket(ticket)
|
err = db.UpdateTicket(ticket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s: db.UpdateTicket failed (ticketHash=%s): %v", funcName, ticket.Hash, err)
|
log.Errorf("%s: db.UpdateTicket error, failed to set fee tx as broadcast (ticketHash=%s): %v",
|
||||||
|
funcName, ticket.Hash, err)
|
||||||
sendError(errInternalError, c)
|
sendError(errInternalError, c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,8 @@ func setVoteChoices(c *gin.Context) {
|
|||||||
ticket.VoteChoices = voteChoices
|
ticket.VoteChoices = voteChoices
|
||||||
err = db.UpdateTicket(ticket)
|
err = db.UpdateTicket(ticket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s: db.UpdateTicket error (ticketHash=%s): %v", funcName, ticket.Hash, err)
|
log.Errorf("%s: db.UpdateTicket error, failed to set vote choices (ticketHash=%s): %v",
|
||||||
|
funcName, ticket.Hash, err)
|
||||||
sendError(errInternalError, c)
|
sendError(errInternalError, c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,6 +148,8 @@
|
|||||||
<td>{{ .FeeTxStatus }}</td>
|
<td>{{ .FeeTxStatus }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>Ticket Outcome</th>
|
||||||
|
<td>{{ .Outcome }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
@ -3,13 +3,18 @@
|
|||||||
<div class="row vsp-stats">
|
<div class="row vsp-stats">
|
||||||
|
|
||||||
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
||||||
<div class="stat-title">Total tickets</div>
|
<div class="stat-title">Live tickets</div>
|
||||||
<div class="stat-value" id="vsp-hash-rate">{{ .TotalTickets }}</div>
|
<div class="stat-value">{{ .Voting }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
||||||
<div class="stat-title">Fee confirmed tickets</div>
|
<div class="stat-title">Voted tickets</div>
|
||||||
<div class="stat-value" id="last-work-height">{{ .FeeConfirmedTickets }}</div>
|
<div class="stat-value">{{ .Voted }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
||||||
|
<div class="stat-title">Revoked tickets</div>
|
||||||
|
<div class="stat-value">{{ .Revoked }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
||||||
|
|||||||
@ -8,6 +8,9 @@ type vspInfoResponse struct {
|
|||||||
VspClosed bool `json:"vspclosed"`
|
VspClosed bool `json:"vspclosed"`
|
||||||
Network string `json:"network"`
|
Network string `json:"network"`
|
||||||
VspdVersion string `json:"vspdversion"`
|
VspdVersion string `json:"vspdversion"`
|
||||||
|
Voting int64 `json:"voting"`
|
||||||
|
Voted int64 `json:"voted"`
|
||||||
|
Revoked int64 `json:"revoked"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FeeAddressRequest struct {
|
type FeeAddressRequest struct {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
// vspInfo is the handler for "GET /api/v3/vspinfo".
|
// vspInfo is the handler for "GET /api/v3/vspinfo".
|
||||||
func vspInfo(c *gin.Context) {
|
func vspInfo(c *gin.Context) {
|
||||||
|
cachedStats := getVSPStats()
|
||||||
sendJSONResponse(vspInfoResponse{
|
sendJSONResponse(vspInfoResponse{
|
||||||
APIVersions: []int64{3},
|
APIVersions: []int64{3},
|
||||||
Timestamp: time.Now().Unix(),
|
Timestamp: time.Now().Unix(),
|
||||||
@ -17,5 +18,8 @@ func vspInfo(c *gin.Context) {
|
|||||||
Network: cfg.NetParams.Name,
|
Network: cfg.NetParams.Name,
|
||||||
VspClosed: cfg.VspClosed,
|
VspClosed: cfg.VspClosed,
|
||||||
VspdVersion: version.String(),
|
VspdVersion: version.String(),
|
||||||
|
Voting: cachedStats.Voting,
|
||||||
|
Voted: cachedStats.Voted,
|
||||||
|
Revoked: cachedStats.Revoked,
|
||||||
}, c)
|
}, c)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user