From: wz Date: Tue, 11 Jun 2019 08:24:14 +0000 (+0800) Subject: add api for vote num (#149) X-Git-Tag: v1.0.5~208^2~44 X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=commitdiff_plain;h=2cba4a674b67c3a4f781d464b90b3cfcedccd993 add api for vote num (#149) * add api for vote num * fix review * fix review --- diff --git a/api/api.go b/api/api.go index 30e71522..074e0380 100644 --- a/api/api.go +++ b/api/api.go @@ -25,9 +25,9 @@ import ( "github.com/vapor/net/websocket" "github.com/vapor/netsync/peers" "github.com/vapor/p2p" + "github.com/vapor/proposal/blockproposer" "github.com/vapor/protocol" "github.com/vapor/wallet" - "github.com/vapor/proposal/blockproposer" ) var ( @@ -245,6 +245,7 @@ func (a *API) buildHandler() { m.Handle("/list-balances", jsonHandler(a.listBalances)) m.Handle("/list-unspent-outputs", jsonHandler(a.listUnspentOutputs)) + m.Handle("/list-account-votes", jsonHandler(a.listAccountVotes)) m.Handle("/decode-program", jsonHandler(a.decodeProgram)) diff --git a/api/query.go b/api/query.go index a3e927bf..938b3d33 100644 --- a/api/query.go +++ b/api/query.go @@ -108,6 +108,26 @@ func (a *API) listBalances(ctx context.Context, filter struct { return NewSuccessResponse(balances) } +func (a *API) listAccountVotes(ctx context.Context, filter struct { + AccountID string `json:"account_id"` + AccountAlias string `json:"account_alias"` +}) Response { + accountID := filter.AccountID + if filter.AccountAlias != "" { + acc, err := a.wallet.AccountMgr.FindByAlias(filter.AccountAlias) + if err != nil { + return NewErrorResponse(err) + } + accountID = acc.ID + } + + votes, err := a.wallet.GetAccountVotes(accountID, "") + if err != nil { + return NewErrorResponse(err) + } + return NewSuccessResponse(votes) +} + // POST /get-transaction func (a *API) getTransaction(ctx context.Context, txInfo struct { TxID string `json:"tx_id"` @@ -293,7 +313,7 @@ func (a *API) listUnspentOutputs(ctx context.Context, filter struct { } accountID = acc.ID } - accountUTXOs := a.wallet.GetAccountUtxos(accountID, filter.ID, filter.Unconfirmed, filter.SmartContract) + accountUTXOs := a.wallet.GetAccountUtxos(accountID, filter.ID, filter.Unconfirmed, filter.SmartContract, false) UTXOs := []query.AnnotatedUTXO{} for _, utxo := range accountUTXOs { diff --git a/wallet/indexer.go b/wallet/indexer.go index f3b7d577..47a8f47c 100644 --- a/wallet/indexer.go +++ b/wallet/indexer.go @@ -2,6 +2,7 @@ package wallet import ( "encoding/binary" + "encoding/hex" "encoding/json" "fmt" "sort" @@ -11,6 +12,7 @@ import ( "github.com/vapor/account" "github.com/vapor/asset" "github.com/vapor/blockchain/query" + "github.com/vapor/consensus" "github.com/vapor/crypto/sha3pool" dbm "github.com/vapor/database/leveldb" chainjson "github.com/vapor/encoding/json" @@ -309,7 +311,7 @@ func (w *Wallet) GetTransactions(accountID string) ([]*query.AnnotatedTx, error) // GetAccountBalances return all account balances func (w *Wallet) GetAccountBalances(accountID string, id string) ([]AccountBalance, error) { - return w.indexBalances(w.GetAccountUtxos(accountID, "", false, false)) + return w.indexBalances(w.GetAccountUtxos(accountID, "", false, false, false)) } // AccountBalance account balance @@ -373,3 +375,72 @@ func (w *Wallet) indexBalances(accountUTXOs []*account.UTXO) ([]AccountBalance, return balances, nil } + +// GetAccountVotes return all account votes +func (w *Wallet) GetAccountVotes(accountID string, id string) ([]AccountVotes, error) { + return w.indexVotes(w.GetAccountUtxos(accountID, "", false, false, true)) +} + +type voteDetail struct { + Vote string `json:"vote"` + VoteAmount uint64 `json:"vote_amount"` +} + +// AccountVotes account vote +type AccountVotes struct { + AccountID string `json:"account_id"` + Alias string `json:"account_alias"` + TotalVoteAmount uint64 `json:"total_vote_amount"` + VoteDetails []voteDetail `json:"vote_details"` +} + +func (w *Wallet) indexVotes(accountUTXOs []*account.UTXO) ([]AccountVotes, error) { + accVote := make(map[string]map[string]uint64) + votes := []AccountVotes{} + + for _, accountUTXO := range accountUTXOs { + if accountUTXO.AssetID != *consensus.BTMAssetID || accountUTXO.Vote == nil { + continue + } + xpub := hex.EncodeToString(accountUTXO.Vote) + if _, ok := accVote[accountUTXO.AccountID]; ok { + accVote[accountUTXO.AccountID][xpub] += accountUTXO.Amount + } else { + accVote[accountUTXO.AccountID] = map[string]uint64{xpub: accountUTXO.Amount} + + } + } + + var sortedAccount []string + for k := range accVote { + sortedAccount = append(sortedAccount, k) + } + sort.Strings(sortedAccount) + + for _, id := range sortedAccount { + var sortedXpub []string + for k := range accVote[id] { + sortedXpub = append(sortedXpub, k) + } + sort.Strings(sortedXpub) + + voteDetails := []voteDetail{} + voteTotal := uint64(0) + for _, xpub := range sortedXpub { + voteDetails = append(voteDetails, voteDetail{ + Vote: xpub, + VoteAmount: accVote[id][xpub], + }) + voteTotal += accVote[id][xpub] + } + alias := w.AccountMgr.GetAliasByID(id) + votes = append(votes, AccountVotes{ + Alias: alias, + AccountID: id, + VoteDetails: voteDetails, + TotalVoteAmount: voteTotal, + }) + } + + return votes, nil +} diff --git a/wallet/utxo.go b/wallet/utxo.go index 77c956ce..e1373f52 100644 --- a/wallet/utxo.go +++ b/wallet/utxo.go @@ -16,7 +16,7 @@ import ( ) // GetAccountUtxos return all account unspent outputs -func (w *Wallet) GetAccountUtxos(accountID string, id string, unconfirmed, isSmartContract bool) []*account.UTXO { +func (w *Wallet) GetAccountUtxos(accountID string, id string, unconfirmed, isSmartContract bool, vote bool) []*account.UTXO { prefix := account.UTXOPreFix if isSmartContract { prefix = account.SUTXOPrefix @@ -37,6 +37,10 @@ func (w *Wallet) GetAccountUtxos(accountID string, id string, unconfirmed, isSma continue } + if vote && accountUtxo.Vote == nil { + continue + } + if accountID == accountUtxo.AccountID || accountID == "" { accountUtxos = append(accountUtxos, accountUtxo) } diff --git a/wallet/utxo_test.go b/wallet/utxo_test.go index e5fb1b88..c5aad355 100644 --- a/wallet/utxo_test.go +++ b/wallet/utxo_test.go @@ -197,7 +197,7 @@ func TestGetAccountUtxos(t *testing.T) { w.AccountMgr = account.NewManager(testDB, nil) w.AccountMgr.AddUnconfirmedUtxo(c.unconfirmedUtxos) - gotUtxos := w.GetAccountUtxos("", c.id, c.unconfirmed, c.isSmartContract) + gotUtxos := w.GetAccountUtxos("", c.id, c.unconfirmed, c.isSmartContract, false) if !testutil.DeepEqual(gotUtxos, c.wantUtxos) { t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos) }