Browse Source

Update TxID to avoid collisions on DB (fix #503)

feature/sql-semaphore1
arnaucube 3 years ago
parent
commit
aade6220d4
14 changed files with 220 additions and 59 deletions
  1. +9
    -9
      api/api_test.go
  2. +3
    -3
      api/txshistory_test.go
  3. +5
    -5
      api/txspool_test.go
  4. +17
    -3
      common/l1tx.go
  5. +68
    -2
      common/l1tx_test.go
  6. +42
    -6
      common/l2tx.go
  7. +2
    -1
      common/l2tx_test.go
  8. +3
    -9
      common/pooll2tx.go
  9. +51
    -1
      common/pooll2tx_test.go
  10. +1
    -1
      common/tx.go
  11. +4
    -3
      common/tx_test.go
  12. +14
    -14
      db/historydb/historydb_test.go
  13. +1
    -1
      test/historydb.go
  14. +0
    -1
      test/til/txs.go

+ 9
- 9
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

+ 3
- 3
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)
}

+ 5
- 5
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)
}

+ 17
- 3
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
}

+ 68
- 2
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)
}

+ 42
- 6
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

+ 2
- 1
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) {

+ 3
- 9
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
}

+ 51
- 1
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)
}

+ 1
- 1
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 (

+ 4
- 3
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)

+ 14
- 14
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)

+ 1
- 1
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,

+ 0
- 1
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)

Loading…
Cancel
Save