OSDN Git Service

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