From fac8577badfae13593cab49cb6975ad9ed95bf26 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Fri, 6 Nov 2020 15:24:12 +0100 Subject: [PATCH] Update tx bytes parsers methods --- common/fee_test.go | 5 ++++- common/l1tx.go | 19 ++++++++++++++++--- common/l1tx_test.go | 1 + common/l2tx.go | 35 ++++++++++++++++++++--------------- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/common/fee_test.go b/common/fee_test.go index 63219e8..0b6be7f 100644 --- a/common/fee_test.go +++ b/common/fee_test.go @@ -48,8 +48,11 @@ func TestCalcFeeAmount(t *testing.T) { } func TestFeePrintSQLSwitch(t *testing.T) { + debug := false for i := 0; i < 256; i++ { f := FeeSelector(i).Percentage() - fmt.Printf(" WHEN $1 = %03d THEN %.6e\n", i, f) + if debug { + fmt.Printf(" WHEN $1 = %03d THEN %.6e\n", i, f) + } } } diff --git a/common/l1tx.go b/common/l1tx.go index ceddb31..a98ecdf 100644 --- a/common/l1tx.go +++ b/common/l1tx.go @@ -146,8 +146,11 @@ func (tx L1Tx) Tx() Tx { return genericTx } -// BytesUser encodes a L1Tx into []byte -func (tx *L1Tx) BytesUser() ([]byte, error) { +// BytesGeneric returns the generic representation of a L1Tx. This method is +// used to compute the []byte representation of a L1UserTx, and also to compute +// the L1TxData for the ZKInputs (at the HashGlobalInputs), using this method +// for L1CoordinatorTxs & L1UserTxs (for the ZKInputs case). +func (tx *L1Tx) BytesGeneric() ([]byte, error) { var b [L1UserTxBytesLen]byte copy(b[0:20], tx.FromEthAddr.Bytes()) pkCompL := tx.FromBJJ.Compress() @@ -177,8 +180,19 @@ func (tx *L1Tx) BytesUser() ([]byte, error) { return b[:], nil } +// BytesUser encodes a L1UserTx into []byte +func (tx *L1Tx) BytesUser() ([]byte, error) { + if !tx.UserOrigin { + return nil, fmt.Errorf("Can not calculate BytesUser() for a L1CoordinatorTx") + } + return tx.BytesGeneric() +} + // BytesCoordinatorTx encodes a L1CoordinatorTx into []byte func (tx *L1Tx) BytesCoordinatorTx(compressedSignatureBytes []byte) ([]byte, error) { + if tx.UserOrigin { + return nil, fmt.Errorf("Can not calculate BytesCoordinatorTx() for a L1UserTx") + } var b [L1CoordinatorTxBytesLen]byte v := compressedSignatureBytes[64] s := compressedSignatureBytes[32:64] @@ -210,7 +224,6 @@ func L1UserTxFromBytes(b []byte) (*L1Tx, error) { var pkComp babyjub.PublicKeyComp copy(pkComp[:], pkCompL) tx.FromBJJ, err = pkComp.Decompress() - if err != nil { return nil, err } diff --git a/common/l1tx_test.go b/common/l1tx_test.go index c04b08a..9b952d0 100644 --- a/common/l1tx_test.go +++ b/common/l1tx_test.go @@ -109,6 +109,7 @@ func TestL1TxByteParsersCompatibility(t *testing.T) { FromIdx: Idx(29767899), FromBJJ: pk, FromEthAddr: ethCommon.HexToAddress("0x85dab5b9e2e361d0c208d77be90efcc0439b0a53"), + UserOrigin: true, } expected, err := utils.HexDecode("85dab5b9e2e361d0c208d77be90efcc0439b0a530dd02deb2c81068e7a0f7e327df80b4ab79ee1f41a7def613e73a20c32eece5a000001c638db8be880f00020039c0000053cb88d") diff --git a/common/l2tx.go b/common/l2tx.go index a2bb296..2ce279c 100644 --- a/common/l2tx.go +++ b/common/l2tx.go @@ -105,49 +105,54 @@ func L2TxsToPoolL2Txs(txs []L2Tx) []PoolL2Tx { // Bytes encodes a L2Tx into []byte func (tx *L2Tx) Bytes(nLevels int) ([]byte, error) { - fromIdxNumBytes := nLevels / 8 //nolint:gomnd - toIdxNumBytes := nLevels / 8 //nolint:gomnd - var b []byte + idxLen := nLevels / 8 //nolint:gomnd + + b := make([]byte, ((nLevels*2)+16+8)/8) + fromIdxBytes, err := tx.FromIdx.Bytes() if err != nil { return nil, err } - b = append(b, fromIdxBytes[6-fromIdxNumBytes:]...) + copy(b[0:idxLen], fromIdxBytes[6-idxLen:]) // [6-idxLen:] as is BigEndian + toIdxBytes, err := tx.ToIdx.Bytes() if err != nil { return nil, err } - b = append(b, toIdxBytes[6-toIdxNumBytes:]...) + copy(b[idxLen:idxLen*2], toIdxBytes[6-idxLen:]) + amountFloat16, err := NewFloat16(tx.Amount) if err != nil { return nil, err } - b = append(b, amountFloat16.Bytes()...) - b = append(b, byte(tx.Fee)) + + copy(b[idxLen*2:idxLen*2+2], amountFloat16.Bytes()) + b[idxLen*2+2] = byte(tx.Fee) + return b[:], nil } // L2TxFromBytes decodes a L1Tx from []byte func L2TxFromBytes(b []byte, nLevels int) (*L2Tx, error) { - fromIdxNumByte := nLevels / 8 //nolint:gomnd - toIdxNumByte := fromIdxNumByte + nLevels/8 //nolint:gomnd - amountLenBytes := 2 - amountNumByte := toIdxNumByte + amountLenBytes + idxLen := nLevels / 8 //nolint:gomnd tx := &L2Tx{} var err error + var paddedFromIdxBytes [6]byte - copy(paddedFromIdxBytes[6-len(b[0:fromIdxNumByte]):], b[0:fromIdxNumByte]) + copy(paddedFromIdxBytes[6-idxLen:], b[0:idxLen]) tx.FromIdx, err = IdxFromBytes(paddedFromIdxBytes[:]) if err != nil { return nil, err } + var paddedToIdxBytes [6]byte - copy(paddedToIdxBytes[6-len(b[fromIdxNumByte:toIdxNumByte]):6], b[fromIdxNumByte:toIdxNumByte]) + copy(paddedToIdxBytes[6-idxLen:6], b[idxLen:idxLen*2]) tx.ToIdx, err = IdxFromBytes(paddedToIdxBytes[:]) if err != nil { return nil, err } - tx.Amount = Float16FromBytes(b[toIdxNumByte:amountNumByte]).BigInt() - tx.Fee = FeeSelector(b[amountNumByte]) + + tx.Amount = Float16FromBytes(b[idxLen*2 : idxLen*2+2]).BigInt() + tx.Fee = FeeSelector(b[idxLen*2+2]) return tx, nil }