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 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}