mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-06 19:06:42 +01:00
Update TxID to avoid collisions on DB (fix #503)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
txID, err := tx.L2Tx().CalculateTxID()
|
||||
if err != nil {
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
copy(tx.TxID[1:7], fromIdxBytes[:])
|
||||
nonceBytes, err := tx.Nonce.Bytes()
|
||||
if err != nil {
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
copy(tx.TxID[7:12], nonceBytes[:])
|
||||
tx.TxID = txID
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ const (
|
||||
TxIDPrefixL2Tx = byte(2)
|
||||
|
||||
// TxIDLen is the length of the TxID byte array
|
||||
TxIDLen = 12
|
||||
TxIDLen = 33
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user