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.

126 lines
3.5 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. }
  30. // Tx returns a *Tx from the L1Tx
  31. func (tx *L1Tx) Tx() *Tx {
  32. f := new(big.Float).SetInt(tx.Amount)
  33. amountFloat, _ := f.Float64()
  34. genericTx := &Tx{
  35. IsL1: true,
  36. TxID: tx.TxID,
  37. Type: tx.Type,
  38. Position: tx.Position,
  39. FromIdx: tx.FromIdx,
  40. ToIdx: tx.ToIdx,
  41. Amount: tx.Amount,
  42. AmountFloat: amountFloat,
  43. TokenID: tx.TokenID,
  44. ToForgeL1TxsNum: tx.ToForgeL1TxsNum,
  45. UserOrigin: tx.UserOrigin,
  46. FromEthAddr: tx.FromEthAddr,
  47. FromBJJ: tx.FromBJJ,
  48. LoadAmount: tx.LoadAmount,
  49. EthBlockNum: tx.EthBlockNum,
  50. }
  51. if tx.LoadAmount != nil {
  52. lf := new(big.Float).SetInt(tx.LoadAmount)
  53. loadAmountFloat, _ := lf.Float64()
  54. genericTx.LoadAmountFloat = loadAmountFloat
  55. }
  56. return genericTx
  57. }
  58. // Bytes encodes a L1Tx into []byte
  59. func (tx *L1Tx) Bytes(nLevels int) ([]byte, error) {
  60. var b [L1TxBytesLen]byte
  61. copy(b[0:20], tx.FromEthAddr.Bytes())
  62. pkComp := tx.FromBJJ.Compress()
  63. copy(b[20:52], pkComp[:])
  64. fromIdxBytes, err := tx.FromIdx.Bytes()
  65. if err != nil {
  66. return nil, err
  67. }
  68. copy(b[52:58], fromIdxBytes[:])
  69. loadAmountFloat16, err := NewFloat16(tx.LoadAmount)
  70. if err != nil {
  71. return nil, err
  72. }
  73. copy(b[58:60], loadAmountFloat16.Bytes())
  74. amountFloat16, err := NewFloat16(tx.Amount)
  75. if err != nil {
  76. return nil, err
  77. }
  78. copy(b[60:62], amountFloat16.Bytes())
  79. copy(b[62:66], tx.TokenID.Bytes())
  80. toIdxBytes, err := tx.ToIdx.Bytes()
  81. if err != nil {
  82. return nil, err
  83. }
  84. copy(b[66:72], toIdxBytes[:])
  85. return b[:], nil
  86. }
  87. // L1TxFromBytes decodes a L1Tx from []byte
  88. func L1TxFromBytes(b []byte) (*L1Tx, error) {
  89. if len(b) != L1TxBytesLen {
  90. return nil, fmt.Errorf("Can not parse L1Tx bytes, expected length %d, current: %d", 68, len(b))
  91. }
  92. tx := &L1Tx{}
  93. var err error
  94. tx.FromEthAddr = ethCommon.BytesToAddress(b[0:20])
  95. pkCompB := b[20:52]
  96. var pkComp babyjub.PublicKeyComp
  97. copy(pkComp[:], pkCompB)
  98. tx.FromBJJ, err = pkComp.Decompress()
  99. if err != nil {
  100. return nil, err
  101. }
  102. tx.FromIdx, err = IdxFromBytes(b[52:58])
  103. if err != nil {
  104. return nil, err
  105. }
  106. tx.LoadAmount = Float16FromBytes(b[58:60]).BigInt()
  107. tx.Amount = Float16FromBytes(b[60:62]).BigInt()
  108. tx.TokenID, err = TokenIDFromBytes(b[62:66])
  109. if err != nil {
  110. return nil, err
  111. }
  112. tx.ToIdx, err = IdxFromBytes(b[66:72])
  113. if err != nil {
  114. return nil, err
  115. }
  116. return tx, nil
  117. }