diff --git a/api/api_test.go b/api/api_test.go index 11fe3cc..c84ea6a 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -60,7 +60,7 @@ var SetBlockchain = ` // close Block:0, Batch:1 > batch - CreateAccountDeposit(0) A: 11111111100000000000 + CreateAccountDeposit(0) A: 11100000000000000 CreateAccountDeposit(1) C: 22222222200000000000 CreateAccountCoordinator(0) C @@ -89,8 +89,8 @@ var SetBlockchain = ` CreateAccountCoordinator(1) B - Transfer(1) A-B: 11111100000000000 (2) - Transfer(0) B-C: 22222200000000000 (3) + Transfer(1) A-B: 11100000000000000 (2) + Transfer(0) B-C: 22200000000000000 (3) // close Block:0, Batch:7 > batchL1 // forge L1User{1}, forge L1Coord{2}, forge L2{2} @@ -98,10 +98,10 @@ var SetBlockchain = ` Deposit(0) C: 66666666600000000000 DepositTransfer(0) C-D: 77777777700000000000, 12377777700000000000 - Transfer(0) A-B: 33333300000000000 (111) - Transfer(0) C-A: 44444400000000000 (222) - Transfer(1) B-C: 55555500000000000 (123) - Exit(0) A: 66666600000000000 (44) + Transfer(0) A-B: 33350000000000000 (111) + Transfer(0) C-A: 44450000000000000 (222) + Transfer(1) B-C: 55550000000000000 (123) + Exit(0) A: 66650000000000000 (44) ForceTransfer(0) D-B: 77777700000000000 ForceExit(0) B: 88888800000000000 @@ -110,8 +110,8 @@ var SetBlockchain = ` > batchL1 > block - Transfer(0) D-A: 99999900000000000 (77) - Transfer(0) B-D: 12312300000000000 (55) + Transfer(0) D-A: 99950000000000000 (77) + Transfer(0) B-D: 12300000000000000 (55) // close Block:1, Batch:1 > batchL1 diff --git a/api/txshistory_test.go b/api/txshistory_test.go index 4a35890..cbef007 100644 --- a/api/txshistory_test.go +++ b/api/txshistory_test.go @@ -452,11 +452,11 @@ func TestGetHistoryTx(t *testing.T) { fetchedTxs = append(fetchedTxs, fetchedTx) } assertTxs(t, tc.txs, fetchedTxs) - // 400 + // 400, due invalid TxID err := doBadReq("GET", endpoint+"0x001", nil, 400) assert.NoError(t, err) - // 404 - err = doBadReq("GET", endpoint+"0x00000000000001e240004700", nil, 404) + // 404, due inexistent TxID in DB + err = doBadReq("GET", endpoint+"0x00eb5e95e1ce5e9f6c4ed402d415e8d0bdd7664769cfd2064d28da04a2c76be432", nil, 404) assert.NoError(t, err) } diff --git a/api/txspool_test.go b/api/txspool_test.go index 4973054..755c485 100644 --- a/api/txspool_test.go +++ b/api/txspool_test.go @@ -184,7 +184,7 @@ func TestPoolTxs(t *testing.T) { // 400 // Wrong fee badTx := tc.poolTxsToSend[0] - badTx.Amount = "99999999999999999999999" + badTx.Amount = "99950000000000000" badTx.Fee = 255 jsonTxBytes, err := json.Marshal(badTx) assert.NoError(t, err) @@ -231,11 +231,11 @@ func TestPoolTxs(t *testing.T) { ) assertPoolTx(t, tx, fetchedTx) } - // 400 - err = doBadReq("GET", endpoint+"0xG20000000156660000000090", nil, 400) + // 400, due invalid TxID + err = doBadReq("GET", endpoint+"0xG2241b6f2b1dd772dba391f4a1a3407c7c21f598d86e2585a14e616fb4a255f823", nil, 400) assert.NoError(t, err) - // 404 - err = doBadReq("GET", endpoint+"0x020000000156660000000090", nil, 404) + // 404, due inexistent TxID in DB + err = doBadReq("GET", endpoint+"0x02241b6f2b1dd772dba391f4a1a3407c7c21f598d86e2585a14e616fb4a255f823", nil, 404) assert.NoError(t, err) } diff --git a/common/l1tx.go b/common/l1tx.go index ac15b40..222d05d 100644 --- a/common/l1tx.go +++ b/common/l1tx.go @@ -1,6 +1,7 @@ package common import ( + "crypto/sha256" "encoding/binary" "fmt" "math/big" @@ -111,26 +112,39 @@ func (tx *L1Tx) SetType() error { // SetID sets the ID of the transaction. For L1UserTx uses (ToForgeL1TxsNum, // Position), for L1CoordinatorTx uses (BatchNum, Position). func (tx *L1Tx) SetID() error { + var b []byte if tx.UserOrigin { if tx.ToForgeL1TxsNum == nil { return tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == true && L1Tx.ToForgeL1TxsNum == nil")) } tx.TxID[0] = TxIDPrefixL1UserTx + var toForgeL1TxsNumBytes [8]byte binary.BigEndian.PutUint64(toForgeL1TxsNumBytes[:], uint64(*tx.ToForgeL1TxsNum)) - copy(tx.TxID[1:9], toForgeL1TxsNumBytes[:]) + b = append(b, toForgeL1TxsNumBytes[:]...) } else { if tx.BatchNum == nil { return tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == false && L1Tx.BatchNum == nil")) } tx.TxID[0] = TxIDPrefixL1CoordTx + var batchNumBytes [8]byte binary.BigEndian.PutUint64(batchNumBytes[:], uint64(*tx.BatchNum)) - copy(tx.TxID[1:9], batchNumBytes[:]) + b = append(b, batchNumBytes[:]...) } var positionBytes [2]byte binary.BigEndian.PutUint16(positionBytes[:], uint16(tx.Position)) - copy(tx.TxID[9:11], positionBytes[:]) + b = append(b, positionBytes[:]...) + + // calculate hash + h := sha256.New() + _, err := h.Write(b[:]) + if err != nil { + return tracerr.Wrap(err) + } + r := h.Sum(nil) + + copy(tx.TxID[1:], r) return nil } diff --git a/common/l1tx_test.go b/common/l1tx_test.go index 1f56d28..2eef303 100644 --- a/common/l1tx_test.go +++ b/common/l1tx_test.go @@ -29,7 +29,7 @@ func TestNewL1UserTx(t *testing.T) { } l1Tx, err := NewL1Tx(l1Tx) assert.NoError(t, err) - assert.Equal(t, "0x00000000000001e240004700", l1Tx.TxID.String()) + assert.Equal(t, "0x00eb5e95e1ce5e9f6c4ed402d415e8d0bdd7664769cfd2064d28da04a2c76be432", l1Tx.TxID.String()) } func TestNewL1CoordinatorTx(t *testing.T) { @@ -46,7 +46,7 @@ func TestNewL1CoordinatorTx(t *testing.T) { } l1Tx, err := NewL1Tx(l1Tx) assert.NoError(t, err) - assert.Equal(t, "0x01000000000000cafe005800", l1Tx.TxID.String()) + assert.Equal(t, "0x01b8ae2bf60cb8f7c2315a27f13c8863fa2370d15ccc2e68490e197030ba22b97e", l1Tx.TxID.String()) } func TestL1TxCompressedData(t *testing.T) { @@ -279,3 +279,69 @@ func TestL1CoordinatorTxByteParsersCompatibility(t *testing.T) { assert.Equal(t, expected, encodeData) } + +func TestL1TxID(t *testing.T) { + // L1UserTx + i64_1 := int64(1) + i64_2 := int64(2) + tx0 := L1Tx{ + UserOrigin: true, + ToForgeL1TxsNum: &i64_1, + Position: 1, + } + err := tx0.SetID() + require.NoError(t, err) + assert.Equal(t, TxIDPrefixL1UserTx, tx0.TxID[0]) + + // differ ToForgeL1TxsNum + tx1 := L1Tx{ + UserOrigin: true, + ToForgeL1TxsNum: &i64_2, + Position: 1, + } + err = tx1.SetID() + require.NoError(t, err) + assert.NotEqual(t, tx0.TxID, tx1.TxID) + + // differ Position + tx1 = L1Tx{ + UserOrigin: true, + ToForgeL1TxsNum: &i64_1, + Position: 2, + } + err = tx1.SetID() + require.NoError(t, err) + assert.NotEqual(t, tx0.TxID, tx1.TxID) + + // L1CoordinatorTx + bn1 := BatchNum(1) + bn2 := BatchNum(2) + tx0 = L1Tx{ + UserOrigin: false, + BatchNum: &bn1, + Position: 1, + } + err = tx0.SetID() + require.NoError(t, err) + assert.Equal(t, TxIDPrefixL1CoordTx, tx0.TxID[0]) + + // differ BatchNum + tx1 = L1Tx{ + UserOrigin: false, + BatchNum: &bn2, + Position: 1, + } + err = tx1.SetID() + require.NoError(t, err) + assert.NotEqual(t, tx0.TxID, tx1.TxID) + + // differ Position + tx1 = L1Tx{ + UserOrigin: false, + BatchNum: &bn1, + Position: 2, + } + err = tx1.SetID() + require.NoError(t, err) + assert.NotEqual(t, tx0.TxID, tx1.TxID) +} diff --git a/common/l2tx.go b/common/l2tx.go index 050d292..a27541d 100644 --- a/common/l2tx.go +++ b/common/l2tx.go @@ -1,6 +1,7 @@ package common import ( + "crypto/sha256" "fmt" "math/big" @@ -66,18 +67,53 @@ func (tx *L2Tx) SetType() error { // SetID sets the ID of the transaction 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() 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() 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 diff --git a/common/l2tx_test.go b/common/l2tx_test.go index 3da38d2..4430407 100644 --- a/common/l2tx_test.go +++ b/common/l2tx_test.go @@ -13,12 +13,13 @@ func TestNewL2Tx(t *testing.T) { l2Tx := &L2Tx{ FromIdx: 87654, ToIdx: 300, + TokenID: 5, Amount: big.NewInt(4), Nonce: 144, } l2Tx, err := NewL2Tx(l2Tx) assert.NoError(t, err) - assert.Equal(t, "0x020000000156660000000090", l2Tx.TxID.String()) + assert.Equal(t, "0x024f67ec893467419cdfacfc9152e55dc7ce16088952bf2b3442732fd046bd031c", l2Tx.TxID.String()) } func TestL2TxByteParsers(t *testing.T) { diff --git a/common/pooll2tx.go b/common/pooll2tx.go index dd88c0a..b71288b 100644 --- a/common/pooll2tx.go +++ b/common/pooll2tx.go @@ -102,19 +102,13 @@ func (tx *PoolL2Tx) SetType() error { return nil } -// SetID sets the ID of the transaction. Uses (FromIdx, Nonce). +// SetID sets the ID of the transaction func (tx *PoolL2Tx) SetID() error { - tx.TxID[0] = TxIDPrefixL2Tx - fromIdxBytes, err := tx.FromIdx.Bytes() - if err != nil { - return tracerr.Wrap(err) - } - copy(tx.TxID[1:7], fromIdxBytes[:]) - nonceBytes, err := tx.Nonce.Bytes() + txID, err := tx.L2Tx().CalculateTxID() if err != nil { return tracerr.Wrap(err) } - copy(tx.TxID[7:12], nonceBytes[:]) + tx.TxID = txID return nil } diff --git a/common/pooll2tx_test.go b/common/pooll2tx_test.go index 56f124a..44282c2 100644 --- a/common/pooll2tx_test.go +++ b/common/pooll2tx_test.go @@ -21,7 +21,7 @@ func TestNewPoolL2Tx(t *testing.T) { } poolL2Tx, err := NewPoolL2Tx(poolL2Tx) assert.NoError(t, err) - assert.Equal(t, "0x020000000156660000000090", poolL2Tx.TxID.String()) + assert.Equal(t, "0x024f67ec893467419cdfacfc9152e55dc7ce16088952bf2b3442732fd046bd031c", poolL2Tx.TxID.String()) } func TestTxCompressedData(t *testing.T) { @@ -170,3 +170,53 @@ func TestDecompressEmptyBJJComp(t *testing.T) { assert.Equal(t, "2957874849018779266517920829765869116077630550401372566248359756137677864698", pk.X.String()) assert.Equal(t, "0", pk.Y.String()) } + +func TestPoolL2TxID(t *testing.T) { + tx0 := PoolL2Tx{ + FromIdx: 5, + ToIdx: 5, + Amount: big.NewInt(5), + Fee: 126, + TokenID: 5, + Nonce: 5, + } + err := tx0.SetID() + require.NoError(t, err) + + // differ TokenID + tx1 := PoolL2Tx{ + FromIdx: 5, + ToIdx: 5, + Amount: big.NewInt(5), + Fee: 126, + TokenID: 4, + Nonce: 5, + } + err = tx1.SetID() + require.NoError(t, err) + assert.NotEqual(t, tx0.TxID, tx1.TxID) + // differ Nonce + tx1 = PoolL2Tx{ + FromIdx: 5, + ToIdx: 5, + Amount: big.NewInt(5), + Fee: 126, + TokenID: 5, + Nonce: 4, + } + err = tx1.SetID() + require.NoError(t, err) + assert.NotEqual(t, tx0.TxID, tx1.TxID) + // differ Fee + tx1 = PoolL2Tx{ + FromIdx: 5, + ToIdx: 5, + Amount: big.NewInt(5), + Fee: 124, + TokenID: 5, + Nonce: 5, + } + err = tx1.SetID() + require.NoError(t, err) + assert.NotEqual(t, tx0.TxID, tx1.TxID) +} diff --git a/common/tx.go b/common/tx.go index cdbb486..526c87e 100644 --- a/common/tx.go +++ b/common/tx.go @@ -31,7 +31,7 @@ const ( TxIDPrefixL2Tx = byte(2) // TxIDLen is the length of the TxID byte array - TxIDLen = 12 + TxIDLen = 33 ) var ( diff --git a/common/tx_test.go b/common/tx_test.go index e1ae33f..a82a139 100644 --- a/common/tx_test.go +++ b/common/tx_test.go @@ -21,8 +21,9 @@ func TestSignatureConstant(t *testing.T) { func TestTxIDScannerValue(t *testing.T) { txid0 := &TxID{} txid1 := &TxID{} - txid0B := [12]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} - txid1B := [12]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + txid0B := [TxIDLen]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2} + txid1B := [TxIDLen]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + copy(txid0[:], txid0B[:]) copy(txid1[:], txid1B[:]) @@ -37,7 +38,7 @@ func TestTxIDScannerValue(t *testing.T) { } func TestTxIDMarshalers(t *testing.T) { - h := []byte("0x00000000000001e240004700") + h := []byte("0x02f8b4197b990fcef7ab11021675b4532e584b2c6b3f32562a5128ff00dceb9a5b") var txid TxID err := txid.UnmarshalText(h) assert.NoError(t, err) diff --git a/db/historydb/historydb_test.go b/db/historydb/historydb_test.go index 4bd2549..2472539 100644 --- a/db/historydb/historydb_test.go +++ b/db/historydb/historydb_test.go @@ -484,16 +484,16 @@ func TestTxs(t *testing.T) { assert.Equal(t, common.TxTypeCreateAccountDeposit, dbL1Txs[9].Type) // Tx ID - assert.Equal(t, "0x000000000000000001000000", dbL1Txs[0].TxID.String()) - assert.Equal(t, "0x000000000000000001000100", dbL1Txs[1].TxID.String()) - assert.Equal(t, "0x000000000000000003000000", dbL1Txs[2].TxID.String()) - assert.Equal(t, "0x000000000000000005000000", dbL1Txs[3].TxID.String()) - assert.Equal(t, "0x000000000000000005000100", dbL1Txs[4].TxID.String()) - assert.Equal(t, "0x000000000000000005000200", dbL1Txs[5].TxID.String()) - assert.Equal(t, "0x000000000000000006000000", dbL1Txs[6].TxID.String()) - assert.Equal(t, "0x000000000000000006000100", dbL1Txs[7].TxID.String()) - assert.Equal(t, "0x000000000000000008000000", dbL1Txs[8].TxID.String()) - assert.Equal(t, "0x000000000000000009000000", dbL1Txs[9].TxID.String()) + assert.Equal(t, "0x00c4f3fb5c0f7f76b3fe0a74a6ae7472e6a5ef9d66db08df7d0a7e4980c578c55a", dbL1Txs[0].TxID.String()) + assert.Equal(t, "0x00b0c7398bfd31f7a6c0b4d3f80c73cfe9cdb541bdb6eccc6b9097976f9535fb01", dbL1Txs[1].TxID.String()) + assert.Equal(t, "0x00bc12304d5d1aca95c356394bfa2e331e4ccb21e250c6a7442d92e02371eca9ff", dbL1Txs[2].TxID.String()) + assert.Equal(t, "0x0063077b5c07999b460aa31dc3ea300f5923afa08f117e8ed7476aae299ed4b74b", dbL1Txs[3].TxID.String()) + assert.Equal(t, "0x003f8b27b160e7b98ee5275de5ace264ae45891ac219a1b7c03863b5a764176b03", dbL1Txs[4].TxID.String()) + assert.Equal(t, "0x00937115a38e1c049aab568b3281e005c206a3e18e87400ce6c62c83599a3bafbd", dbL1Txs[5].TxID.String()) + assert.Equal(t, "0x006118820894c0acdc230d65fe739a4082c9eed3be1f5020f544d855e36dc4eae6", dbL1Txs[6].TxID.String()) + assert.Equal(t, "0x003e5aede622ad4ebbc436d178eb83d15f8b38614eda6e90b1acb88034a0eb177d", dbL1Txs[7].TxID.String()) + assert.Equal(t, "0x007682bb57dfd4d2e98a5c7836d0dc92bee86edefad6db6ad123415991d79fd69d", dbL1Txs[8].TxID.String()) + assert.Equal(t, "0x006d068c5ee574706ed23bc357390da1c5bc5e144f51a32dcd38faf50be60813d6", dbL1Txs[9].TxID.String()) // Tx From IDx assert.Equal(t, common.Idx(0), dbL1Txs[0].FromIdx) @@ -610,10 +610,10 @@ func TestTxs(t *testing.T) { assert.Equal(t, common.TxTypeExit, dbL2Txs[3].Type) // Tx ID - assert.Equal(t, "0x020000000001030000000000", dbL2Txs[0].TxID.String()) - assert.Equal(t, "0x020000000001010000000000", dbL2Txs[1].TxID.String()) - assert.Equal(t, "0x020000000001000000000000", dbL2Txs[2].TxID.String()) - assert.Equal(t, "0x020000000001000000000001", dbL2Txs[3].TxID.String()) + assert.Equal(t, "0x0216d6fd29ec664d30a5db5c11401b79624388acc1c8bdd7ec4d29c9fbc82e6bbd", dbL2Txs[0].TxID.String()) + assert.Equal(t, "0x024a99c757c9ded6156cea463e9e7b1ebed51c323dae1f1dc1bea5068f5c688f3a", dbL2Txs[1].TxID.String()) + assert.Equal(t, "0x0239d316ab550bf8ee20a48f9a89d511baa069207d24ccdc4cfcea0dc04e0659df", dbL2Txs[2].TxID.String()) + assert.Equal(t, "0x02c7233141caf1f99d4d5d2013da01c709e73ee3c9b46f3d5635b02d14e6177a9d", dbL2Txs[3].TxID.String()) // Tx From and To IDx assert.Equal(t, dbL2Txs[0].ToIdx, dbL2Txs[2].FromIdx) diff --git a/test/historydb.go b/test/historydb.go index 861eb3b..c8ccff9 100644 --- a/test/historydb.go +++ b/test/historydb.go @@ -282,7 +282,7 @@ func GenL2Txs( amount := big.NewInt(int64(i + 1)) fee := common.FeeSelector(i % 256) //nolint:gomnd tx := common.L2Tx{ - TxID: common.TxID([12]byte{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, byte(i)}), // only for testing purposes + TxID: common.TxID([common.TxIDLen]byte{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, byte(i)}), // only for testing purposes BatchNum: batches[i%len(batches)].BatchNum, Position: i - fromIdx, Amount: amount, diff --git a/test/til/txs.go b/test/til/txs.go index 1f84027..f3b43f9 100644 --- a/test/til/txs.go +++ b/test/til/txs.go @@ -370,7 +370,6 @@ func (tc *Context) generateBlocks() ([]common.BlockData, error) { } tc.currBatch.L1Batch = true if err := tc.setIdxs(); err != nil { - log.Error(err) return nil, tracerr.Wrap(err) } toForgeL1TxsNum := int64(tc.openToForge)