To allow signing with addresses other than the commitment address, add an alternate signature address. In order to continue to prove that the address was chosen by the user, add an alternate signature history. Only allow one record per ticket to be saved to cap needed db space.
88 lines
2.8 KiB
Go
88 lines
2.8 KiB
Go
// Copyright (c) 2021 The Decred developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package database
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
bolt "go.etcd.io/bbolt"
|
|
)
|
|
|
|
const (
|
|
// initialVersion is the version of a freshly created database which has had
|
|
// no upgrades applied.
|
|
initialVersion = 1
|
|
|
|
// removeOldFeeTxVersion deletes any raw fee transactions which remain in
|
|
// the database after already having been confirmed on-chain. There is no
|
|
// need to keep these, and they take up a lot of space.
|
|
removeOldFeeTxVersion = 2
|
|
|
|
// ticketBucketVersion changes the way tickets are stored. Previously they
|
|
// were stored as JSON encoded strings in a single bucket. This upgrade
|
|
// moves each ticket into its own bucket and does away with JSON encoding.
|
|
ticketBucketVersion = 3
|
|
|
|
// altSigVersion adds a bucket to store alternate signatures used to verify
|
|
// messages sent to the vspd.
|
|
altSigVersion = 4
|
|
|
|
// latestVersion is the latest version of the database that is understood by
|
|
// vspd. Databases with recorded versions higher than this will fail to open
|
|
// (meaning any upgrades prevent reverting to older software).
|
|
latestVersion = altSigVersion
|
|
)
|
|
|
|
// upgrades maps between old database versions and the upgrade function to
|
|
// upgrade the database to the next version.
|
|
var upgrades = []func(tx *bolt.DB) error{
|
|
initialVersion: removeOldFeeTxUpgrade,
|
|
removeOldFeeTxVersion: ticketBucketUpgrade,
|
|
ticketBucketVersion: altSigUpgrade,
|
|
}
|
|
|
|
// v1Ticket has the json tags required to unmarshal tickets stored in the
|
|
// v1 database format.
|
|
type v1Ticket struct {
|
|
Hash string `json:"hsh"`
|
|
PurchaseHeight int64 `json:"phgt"`
|
|
CommitmentAddress string `json:"cmtaddr"`
|
|
FeeAddressIndex uint32 `json:"faddridx"`
|
|
FeeAddress string `json:"faddr"`
|
|
FeeAmount int64 `json:"famt"`
|
|
FeeExpiration int64 `json:"fexp"`
|
|
Confirmed bool `json:"conf"`
|
|
VotingWIF string `json:"vwif"`
|
|
VoteChoices map[string]string `json:"vchces"`
|
|
FeeTxHex string `json:"fhex"`
|
|
FeeTxHash string `json:"fhsh"`
|
|
FeeTxStatus FeeStatus `json:"fsts"`
|
|
Outcome TicketOutcome `json:"otcme"`
|
|
}
|
|
|
|
// Upgrade will update the database to the latest known version.
|
|
func (vdb *VspDatabase) Upgrade(currentVersion uint32) error {
|
|
if currentVersion == latestVersion {
|
|
// No upgrades required.
|
|
return nil
|
|
}
|
|
|
|
if currentVersion > latestVersion {
|
|
// Database is too new.
|
|
return fmt.Errorf("expected database version <= %d, got %d",
|
|
latestVersion, currentVersion)
|
|
}
|
|
|
|
// Execute all necessary upgrades in order.
|
|
for _, upgrade := range upgrades[currentVersion:] {
|
|
err := upgrade(vdb.db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|