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.

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