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 // Parse body
34 var apiAuth accountCreationAuthAPI
35 if err := c.ShouldBindJSON(&apiAuth); err != nil {
36 retBadReq(err, c)
37 return
38 }
39 // API to common + verify signature
40 dbAuth, err := accountCreationAuthAPIToCommon(&apiAuth)
41 if err != nil {
42 retBadReq(err, c)
43 return
44 }
45 // Insert to DB
46 if err := l2.AddAccountCreationAuth(dbAuth); err != nil {
47 retSQLErr(err, c)
48 return
49 }
50 // Return OK
51 c.Status(http.StatusOK)
52}
53
54func getAccountCreationAuth(c *gin.Context) {
55 // Get hezEthereumAddress
56 addr, err := parseParamHezEthAddr(c)
57 if err != nil {
58 retBadReq(err, c)
59 return
60 }
61 // Fetch auth from l2DB
62 dbAuth, err := l2.GetAccountCreationAuth(*addr)
63 if err != nil {
64 retSQLErr(err, c)
65 return
66 }
67 apiAuth := accountCreationAuthToAPI(dbAuth)
68 // Build succesfull response
69 c.JSON(http.StatusOK, apiAuth)
70}
71
72func postPoolTx(c *gin.Context) {
73 // Parse body
74 var receivedTx receivedPoolTx
75 if err := c.ShouldBindJSON(&receivedTx); err != nil {
76 retBadReq(err, c)
77 return
78 }
79 // Transform from received to insert format and validate
80 writeTx, err := receivedTx.toDBWritePoolL2Tx()
81 if err != nil {
82 retBadReq(err, c)
83 return
84 }
85 // Insert to DB
86 if err := l2.AddTx(writeTx); err != nil {
87 retSQLErr(err, c)
88 return
89 }
90 // Return TxID
91 c.JSON(http.StatusOK, writeTx.TxID.String())
92}
93
94func getPoolTx(c *gin.Context) {
95 // Get TxID
96 txID, err := parseParamTxID(c)
97 if err != nil {
98 retBadReq(err, c)
99 return
100 }
101 // Fetch tx from l2DB
102 dbTx, err := l2.GetTx(txID)
103 if err != nil {
104 retSQLErr(err, c)
105 return
106 }
107 apiTx := poolL2TxReadToSend(dbTx)
108 // Build succesfull response
109 c.JSON(http.StatusOK, apiTx)
110}
111
112func getAccounts(c *gin.Context) {
113
114}
115
116func getAccount(c *gin.Context) {
117
118}
119
120func getExits(c *gin.Context) {
121 // Get query parameters
122 // Account filters
123 tokenID, addr, bjj, idx, err := parseAccountFilters(c)
124 if err != nil {
125 retBadReq(err, c)
126 return
127 }
128 // BatchNum
129 batchNum, err := parseQueryUint("batchNum", nil, 0, maxUint32, c)
130 if err != nil {
131 retBadReq(err, c)
132 return
133 }
134 // Pagination
135 fromItem, order, limit, err := parsePagination(c)
136 if err != nil {
137 retBadReq(err, c)
138 return
139 }
140
141 // Fetch exits from historyDB
142 exits, pagination, err := h.GetExits(
143 addr, bjj, tokenID, idx, batchNum, fromItem, limit, order,
144 )
145 if err != nil {
146 retSQLErr(err, c)
147 return
148 }
149
150 // Build succesfull response
151 apiExits := historyExitsToAPI(exits)
152 c.JSON(http.StatusOK, &exitsAPI{
153 Exits: apiExits,
154 Pagination: pagination,
155 })
156}
157
158func getExit(c *gin.Context) {
159 // Get batchNum and accountIndex
160 batchNum, err := parseParamUint("batchNum", nil, 0, maxUint32, c)
161 if err != nil {
162 retBadReq(err, c)
163 return
164 }
165 idx, err := parseParamIdx(c)
166 if err != nil {
167 retBadReq(err, c)
168 return
169 }
170 // Fetch tx from historyDB
171 exit, err := h.GetExit(batchNum, idx)
172 if err != nil {
173 retSQLErr(err, c)
174 return
175 }
176 apiExits := historyExitsToAPI([]historydb.HistoryExit{*exit})
177 // Build succesfull response
178 c.JSON(http.StatusOK, apiExits[0])
179}
180
181func getHistoryTx(c *gin.Context) {
182 // Get TxID
183 txID, err := parseParamTxID(c)
184 if err != nil {
185 retBadReq(err, c)
186 return
187 }
188 // Fetch tx from historyDB
189 tx, err := h.GetHistoryTx(txID)
190 if err != nil {
191 retSQLErr(err, c)
192 return
193 }
194 apiTxs := historyTxsToAPI([]historydb.HistoryTx{*tx})
195 // Build succesfull response
196 c.JSON(http.StatusOK, apiTxs[0])
197}
198
199func getSlots(c *gin.Context) {
200
201}
202
203func getBids(c *gin.Context) {
204
205}
206
207func getNextForgers(c *gin.Context) {
208
209}
210
211func getState(c *gin.Context) {
212
213}
214
215func getConfig(c *gin.Context) {
216 c.JSON(http.StatusOK, cg)
217}
218
219func getTokens(c *gin.Context) {
220 // Account filters
221 tokenIDs, symbols, name, err := parseTokenFilters(c)
222 if err != nil {
223 retBadReq(err, c)
224 return
225 }
226 // Pagination
227 fromItem, order, limit, err := parsePagination(c)
228 if err != nil {
229 retBadReq(err, c)
230 return
231 }
232 // Fetch exits from historyDB
233 tokens, pagination, err := h.GetTokens(
234 tokenIDs, symbols, name, fromItem, limit, order,
235 )
236 if err != nil {
237 retSQLErr(err, c)
238 return
239 }
240
241 // Build succesfull response
242 apiTokens := tokensToAPI(tokens)
243 c.JSON(http.StatusOK, &tokensAPI{
244 Tokens: apiTokens,
245 Pagination: pagination,
246 })
247}
248
249func getToken(c *gin.Context) {
250 // Get TokenID
251 tokenIDUint, err := parseParamUint("id", nil, 0, maxUint32, c)
252 if err != nil {
253 retBadReq(err, c)
254 return
255 }
256 tokenID := common.TokenID(*tokenIDUint)
257 // Fetch token from historyDB
258 token, err := h.GetToken(tokenID)
259 if err != nil {
260 retSQLErr(err, c)
261 return
262 }
263 apiToken := tokensToAPI([]historydb.TokenRead{*token})
264 c.JSON(http.StatusOK, apiToken[0])
265}
266
267func getRecommendedFee(c *gin.Context) {
268
269}
270
271func getCoordinators(c *gin.Context) {
272 // Pagination
273 fromItem, order, limit, err := parsePagination(c)
274 if err != nil {
275 retBadReq(err, c)
276 return
277 }
278
279 // Fetch coordinators from historyDB
280 coordinators, pagination, err := h.GetCoordinators(fromItem, limit, order)
281 if err != nil {
282 retSQLErr(err, c)
283 return
284 }
285
286 // Build succesfull response
287 apiCoordinators := coordinatorsToAPI(coordinators)
288 c.JSON(http.StatusOK, &coordinatorsAPI{
289 Coordinators: apiCoordinators,
290 Pagination: pagination,
291 })
292}
293
294func getCoordinator(c *gin.Context) {
295 // Get bidderAddr
296 const name = "bidderAddr"
297 bidderAddr, err := parseParamEthAddr(name, c)
298
299 if err != nil {
300 retBadReq(err, c)
301 return
302 } else if bidderAddr == nil {
303 retBadReq(ErrNillBidderAddr, c)
304 return
305 }
306
307 coordinator, err := h.GetCoordinator(*bidderAddr)
308 if err != nil {
309 retSQLErr(err, c)
310 return
311 }
312
313 apiCoordinator := coordinatorsToAPI([]historydb.HistoryCoordinator{*coordinator})
314 c.JSON(http.StatusOK, apiCoordinator[0])
315}
316
317func retSQLErr(err error, c *gin.Context) {
318 if err == sql.ErrNoRows {
319 c.JSON(http.StatusNotFound, errorMsg{
320 Message: err.Error(),
321 })
322 } else {
323 c.JSON(http.StatusInternalServerError, errorMsg{
324 Message: err.Error(),
325 })
326 }
327}
328
329func retBadReq(err error, c *gin.Context) {
330 c.JSON(http.StatusBadRequest, errorMsg{
331 Message: err.Error(),
332 })
333}