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.

131 lines
4.6 KiB

  1. package common
  2. import (
  3. "database/sql/driver"
  4. "encoding/hex"
  5. "errors"
  6. "fmt"
  7. "math/big"
  8. ethCommon "github.com/ethereum/go-ethereum/common"
  9. "github.com/iden3/go-iden3-crypto/babyjub"
  10. )
  11. const (
  12. // TXIDPrefixL1CoordTx is the prefix that determines that the TxID is
  13. // for a L1CoordinatorTx
  14. //nolinter:gomnd
  15. TxIDPrefixL1CoordTx = byte(1)
  16. // TxIDPrefixL2Tx is the prefix that determines that the TxID is for a
  17. // L2Tx (or PoolL2Tx)
  18. //nolinter:gomnd
  19. TxIDPrefixL2Tx = byte(2)
  20. // TxIDLen is the length of the TxID byte array
  21. TxIDLen = 12
  22. )
  23. // TxID is the identifier of a Hermez network transaction
  24. type TxID [TxIDLen]byte
  25. // Scan implements Scanner for database/sql.
  26. func (txid *TxID) Scan(src interface{}) error {
  27. srcB, ok := src.([]byte)
  28. if !ok {
  29. return fmt.Errorf("can't scan %T into TxID", src)
  30. }
  31. if len(srcB) != TxIDLen {
  32. return fmt.Errorf("can't scan []byte of len %d into TxID, need %d", len(srcB), TxIDLen)
  33. }
  34. copy(txid[:], srcB)
  35. return nil
  36. }
  37. // Value implements valuer for database/sql.
  38. func (txid TxID) Value() (driver.Value, error) {
  39. return txid[:], nil
  40. }
  41. // String returns a string hexadecimal representation of the TxID
  42. func (txid TxID) String() string {
  43. return "0x" + hex.EncodeToString(txid[:])
  44. }
  45. // TxType is a string that represents the type of a Hermez network transaction
  46. type TxType string
  47. const (
  48. // TxTypeExit represents L2->L1 token transfer. A leaf for this account appears in the exit tree of the block
  49. TxTypeExit TxType = "Exit"
  50. // TxTypeTransfer represents L2->L2 token transfer
  51. TxTypeTransfer TxType = "Transfer"
  52. // TxTypeDeposit represents L1->L2 transfer
  53. TxTypeDeposit TxType = "Deposit"
  54. // TxTypeCreateAccountDeposit represents creation of a new leaf in the state tree (newAcconut) + L1->L2 transfer
  55. TxTypeCreateAccountDeposit TxType = "CreateAccountDeposit"
  56. // TxTypeCreateAccountDepositTransfer represents L1->L2 transfer + L2->L2 transfer
  57. TxTypeCreateAccountDepositTransfer TxType = "CreateAccountDepositTransfer"
  58. // TxTypeDepositTransfer TBD
  59. TxTypeDepositTransfer TxType = "DepositTransfer"
  60. // TxTypeForceTransfer TBD
  61. TxTypeForceTransfer TxType = "ForceTransfer"
  62. // TxTypeForceExit TBD
  63. TxTypeForceExit TxType = "ForceExit"
  64. // TxTypeTransferToEthAddr TBD
  65. TxTypeTransferToEthAddr TxType = "TransferToEthAddr"
  66. // TxTypeTransferToBJJ TBD
  67. TxTypeTransferToBJJ TxType = "TransferToBJJ"
  68. )
  69. // Tx is a struct used by the TxSelector & BatchBuilder as a generic type generated from L1Tx & PoolL2Tx
  70. type Tx struct {
  71. // Generic
  72. IsL1 bool `meddler:"is_l1"`
  73. TxID TxID `meddler:"id"`
  74. Type TxType `meddler:"type"`
  75. Position int `meddler:"position"`
  76. FromIdx *Idx `meddler:"from_idx"`
  77. ToIdx *Idx `meddler:"to_idx"`
  78. Amount *big.Int `meddler:"amount,bigint"`
  79. AmountFloat float64 `meddler:"amount_f"`
  80. TokenID TokenID `meddler:"token_id"`
  81. USD *float64 `meddler:"amount_usd"`
  82. BatchNum *BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged. If the tx is L2, this must be != 0
  83. EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue
  84. // L1
  85. ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
  86. UserOrigin *bool `meddler:"user_origin"` // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes
  87. FromEthAddr *ethCommon.Address `meddler:"from_eth_addr"`
  88. FromBJJ *babyjub.PublicKey `meddler:"from_bjj"`
  89. LoadAmount *big.Int `meddler:"load_amount,bigintnull"`
  90. LoadAmountFloat *float64 `meddler:"load_amount_f"`
  91. LoadAmountUSD *float64 `meddler:"load_amount_usd"`
  92. // L2
  93. Fee *FeeSelector `meddler:"fee"`
  94. FeeUSD *float64 `meddler:"fee_usd"`
  95. Nonce *Nonce `meddler:"nonce"`
  96. }
  97. // L1Tx returns a *L1Tx from the Tx
  98. func (tx *Tx) L1Tx() (*L1Tx, error) {
  99. if tx.UserOrigin == nil || tx.FromEthAddr == nil {
  100. return nil, errors.New("Tx must have UserOrigin != nil and FromEthAddr != nil in order to be able to transform to L1Tx")
  101. }
  102. return &L1Tx{
  103. TxID: tx.TxID,
  104. ToForgeL1TxsNum: tx.ToForgeL1TxsNum,
  105. Position: tx.Position,
  106. UserOrigin: *tx.UserOrigin,
  107. FromIdx: tx.FromIdx,
  108. FromEthAddr: *tx.FromEthAddr,
  109. FromBJJ: tx.FromBJJ,
  110. ToIdx: *tx.ToIdx,
  111. TokenID: tx.TokenID,
  112. Amount: tx.Amount,
  113. LoadAmount: tx.LoadAmount,
  114. EthBlockNum: tx.EthBlockNum,
  115. Type: tx.Type,
  116. BatchNum: tx.BatchNum,
  117. }, nil
  118. }