arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
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 getHistoryTxs(c *gin.Context) {
182	// Get query parameters
183	tokenID, addr, bjj, idx, err := parseAccountFilters(c)
184	if err != nil {
185		retBadReq(err, c)
186		return
187	}
188	// BatchNum
189	batchNum, err := parseQueryUint("batchNum", nil, 0, maxUint32, c)
190	if err != nil {
191		retBadReq(err, c)
192		return
193	}
194	// TxType
195	txType, err := parseQueryTxType(c)
196	if err != nil {
197		retBadReq(err, c)
198		return
199	}
200	// Pagination
201	fromItem, order, limit, err := parsePagination(c)
202	if err != nil {
203		retBadReq(err, c)
204		return
205	}
206
207	// Fetch txs from historyDB
208	txs, pagination, err := h.GetHistoryTxs(
209		addr, bjj, tokenID, idx, batchNum, txType, fromItem, limit, order,
210	)
211	if err != nil {
212		retSQLErr(err, c)
213		return
214	}
215
216	// Build succesfull response
217	apiTxs := historyTxsToAPI(txs)
218	c.JSON(http.StatusOK, &historyTxsAPI{
219		Txs:        apiTxs,
220		Pagination: pagination,
221	})
222}
223
224func getHistoryTx(c *gin.Context) {
225	// Get TxID
226	txID, err := parseParamTxID(c)
227	if err != nil {
228		retBadReq(err, c)
229		return
230	}
231	// Fetch tx from historyDB
232	tx, err := h.GetHistoryTx(txID)
233	if err != nil {
234		retSQLErr(err, c)
235		return
236	}
237	apiTxs := historyTxsToAPI([]historydb.HistoryTx{*tx})
238	// Build succesfull response
239	c.JSON(http.StatusOK, apiTxs[0])
240}
241
242func getBatches(c *gin.Context) {
243
244}
245
246func getBatch(c *gin.Context) {
247
248}
249
250func getFullBatch(c *gin.Context) {
251
252}
253
254func getSlots(c *gin.Context) {
255
256}
257
258func getBids(c *gin.Context) {
259
260}
261
262func getNextForgers(c *gin.Context) {
263
264}
265
266func getState(c *gin.Context) {
267
268}
269
270func getConfig(c *gin.Context) {
271	c.JSON(http.StatusOK, cg)
272}
273
274func getTokens(c *gin.Context) {
275	// Account filters
276	tokenIDs, symbols, name, err := parseTokenFilters(c)
277	if err != nil {
278		retBadReq(err, c)
279		return
280	}
281	// Pagination
282	fromItem, order, limit, err := parsePagination(c)
283	if err != nil {
284		retBadReq(err, c)
285		return
286	}
287	// Fetch exits from historyDB
288	tokens, pagination, err := h.GetTokens(
289		tokenIDs, symbols, name, fromItem, limit, order,
290	)
291	if err != nil {
292		retSQLErr(err, c)
293		return
294	}
295
296	// Build succesfull response
297	apiTokens := tokensToAPI(tokens)
298	c.JSON(http.StatusOK, &tokensAPI{
299		Tokens:     apiTokens,
300		Pagination: pagination,
301	})
302}
303
304func getToken(c *gin.Context) {
305	// Get TokenID
306	tokenIDUint, err := parseParamUint("id", nil, 0, maxUint32, c)
307	if err != nil {
308		retBadReq(err, c)
309		return
310	}
311	tokenID := common.TokenID(*tokenIDUint)
312	// Fetch token from historyDB
313	token, err := h.GetToken(tokenID)
314	if err != nil {
315		retSQLErr(err, c)
316		return
317	}
318	apiToken := tokensToAPI([]historydb.TokenRead{*token})
319	c.JSON(http.StatusOK, apiToken[0])
320}
321
322func getRecommendedFee(c *gin.Context) {
323
324}
325
326func getCoordinators(c *gin.Context) {
327	// Pagination
328	fromItem, order, limit, err := parsePagination(c)
329	if err != nil {
330		retBadReq(err, c)
331		return
332	}
333
334	// Fetch coordinators from historyDB
335	coordinators, pagination, err := h.GetCoordinators(fromItem, limit, order)
336	if err != nil {
337		retSQLErr(err, c)
338		return
339	}
340
341	// Build succesfull response
342	apiCoordinators := coordinatorsToAPI(coordinators)
343	c.JSON(http.StatusOK, &coordinatorsAPI{
344		Coordinators: apiCoordinators,
345		Pagination:   pagination,
346	})
347}
348
349func getCoordinator(c *gin.Context) {
350	// Get bidderAddr
351	const name = "bidderAddr"
352	bidderAddr, err := parseEthAddr(c, name)
353
354	if err != nil {
355		retBadReq(err, c)
356		return
357	} else if bidderAddr == nil {
358		retBadReq(ErrNillBidderAddr, c)
359		return
360	}
361
362	coordinator, err := h.GetCoordinator(*bidderAddr)
363	if err != nil {
364		retSQLErr(err, c)
365		return
366	}
367
368	apiCoordinator := coordinatorsToAPI([]historydb.HistoryCoordinator{*coordinator})
369	c.JSON(http.StatusOK, apiCoordinator[0])
370}
371
372func retSQLErr(err error, c *gin.Context) {
373	if err == sql.ErrNoRows {
374		c.JSON(http.StatusNotFound, errorMsg{
375			Message: err.Error(),
376		})
377	} else {
378		c.JSON(http.StatusInternalServerError, errorMsg{
379			Message: err.Error(),
380		})
381	}
382}
383
384func retBadReq(err error, c *gin.Context) {
385	c.JSON(http.StatusBadRequest, errorMsg{
386		Message: err.Error(),
387	})
388}