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.

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