|
@ -1,6 +1,7 @@ |
|
|
package common |
|
|
package common |
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
|
|
|
"crypto/sha256" |
|
|
"fmt" |
|
|
"fmt" |
|
|
"math/big" |
|
|
"math/big" |
|
|
|
|
|
|
|
@ -10,16 +11,19 @@ import ( |
|
|
// L2Tx is a struct that represents an already forged L2 tx
|
|
|
// L2Tx is a struct that represents an already forged L2 tx
|
|
|
type L2Tx struct { |
|
|
type L2Tx struct { |
|
|
// Stored in DB: mandatory fileds
|
|
|
// Stored in DB: mandatory fileds
|
|
|
TxID TxID `meddler:"id"` |
|
|
|
|
|
BatchNum BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged.
|
|
|
|
|
|
Position int `meddler:"position"` |
|
|
|
|
|
FromIdx Idx `meddler:"from_idx"` |
|
|
|
|
|
ToIdx Idx `meddler:"to_idx"` |
|
|
|
|
|
Amount *big.Int `meddler:"amount,bigint"` |
|
|
|
|
|
Fee FeeSelector `meddler:"fee"` |
|
|
|
|
|
Nonce Nonce `meddler:"nonce"` |
|
|
|
|
|
Type TxType `meddler:"type"` |
|
|
|
|
|
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L2Tx was added to the queue
|
|
|
|
|
|
|
|
|
TxID TxID `meddler:"id"` |
|
|
|
|
|
BatchNum BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged.
|
|
|
|
|
|
Position int `meddler:"position"` |
|
|
|
|
|
FromIdx Idx `meddler:"from_idx"` |
|
|
|
|
|
ToIdx Idx `meddler:"to_idx"` |
|
|
|
|
|
// TokenID is filled by the TxProcessor
|
|
|
|
|
|
TokenID TokenID `meddler:"token_id"` |
|
|
|
|
|
Amount *big.Int `meddler:"amount,bigint"` |
|
|
|
|
|
Fee FeeSelector `meddler:"fee"` |
|
|
|
|
|
// Nonce is filled by the TxProcessor
|
|
|
|
|
|
Nonce Nonce `meddler:"nonce"` |
|
|
|
|
|
Type TxType `meddler:"type"` |
|
|
|
|
|
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L2Tx was added to the queue
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// NewL2Tx returns the given L2Tx with the TxId & Type parameters calculated
|
|
|
// NewL2Tx returns the given L2Tx with the TxId & Type parameters calculated
|
|
@ -63,18 +67,53 @@ func (tx *L2Tx) SetType() error { |
|
|
|
|
|
|
|
|
// SetID sets the ID of the transaction
|
|
|
// SetID sets the ID of the transaction
|
|
|
func (tx *L2Tx) SetID() error { |
|
|
func (tx *L2Tx) SetID() error { |
|
|
tx.TxID[0] = TxIDPrefixL2Tx |
|
|
|
|
|
|
|
|
txID, err := tx.CalculateTxID() |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return err |
|
|
|
|
|
} |
|
|
|
|
|
tx.TxID = txID |
|
|
|
|
|
return nil |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// CalculateTxID returns the TxID of the transaction. This method is used to
|
|
|
|
|
|
// set the TxID for L2Tx and for PoolL2Tx.
|
|
|
|
|
|
func (tx L2Tx) CalculateTxID() ([TxIDLen]byte, error) { |
|
|
|
|
|
var txID TxID |
|
|
|
|
|
var b []byte |
|
|
|
|
|
// FromIdx
|
|
|
fromIdxBytes, err := tx.FromIdx.Bytes() |
|
|
fromIdxBytes, err := tx.FromIdx.Bytes() |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
return tracerr.Wrap(err) |
|
|
|
|
|
|
|
|
return txID, tracerr.Wrap(err) |
|
|
} |
|
|
} |
|
|
copy(tx.TxID[1:7], fromIdxBytes[:]) |
|
|
|
|
|
|
|
|
b = append(b, fromIdxBytes[:]...) |
|
|
|
|
|
// TokenID
|
|
|
|
|
|
b = append(b, tx.TokenID.Bytes()[:]...) |
|
|
|
|
|
// Amount
|
|
|
|
|
|
amountFloat16, err := NewFloat16(tx.Amount) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return txID, tracerr.Wrap(fmt.Errorf("%s: %d", err, tx.Amount)) |
|
|
|
|
|
} |
|
|
|
|
|
b = append(b, amountFloat16.Bytes()...) |
|
|
|
|
|
// Nonce
|
|
|
nonceBytes, err := tx.Nonce.Bytes() |
|
|
nonceBytes, err := tx.Nonce.Bytes() |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
return tracerr.Wrap(err) |
|
|
|
|
|
|
|
|
return txID, tracerr.Wrap(err) |
|
|
} |
|
|
} |
|
|
copy(tx.TxID[7:12], nonceBytes[:]) |
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
|
b = append(b, nonceBytes[:]...) |
|
|
|
|
|
// Fee
|
|
|
|
|
|
b = append(b, byte(tx.Fee)) |
|
|
|
|
|
|
|
|
|
|
|
// calculate hash
|
|
|
|
|
|
h := sha256.New() |
|
|
|
|
|
_, err = h.Write(b) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return txID, tracerr.Wrap(err) |
|
|
|
|
|
} |
|
|
|
|
|
r := h.Sum(nil) |
|
|
|
|
|
|
|
|
|
|
|
txID[0] = TxIDPrefixL2Tx |
|
|
|
|
|
copy(txID[1:], r) |
|
|
|
|
|
return txID, nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Tx returns a *Tx from the L2Tx
|
|
|
// Tx returns a *Tx from the L2Tx
|
|
@ -92,6 +131,7 @@ func (tx *L2Tx) Tx() *Tx { |
|
|
Position: tx.Position, |
|
|
Position: tx.Position, |
|
|
FromIdx: tx.FromIdx, |
|
|
FromIdx: tx.FromIdx, |
|
|
ToIdx: tx.ToIdx, |
|
|
ToIdx: tx.ToIdx, |
|
|
|
|
|
TokenID: tx.TokenID, |
|
|
Amount: tx.Amount, |
|
|
Amount: tx.Amount, |
|
|
BatchNum: batchNum, |
|
|
BatchNum: batchNum, |
|
|
EthBlockNum: tx.EthBlockNum, |
|
|
EthBlockNum: tx.EthBlockNum, |
|
@ -107,6 +147,7 @@ func (tx L2Tx) PoolL2Tx() *PoolL2Tx { |
|
|
TxID: tx.TxID, |
|
|
TxID: tx.TxID, |
|
|
FromIdx: tx.FromIdx, |
|
|
FromIdx: tx.FromIdx, |
|
|
ToIdx: tx.ToIdx, |
|
|
ToIdx: tx.ToIdx, |
|
|
|
|
|
TokenID: tx.TokenID, |
|
|
Amount: tx.Amount, |
|
|
Amount: tx.Amount, |
|
|
Fee: tx.Fee, |
|
|
Fee: tx.Fee, |
|
|
Nonce: tx.Nonce, |
|
|
Nonce: tx.Nonce, |
|
@ -134,6 +175,7 @@ func TxIDsFromL2Txs(txs []L2Tx) []TxID { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// BytesDataAvailability encodes a L2Tx into []byte for the Data Availability
|
|
|
// BytesDataAvailability encodes a L2Tx into []byte for the Data Availability
|
|
|
|
|
|
// [ fromIdx | toIdx | amountFloat16 | Fee ]
|
|
|
func (tx L2Tx) BytesDataAvailability(nLevels uint32) ([]byte, error) { |
|
|
func (tx L2Tx) BytesDataAvailability(nLevels uint32) ([]byte, error) { |
|
|
idxLen := nLevels / 8 //nolint:gomnd
|
|
|
idxLen := nLevels / 8 //nolint:gomnd
|
|
|
|
|
|
|
|
|