mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Merge pull request #507 from hermeznetwork/feature/txid-fixcollisions
Feature/txid fixcollisions
This commit is contained in:
@@ -60,7 +60,7 @@ var SetBlockchain = `
|
|||||||
// close Block:0, Batch:1
|
// close Block:0, Batch:1
|
||||||
> batch
|
> batch
|
||||||
|
|
||||||
CreateAccountDeposit(0) A: 11111111100000000000
|
CreateAccountDeposit(0) A: 11100000000000000
|
||||||
CreateAccountDeposit(1) C: 22222222200000000000
|
CreateAccountDeposit(1) C: 22222222200000000000
|
||||||
CreateAccountCoordinator(0) C
|
CreateAccountCoordinator(0) C
|
||||||
|
|
||||||
@@ -89,8 +89,8 @@ var SetBlockchain = `
|
|||||||
|
|
||||||
CreateAccountCoordinator(1) B
|
CreateAccountCoordinator(1) B
|
||||||
|
|
||||||
Transfer(1) A-B: 11111100000000000 (2)
|
Transfer(1) A-B: 11100000000000000 (2)
|
||||||
Transfer(0) B-C: 22222200000000000 (3)
|
Transfer(0) B-C: 22200000000000000 (3)
|
||||||
|
|
||||||
// close Block:0, Batch:7
|
// close Block:0, Batch:7
|
||||||
> batchL1 // forge L1User{1}, forge L1Coord{2}, forge L2{2}
|
> batchL1 // forge L1User{1}, forge L1Coord{2}, forge L2{2}
|
||||||
@@ -98,10 +98,10 @@ var SetBlockchain = `
|
|||||||
Deposit(0) C: 66666666600000000000
|
Deposit(0) C: 66666666600000000000
|
||||||
DepositTransfer(0) C-D: 77777777700000000000, 12377777700000000000
|
DepositTransfer(0) C-D: 77777777700000000000, 12377777700000000000
|
||||||
|
|
||||||
Transfer(0) A-B: 33333300000000000 (111)
|
Transfer(0) A-B: 33350000000000000 (111)
|
||||||
Transfer(0) C-A: 44444400000000000 (222)
|
Transfer(0) C-A: 44450000000000000 (222)
|
||||||
Transfer(1) B-C: 55555500000000000 (123)
|
Transfer(1) B-C: 55550000000000000 (123)
|
||||||
Exit(0) A: 66666600000000000 (44)
|
Exit(0) A: 66650000000000000 (44)
|
||||||
|
|
||||||
ForceTransfer(0) D-B: 77777700000000000
|
ForceTransfer(0) D-B: 77777700000000000
|
||||||
ForceExit(0) B: 88888800000000000
|
ForceExit(0) B: 88888800000000000
|
||||||
@@ -110,8 +110,8 @@ var SetBlockchain = `
|
|||||||
> batchL1
|
> batchL1
|
||||||
> block
|
> block
|
||||||
|
|
||||||
Transfer(0) D-A: 99999900000000000 (77)
|
Transfer(0) D-A: 99950000000000000 (77)
|
||||||
Transfer(0) B-D: 12312300000000000 (55)
|
Transfer(0) B-D: 12300000000000000 (55)
|
||||||
|
|
||||||
// close Block:1, Batch:1
|
// close Block:1, Batch:1
|
||||||
> batchL1
|
> batchL1
|
||||||
|
|||||||
@@ -452,11 +452,11 @@ func TestGetHistoryTx(t *testing.T) {
|
|||||||
fetchedTxs = append(fetchedTxs, fetchedTx)
|
fetchedTxs = append(fetchedTxs, fetchedTx)
|
||||||
}
|
}
|
||||||
assertTxs(t, tc.txs, fetchedTxs)
|
assertTxs(t, tc.txs, fetchedTxs)
|
||||||
// 400
|
// 400, due invalid TxID
|
||||||
err := doBadReq("GET", endpoint+"0x001", nil, 400)
|
err := doBadReq("GET", endpoint+"0x001", nil, 400)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// 404
|
// 404, due inexistent TxID in DB
|
||||||
err = doBadReq("GET", endpoint+"0x00000000000001e240004700", nil, 404)
|
err = doBadReq("GET", endpoint+"0x00eb5e95e1ce5e9f6c4ed402d415e8d0bdd7664769cfd2064d28da04a2c76be432", nil, 404)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ func TestPoolTxs(t *testing.T) {
|
|||||||
// 400
|
// 400
|
||||||
// Wrong fee
|
// Wrong fee
|
||||||
badTx := tc.poolTxsToSend[0]
|
badTx := tc.poolTxsToSend[0]
|
||||||
badTx.Amount = "99999999999999999999999"
|
badTx.Amount = "99950000000000000"
|
||||||
badTx.Fee = 255
|
badTx.Fee = 255
|
||||||
jsonTxBytes, err := json.Marshal(badTx)
|
jsonTxBytes, err := json.Marshal(badTx)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -231,11 +231,11 @@ func TestPoolTxs(t *testing.T) {
|
|||||||
)
|
)
|
||||||
assertPoolTx(t, tx, fetchedTx)
|
assertPoolTx(t, tx, fetchedTx)
|
||||||
}
|
}
|
||||||
// 400
|
// 400, due invalid TxID
|
||||||
err = doBadReq("GET", endpoint+"0xG20000000156660000000090", nil, 400)
|
err = doBadReq("GET", endpoint+"0xG2241b6f2b1dd772dba391f4a1a3407c7c21f598d86e2585a14e616fb4a255f823", nil, 400)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// 404
|
// 404, due inexistent TxID in DB
|
||||||
err = doBadReq("GET", endpoint+"0x020000000156660000000090", nil, 404)
|
err = doBadReq("GET", endpoint+"0x02241b6f2b1dd772dba391f4a1a3407c7c21f598d86e2585a14e616fb4a255f823", nil, 404)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
@@ -111,26 +112,39 @@ func (tx *L1Tx) SetType() error {
|
|||||||
// SetID sets the ID of the transaction. For L1UserTx uses (ToForgeL1TxsNum,
|
// SetID sets the ID of the transaction. For L1UserTx uses (ToForgeL1TxsNum,
|
||||||
// Position), for L1CoordinatorTx uses (BatchNum, Position).
|
// Position), for L1CoordinatorTx uses (BatchNum, Position).
|
||||||
func (tx *L1Tx) SetID() error {
|
func (tx *L1Tx) SetID() error {
|
||||||
|
var b []byte
|
||||||
if tx.UserOrigin {
|
if tx.UserOrigin {
|
||||||
if tx.ToForgeL1TxsNum == nil {
|
if tx.ToForgeL1TxsNum == nil {
|
||||||
return tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == true && L1Tx.ToForgeL1TxsNum == nil"))
|
return tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == true && L1Tx.ToForgeL1TxsNum == nil"))
|
||||||
}
|
}
|
||||||
tx.TxID[0] = TxIDPrefixL1UserTx
|
tx.TxID[0] = TxIDPrefixL1UserTx
|
||||||
|
|
||||||
var toForgeL1TxsNumBytes [8]byte
|
var toForgeL1TxsNumBytes [8]byte
|
||||||
binary.BigEndian.PutUint64(toForgeL1TxsNumBytes[:], uint64(*tx.ToForgeL1TxsNum))
|
binary.BigEndian.PutUint64(toForgeL1TxsNumBytes[:], uint64(*tx.ToForgeL1TxsNum))
|
||||||
copy(tx.TxID[1:9], toForgeL1TxsNumBytes[:])
|
b = append(b, toForgeL1TxsNumBytes[:]...)
|
||||||
} else {
|
} else {
|
||||||
if tx.BatchNum == nil {
|
if tx.BatchNum == nil {
|
||||||
return tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == false && L1Tx.BatchNum == nil"))
|
return tracerr.Wrap(fmt.Errorf("L1Tx.UserOrigin == false && L1Tx.BatchNum == nil"))
|
||||||
}
|
}
|
||||||
tx.TxID[0] = TxIDPrefixL1CoordTx
|
tx.TxID[0] = TxIDPrefixL1CoordTx
|
||||||
|
|
||||||
var batchNumBytes [8]byte
|
var batchNumBytes [8]byte
|
||||||
binary.BigEndian.PutUint64(batchNumBytes[:], uint64(*tx.BatchNum))
|
binary.BigEndian.PutUint64(batchNumBytes[:], uint64(*tx.BatchNum))
|
||||||
copy(tx.TxID[1:9], batchNumBytes[:])
|
b = append(b, batchNumBytes[:]...)
|
||||||
}
|
}
|
||||||
var positionBytes [2]byte
|
var positionBytes [2]byte
|
||||||
binary.BigEndian.PutUint16(positionBytes[:], uint16(tx.Position))
|
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
|
return nil
|
||||||
}
|
}
|
||||||
@@ -205,6 +219,7 @@ func (tx L1Tx) TxCompressedData(chainID uint16) (*big.Int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BytesDataAvailability encodes a L1Tx into []byte for the Data Availability
|
// BytesDataAvailability encodes a L1Tx into []byte for the Data Availability
|
||||||
|
// [ fromIdx | toIdx | amountFloat16 | Fee ]
|
||||||
func (tx *L1Tx) BytesDataAvailability(nLevels uint32) ([]byte, error) {
|
func (tx *L1Tx) BytesDataAvailability(nLevels uint32) ([]byte, error) {
|
||||||
idxLen := nLevels / 8 //nolint:gomnd
|
idxLen := nLevels / 8 //nolint:gomnd
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func TestNewL1UserTx(t *testing.T) {
|
|||||||
}
|
}
|
||||||
l1Tx, err := NewL1Tx(l1Tx)
|
l1Tx, err := NewL1Tx(l1Tx)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "0x00000000000001e240004700", l1Tx.TxID.String())
|
assert.Equal(t, "0x00eb5e95e1ce5e9f6c4ed402d415e8d0bdd7664769cfd2064d28da04a2c76be432", l1Tx.TxID.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewL1CoordinatorTx(t *testing.T) {
|
func TestNewL1CoordinatorTx(t *testing.T) {
|
||||||
@@ -46,7 +46,7 @@ func TestNewL1CoordinatorTx(t *testing.T) {
|
|||||||
}
|
}
|
||||||
l1Tx, err := NewL1Tx(l1Tx)
|
l1Tx, err := NewL1Tx(l1Tx)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "0x01000000000000cafe005800", l1Tx.TxID.String())
|
assert.Equal(t, "0x01b8ae2bf60cb8f7c2315a27f13c8863fa2370d15ccc2e68490e197030ba22b97e", l1Tx.TxID.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestL1TxCompressedData(t *testing.T) {
|
func TestL1TxCompressedData(t *testing.T) {
|
||||||
@@ -279,3 +279,69 @@ func TestL1CoordinatorTxByteParsersCompatibility(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, expected, encodeData)
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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"`
|
TxID TxID `meddler:"id"`
|
||||||
BatchNum BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged.
|
BatchNum BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged.
|
||||||
Position int `meddler:"position"`
|
Position int `meddler:"position"`
|
||||||
FromIdx Idx `meddler:"from_idx"`
|
FromIdx Idx `meddler:"from_idx"`
|
||||||
ToIdx Idx `meddler:"to_idx"`
|
ToIdx Idx `meddler:"to_idx"`
|
||||||
Amount *big.Int `meddler:"amount,bigint"`
|
// TokenID is filled by the TxProcessor
|
||||||
Fee FeeSelector `meddler:"fee"`
|
TokenID TokenID `meddler:"token_id"`
|
||||||
Nonce Nonce `meddler:"nonce"`
|
Amount *big.Int `meddler:"amount,bigint"`
|
||||||
Type TxType `meddler:"type"`
|
Fee FeeSelector `meddler:"fee"`
|
||||||
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L2Tx was added to the queue
|
// 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[:])
|
b = append(b, nonceBytes[:]...)
|
||||||
return nil
|
// 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
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,13 @@ func TestNewL2Tx(t *testing.T) {
|
|||||||
l2Tx := &L2Tx{
|
l2Tx := &L2Tx{
|
||||||
FromIdx: 87654,
|
FromIdx: 87654,
|
||||||
ToIdx: 300,
|
ToIdx: 300,
|
||||||
|
TokenID: 5,
|
||||||
Amount: big.NewInt(4),
|
Amount: big.NewInt(4),
|
||||||
Nonce: 144,
|
Nonce: 144,
|
||||||
}
|
}
|
||||||
l2Tx, err := NewL2Tx(l2Tx)
|
l2Tx, err := NewL2Tx(l2Tx)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "0x020000000156660000000090", l2Tx.TxID.String())
|
assert.Equal(t, "0x024f67ec893467419cdfacfc9152e55dc7ce16088952bf2b3442732fd046bd031c", l2Tx.TxID.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestL2TxByteParsers(t *testing.T) {
|
func TestL2TxByteParsers(t *testing.T) {
|
||||||
|
|||||||
@@ -102,19 +102,13 @@ func (tx *PoolL2Tx) SetType() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetID sets the ID of the transaction. Uses (FromIdx, Nonce).
|
// SetID sets the ID of the transaction
|
||||||
func (tx *PoolL2Tx) SetID() error {
|
func (tx *PoolL2Tx) SetID() error {
|
||||||
tx.TxID[0] = TxIDPrefixL2Tx
|
txID, err := tx.L2Tx().CalculateTxID()
|
||||||
fromIdxBytes, err := tx.FromIdx.Bytes()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tracerr.Wrap(err)
|
return tracerr.Wrap(err)
|
||||||
}
|
}
|
||||||
copy(tx.TxID[1:7], fromIdxBytes[:])
|
tx.TxID = txID
|
||||||
nonceBytes, err := tx.Nonce.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
return tracerr.Wrap(err)
|
|
||||||
}
|
|
||||||
copy(tx.TxID[7:12], nonceBytes[:])
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +275,8 @@ func (tx *PoolL2Tx) RqTxCompressedDataV2() (*big.Int, error) {
|
|||||||
return bi, nil
|
return bi, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HashToSign returns the computed Poseidon hash from the *PoolL2Tx that will be signed by the sender.
|
// HashToSign returns the computed Poseidon hash from the *PoolL2Tx that will
|
||||||
|
// be signed by the sender.
|
||||||
func (tx *PoolL2Tx) HashToSign(chainID uint16) (*big.Int, error) {
|
func (tx *PoolL2Tx) HashToSign(chainID uint16) (*big.Int, error) {
|
||||||
toCompressedData, err := tx.TxCompressedData(chainID)
|
toCompressedData, err := tx.TxCompressedData(chainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -331,6 +326,7 @@ func (tx PoolL2Tx) L2Tx() L2Tx {
|
|||||||
TxID: tx.TxID,
|
TxID: tx.TxID,
|
||||||
FromIdx: tx.FromIdx,
|
FromIdx: tx.FromIdx,
|
||||||
ToIdx: toIdx,
|
ToIdx: toIdx,
|
||||||
|
TokenID: tx.TokenID,
|
||||||
Amount: tx.Amount,
|
Amount: tx.Amount,
|
||||||
Fee: tx.Fee,
|
Fee: tx.Fee,
|
||||||
Nonce: tx.Nonce,
|
Nonce: tx.Nonce,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func TestNewPoolL2Tx(t *testing.T) {
|
|||||||
}
|
}
|
||||||
poolL2Tx, err := NewPoolL2Tx(poolL2Tx)
|
poolL2Tx, err := NewPoolL2Tx(poolL2Tx)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "0x020000000156660000000090", poolL2Tx.TxID.String())
|
assert.Equal(t, "0x024f67ec893467419cdfacfc9152e55dc7ce16088952bf2b3442732fd046bd031c", poolL2Tx.TxID.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTxCompressedData(t *testing.T) {
|
func TestTxCompressedData(t *testing.T) {
|
||||||
@@ -170,3 +170,53 @@ func TestDecompressEmptyBJJComp(t *testing.T) {
|
|||||||
assert.Equal(t, "2957874849018779266517920829765869116077630550401372566248359756137677864698", pk.X.String())
|
assert.Equal(t, "2957874849018779266517920829765869116077630550401372566248359756137677864698", pk.X.String())
|
||||||
assert.Equal(t, "0", pk.Y.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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const (
|
|||||||
TxIDPrefixL2Tx = byte(2)
|
TxIDPrefixL2Tx = byte(2)
|
||||||
|
|
||||||
// TxIDLen is the length of the TxID byte array
|
// TxIDLen is the length of the TxID byte array
|
||||||
TxIDLen = 12
|
TxIDLen = 33
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ func TestSignatureConstant(t *testing.T) {
|
|||||||
func TestTxIDScannerValue(t *testing.T) {
|
func TestTxIDScannerValue(t *testing.T) {
|
||||||
txid0 := &TxID{}
|
txid0 := &TxID{}
|
||||||
txid1 := &TxID{}
|
txid1 := &TxID{}
|
||||||
txid0B := [12]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
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 := [12]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
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(txid0[:], txid0B[:])
|
||||||
copy(txid1[:], txid1B[:])
|
copy(txid1[:], txid1B[:])
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ func TestTxIDScannerValue(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTxIDMarshalers(t *testing.T) {
|
func TestTxIDMarshalers(t *testing.T) {
|
||||||
h := []byte("0x00000000000001e240004700")
|
h := []byte("0x02f8b4197b990fcef7ab11021675b4532e584b2c6b3f32562a5128ff00dceb9a5b")
|
||||||
var txid TxID
|
var txid TxID
|
||||||
err := txid.UnmarshalText(h)
|
err := txid.UnmarshalText(h)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
@@ -906,6 +906,7 @@ func (hdb *HistoryDB) addL2Txs(d meddler.DB, l2txs []common.L2Tx) error {
|
|||||||
FromIdx: &l2txs[i].FromIdx,
|
FromIdx: &l2txs[i].FromIdx,
|
||||||
EffectiveFromIdx: &l2txs[i].FromIdx,
|
EffectiveFromIdx: &l2txs[i].FromIdx,
|
||||||
ToIdx: l2txs[i].ToIdx,
|
ToIdx: l2txs[i].ToIdx,
|
||||||
|
TokenID: l2txs[i].TokenID,
|
||||||
Amount: l2txs[i].Amount,
|
Amount: l2txs[i].Amount,
|
||||||
AmountFloat: amountFloat,
|
AmountFloat: amountFloat,
|
||||||
BatchNum: &l2txs[i].BatchNum,
|
BatchNum: &l2txs[i].BatchNum,
|
||||||
@@ -1278,8 +1279,8 @@ func (hdb *HistoryDB) GetAllL2Txs() ([]common.L2Tx, error) {
|
|||||||
err := meddler.QueryAll(
|
err := meddler.QueryAll(
|
||||||
hdb.db, &txs,
|
hdb.db, &txs,
|
||||||
`SELECT tx.id, tx.batch_num, tx.position,
|
`SELECT tx.id, tx.batch_num, tx.position,
|
||||||
tx.from_idx, tx.to_idx, tx.amount, tx.fee, tx.nonce,
|
tx.from_idx, tx.to_idx, tx.amount, tx.token_id,
|
||||||
tx.type, tx.eth_block_num
|
tx.fee, tx.nonce, tx.type, tx.eth_block_num
|
||||||
FROM tx WHERE is_l1 = FALSE ORDER BY item_id;`,
|
FROM tx WHERE is_l1 = FALSE ORDER BY item_id;`,
|
||||||
)
|
)
|
||||||
return db.SlicePtrsToSlice(txs).([]common.L2Tx), tracerr.Wrap(err)
|
return db.SlicePtrsToSlice(txs).([]common.L2Tx), tracerr.Wrap(err)
|
||||||
|
|||||||
@@ -484,16 +484,16 @@ func TestTxs(t *testing.T) {
|
|||||||
assert.Equal(t, common.TxTypeCreateAccountDeposit, dbL1Txs[9].Type)
|
assert.Equal(t, common.TxTypeCreateAccountDeposit, dbL1Txs[9].Type)
|
||||||
|
|
||||||
// Tx ID
|
// Tx ID
|
||||||
assert.Equal(t, "0x000000000000000001000000", dbL1Txs[0].TxID.String())
|
assert.Equal(t, "0x00c4f3fb5c0f7f76b3fe0a74a6ae7472e6a5ef9d66db08df7d0a7e4980c578c55a", dbL1Txs[0].TxID.String())
|
||||||
assert.Equal(t, "0x000000000000000001000100", dbL1Txs[1].TxID.String())
|
assert.Equal(t, "0x00b0c7398bfd31f7a6c0b4d3f80c73cfe9cdb541bdb6eccc6b9097976f9535fb01", dbL1Txs[1].TxID.String())
|
||||||
assert.Equal(t, "0x000000000000000003000000", dbL1Txs[2].TxID.String())
|
assert.Equal(t, "0x00bc12304d5d1aca95c356394bfa2e331e4ccb21e250c6a7442d92e02371eca9ff", dbL1Txs[2].TxID.String())
|
||||||
assert.Equal(t, "0x000000000000000005000000", dbL1Txs[3].TxID.String())
|
assert.Equal(t, "0x0063077b5c07999b460aa31dc3ea300f5923afa08f117e8ed7476aae299ed4b74b", dbL1Txs[3].TxID.String())
|
||||||
assert.Equal(t, "0x000000000000000005000100", dbL1Txs[4].TxID.String())
|
assert.Equal(t, "0x003f8b27b160e7b98ee5275de5ace264ae45891ac219a1b7c03863b5a764176b03", dbL1Txs[4].TxID.String())
|
||||||
assert.Equal(t, "0x000000000000000005000200", dbL1Txs[5].TxID.String())
|
assert.Equal(t, "0x00937115a38e1c049aab568b3281e005c206a3e18e87400ce6c62c83599a3bafbd", dbL1Txs[5].TxID.String())
|
||||||
assert.Equal(t, "0x000000000000000006000000", dbL1Txs[6].TxID.String())
|
assert.Equal(t, "0x006118820894c0acdc230d65fe739a4082c9eed3be1f5020f544d855e36dc4eae6", dbL1Txs[6].TxID.String())
|
||||||
assert.Equal(t, "0x000000000000000006000100", dbL1Txs[7].TxID.String())
|
assert.Equal(t, "0x003e5aede622ad4ebbc436d178eb83d15f8b38614eda6e90b1acb88034a0eb177d", dbL1Txs[7].TxID.String())
|
||||||
assert.Equal(t, "0x000000000000000008000000", dbL1Txs[8].TxID.String())
|
assert.Equal(t, "0x007682bb57dfd4d2e98a5c7836d0dc92bee86edefad6db6ad123415991d79fd69d", dbL1Txs[8].TxID.String())
|
||||||
assert.Equal(t, "0x000000000000000009000000", dbL1Txs[9].TxID.String())
|
assert.Equal(t, "0x006d068c5ee574706ed23bc357390da1c5bc5e144f51a32dcd38faf50be60813d6", dbL1Txs[9].TxID.String())
|
||||||
|
|
||||||
// Tx From IDx
|
// Tx From IDx
|
||||||
assert.Equal(t, common.Idx(0), dbL1Txs[0].FromIdx)
|
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)
|
assert.Equal(t, common.TxTypeExit, dbL2Txs[3].Type)
|
||||||
|
|
||||||
// Tx ID
|
// Tx ID
|
||||||
assert.Equal(t, "0x020000000001030000000000", dbL2Txs[0].TxID.String())
|
assert.Equal(t, "0x0216d6fd29ec664d30a5db5c11401b79624388acc1c8bdd7ec4d29c9fbc82e6bbd", dbL2Txs[0].TxID.String())
|
||||||
assert.Equal(t, "0x020000000001010000000000", dbL2Txs[1].TxID.String())
|
assert.Equal(t, "0x024a99c757c9ded6156cea463e9e7b1ebed51c323dae1f1dc1bea5068f5c688f3a", dbL2Txs[1].TxID.String())
|
||||||
assert.Equal(t, "0x020000000001000000000000", dbL2Txs[2].TxID.String())
|
assert.Equal(t, "0x0239d316ab550bf8ee20a48f9a89d511baa069207d24ccdc4cfcea0dc04e0659df", dbL2Txs[2].TxID.String())
|
||||||
assert.Equal(t, "0x020000000001000000000001", dbL2Txs[3].TxID.String())
|
assert.Equal(t, "0x02c7233141caf1f99d4d5d2013da01c709e73ee3c9b46f3d5635b02d14e6177a9d", dbL2Txs[3].TxID.String())
|
||||||
|
|
||||||
// Tx From and To IDx
|
// Tx From and To IDx
|
||||||
assert.Equal(t, dbL2Txs[0].ToIdx, dbL2Txs[2].FromIdx)
|
assert.Equal(t, dbL2Txs[0].ToIdx, dbL2Txs[2].FromIdx)
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ func GenL2Txs(
|
|||||||
amount := big.NewInt(int64(i + 1))
|
amount := big.NewInt(int64(i + 1))
|
||||||
fee := common.FeeSelector(i % 256) //nolint:gomnd
|
fee := common.FeeSelector(i % 256) //nolint:gomnd
|
||||||
tx := common.L2Tx{
|
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,
|
BatchNum: batches[i%len(batches)].BatchNum,
|
||||||
Position: i - fromIdx,
|
Position: i - fromIdx,
|
||||||
Amount: amount,
|
Amount: amount,
|
||||||
|
|||||||
@@ -370,7 +370,6 @@ func (tc *Context) generateBlocks() ([]common.BlockData, error) {
|
|||||||
}
|
}
|
||||||
tc.currBatch.L1Batch = true
|
tc.currBatch.L1Batch = true
|
||||||
if err := tc.setIdxs(); err != nil {
|
if err := tc.setIdxs(); err != nil {
|
||||||
log.Error(err)
|
|
||||||
return nil, tracerr.Wrap(err)
|
return nil, tracerr.Wrap(err)
|
||||||
}
|
}
|
||||||
toForgeL1TxsNum := int64(tc.openToForge)
|
toForgeL1TxsNum := int64(tc.openToForge)
|
||||||
@@ -818,6 +817,7 @@ func (tc *Context) FillBlocksForgedL1UserTxs(blocks []common.BlockData) error {
|
|||||||
// - blocks[].Rollup.Batch.L2Txs[].TxID
|
// - blocks[].Rollup.Batch.L2Txs[].TxID
|
||||||
// - blocks[].Rollup.Batch.L2Txs[].Position
|
// - blocks[].Rollup.Batch.L2Txs[].Position
|
||||||
// - blocks[].Rollup.Batch.L2Txs[].Nonce
|
// - blocks[].Rollup.Batch.L2Txs[].Nonce
|
||||||
|
// - blocks[].Rollup.Batch.L2Txs[].TokenID
|
||||||
// - blocks[].Rollup.Batch.ExitTree
|
// - blocks[].Rollup.Batch.ExitTree
|
||||||
// - blocks[].Rollup.Batch.CreatedAccounts
|
// - blocks[].Rollup.Batch.CreatedAccounts
|
||||||
// - blocks[].Rollup.Batch.FeeIdxCoordinator
|
// - blocks[].Rollup.Batch.FeeIdxCoordinator
|
||||||
@@ -915,6 +915,7 @@ func (tc *Context) FillBlocksExtra(blocks []common.BlockData, cfg *ConfigExtra)
|
|||||||
tx.Position = position
|
tx.Position = position
|
||||||
position++
|
position++
|
||||||
tx.Nonce = tc.extra.nonces[tx.FromIdx]
|
tx.Nonce = tc.extra.nonces[tx.FromIdx]
|
||||||
|
tx.TokenID = tc.accountsByIdx[int(tx.FromIdx)].TokenID
|
||||||
tc.extra.nonces[tx.FromIdx]++
|
tc.extra.nonces[tx.FromIdx]++
|
||||||
if err := tx.SetID(); err != nil {
|
if err := tx.SetID(); err != nil {
|
||||||
return tracerr.Wrap(err)
|
return tracerr.Wrap(err)
|
||||||
|
|||||||
Reference in New Issue
Block a user