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