mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Update txs constructors and helpers
For each tx, move the logic of setting the Type and TxID to separate functions, so that they can be called when necessary. In synchronizer, set all the required fields using the `SetID` and `SetType` for l2txs when needed. This is necessary because the `ProcessTxs()` works with `common.PoolL2Tx`, which misses some fields from `common.L2Tx`, and because `ProcessTxs()` needs the Type to be set, but at the same time `ProcessTxs()` sets the Nonce, which is required for the `TxID`.
This commit is contained in:
108
common/l1tx.go
108
common/l1tx.go
@@ -50,74 +50,88 @@ type L1Tx struct {
|
||||
|
||||
// NewL1Tx returns the given L1Tx with the TxId & Type parameters calculated
|
||||
// from the L1Tx values
|
||||
func NewL1Tx(l1Tx *L1Tx) (*L1Tx, error) {
|
||||
// calculate TxType
|
||||
var txType TxType
|
||||
if l1Tx.FromIdx == 0 {
|
||||
if l1Tx.ToIdx == Idx(0) {
|
||||
txType = TxTypeCreateAccountDeposit
|
||||
} else if l1Tx.ToIdx >= IdxUserThreshold {
|
||||
txType = TxTypeCreateAccountDepositTransfer
|
||||
} else {
|
||||
return l1Tx, tracerr.Wrap(fmt.Errorf("Can not determine type of L1Tx, invalid ToIdx value: %d", l1Tx.ToIdx))
|
||||
}
|
||||
} else if l1Tx.FromIdx >= IdxUserThreshold {
|
||||
if l1Tx.ToIdx == Idx(0) {
|
||||
txType = TxTypeDeposit
|
||||
} else if l1Tx.ToIdx == Idx(1) {
|
||||
txType = TxTypeForceExit
|
||||
} else if l1Tx.ToIdx >= IdxUserThreshold {
|
||||
if l1Tx.DepositAmount.Int64() == int64(0) {
|
||||
txType = TxTypeForceTransfer
|
||||
} else {
|
||||
txType = TxTypeDepositTransfer
|
||||
}
|
||||
} else {
|
||||
return l1Tx, tracerr.Wrap(fmt.Errorf("Can not determine type of L1Tx, invalid ToIdx value: %d", l1Tx.ToIdx))
|
||||
}
|
||||
} else {
|
||||
return l1Tx, tracerr.Wrap(fmt.Errorf("Can not determine type of L1Tx, invalid FromIdx value: %d", l1Tx.FromIdx))
|
||||
func NewL1Tx(tx *L1Tx) (*L1Tx, error) {
|
||||
txTypeOld := tx.Type
|
||||
if err := tx.SetType(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If original Type doesn't match the correct one, return error
|
||||
if txTypeOld != "" && txTypeOld != tx.Type {
|
||||
return nil, tracerr.Wrap(fmt.Errorf("L1Tx.Type: %s, should be: %s",
|
||||
tx.Type, txTypeOld))
|
||||
}
|
||||
|
||||
if l1Tx.Type != "" && l1Tx.Type != txType {
|
||||
return l1Tx, tracerr.Wrap(fmt.Errorf("L1Tx.Type: %s, should be: %s", l1Tx.Type, txType))
|
||||
txIDOld := tx.TxID
|
||||
if err := tx.SetID(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l1Tx.Type = txType
|
||||
|
||||
txID, err := l1Tx.CalcTxID()
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
// If original TxID doesn't match the correct one, return error
|
||||
if txIDOld != (TxID{}) && txIDOld != tx.TxID {
|
||||
return tx, tracerr.Wrap(fmt.Errorf("L1Tx.TxID: %s, should be: %s",
|
||||
tx.TxID.String(), txIDOld.String()))
|
||||
}
|
||||
l1Tx.TxID = *txID
|
||||
|
||||
return l1Tx, nil
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// CalcTxID calculates the TxId of the L1Tx
|
||||
func (tx *L1Tx) CalcTxID() (*TxID, error) {
|
||||
var txID TxID
|
||||
// SetType sets the type of the transaction
|
||||
func (tx *L1Tx) SetType() error {
|
||||
if tx.FromIdx == 0 {
|
||||
if tx.ToIdx == Idx(0) {
|
||||
tx.Type = TxTypeCreateAccountDeposit
|
||||
} else if tx.ToIdx >= IdxUserThreshold {
|
||||
tx.Type = TxTypeCreateAccountDepositTransfer
|
||||
} else {
|
||||
return tracerr.Wrap(fmt.Errorf(
|
||||
"Can not determine type of L1Tx, invalid ToIdx value: %d", tx.ToIdx))
|
||||
}
|
||||
} else if tx.FromIdx >= IdxUserThreshold {
|
||||
if tx.ToIdx == Idx(0) {
|
||||
tx.Type = TxTypeDeposit
|
||||
} else if tx.ToIdx == Idx(1) {
|
||||
tx.Type = TxTypeForceExit
|
||||
} else if tx.ToIdx >= IdxUserThreshold {
|
||||
if tx.DepositAmount.Int64() == int64(0) {
|
||||
tx.Type = TxTypeForceTransfer
|
||||
} else {
|
||||
tx.Type = TxTypeDepositTransfer
|
||||
}
|
||||
} else {
|
||||
return tracerr.Wrap(fmt.Errorf(
|
||||
"Can not determine type of L1Tx, invalid ToIdx value: %d", tx.ToIdx))
|
||||
}
|
||||
} else {
|
||||
return tracerr.Wrap(fmt.Errorf(
|
||||
"Can not determine type of L1Tx, invalid FromIdx value: %d", tx.FromIdx))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetID sets the ID of the transaction. For L1UserTx uses (ToForgeL1TxsNum,
|
||||
// Position), for L1CoordinatorTx uses (BatchNum, Position).
|
||||
func (tx *L1Tx) SetID() error {
|
||||
if tx.UserOrigin {
|
||||
if tx.ToForgeL1TxsNum == nil {
|
||||
return nil, tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == true && L1Tx.ToForgeL1TxsNum == nil"))
|
||||
return tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == true && L1Tx.ToForgeL1TxsNum == nil"))
|
||||
}
|
||||
txID[0] = TxIDPrefixL1UserTx
|
||||
tx.TxID[0] = TxIDPrefixL1UserTx
|
||||
var toForgeL1TxsNumBytes [8]byte
|
||||
binary.BigEndian.PutUint64(toForgeL1TxsNumBytes[:], uint64(*tx.ToForgeL1TxsNum))
|
||||
copy(txID[1:9], toForgeL1TxsNumBytes[:])
|
||||
copy(tx.TxID[1:9], toForgeL1TxsNumBytes[:])
|
||||
} else {
|
||||
if tx.BatchNum == nil {
|
||||
return nil, tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == false && L1Tx.BatchNum == nil"))
|
||||
return tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == false && L1Tx.BatchNum == nil"))
|
||||
}
|
||||
txID[0] = TxIDPrefixL1CoordTx
|
||||
tx.TxID[0] = TxIDPrefixL1CoordTx
|
||||
var batchNumBytes [8]byte
|
||||
binary.BigEndian.PutUint64(batchNumBytes[:], uint64(*tx.BatchNum))
|
||||
copy(txID[1:9], batchNumBytes[:])
|
||||
copy(tx.TxID[1:9], batchNumBytes[:])
|
||||
}
|
||||
var positionBytes [2]byte
|
||||
binary.BigEndian.PutUint16(positionBytes[:], uint16(tx.Position))
|
||||
copy(txID[9:11], positionBytes[:])
|
||||
copy(tx.TxID[9:11], positionBytes[:])
|
||||
|
||||
return &txID, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tx returns a *Tx from the L1Tx
|
||||
|
||||
@@ -24,38 +24,57 @@ type L2Tx struct {
|
||||
|
||||
// NewL2Tx returns the given L2Tx with the TxId & Type parameters calculated
|
||||
// from the L2Tx values
|
||||
func NewL2Tx(l2Tx *L2Tx) (*L2Tx, error) {
|
||||
// calculate TxType
|
||||
var txType TxType
|
||||
if l2Tx.ToIdx == Idx(1) {
|
||||
txType = TxTypeExit
|
||||
} else if l2Tx.ToIdx >= IdxUserThreshold {
|
||||
txType = TxTypeTransfer
|
||||
func NewL2Tx(tx *L2Tx) (*L2Tx, error) {
|
||||
txTypeOld := tx.Type
|
||||
if err := tx.SetType(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If original Type doesn't match the correct one, return error
|
||||
if txTypeOld != "" && txTypeOld != tx.Type {
|
||||
return nil, tracerr.Wrap(fmt.Errorf("L2Tx.Type: %s, should be: %s",
|
||||
tx.Type, txTypeOld))
|
||||
}
|
||||
|
||||
txIDOld := tx.TxID
|
||||
if err := tx.SetID(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If original TxID doesn't match the correct one, return error
|
||||
if txIDOld != (TxID{}) && txIDOld != tx.TxID {
|
||||
return tx, tracerr.Wrap(fmt.Errorf("L2Tx.TxID: %s, should be: %s",
|
||||
tx.TxID.String(), txIDOld.String()))
|
||||
}
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// SetType sets the type of the transaction. Uses (FromIdx, Nonce).
|
||||
func (tx *L2Tx) SetType() error {
|
||||
if tx.ToIdx == Idx(1) {
|
||||
tx.Type = TxTypeExit
|
||||
} else if tx.ToIdx >= IdxUserThreshold {
|
||||
tx.Type = TxTypeTransfer
|
||||
} else {
|
||||
return l2Tx, tracerr.Wrap(fmt.Errorf("Can not determine type of L2Tx, invalid ToIdx value: %d", l2Tx.ToIdx))
|
||||
return tracerr.Wrap(fmt.Errorf(
|
||||
"cannot determine type of L2Tx, invalid ToIdx value: %d", tx.ToIdx))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// if TxType!=l2Tx.TxType return error
|
||||
if l2Tx.Type != "" && l2Tx.Type != txType {
|
||||
return l2Tx, tracerr.Wrap(fmt.Errorf("L2Tx.Type: %s, should be: %s", l2Tx.Type, txType))
|
||||
}
|
||||
l2Tx.Type = txType
|
||||
|
||||
var txid [TxIDLen]byte
|
||||
txid[0] = TxIDPrefixL2Tx
|
||||
fromIdxBytes, err := l2Tx.FromIdx.Bytes()
|
||||
// SetID sets the ID of the transaction
|
||||
func (tx *L2Tx) SetID() error {
|
||||
tx.TxID[0] = TxIDPrefixL2Tx
|
||||
fromIdxBytes, err := tx.FromIdx.Bytes()
|
||||
if err != nil {
|
||||
return l2Tx, tracerr.Wrap(err)
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
copy(txid[1:7], fromIdxBytes[:])
|
||||
nonceBytes, err := l2Tx.Nonce.Bytes()
|
||||
copy(tx.TxID[1:7], fromIdxBytes[:])
|
||||
nonceBytes, err := tx.Nonce.Bytes()
|
||||
if err != nil {
|
||||
return l2Tx, tracerr.Wrap(err)
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
copy(txid[7:12], nonceBytes[:])
|
||||
l2Tx.TxID = TxID(txid)
|
||||
|
||||
return l2Tx, nil
|
||||
copy(tx.TxID[7:12], nonceBytes[:])
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tx returns a *Tx from the L2Tx
|
||||
|
||||
@@ -50,49 +50,62 @@ type PoolL2Tx struct {
|
||||
|
||||
// NewPoolL2Tx returns the given L2Tx with the TxId & Type parameters calculated
|
||||
// from the L2Tx values
|
||||
func NewPoolL2Tx(poolL2Tx *PoolL2Tx) (*PoolL2Tx, error) {
|
||||
// calculate TxType
|
||||
var txType TxType
|
||||
if poolL2Tx.ToIdx >= IdxUserThreshold {
|
||||
txType = TxTypeTransfer
|
||||
} else if poolL2Tx.ToIdx == 1 {
|
||||
txType = TxTypeExit
|
||||
} else if poolL2Tx.ToIdx == 0 {
|
||||
if poolL2Tx.ToBJJ != nil && poolL2Tx.ToEthAddr == FFAddr {
|
||||
txType = TxTypeTransferToBJJ
|
||||
} else if poolL2Tx.ToEthAddr != FFAddr && poolL2Tx.ToEthAddr != EmptyAddr {
|
||||
txType = TxTypeTransferToEthAddr
|
||||
func NewPoolL2Tx(tx *PoolL2Tx) (*PoolL2Tx, error) {
|
||||
txTypeOld := tx.Type
|
||||
if err := tx.SetType(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If original Type doesn't match the correct one, return error
|
||||
if txTypeOld != "" && txTypeOld != tx.Type {
|
||||
return nil, tracerr.Wrap(fmt.Errorf("L2Tx.Type: %s, should be: %s",
|
||||
tx.Type, txTypeOld))
|
||||
}
|
||||
|
||||
txIDOld := tx.TxID
|
||||
if err := tx.SetID(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If original TxID doesn't match the correct one, return error
|
||||
if txIDOld != (TxID{}) && txIDOld != tx.TxID {
|
||||
return tx, tracerr.Wrap(fmt.Errorf("PoolL2Tx.TxID: %s, should be: %s",
|
||||
tx.TxID.String(), txIDOld.String()))
|
||||
}
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// SetType sets the type of the transaction
|
||||
func (tx *PoolL2Tx) SetType() error {
|
||||
if tx.ToIdx >= IdxUserThreshold {
|
||||
tx.Type = TxTypeTransfer
|
||||
} else if tx.ToIdx == 1 {
|
||||
tx.Type = TxTypeExit
|
||||
} else if tx.ToIdx == 0 {
|
||||
if tx.ToBJJ != nil && tx.ToEthAddr == FFAddr {
|
||||
tx.Type = TxTypeTransferToBJJ
|
||||
} else if tx.ToEthAddr != FFAddr && tx.ToEthAddr != EmptyAddr {
|
||||
tx.Type = TxTypeTransferToEthAddr
|
||||
}
|
||||
} else {
|
||||
return nil, tracerr.Wrap(errors.New("malformed transaction"))
|
||||
return tracerr.Wrap(errors.New("malformed transaction"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// if TxType!=poolL2Tx.TxType return error
|
||||
if poolL2Tx.Type != "" && poolL2Tx.Type != txType {
|
||||
return poolL2Tx, tracerr.Wrap(fmt.Errorf("type: %s, should be: %s", poolL2Tx.Type, txType))
|
||||
}
|
||||
poolL2Tx.Type = txType
|
||||
|
||||
var txid [TxIDLen]byte
|
||||
txid[0] = TxIDPrefixL2Tx
|
||||
fromIdxBytes, err := poolL2Tx.FromIdx.Bytes()
|
||||
// SetID sets the ID of the transaction. Uses (FromIdx, Nonce).
|
||||
func (tx *PoolL2Tx) SetID() error {
|
||||
tx.TxID[0] = TxIDPrefixL2Tx
|
||||
fromIdxBytes, err := tx.FromIdx.Bytes()
|
||||
if err != nil {
|
||||
return poolL2Tx, tracerr.Wrap(err)
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
copy(txid[1:7], fromIdxBytes[:])
|
||||
nonceBytes, err := poolL2Tx.Nonce.Bytes()
|
||||
copy(tx.TxID[1:7], fromIdxBytes[:])
|
||||
nonceBytes, err := tx.Nonce.Bytes()
|
||||
if err != nil {
|
||||
return poolL2Tx, tracerr.Wrap(err)
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
copy(txid[7:12], nonceBytes[:])
|
||||
txID := TxID(txid)
|
||||
|
||||
// if TxID!=poolL2Tx.TxID return error
|
||||
if poolL2Tx.TxID != (TxID{}) && poolL2Tx.TxID != txID {
|
||||
return poolL2Tx, tracerr.Wrap(fmt.Errorf("id: %s, should be: %s", poolL2Tx.TxID.String(), txID.String()))
|
||||
}
|
||||
poolL2Tx.TxID = txID
|
||||
return poolL2Tx, nil
|
||||
copy(tx.TxID[7:12], nonceBytes[:])
|
||||
return nil
|
||||
}
|
||||
|
||||
// TxCompressedData spec:
|
||||
@@ -305,11 +318,11 @@ func (tx PoolL2Tx) Tx() Tx {
|
||||
|
||||
// PoolL2TxsToL2Txs returns an array of []L2Tx from an array of []PoolL2Tx
|
||||
func PoolL2TxsToL2Txs(txs []PoolL2Tx) ([]L2Tx, error) {
|
||||
var r []L2Tx
|
||||
for _, poolTx := range txs {
|
||||
r = append(r, poolTx.L2Tx())
|
||||
l2Txs := make([]L2Tx, len(txs))
|
||||
for i, poolTx := range txs {
|
||||
l2Txs[i] = poolTx.L2Tx()
|
||||
}
|
||||
return r, nil
|
||||
return l2Txs, nil
|
||||
}
|
||||
|
||||
// PoolL2TxState is a struct that represents the status of a L2 transaction
|
||||
|
||||
Reference in New Issue
Block a user