From ab5aa4dd6d02787f3cf4221ea70e2ae8f57a5893 Mon Sep 17 00:00:00 2001 From: jholdstock Date: Sun, 14 Nov 2021 12:50:31 +0000 Subject: [PATCH] Clarify "setaltsig" terminology. Stardardize "alt sig"/"alt signature"/"alt signing address" terminology to "alternate signing address". --- background/background.go | 6 +- database/altsig.go | 124 ------------------ database/altsig_test.go | 117 ----------------- database/altsignaddr.go | 123 +++++++++++++++++ database/altsignaddr_test.go | 118 +++++++++++++++++ database/database.go | 4 +- database/database_test.go | 16 ++- database/upgrade_v4.go | 12 +- database/upgrades.go | 10 +- docs/api.md | 6 +- webapi/admin.go | 14 +- webapi/middleware.go | 12 +- webapi/{setaltsig.go => setaltsignaddr.go} | 44 +++---- ...taltsig_test.go => setaltsignaddr_test.go} | 77 +++++------ webapi/templates/ticket-search-result.html | 4 +- webapi/types.go | 16 +-- webapi/webapi.go | 2 +- 17 files changed, 355 insertions(+), 350 deletions(-) delete mode 100644 database/altsig.go delete mode 100644 database/altsig_test.go create mode 100644 database/altsignaddr.go create mode 100644 database/altsignaddr_test.go rename webapi/{setaltsig.go => setaltsignaddr.go} (70%) rename webapi/{setaltsig_test.go => setaltsignaddr_test.go} (76%) diff --git a/background/background.go b/background/background.go index 0251bf1..d826a94 100644 --- a/background/background.go +++ b/background/background.go @@ -103,11 +103,11 @@ func blockConnected() { funcName, ticket.Hash, err) } - // This will not error if an alternate signature does not + // This will not error if an alternate signing address does not // exist for ticket. - err = db.DeleteAltSig(ticket.Hash) + err = db.DeleteAltSignAddr(ticket.Hash) if err != nil { - log.Errorf("%s: db.DeleteAltSig error (ticketHash=%s): %v", + log.Errorf("%s: db.DeleteAltSignAddr error (ticketHash=%s): %v", funcName, ticket.Hash, err) } } else { diff --git a/database/altsig.go b/database/altsig.go deleted file mode 100644 index 287a9c6..0000000 --- a/database/altsig.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2020-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 ( - "errors" - "fmt" - - bolt "go.etcd.io/bbolt" -) - -// The keys used to store the altsig in the database. -var ( - altSigAddrK = []byte("altsig") - reqK = []byte("req") - reqSigK = []byte("reqsig") - resK = []byte("res") - resSigK = []byte("ressig") -) - -// AltSigData holds the information needed to prove that a client added an -// alternate signature address. -type AltSigData struct { - // AltSigAddr is the new alternate signature address. It is base 58 - // encoded. - AltSigAddr string - // Req is the original request to set an alternate signature. - Req []byte - // ReqSig is the request's signature signed by the private key that - // corresponds to the address. It is base 64 encoded. - ReqSig string - // Res is the original response from the server to the alternate - // signature address. - Res []byte - // ResSig is the response's signature signed by the server. It is base - // 64 encoded. - ResSig string -} - -// InsertAltSig will insert the provided ticket into the database. Returns an -// error if data for the ticket hash already exist. -// -// Passed data must have no empty fields. -func (vdb *VspDatabase) InsertAltSig(ticketHash string, data *AltSigData) error { - if data == nil { - return errors.New("alt sig data must not be nil for inserts") - } - - if data.AltSigAddr == "" || len(data.Req) == 0 || data.ReqSig == "" || - len(data.Res) == 0 || data.ResSig == "" { - return errors.New("alt sig data has empty parameters") - } - - return vdb.db.Update(func(tx *bolt.Tx) error { - altSigBkt := tx.Bucket(vspBktK).Bucket(altSigBktK) - - // Create a bucket for the new altsig. Returns an error if bucket - // already exists. - bkt, err := altSigBkt.CreateBucket([]byte(ticketHash)) - if err != nil { - return fmt.Errorf("could not create bucket for altsig: %w", err) - } - - if err := bkt.Put(altSigAddrK, []byte(data.AltSigAddr)); err != nil { - return err - } - - if err := bkt.Put(reqK, data.Req); err != nil { - return err - } - - if err := bkt.Put(reqSigK, []byte(data.ReqSig)); err != nil { - return err - } - - if err := bkt.Put(resK, data.Res); err != nil { - return err - } - return bkt.Put(resSigK, []byte(data.ResSig)) - }) -} - -// DeleteAltSig deletes an altsig from the database. Does not error if there is -// no altsig in the database. -func (vdb *VspDatabase) DeleteAltSig(ticketHash string) error { - return vdb.db.Update(func(tx *bolt.Tx) error { - altSigBkt := tx.Bucket(vspBktK).Bucket(altSigBktK) - - // Don't attempt delete if doesn't exist. - bkt := altSigBkt.Bucket([]byte(ticketHash)) - if bkt == nil { - return nil - } - - err := altSigBkt.DeleteBucket([]byte(ticketHash)) - if err != nil { - return fmt.Errorf("could not delete altsig: %w", err) - } - - return nil - }) -} - -// AltSigData retrieves a ticket's alternate signature data. Existence of an -// alternate signature can be inferred by no error and nil data return. -func (vdb *VspDatabase) AltSigData(ticketHash string) (*AltSigData, error) { - var h *AltSigData - return h, vdb.db.View(func(tx *bolt.Tx) error { - bkt := tx.Bucket(vspBktK).Bucket(altSigBktK).Bucket([]byte(ticketHash)) - if bkt == nil { - return nil - } - h = &AltSigData{ - AltSigAddr: string(bkt.Get(altSigAddrK)), - Req: bkt.Get(reqK), - ReqSig: string(bkt.Get(reqSigK)), - Res: bkt.Get(resK), - ResSig: string(bkt.Get(resSigK)), - } - return nil - }) -} diff --git a/database/altsig_test.go b/database/altsig_test.go deleted file mode 100644 index 53b1c08..0000000 --- a/database/altsig_test.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2020-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 ( - "reflect" - "testing" -) - -func exampleAltSigData() *AltSigData { - return &AltSigData{ - AltSigAddr: randString(35, addrCharset), - Req: randBytes(1000), - ReqSig: randString(96, sigCharset), - Res: randBytes(1000), - ResSig: randString(96, sigCharset), - } -} - -func ensureData(t *testing.T, ticketHash string, wantData *AltSigData) { - t.Helper() - - data, err := db.AltSigData(ticketHash) - if err != nil { - t.Fatalf("unexpected error fetching alt signature data: %v", err) - } - if !reflect.DeepEqual(wantData, data) { - t.Fatal("want data different than actual") - } -} - -func testAltSigData(t *testing.T) { - ticketHash := randString(64, hexCharset) - - // Not added yet so no values should exist in the db. - h, err := db.AltSigData(ticketHash) - if err != nil { - t.Fatalf("unexpected error fetching alt signature data: %v", err) - } - if h != nil { - t.Fatal("expected no data") - } - - // Insert an altsig. - data := exampleAltSigData() - if err := db.InsertAltSig(ticketHash, data); err != nil { - t.Fatalf("unexpected error storing altsig in database: %v", err) - } - - ensureData(t, ticketHash, data) -} - -func testInsertAltSig(t *testing.T) { - ticketHash := randString(64, hexCharset) - - // Not added yet so no values should exist in the db. - ensureData(t, ticketHash, nil) - - data := exampleAltSigData() - // Clear alt sig addr for test. - data.AltSigAddr = "" - - if err := db.InsertAltSig(ticketHash, data); err == nil { - t.Fatalf("expected error for insert blank address") - } - - if err := db.InsertAltSig(ticketHash, nil); err == nil { - t.Fatalf("expected error for nil data") - } - - // Still no change on errors. - ensureData(t, ticketHash, nil) - - // Re-add alt sig addr. - data.AltSigAddr = randString(35, addrCharset) - - // Insert an altsig. - if err := db.InsertAltSig(ticketHash, data); err != nil { - t.Fatalf("unexpected error storing altsig in database: %v", err) - } - - ensureData(t, ticketHash, data) - - // Further additions should error and not change the data. - secondData := exampleAltSigData() - secondData.AltSigAddr = data.AltSigAddr - if err := db.InsertAltSig(ticketHash, secondData); err == nil { - t.Fatalf("expected error for second altsig addition") - } - - ensureData(t, ticketHash, data) -} - -func testDeleteAltSig(t *testing.T) { - ticketHash := randString(64, hexCharset) - - // Nothing to delete. - if err := db.DeleteAltSig(ticketHash); err != nil { - t.Fatalf("unexpected error deleting nonexistant altsig") - } - - // Insert an altsig. - data := exampleAltSigData() - if err := db.InsertAltSig(ticketHash, data); err != nil { - t.Fatalf("unexpected error storing altsig in database: %v", err) - } - - ensureData(t, ticketHash, data) - - if err := db.DeleteAltSig(ticketHash); err != nil { - t.Fatalf("unexpected error deleting altsig: %v", err) - } - - ensureData(t, ticketHash, nil) -} diff --git a/database/altsignaddr.go b/database/altsignaddr.go new file mode 100644 index 0000000..a430a1c --- /dev/null +++ b/database/altsignaddr.go @@ -0,0 +1,123 @@ +// Copyright (c) 2020-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 ( + "errors" + "fmt" + + bolt "go.etcd.io/bbolt" +) + +// The keys used to store alternate signing addresses in the database. +var ( + altSignAddrK = []byte("altsig") + reqK = []byte("req") + reqSigK = []byte("reqsig") + respK = []byte("res") + respSigK = []byte("ressig") +) + +// AltSignAddrData holds the information needed to prove that a client added an +// alternate signing address. +type AltSignAddrData struct { + // AltSignAddr is the new alternate signing address. It is base 58 encoded. + AltSignAddr string + // Req is the original request to set an alternate signing address. + Req []byte + // ReqSig is the request's signature signed by the commitment address of the + // corresponding ticket. It is base 64 encoded. + ReqSig string + // Resp is the original response from the server to the alternate signing + // address. + Resp []byte + // RespSig is the response's signature signed by the server. It is base 64 + // encoded. + RespSig string +} + +// InsertAltSignAddr will insert the provided alternate signing address into the +// database. Returns an error if data for the ticket hash already exist. +// +// Passed data must have no empty fields. +func (vdb *VspDatabase) InsertAltSignAddr(ticketHash string, data *AltSignAddrData) error { + if data == nil { + return errors.New("alt sign addr data must not be nil for inserts") + } + + if data.AltSignAddr == "" || len(data.Req) == 0 || data.ReqSig == "" || + len(data.Resp) == 0 || data.RespSig == "" { + return errors.New("alt sign addr data has empty parameters") + } + + return vdb.db.Update(func(tx *bolt.Tx) error { + altSignAddrBkt := tx.Bucket(vspBktK).Bucket(altSignAddrBktK) + + // Create a bucket for the new alt sign addr. Returns an error if bucket + // already exists. + bkt, err := altSignAddrBkt.CreateBucket([]byte(ticketHash)) + if err != nil { + return fmt.Errorf("could not create bucket for alt sign addr: %w", err) + } + + if err := bkt.Put(altSignAddrK, []byte(data.AltSignAddr)); err != nil { + return err + } + + if err := bkt.Put(reqK, data.Req); err != nil { + return err + } + + if err := bkt.Put(reqSigK, []byte(data.ReqSig)); err != nil { + return err + } + + if err := bkt.Put(respK, data.Resp); err != nil { + return err + } + return bkt.Put(respSigK, []byte(data.RespSig)) + }) +} + +// DeleteAltSignAddr deletes an alternate signing address from the database. +// Does not error if there is no record in the database to delete. +func (vdb *VspDatabase) DeleteAltSignAddr(ticketHash string) error { + return vdb.db.Update(func(tx *bolt.Tx) error { + altSignAddrBkt := tx.Bucket(vspBktK).Bucket(altSignAddrBktK) + + // Don't attempt delete if doesn't exist. + bkt := altSignAddrBkt.Bucket([]byte(ticketHash)) + if bkt == nil { + return nil + } + + err := altSignAddrBkt.DeleteBucket([]byte(ticketHash)) + if err != nil { + return fmt.Errorf("could not delete altsignaddr: %w", err) + } + + return nil + }) +} + +// AltSignAddrData retrieves a ticket's alternate signing data. Existence of an +// alternate signing address can be inferred by no error and nil data return. +func (vdb *VspDatabase) AltSignAddrData(ticketHash string) (*AltSignAddrData, error) { + var h *AltSignAddrData + return h, vdb.db.View(func(tx *bolt.Tx) error { + bkt := tx.Bucket(vspBktK).Bucket(altSignAddrBktK).Bucket([]byte(ticketHash)) + if bkt == nil { + return nil + } + h = &AltSignAddrData{ + AltSignAddr: string(bkt.Get(altSignAddrK)), + Req: bkt.Get(reqK), + ReqSig: string(bkt.Get(reqSigK)), + Resp: bkt.Get(respK), + RespSig: string(bkt.Get(respSigK)), + } + return nil + }) +} diff --git a/database/altsignaddr_test.go b/database/altsignaddr_test.go new file mode 100644 index 0000000..9510e61 --- /dev/null +++ b/database/altsignaddr_test.go @@ -0,0 +1,118 @@ +// Copyright (c) 2020-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 ( + "reflect" + "testing" +) + +func exampleAltSignAddrData() *AltSignAddrData { + return &AltSignAddrData{ + AltSignAddr: randString(35, addrCharset), + Req: randBytes(1000), + ReqSig: randString(96, sigCharset), + Resp: randBytes(1000), + RespSig: randString(96, sigCharset), + } +} + +// ensureData will confirm that the provided data exists in the database. +func ensureData(t *testing.T, ticketHash string, wantData *AltSignAddrData) { + t.Helper() + + data, err := db.AltSignAddrData(ticketHash) + if err != nil { + t.Fatalf("unexpected error fetching alt sign address data: %v", err) + } + if !reflect.DeepEqual(wantData, data) { + t.Fatal("want data different than actual") + } +} + +func testAltSignAddrData(t *testing.T) { + ticketHash := randString(64, hexCharset) + + // Not added yet so no values should exist in the db. + h, err := db.AltSignAddrData(ticketHash) + if err != nil { + t.Fatalf("unexpected error fetching alt sign address data: %v", err) + } + if h != nil { + t.Fatal("expected no data") + } + + // Insert an alt sign address. + data := exampleAltSignAddrData() + if err := db.InsertAltSignAddr(ticketHash, data); err != nil { + t.Fatalf("unexpected error storing alt sign addr in database: %v", err) + } + + ensureData(t, ticketHash, data) +} + +func testInsertAltSignAddr(t *testing.T) { + ticketHash := randString(64, hexCharset) + + // Not added yet so no values should exist in the db. + ensureData(t, ticketHash, nil) + + data := exampleAltSignAddrData() + // Clear alt sign addr for test. + data.AltSignAddr = "" + + if err := db.InsertAltSignAddr(ticketHash, data); err == nil { + t.Fatalf("expected error for insert blank address") + } + + if err := db.InsertAltSignAddr(ticketHash, nil); err == nil { + t.Fatalf("expected error for nil data") + } + + // Still no change on errors. + ensureData(t, ticketHash, nil) + + // Re-add alt sig addr. + data.AltSignAddr = randString(35, addrCharset) + + // Insert an alt sign addr. + if err := db.InsertAltSignAddr(ticketHash, data); err != nil { + t.Fatalf("unexpected error storing alt sig addr in database: %v", err) + } + + ensureData(t, ticketHash, data) + + // Further additions should error and not change the data. + secondData := exampleAltSignAddrData() + secondData.AltSignAddr = data.AltSignAddr + if err := db.InsertAltSignAddr(ticketHash, secondData); err == nil { + t.Fatalf("expected error for second alt sig addr addition") + } + + ensureData(t, ticketHash, data) +} + +func testDeleteAltSignAddr(t *testing.T) { + ticketHash := randString(64, hexCharset) + + // Nothing to delete. + if err := db.DeleteAltSignAddr(ticketHash); err != nil { + t.Fatalf("unexpected error deleting nonexistant alt sign addr") + } + + // Insert an alt sign addr. + data := exampleAltSignAddrData() + if err := db.InsertAltSignAddr(ticketHash, data); err != nil { + t.Fatalf("unexpected error storing alt sign addr in database: %v", err) + } + + ensureData(t, ticketHash, data) + + if err := db.DeleteAltSignAddr(ticketHash); err != nil { + t.Fatalf("unexpected error deleting alt sign addr: %v", err) + } + + ensureData(t, ticketHash, nil) +} diff --git a/database/database.go b/database/database.go index c4cda08..e9b8881 100644 --- a/database/database.go +++ b/database/database.go @@ -50,8 +50,8 @@ var ( privateKeyK = []byte("privatekey") // lastaddressindex is the index of the last address used for fees. lastAddressIndexK = []byte("lastaddressindex") - // altSigBktK stores alternate signatures. - altSigBktK = []byte("altsigbkt") + // altSignAddrBktK stores alternate signing addresses. + altSignAddrBktK = []byte("altsigbkt") ) const ( diff --git a/database/database_test.go b/database/database_test.go index 1eaf343..f39f0f2 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 The Decred developers +// Copyright (c) 2020-2021 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -24,9 +24,13 @@ const ( feeXPub = "feexpub" maxVoteChangeRecords = 3 + // addrCharset is a list of all valid DCR address characters. addrCharset = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" - hexCharset = "1234567890abcdef" - sigCharset = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/=" + // hexCharset is a list of all valid hexadecimal characters. + hexCharset = "1234567890abcdef" + // sigCharset is a list of all valid request/response signature characters + // (base64 encoding). + sigCharset = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/=" ) var ( @@ -72,9 +76,9 @@ func TestDatabase(t *testing.T) { "testDeleteTicket": testDeleteTicket, "testVoteChangeRecords": testVoteChangeRecords, "testHTTPBackup": testHTTPBackup, - "testAltSigData": testAltSigData, - "testInsertAltSig": testInsertAltSig, - "testDeleteAltSig": testDeleteAltSig, + "testAltSignAddrData": testAltSignAddrData, + "testInsertAltSignAddr": testInsertAltSignAddr, + "testDeleteAltSignAddr": testDeleteAltSignAddr, } for testName, test := range tests { diff --git a/database/upgrade_v4.go b/database/upgrade_v4.go index de12b24..9dec049 100644 --- a/database/upgrade_v4.go +++ b/database/upgrade_v4.go @@ -10,22 +10,22 @@ import ( bolt "go.etcd.io/bbolt" ) -func altSigUpgrade(db *bolt.DB) error { - log.Infof("Upgrading database to version %d", altSigVersion) +func altSignAddrUpgrade(db *bolt.DB) error { + log.Infof("Upgrading database to version %d", altSignAddrVersion) // Run the upgrade in a single database transaction so it can be safely // rolled back if an error is encountered. err := db.Update(func(tx *bolt.Tx) error { vspBkt := tx.Bucket(vspBktK) - // Create altsig bucket. - _, err := vspBkt.CreateBucket(altSigBktK) + // Create alt sign addr bucket. + _, err := vspBkt.CreateBucket(altSignAddrBktK) if err != nil { - return fmt.Errorf("failed to create %s bucket: %w", altSigBktK, err) + return fmt.Errorf("failed to create %s bucket: %w", altSignAddrBktK, err) } // Update database version. - err = vspBkt.Put(versionK, uint32ToBytes(altSigVersion)) + err = vspBkt.Put(versionK, uint32ToBytes(altSignAddrVersion)) if err != nil { return fmt.Errorf("failed to update db version: %w", err) } diff --git a/database/upgrades.go b/database/upgrades.go index 64a30be..a060837 100644 --- a/database/upgrades.go +++ b/database/upgrades.go @@ -25,14 +25,14 @@ const ( // 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 + // altSignAddrVersion adds a bucket to store alternate sign addresses used + // to verify messages sent to the vspd. + altSignAddrVersion = 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 + latestVersion = altSignAddrVersion ) // upgrades maps between old database versions and the upgrade function to @@ -40,7 +40,7 @@ const ( var upgrades = []func(tx *bolt.DB) error{ initialVersion: removeOldFeeTxUpgrade, removeOldFeeTxVersion: ticketBucketUpgrade, - ticketBucketVersion: altSigUpgrade, + ticketBucketVersion: altSignAddrUpgrade, } // v1Ticket has the json tags required to unmarshal tickets stored in the diff --git a/docs/api.md b/docs/api.md index ada7b1d..041f9b5 100644 --- a/docs/api.md +++ b/docs/api.md @@ -69,12 +69,12 @@ its voting wallets unless both of these calls have succeeded.** Set an alternate signing address for a ticket. The ticket must be valid and will be transmitted to the network if not found. If set, for all future requests -involving this ticket, the vsp will check that a signature is good for this +involving this ticket, the VSP will check that a signature is good for this address and fallback to the commitment address if not. The address must be valid for the network and a pay to secp256k1 ECDSA pubkey hash script. The address can only be set once. Further requests to set a new address will be rejected. -- `POST /api/v3/setaltsig` +- `POST /api/v3/setaltsignaddr` Request: @@ -84,7 +84,7 @@ only be set once. Further requests to set a new address will be rejected. "tickethash":"1b9f5dc3b4872c47f66b148b0633647458123d72a0f0623a90890cc51a668737", "tickethex":"0100000001a8...bfa6e4bf9c5ec1", "parenthex":"0100000022a7...580771a3064710", - "altsigaddress":"Tsfkn6k9AoYgVZRV6ZzcgmuVSgCdJQt9JY2" + "altsignaddress":"Tsfkn6k9AoYgVZRV6ZzcgmuVSgCdJQt9JY2" } ``` diff --git a/webapi/admin.go b/webapi/admin.go index 1e14b34..bb3d99b 100644 --- a/webapi/admin.go +++ b/webapi/admin.go @@ -41,7 +41,7 @@ type searchResult struct { Hash string Found bool Ticket database.Ticket - AltSig string + AltSignAddr string VoteChanges map[uint32]database.VoteChangeRecord MaxVoteChanges int } @@ -169,16 +169,16 @@ func ticketSearch(c *gin.Context) { return } - altSigData, err := db.AltSigData(hash) + altSignAddrData, err := db.AltSignAddrData(hash) if err != nil { - log.Errorf("db.AltSigData error (ticketHash=%s): %v", hash, err) + log.Errorf("db.AltSignAddrData error (ticketHash=%s): %v", hash, err) c.String(http.StatusInternalServerError, "Error getting alt sig from db") return } - altSig := "" - if altSigData != nil { - altSig = altSigData.AltSigAddr + altSignAddr := "" + if altSignAddrData != nil { + altSignAddr = altSignAddrData.AltSignAddr } c.HTML(http.StatusOK, "admin.html", gin.H{ @@ -186,7 +186,7 @@ func ticketSearch(c *gin.Context) { Hash: hash, Found: found, Ticket: ticket, - AltSig: altSig, + AltSignAddr: altSignAddr, VoteChanges: voteChanges, MaxVoteChanges: cfg.MaxVoteChangeRecords, }, diff --git a/webapi/middleware.go b/webapi/middleware.go index a860788..0b66e63 100644 --- a/webapi/middleware.go +++ b/webapi/middleware.go @@ -359,17 +359,17 @@ func vspAuth() gin.HandlerFunc { err = validateSignature(reqBytes, commitmentAddress, c) if err != nil { // Don't return an error straight away if sig validation fails - - // first check if we have an alternate sig address for this ticket. - altSigData, err := db.AltSigData(hash) + // first check if we have an alternate sign address for this ticket. + altSigData, err := db.AltSignAddrData(hash) if err != nil { - log.Errorf("%s: db.AltSigData failed (ticketHash=%s): %v", funcName, hash, err) + log.Errorf("%s: db.AltSignAddrData failed (ticketHash=%s): %v", funcName, hash, err) sendError(errInternalError, c) return } - // If we have no alternate sig, or if validating with the alt sig - // fails, return an error to the client. - if altSigData == nil || validateSignature(reqBytes, altSigData.AltSigAddr, c) != nil { + // If we have no alternate sign address, or if validating with the + // alt sign addr fails, return an error to the client. + if altSigData == nil || validateSignature(reqBytes, altSigData.AltSignAddr, c) != nil { log.Warnf("%s: Bad signature (clientIP=%s, ticketHash=%s)", funcName, c.ClientIP(), hash) sendError(errBadSignature, c) return diff --git a/webapi/setaltsig.go b/webapi/setaltsignaddr.go similarity index 70% rename from webapi/setaltsig.go rename to webapi/setaltsignaddr.go index cd9a6b5..882b474 100644 --- a/webapi/setaltsig.go +++ b/webapi/setaltsignaddr.go @@ -25,10 +25,10 @@ type Node interface { GetRawTransaction(txHash string) (*dcrdtypes.TxRawResult, error) } -// setAltSig is the handler for "POST /api/v3/setaltsig". -func setAltSig(c *gin.Context) { +// setAltSignAddr is the handler for "POST /api/v3/setaltsignaddr". +func setAltSignAddr(c *gin.Context) { - const funcName = "setAltSig" + const funcName = "setAltSignAddr" // Get values which have been added to context by middleware. dcrdClient := c.MustGet(dcrdKey).(Node) @@ -45,23 +45,23 @@ func setAltSig(c *gin.Context) { return } - var request setAltSigRequest + var request setAltSignAddrRequest if err := binding.JSON.BindBody(reqBytes, &request); err != nil { log.Warnf("%s: Bad request (clientIP=%s): %v", funcName, c.ClientIP(), err) sendErrorWithMsg(err.Error(), errBadRequest, c) return } - altSigAddr, ticketHash := request.AltSigAddress, request.TicketHash + altSignAddr, ticketHash := request.AltSignAddress, request.TicketHash - currentData, err := db.AltSigData(ticketHash) + currentData, err := db.AltSignAddrData(ticketHash) if err != nil { - log.Errorf("%s: db.AltSigData (ticketHash=%s): %v", funcName, ticketHash, err) + log.Errorf("%s: db.AltSignAddrData (ticketHash=%s): %v", funcName, ticketHash, err) sendError(errInternalError, c) return } if currentData != nil { - msg := "alternate signature data already exists" + msg := "alternate sign address data already exists" log.Warnf("%s: %s (ticketHash=%s)", funcName, msg, ticketHash) sendErrorWithMsg(msg, errBadRequest, c) return @@ -69,14 +69,14 @@ func setAltSig(c *gin.Context) { } // Fail fast if the pubkey doesn't decode properly. - addr, err := stdaddr.DecodeAddressV0(altSigAddr, cfg.NetParams) + addr, err := stdaddr.DecodeAddressV0(altSignAddr, cfg.NetParams) if err != nil { - log.Warnf("%s: Alt sig address cannot be decoded (clientIP=%s): %v", funcName, c.ClientIP(), err) + log.Warnf("%s: Alt sign address cannot be decoded (clientIP=%s): %v", funcName, c.ClientIP(), err) sendErrorWithMsg(err.Error(), errBadRequest, c) return } if _, ok := addr.(*stdaddr.AddressPubKeyHashEcdsaSecp256k1V0); !ok { - log.Warnf("%s: Alt sig address is unexpected type (clientIP=%s, type=%T)", funcName, c.ClientIP(), addr) + log.Warnf("%s: Alt sign address is unexpected type (clientIP=%s, type=%T)", funcName, c.ClientIP(), addr) sendErrorWithMsg("wrong type for alternate signing address", errBadRequest, c) return } @@ -103,28 +103,26 @@ func setAltSig(c *gin.Context) { return } - sigStr := c.GetHeader("VSP-Client-Signature") - // Send success response to client. - res, resSig := sendJSONResponse(setAltSigResponse{ + resp, respSig := sendJSONResponse(setAltSignAddrResponse{ Timestamp: time.Now().Unix(), Request: reqBytes, }, c) - data := &database.AltSigData{ - AltSigAddr: altSigAddr, - Req: reqBytes, - ReqSig: sigStr, - Res: []byte(res), - ResSig: resSig, + data := &database.AltSignAddrData{ + AltSignAddr: altSignAddr, + Req: reqBytes, + ReqSig: c.GetHeader("VSP-Client-Signature"), + Resp: []byte(resp), + RespSig: respSig, } - err = db.InsertAltSig(ticketHash, data) + err = db.InsertAltSignAddr(ticketHash, data) if err != nil { - log.Errorf("%s: db.InsertAltSig error, failed to set alt data (ticketHash=%s): %v", + log.Errorf("%s: db.InsertAltSignAddr error (ticketHash=%s): %v", funcName, ticketHash, err) return } - log.Debugf("%s: New alt sig pubkey set for ticket: (ticketHash=%s)", funcName, ticketHash) + log.Debugf("%s: New alt sign address set for ticket: (ticketHash=%s)", funcName, ticketHash) } diff --git a/webapi/setaltsig_test.go b/webapi/setaltsignaddr_test.go similarity index 76% rename from webapi/setaltsig_test.go rename to webapi/setaltsignaddr_test.go index 83bffa3..df9f716 100644 --- a/webapi/setaltsig_test.go +++ b/webapi/setaltsignaddr_test.go @@ -27,8 +27,11 @@ import ( ) const ( - sigCharset = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/=" + // hexCharset is a list of all valid hexadecimal characters. hexCharset = "1234567890abcdef" + // sigCharset is a list of all valid request/response signature characters + // (base64 encoding). + sigCharset = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/=" testDb = "test.db" backupDb = "test.db-backup" ) @@ -115,19 +118,19 @@ func (n *testNode) GetRawTransaction(txHash string) (*dcrdtypes.TxRawResult, err return nil, n.getRawTransactionErr } -func TestSetAltSig(t *testing.T) { +func TestSetAltSignAddress(t *testing.T) { const testAddr = "DsVoDXNQqyF3V83PJJ5zMdnB4pQuJHBAh15" tests := []struct { - name string - dcrdClientErr bool - vspClosed bool - deformReq int - addr string - getRawTransactionErr error - canTicketNotVote bool - isExistingAltSig bool - canTicketVoteErr error - wantCode int + name string + dcrdClientErr bool + vspClosed bool + deformReq int + addr string + getRawTransactionErr error + canTicketNotVote bool + isExistingAltSignAddr bool + canTicketVoteErr error + wantCode int }{{ name: "ok", addr: testAddr, @@ -169,20 +172,20 @@ func TestSetAltSig(t *testing.T) { canTicketNotVote: true, wantCode: http.StatusBadRequest, }, { - name: "hist at max", - addr: testAddr, - isExistingAltSig: true, - wantCode: http.StatusBadRequest, + name: "hist at max", + addr: testAddr, + isExistingAltSignAddr: true, + wantCode: http.StatusBadRequest, }} for _, test := range tests { ticketHash := randString(64, hexCharset) - req := &setAltSigRequest{ - Timestamp: time.Now().Unix(), - TicketHash: ticketHash, - TicketHex: randString(504, hexCharset), - ParentHex: randString(504, hexCharset), - AltSigAddress: test.addr, + req := &setAltSignAddrRequest{ + Timestamp: time.Now().Unix(), + TicketHash: ticketHash, + TicketHex: randString(504, hexCharset), + ParentHex: randString(504, hexCharset), + AltSignAddress: test.addr, } reqSig := randString(504, hexCharset) b, err := json.Marshal(req) @@ -190,16 +193,16 @@ func TestSetAltSig(t *testing.T) { t.Fatal(err) } - if test.isExistingAltSig { - data := &database.AltSigData{ - AltSigAddr: test.addr, - Req: b, - ReqSig: reqSig, - Res: randBytes(1000), - ResSig: randString(96, sigCharset), + if test.isExistingAltSignAddr { + data := &database.AltSignAddrData{ + AltSignAddr: test.addr, + Req: b, + ReqSig: reqSig, + Resp: randBytes(1000), + RespSig: randString(96, sigCharset), } - if err := db.InsertAltSig(ticketHash, data); err != nil { - t.Fatalf("%q: unable to insert ticket: %v", test.name, err) + if err := db.InsertAltSignAddr(ticketHash, data); err != nil { + t.Fatalf("%q: unable to insert alt sign addr: %v", test.name, err) } } @@ -223,7 +226,7 @@ func TestSetAltSig(t *testing.T) { c.Set(dcrdKey, tNode) c.Set(dcrdErrorKey, dcrdErr) c.Set(requestBytesKey, b[test.deformReq:]) - setAltSig(c) + setAltSignAddr(c) } r.POST("/", handle) @@ -241,20 +244,20 @@ func TestSetAltSig(t *testing.T) { t.Errorf("%q: expected status %d, got %d", test.name, test.wantCode, w.Code) } - altsig, err := db.AltSigData(ticketHash) + altsig, err := db.AltSignAddrData(ticketHash) if err != nil { - t.Fatalf("%q: unable to get alt sig data: %v", test.name, err) + t.Fatalf("%q: unable to get alt sign addr data: %v", test.name, err) } - if test.wantCode != http.StatusOK && !test.isExistingAltSig { + if test.wantCode != http.StatusOK && !test.isExistingAltSignAddr { if altsig != nil { - t.Fatalf("%q: expected no alt sig saved for errored state", test.name) + t.Fatalf("%q: expected no alt sign addr saved for errored state", test.name) } continue } if !bytes.Equal(b, altsig.Req) || altsig.ReqSig != reqSig { - t.Fatalf("%q: expected alt sig data different than actual", test.name) + t.Fatalf("%q: expected alt sign addr data different than actual", test.name) } } } diff --git a/webapi/templates/ticket-search-result.html b/webapi/templates/ticket-search-result.html index 6e5ed84..ca6d4ba 100644 --- a/webapi/templates/ticket-search-result.html +++ b/webapi/templates/ticket-search-result.html @@ -43,8 +43,8 @@ Alternate Signing Address - - {{ .AltSig }} + + {{ .AltSignAddr }} diff --git a/webapi/types.go b/webapi/types.go index a320cd1..197f297 100644 --- a/webapi/types.go +++ b/webapi/types.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 The Decred developers +// Copyright (c) 2020-2021 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -72,15 +72,15 @@ type ticketStatusResponse struct { Request []byte `json:"request"` } -type setAltSigRequest struct { - Timestamp int64 `json:"timestamp" binding:"required"` - TicketHash string `json:"tickethash" binding:"required"` - TicketHex string `json:"tickethex" binding:"required"` - ParentHex string `json:"parenthex" binding:"required"` - AltSigAddress string `json:"altsigaddress" binding:"required"` +type setAltSignAddrRequest struct { + Timestamp int64 `json:"timestamp" binding:"required"` + TicketHash string `json:"tickethash" binding:"required"` + TicketHex string `json:"tickethex" binding:"required"` + ParentHex string `json:"parenthex" binding:"required"` + AltSignAddress string `json:"altsignaddress" binding:"required"` } -type setAltSigResponse struct { +type setAltSignAddrResponse struct { Timestamp int64 `json:"timestamp"` Request []byte `json:"request"` } diff --git a/webapi/webapi.go b/webapi/webapi.go index 6d25af0..c5083b9 100644 --- a/webapi/webapi.go +++ b/webapi/webapi.go @@ -228,7 +228,7 @@ func router(debugMode bool, cookieSecret []byte, dcrd rpc.DcrdConnect, wallets r api := router.Group("/api/v3") api.GET("/vspinfo", vspInfo) - api.POST("/setaltsig", withDcrdClient(dcrd), broadcastTicket(), vspAuth(), setAltSig) + api.POST("/setaltsignaddr", withDcrdClient(dcrd), broadcastTicket(), vspAuth(), setAltSignAddr) api.POST("/feeaddress", withDcrdClient(dcrd), broadcastTicket(), vspAuth(), feeAddress) api.POST("/ticketstatus", withDcrdClient(dcrd), vspAuth(), ticketStatus) api.POST("/payfee", withDcrdClient(dcrd), vspAuth(), payFee)