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.

130 lines
3.6 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package common
  2. import (
  3. "fmt"
  4. "math/big"
  5. ethCommon "github.com/ethereum/go-ethereum/common"
  6. "github.com/iden3/go-iden3-crypto/babyjub"
  7. )
  8. const (
  9. // L1TxBytesLen is the length of the byte array that represents the L1Tx
  10. L1TxBytesLen = 72
  11. )
  12. // L1Tx is a struct that represents a L1 tx
  13. type L1Tx struct {
  14. // Stored in DB: mandatory fileds
  15. TxID TxID
  16. ToForgeL1TxsNum int64 // toForgeL1TxsNum in which the tx was forged / will be forged
  17. Position int
  18. UserOrigin bool // 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
  19. FromIdx Idx // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
  20. FromEthAddr ethCommon.Address
  21. FromBJJ *babyjub.PublicKey
  22. ToIdx Idx // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
  23. TokenID TokenID
  24. Amount *big.Int
  25. LoadAmount *big.Int
  26. EthBlockNum int64 // Ethereum Block Number in which this L1Tx was added to the queue
  27. Type TxType
  28. BatchNum *BatchNum
  29. USD *float64
  30. LoadAmountUSD *float64
  31. }
  32. // Tx returns a *Tx from the L1Tx
  33. func (tx *L1Tx) Tx() *Tx {
  34. f := new(big.Float).SetInt(tx.Amount)
  35. amountFloat, _ := f.Float64()
  36. genericTx := &Tx{
  37. IsL1: true,
  38. TxID: tx.TxID,
  39. Type: tx.Type,
  40. Position: tx.Position,
  41. FromIdx: tx.FromIdx,
  42. ToIdx: tx.ToIdx,
  43. Amount: tx.Amount,
  44. AmountFloat: amountFloat,
  45. TokenID: tx.TokenID,
  46. ToForgeL1TxsNum: tx.ToForgeL1TxsNum,
  47. UserOrigin: tx.UserOrigin,
  48. FromEthAddr: tx.FromEthAddr,
  49. FromBJJ: tx.FromBJJ,
  50. LoadAmount: tx.LoadAmount,
  51. EthBlockNum: tx.EthBlockNum,
  52. USD: tx.USD,
  53. LoadAmountUSD: tx.LoadAmountUSD,
  54. }
  55. if tx.LoadAmount != nil {
  56. lf := new(big.Float).SetInt(tx.LoadAmount)
  57. loadAmountFloat, _ := lf.Float64()
  58. genericTx.LoadAmountFloat = &loadAmountFloat
  59. }
  60. return genericTx
  61. }
  62. // Bytes encodes a L1Tx into []byte
  63. func (tx *L1Tx) Bytes(nLevels int) ([]byte, error) {
  64. var b [L1TxBytesLen]byte
  65. copy(b[0:20], tx.FromEthAddr.Bytes())
  66. pkComp := tx.FromBJJ.Compress()
  67. copy(b[20:52], pkComp[:])
  68. fromIdxBytes, err := tx.FromIdx.Bytes()
  69. if err != nil {
  70. return nil, err
  71. }
  72. copy(b[52:58], fromIdxBytes[:])
  73. loadAmountFloat16, err := NewFloat16(tx.LoadAmount)
  74. if err != nil {
  75. return nil, err
  76. }
  77. copy(b[58:60], loadAmountFloat16.Bytes())
  78. amountFloat16, err := NewFloat16(tx.Amount)
  79. if err != nil {
  80. return nil, err
  81. }
  82. copy(b[60:62], amountFloat16.Bytes())
  83. copy(b[62:66], tx.TokenID.Bytes())
  84. toIdxBytes, err := tx.ToIdx.Bytes()
  85. if err != nil {
  86. return nil, err
  87. }
  88. copy(b[66:72], toIdxBytes[:])
  89. return b[:], nil
  90. }
  91. // L1TxFromBytes decodes a L1Tx from []byte
  92. func L1TxFromBytes(b []byte) (*L1Tx, error) {
  93. if len(b) != L1TxBytesLen {
  94. return nil, fmt.Errorf("Can not parse L1Tx bytes, expected length %d, current: %d", 68, len(b))
  95. }
  96. tx := &L1Tx{}
  97. var err error
  98. tx.FromEthAddr = ethCommon.BytesToAddress(b[0:20])
  99. pkCompB := b[20:52]
  100. var pkComp babyjub.PublicKeyComp
  101. copy(pkComp[:], pkCompB)
  102. tx.FromBJJ, err = pkComp.Decompress()
  103. if err != nil {
  104. return nil, err
  105. }
  106. tx.FromIdx, err = IdxFromBytes(b[52:58])
  107. if err != nil {
  108. return nil, err
  109. }
  110. tx.LoadAmount = Float16FromBytes(b[58:60]).BigInt()
  111. tx.Amount = Float16FromBytes(b[60:62]).BigInt()
  112. tx.TokenID, err = TokenIDFromBytes(b[62:66])
  113. if err != nil {
  114. return nil, err
  115. }
  116. tx.ToIdx, err = IdxFromBytes(b[66:72])
  117. if err != nil {
  118. return nil, err
  119. }
  120. return tx, nil
  121. }