You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

388 lines
7.5 KiB

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