hermez-node/api/handlers.go
api/handlers.goRaw
1package api
2
3import (
4 "database/sql"
5 "errors"
6 "net/http"
7
8 "github.com/gin-gonic/gin"
9 "github.com/hermeznetwork/hermez-node/common"
10 "github.com/hermeznetwork/hermez-node/db/historydb"
11)
12
13const (
14 // maxLimit is the max permited items to be returned in paginated responses
15 maxLimit uint = 2049
16
17 // dfltOrder indicates how paginated endpoints are ordered if not specified
18 dfltOrder = historydb.OrderAsc
19
20 // dfltLimit indicates the limit of returned items in paginated responses if the query param limit is not provided
21 dfltLimit uint = 20
22
23 // 2^32 -1
24 maxUint32 = 4294967295
25)
26
27var (
28 // ErrNillBidderAddr is used when a nil bidderAddr is received in the getCoordinator method
29 ErrNillBidderAddr = errors.New("biderAddr can not be nil")
30)
31
32func postAccountCreationAuth(c *gin.Context) {
33
34}
35
36func getAccountCreationAuth(c *gin.Context) {
37}
38
39func postPoolTx(c *gin.Context) {
40 // Parse body
41 var receivedTx receivedPoolTx
42 if err := c.ShouldBindJSON(&receivedTx); err != nil {
43 retBadReq(err, c)
44 return
45 }
46 // Transform from received to insert format and validate
47 writeTx, err := receivedTx.toDBWritePoolL2Tx()
48 if err != nil {
49 retBadReq(err, c)
50 return
51 }
52 // Insert to DB
53 if err := l2.AddTx(writeTx); err != nil {
54 retSQLErr(err, c)
55 return
56 }
57 // Return TxID
58 c.JSON(http.StatusOK, writeTx.TxID.String())
59}
60
61func getPoolTx(c *gin.Context) {
62 // Get TxID
63 txID, err := parseParamTxID(c)
64 if err != nil {
65 retBadReq(err, c)
66 return
67 }
68 // Fetch tx from l2DB
69 dbTx, err := l2.GetTx(txID)
70 if err != nil {
71 retSQLErr(err, c)
72 return
73 }
74 apiTx := poolL2TxReadToSend(dbTx)
75 // Build succesfull response
76 c.JSON(http.StatusOK, apiTx)
77}
78
79func getAccounts(c *gin.Context) {
80
81}
82
83func getAccount(c *gin.Context) {
84
85}
86
87func getExits(c *gin.Context) {
88 // Get query parameters
89 // Account filters
90 tokenID, addr, bjj, idx, err := parseAccountFilters(c)
91 if err != nil {
92 retBadReq(err, c)
93 return
94 }
95 // BatchNum
96 batchNum, err := parseQueryUint("batchNum", nil, 0, maxUint32, c)
97 if err != nil {
98 retBadReq(err, c)
99 return
100 }
101 // Pagination
102 fromItem, order, limit, err := parsePagination(c)
103 if err != nil {
104 retBadReq(err, c)
105 return
106 }
107
108 // Fetch exits from historyDB
109 exits, pagination, err := h.GetExits(
110 addr, bjj, tokenID, idx, batchNum, fromItem, limit, order,
111 )
112 if err != nil {
113 retSQLErr(err, c)
114 return
115 }
116
117 // Build succesfull response
118 apiExits := historyExitsToAPI(exits)
119 c.JSON(http.StatusOK, &exitsAPI{
120 Exits: apiExits,
121 Pagination: pagination,
122 })
123}
124
125func getExit(c *gin.Context) {
126 // Get batchNum and accountIndex
127 batchNum, err := parseParamUint("batchNum", nil, 0, maxUint32, c)
128 if err != nil {
129 retBadReq(err, c)
130 return
131 }
132 idx, err := parseParamIdx(c)
133 if err != nil {
134 retBadReq(err, c)
135 return
136 }
137 // Fetch tx from historyDB
138 exit, err := h.GetExit(batchNum, idx)
139 if err != nil {
140 retSQLErr(err, c)
141 return
142 }
143 apiExits := historyExitsToAPI([]historydb.HistoryExit{*exit})
144 // Build succesfull response
145 c.JSON(http.StatusOK, apiExits[0])
146}
147
148func getHistoryTxs(c *gin.Context) {
149 // Get query parameters
150 tokenID, addr, bjj, idx, err := parseAccountFilters(c)
151 if err != nil {
152 retBadReq(err, c)
153 return
154 }
155 // BatchNum
156 batchNum, err := parseQueryUint("batchNum", nil, 0, maxUint32, c)
157 if err != nil {
158 retBadReq(err, c)
159 return
160 }
161 // TxType
162 txType, err := parseQueryTxType(c)
163 if err != nil {
164 retBadReq(err, c)
165 return
166 }
167 // Pagination
168 fromItem, order, limit, err := parsePagination(c)
169 if err != nil {
170 retBadReq(err, c)
171 return
172 }
173
174 // Fetch txs from historyDB
175 txs, pagination, err := h.GetHistoryTxs(
176 addr, bjj, tokenID, idx, batchNum, txType, fromItem, limit, order,
177 )
178 if err != nil {
179 retSQLErr(err, c)
180 return
181 }
182
183 // Build succesfull response
184 apiTxs := historyTxsToAPI(txs)
185 c.JSON(http.StatusOK, &historyTxsAPI{
186 Txs: apiTxs,
187 Pagination: pagination,
188 })
189}
190
191func getHistoryTx(c *gin.Context) {
192 // Get TxID
193 txID, err := parseParamTxID(c)
194 if err != nil {
195 retBadReq(err, c)
196 return
197 }
198 // Fetch tx from historyDB
199 tx, err := h.GetHistoryTx(txID)
200 if err != nil {
201 retSQLErr(err, c)
202 return
203 }
204 apiTxs := historyTxsToAPI([]historydb.HistoryTx{*tx})
205 // Build succesfull response
206 c.JSON(http.StatusOK, apiTxs[0])
207}
208
209func getBatches(c *gin.Context) {
210
211}
212
213func getBatch(c *gin.Context) {
214
215}
216
217func getFullBatch(c *gin.Context) {
218
219}
220
221func getSlots(c *gin.Context) {
222
223}
224
225func getBids(c *gin.Context) {
226
227}
228
229func getNextForgers(c *gin.Context) {
230
231}
232
233func getState(c *gin.Context) {
234
235}
236
237func getConfig(c *gin.Context) {
238 c.JSON(http.StatusOK, cg)
239}
240
241func getTokens(c *gin.Context) {
242 // Account filters
243 tokenIDs, symbols, name, err := parseTokenFilters(c)
244 if err != nil {
245 retBadReq(err, c)
246 return
247 }
248 // Pagination
249 fromItem, order, limit, err := parsePagination(c)
250 if err != nil {
251 retBadReq(err, c)
252 return
253 }
254 // Fetch exits from historyDB
255 tokens, pagination, err := h.GetTokens(
256 tokenIDs, symbols, name, fromItem, limit, order,
257 )
258 if err != nil {
259 retSQLErr(err, c)
260 return
261 }
262
263 // Build succesfull response
264 apiTokens := tokensToAPI(tokens)
265 c.JSON(http.StatusOK, &tokensAPI{
266 Tokens: apiTokens,
267 Pagination: pagination,
268 })
269}
270
271func getToken(c *gin.Context) {
272 // Get TokenID
273 tokenIDUint, err := parseParamUint("id", nil, 0, maxUint32, c)
274 if err != nil {
275 retBadReq(err, c)
276 return
277 }
278 tokenID := common.TokenID(*tokenIDUint)
279 // Fetch token from historyDB
280 token, err := h.GetToken(tokenID)
281 if err != nil {
282 retSQLErr(err, c)
283 return
284 }
285 apiToken := tokensToAPI([]historydb.TokenRead{*token})
286 c.JSON(http.StatusOK, apiToken[0])
287}
288
289func getRecommendedFee(c *gin.Context) {
290
291}
292
293func getCoordinators(c *gin.Context) {
294 // Pagination
295 fromItem, order, limit, err := parsePagination(c)
296 if err != nil {
297 retBadReq(err, c)
298 return
299 }
300
301 // Fetch coordinators from historyDB
302 coordinators, pagination, err := h.GetCoordinators(fromItem, limit, order)
303 if err != nil {
304 retSQLErr(err, c)
305 return
306 }
307
308 // Build succesfull response
309 apiCoordinators := coordinatorsToAPI(coordinators)
310 c.JSON(http.StatusOK, &coordinatorsAPI{
311 Coordinators: apiCoordinators,
312 Pagination: pagination,
313 })
314}
315
316func getCoordinator(c *gin.Context) {
317 // Get bidderAddr
318 const name = "bidderAddr"
319 bidderAddr, err := parseEthAddr(c, name)
320
321 if err != nil {
322 retBadReq(err, c)
323 return
324 } else if bidderAddr == nil {
325 retBadReq(ErrNillBidderAddr, c)
326 return
327 }
328
329 coordinator, err := h.GetCoordinator(*bidderAddr)
330 if err != nil {
331 retSQLErr(err, c)
332 return
333 }
334
335 apiCoordinator := coordinatorsToAPI([]historydb.HistoryCoordinator{*coordinator})
336 c.JSON(http.StatusOK, apiCoordinator[0])
337}
338
339func retSQLErr(err error, c *gin.Context) {
340 if err == sql.ErrNoRows {
341 c.JSON(http.StatusNotFound, errorMsg{
342 Message: err.Error(),
343 })
344 } else {
345 c.JSON(http.StatusInternalServerError, errorMsg{
346 Message: err.Error(),
347 })
348 }
349}
350
351func retBadReq(err error, c *gin.Context) {
352 c.JSON(http.StatusBadRequest, errorMsg{
353 Message: err.Error(),
354 })
355}