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.

333 lines
6.6 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 getHistoryTx(c *gin.Context) {
  162. // Get TxID
  163. txID, err := parseParamTxID(c)
  164. if err != nil {
  165. retBadReq(err, c)
  166. return
  167. }
  168. // Fetch tx from historyDB
  169. tx, err := h.GetHistoryTx(txID)
  170. if err != nil {
  171. retSQLErr(err, c)
  172. return
  173. }
  174. apiTxs := historyTxsToAPI([]historydb.HistoryTx{*tx})
  175. // Build succesfull response
  176. c.JSON(http.StatusOK, apiTxs[0])
  177. }
  178. func getSlots(c *gin.Context) {
  179. }
  180. func getBids(c *gin.Context) {
  181. }
  182. func getNextForgers(c *gin.Context) {
  183. }
  184. func getState(c *gin.Context) {
  185. }
  186. func getConfig(c *gin.Context) {
  187. c.JSON(http.StatusOK, cg)
  188. }
  189. func getTokens(c *gin.Context) {
  190. // Account filters
  191. tokenIDs, symbols, name, err := parseTokenFilters(c)
  192. if err != nil {
  193. retBadReq(err, c)
  194. return
  195. }
  196. // Pagination
  197. fromItem, order, limit, err := parsePagination(c)
  198. if err != nil {
  199. retBadReq(err, c)
  200. return
  201. }
  202. // Fetch exits from historyDB
  203. tokens, pagination, err := h.GetTokens(
  204. tokenIDs, symbols, name, fromItem, limit, order,
  205. )
  206. if err != nil {
  207. retSQLErr(err, c)
  208. return
  209. }
  210. // Build succesfull response
  211. apiTokens := tokensToAPI(tokens)
  212. c.JSON(http.StatusOK, &tokensAPI{
  213. Tokens: apiTokens,
  214. Pagination: pagination,
  215. })
  216. }
  217. func getToken(c *gin.Context) {
  218. // Get TokenID
  219. tokenIDUint, err := parseParamUint("id", nil, 0, maxUint32, c)
  220. if err != nil {
  221. retBadReq(err, c)
  222. return
  223. }
  224. tokenID := common.TokenID(*tokenIDUint)
  225. // Fetch token from historyDB
  226. token, err := h.GetToken(tokenID)
  227. if err != nil {
  228. retSQLErr(err, c)
  229. return
  230. }
  231. apiToken := tokensToAPI([]historydb.TokenRead{*token})
  232. c.JSON(http.StatusOK, apiToken[0])
  233. }
  234. func getRecommendedFee(c *gin.Context) {
  235. }
  236. func getCoordinators(c *gin.Context) {
  237. // Pagination
  238. fromItem, order, limit, err := parsePagination(c)
  239. if err != nil {
  240. retBadReq(err, c)
  241. return
  242. }
  243. // Fetch coordinators from historyDB
  244. coordinators, pagination, err := h.GetCoordinators(fromItem, limit, order)
  245. if err != nil {
  246. retSQLErr(err, c)
  247. return
  248. }
  249. // Build succesfull response
  250. apiCoordinators := coordinatorsToAPI(coordinators)
  251. c.JSON(http.StatusOK, &coordinatorsAPI{
  252. Coordinators: apiCoordinators,
  253. Pagination: pagination,
  254. })
  255. }
  256. func getCoordinator(c *gin.Context) {
  257. // Get bidderAddr
  258. const name = "bidderAddr"
  259. bidderAddr, err := parseParamEthAddr(name, c)
  260. if err != nil {
  261. retBadReq(err, c)
  262. return
  263. } else if bidderAddr == nil {
  264. retBadReq(ErrNillBidderAddr, c)
  265. return
  266. }
  267. coordinator, err := h.GetCoordinator(*bidderAddr)
  268. if err != nil {
  269. retSQLErr(err, c)
  270. return
  271. }
  272. apiCoordinator := coordinatorsToAPI([]historydb.HistoryCoordinator{*coordinator})
  273. c.JSON(http.StatusOK, apiCoordinator[0])
  274. }
  275. func retSQLErr(err error, c *gin.Context) {
  276. if err == sql.ErrNoRows {
  277. c.JSON(http.StatusNotFound, errorMsg{
  278. Message: err.Error(),
  279. })
  280. } else {
  281. c.JSON(http.StatusInternalServerError, errorMsg{
  282. Message: err.Error(),
  283. })
  284. }
  285. }
  286. func retBadReq(err error, c *gin.Context) {
  287. c.JSON(http.StatusBadRequest, errorMsg{
  288. Message: err.Error(),
  289. })
  290. }