OSDN Git Service

Merge branch 'dev' into dev-gas
[bytom/bytom.git] / api / query.go
1 package api
2
3 import (
4         "context"
5         "fmt"
6
7         log "github.com/sirupsen/logrus"
8
9         "github.com/bytom/account"
10         "github.com/bytom/blockchain/query"
11         "github.com/bytom/consensus"
12         chainjson "github.com/bytom/encoding/json"
13         "github.com/bytom/protocol/bc"
14 )
15
16 // POST /list-accounts
17 func (a *API) listAccounts(ctx context.Context, filter struct {
18         ID string `json:"id"`
19 }) Response {
20         accounts, err := a.wallet.AccountMgr.ListAccounts(filter.ID)
21         if err != nil {
22                 log.Errorf("listAccounts: %v", err)
23                 return NewErrorResponse(err)
24         }
25
26         var annotatedAccounts []query.AnnotatedAccount
27         for _, acc := range accounts {
28                 annotatedAccounts = append(annotatedAccounts, *account.Annotated(acc))
29         }
30
31         return NewSuccessResponse(annotatedAccounts)
32 }
33
34 // POST /list-assets
35 func (a *API) listAssets(ctx context.Context, filter struct {
36         ID string `json:"id"`
37 }) Response {
38         assets, err := a.wallet.AssetReg.ListAssets(filter.ID)
39         if err != nil {
40                 log.Errorf("listAssets: %v", err)
41                 return NewErrorResponse(err)
42         }
43
44         return NewSuccessResponse(assets)
45 }
46
47 // POST /listBalances
48 func (a *API) listBalances(ctx context.Context) Response {
49         return NewSuccessResponse(a.wallet.GetAccountBalances(""))
50 }
51
52 // POST /get-transaction
53 func (a *API) getTransaction(ctx context.Context, txInfo struct {
54         TxID string `json:"tx_id"`
55 }) Response {
56         transaction, err := a.wallet.GetTransactionByTxID(txInfo.TxID)
57         if err != nil {
58                 log.Errorf("getTransaction error: %v", err)
59                 return NewErrorResponse(err)
60         }
61
62         return NewSuccessResponse(transaction)
63 }
64
65 // POST /list-transactions
66 func (a *API) listTransactions(ctx context.Context, filter struct {
67         ID        string `json:"id"`
68         AccountID string `json:"account_id"`
69         Detail    bool   `json:"detail"`
70 }) Response {
71         var transactions []*query.AnnotatedTx
72         var err error
73
74         if filter.AccountID != "" {
75                 transactions, err = a.wallet.GetTransactionsByAccountID(filter.AccountID)
76         } else {
77                 transactions, err = a.wallet.GetTransactionsByTxID(filter.ID)
78         }
79
80         if err != nil {
81                 log.Errorf("listTransactions: %v", err)
82                 return NewErrorResponse(err)
83         }
84
85         if filter.Detail == false {
86                 txSummary := a.wallet.GetTransactionsSummary(transactions)
87                 return NewSuccessResponse(txSummary)
88         }
89         return NewSuccessResponse(transactions)
90 }
91
92 // POST /get-unconfirmed-transaction
93 func (a *API) getUnconfirmedTx(ctx context.Context, filter struct {
94         TxID chainjson.HexBytes `json:"tx_id"`
95 }) Response {
96         var tmpTxID [32]byte
97         copy(tmpTxID[:], filter.TxID[:])
98
99         txHash := bc.NewHash(tmpTxID)
100         txPool := a.chain.GetTxPool()
101         txDesc, err := txPool.GetTransaction(&txHash)
102         if err != nil {
103                 return NewErrorResponse(err)
104         }
105
106         tx := &BlockTx{
107                 ID:         txDesc.Tx.ID,
108                 Version:    txDesc.Tx.Version,
109                 Size:       txDesc.Tx.SerializedSize,
110                 TimeRange:  txDesc.Tx.TimeRange,
111                 Inputs:     []*query.AnnotatedInput{},
112                 Outputs:    []*query.AnnotatedOutput{},
113                 StatusFail: false,
114         }
115
116         for i := range txDesc.Tx.Inputs {
117                 tx.Inputs = append(tx.Inputs, a.wallet.BuildAnnotatedInput(txDesc.Tx, uint32(i)))
118         }
119         for i := range txDesc.Tx.Outputs {
120                 tx.Outputs = append(tx.Outputs, a.wallet.BuildAnnotatedOutput(txDesc.Tx, i))
121         }
122
123         return NewSuccessResponse(tx)
124 }
125
126 // POST /list-unconfirmed-transactions
127 func (a *API) listUnconfirmedTxs(ctx context.Context) Response {
128         txIDs := []bc.Hash{}
129
130         txPool := a.chain.GetTxPool()
131         txs := txPool.GetTransactions()
132         for _, txDesc := range txs {
133                 txIDs = append(txIDs, bc.Hash(txDesc.Tx.ID))
134         }
135
136         return NewSuccessResponse(txIDs)
137 }
138
139 // POST /list-unspent-outputs
140 func (a *API) listUnspentOutputs(ctx context.Context, filter struct {
141         ID string `json:"id"`
142 }) Response {
143         accountUTXOs := a.wallet.GetAccountUTXOs(filter.ID)
144
145         var UTXOs []query.AnnotatedUTXO
146         for _, utxo := range accountUTXOs {
147                 UTXOs = append([]query.AnnotatedUTXO{{
148                         AccountID:           utxo.AccountID,
149                         OutputID:            utxo.OutputID.String(),
150                         SourceID:            utxo.SourceID.String(),
151                         AssetID:             utxo.AssetID.String(),
152                         Amount:              utxo.Amount,
153                         SourcePos:           utxo.SourcePos,
154                         Program:             fmt.Sprintf("%x", utxo.ControlProgram),
155                         ControlProgramIndex: utxo.ControlProgramIndex,
156                         Address:             utxo.Address,
157                         ValidHeight:         utxo.ValidHeight,
158                         Alias:               a.wallet.AccountMgr.GetAliasByID(utxo.AccountID),
159                         AssetAlias:          a.wallet.AssetReg.GetAliasByID(utxo.AssetID.String()),
160                         Change:              utxo.Change,
161                 }}, UTXOs...)
162         }
163
164         return NewSuccessResponse(UTXOs)
165 }
166
167 // return gasRate
168 func (a *API) gasRate() Response {
169         gasrate := map[string]int64{"gasRate": consensus.VMGasRate}
170         return NewSuccessResponse(gasrate)
171 }