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.

198 lines
6.4 KiB

  1. package api
  2. import (
  3. "encoding/base64"
  4. "encoding/hex"
  5. "errors"
  6. "math/big"
  7. "strconv"
  8. "strings"
  9. "time"
  10. ethCommon "github.com/ethereum/go-ethereum/common"
  11. "github.com/hermeznetwork/hermez-node/common"
  12. "github.com/hermeznetwork/hermez-node/db"
  13. "github.com/hermeznetwork/hermez-node/db/historydb"
  14. "github.com/hermeznetwork/hermez-node/eth"
  15. "github.com/iden3/go-iden3-crypto/babyjub"
  16. )
  17. const exitIdx = "hez:EXIT:1"
  18. type errorMsg struct {
  19. Message string
  20. }
  21. func bjjToString(bjj *babyjub.PublicKey) string {
  22. pkComp := [32]byte(bjj.Compress())
  23. sum := pkComp[0]
  24. for i := 1; i < len(pkComp); i++ {
  25. sum += pkComp[i]
  26. }
  27. bjjSum := append(pkComp[:], sum)
  28. return "hez:" + base64.RawURLEncoding.EncodeToString(bjjSum)
  29. }
  30. func ethAddrToHez(addr ethCommon.Address) string {
  31. return "hez:" + addr.String()
  32. }
  33. func idxToHez(idx common.Idx, tokenSymbol string) string {
  34. if idx == 1 {
  35. return exitIdx
  36. }
  37. return "hez:" + tokenSymbol + ":" + strconv.Itoa(int(idx))
  38. }
  39. // Exit
  40. type exitsAPI struct {
  41. Exits []exitAPI `json:"exits"`
  42. Pagination *db.Pagination `json:"pagination"`
  43. }
  44. func (e *exitsAPI) GetPagination() *db.Pagination {
  45. if e.Exits[0].ItemID < e.Exits[len(e.Exits)-1].ItemID {
  46. e.Pagination.FirstReturnedItem = e.Exits[0].ItemID
  47. e.Pagination.LastReturnedItem = e.Exits[len(e.Exits)-1].ItemID
  48. } else {
  49. e.Pagination.LastReturnedItem = e.Exits[0].ItemID
  50. e.Pagination.FirstReturnedItem = e.Exits[len(e.Exits)-1].ItemID
  51. }
  52. return e.Pagination
  53. }
  54. func (e *exitsAPI) Len() int { return len(e.Exits) }
  55. type merkleProofAPI struct {
  56. Root string
  57. Siblings []string
  58. OldKey string
  59. OldValue string
  60. IsOld0 bool
  61. Key string
  62. Value string
  63. Fnc int
  64. }
  65. type exitAPI struct {
  66. ItemID int `json:"itemId"`
  67. BatchNum common.BatchNum `json:"batchNum"`
  68. AccountIdx string `json:"accountIndex"`
  69. MerkleProof merkleProofAPI `json:"merkleProof"`
  70. Balance string `json:"balance"`
  71. InstantWithdrawn *int64 `json:"instantWithdrawn"`
  72. DelayedWithdrawRequest *int64 `json:"delayedWithdrawRequest"`
  73. DelayedWithdrawn *int64 `json:"delayedWithdrawn"`
  74. Token historydb.TokenWithUSD `json:"token"`
  75. }
  76. func historyExitsToAPI(dbExits []historydb.HistoryExit) []exitAPI {
  77. apiExits := []exitAPI{}
  78. for i := 0; i < len(dbExits); i++ {
  79. exit := exitAPI{
  80. ItemID: dbExits[i].ItemID,
  81. BatchNum: dbExits[i].BatchNum,
  82. AccountIdx: idxToHez(dbExits[i].AccountIdx, dbExits[i].TokenSymbol),
  83. MerkleProof: merkleProofAPI{
  84. Root: dbExits[i].MerkleProof.Root.String(),
  85. OldKey: dbExits[i].MerkleProof.OldKey.String(),
  86. OldValue: dbExits[i].MerkleProof.OldValue.String(),
  87. IsOld0: dbExits[i].MerkleProof.IsOld0,
  88. Key: dbExits[i].MerkleProof.Key.String(),
  89. Value: dbExits[i].MerkleProof.Value.String(),
  90. Fnc: dbExits[i].MerkleProof.Fnc,
  91. },
  92. Balance: dbExits[i].Balance.String(),
  93. InstantWithdrawn: dbExits[i].InstantWithdrawn,
  94. DelayedWithdrawRequest: dbExits[i].DelayedWithdrawRequest,
  95. DelayedWithdrawn: dbExits[i].DelayedWithdrawn,
  96. Token: historydb.TokenWithUSD{
  97. TokenID: dbExits[i].TokenID,
  98. EthBlockNum: dbExits[i].TokenEthBlockNum,
  99. EthAddr: dbExits[i].TokenEthAddr,
  100. Name: dbExits[i].TokenName,
  101. Symbol: dbExits[i].TokenSymbol,
  102. Decimals: dbExits[i].TokenDecimals,
  103. USD: dbExits[i].TokenUSD,
  104. USDUpdate: dbExits[i].TokenUSDUpdate,
  105. },
  106. }
  107. siblings := []string{}
  108. for j := 0; j < len(dbExits[i].MerkleProof.Siblings); j++ {
  109. siblings = append(siblings, dbExits[i].MerkleProof.Siblings[j].String())
  110. }
  111. exit.MerkleProof.Siblings = siblings
  112. apiExits = append(apiExits, exit)
  113. }
  114. return apiExits
  115. }
  116. // Config
  117. type rollupConstants struct {
  118. PublicConstants eth.RollupPublicConstants `json:"publicConstants"`
  119. MaxFeeIdxCoordinator int `json:"maxFeeIdxCoordinator"`
  120. ReservedIdx int `json:"reservedIdx"`
  121. ExitIdx int `json:"exitIdx"`
  122. LimitLoadAmount *big.Int `json:"limitLoadAmount"`
  123. LimitL2TransferAmount *big.Int `json:"limitL2TransferAmount"`
  124. LimitTokens int `json:"limitTokens"`
  125. L1CoordinatorTotalBytes int `json:"l1CoordinatorTotalBytes"`
  126. L1UserTotalBytes int `json:"l1UserTotalBytes"`
  127. MaxL1UserTx int `json:"maxL1UserTx"`
  128. MaxL1Tx int `json:"maxL1Tx"`
  129. InputSHAConstantBytes int `json:"inputSHAConstantBytes"`
  130. NumBuckets int `json:"numBuckets"`
  131. MaxWithdrawalDelay int `json:"maxWithdrawalDelay"`
  132. ExchangeMultiplier int `json:"exchangeMultiplier"`
  133. }
  134. type configAPI struct {
  135. RollupConstants rollupConstants `json:"hermez"`
  136. AuctionConstants eth.AuctionConstants `json:"auction"`
  137. WDelayerConstants eth.WDelayerConstants `json:"withdrawalDelayer"`
  138. }
  139. // AccountCreationAuth
  140. type accountCreationAuthAPI struct {
  141. EthAddr string `json:"hezEthereumAddress" binding:"required"`
  142. BJJ string `json:"bjj" binding:"required"`
  143. Signature string `json:"signature" binding:"required"`
  144. Timestamp time.Time `json:"timestamp"`
  145. }
  146. func accountCreationAuthToAPI(dbAuth *common.AccountCreationAuth) *accountCreationAuthAPI {
  147. return &accountCreationAuthAPI{
  148. EthAddr: ethAddrToHez(dbAuth.EthAddr),
  149. BJJ: bjjToString(dbAuth.BJJ),
  150. Signature: "0x" + hex.EncodeToString(dbAuth.Signature),
  151. Timestamp: dbAuth.Timestamp,
  152. }
  153. }
  154. func accountCreationAuthAPIToCommon(apiAuth *accountCreationAuthAPI) (*common.AccountCreationAuth, error) {
  155. ethAddr, err := hezStringToEthAddr(apiAuth.EthAddr, "hezEthereumAddress")
  156. if err != nil {
  157. return nil, err
  158. }
  159. bjj, err := hezStringToBJJ(apiAuth.BJJ, "bjj")
  160. if err != nil {
  161. return nil, err
  162. }
  163. without0x := strings.TrimPrefix(apiAuth.Signature, "0x")
  164. s, err := hex.DecodeString(without0x)
  165. if err != nil {
  166. return nil, err
  167. }
  168. auth := &common.AccountCreationAuth{
  169. EthAddr: *ethAddr,
  170. BJJ: bjj,
  171. Signature: s,
  172. Timestamp: apiAuth.Timestamp,
  173. }
  174. if !auth.VerifySignature() {
  175. return nil, errors.New("invalid signature")
  176. }
  177. return auth, nil
  178. }