arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/common/pooll2tx_test.go
common/pooll2tx_test.goRaw
  1package common
  2
  3import (
  4	"encoding/hex"
  5	"math/big"
  6	"testing"
  7
  8	ethCommon "github.com/ethereum/go-ethereum/common"
  9	"github.com/iden3/go-iden3-crypto/babyjub"
 10	"github.com/stretchr/testify/assert"
 11	"github.com/stretchr/testify/require"
 12)
 13
 14func TestNewPoolL2Tx(t *testing.T) {
 15	poolL2Tx := &PoolL2Tx{
 16		FromIdx: 87654,
 17		ToIdx:   300,
 18		Amount:  big.NewInt(4),
 19		TokenID: 5,
 20		Nonce:   144,
 21	}
 22	poolL2Tx, err := NewPoolL2Tx(poolL2Tx)
 23	assert.NoError(t, err)
 24	assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e",
 25		poolL2Tx.TxID.String())
 26}
 27
 28func TestTxCompressedDataAndTxCompressedDataV2JSVectors(t *testing.T) {
 29	// test vectors values generated from javascript implementation
 30	var skPositive babyjub.PrivateKey // 'Positive' refers to the sign
 31	_, err := hex.Decode(skPositive[:],
 32		[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
 33	assert.NoError(t, err)
 34
 35	var skNegative babyjub.PrivateKey // 'Negative' refers to the sign
 36	_, err = hex.Decode(skNegative[:],
 37		[]byte("0001020304050607080900010203040506070809000102030405060708090002"))
 38	assert.NoError(t, err)
 39
 40	amount, ok := new(big.Int).SetString("343597383670000000000000000000000000000000", 10)
 41	require.True(t, ok)
 42	tx := PoolL2Tx{
 43		FromIdx: (1 << 48) - 1,
 44		ToIdx:   (1 << 48) - 1,
 45		Amount:  amount,
 46		TokenID: (1 << 32) - 1,
 47		Nonce:   (1 << 40) - 1,
 48		Fee:     (1 << 3) - 1,
 49		ToBJJ:   skPositive.Public().Compress(),
 50	}
 51	txCompressedData, err := tx.TxCompressedData(uint16((1 << 16) - 1))
 52	require.NoError(t, err)
 53	expectedStr := "0107ffffffffffffffffffffffffffffffffffffffffffffffc60be60f"
 54	assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
 55
 56	txCompressedDataV2, err := tx.TxCompressedDataV2()
 57	require.NoError(t, err)
 58	expectedStr = "0107ffffffffffffffffffffffffffffffffffffffffffffffffffff"
 59	assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedDataV2.Bytes()))
 60
 61	tx = PoolL2Tx{
 62		FromIdx: 0,
 63		ToIdx:   0,
 64		Amount:  big.NewInt(0),
 65		TokenID: 0,
 66		Nonce:   0,
 67		Fee:     0,
 68		ToBJJ:   skNegative.Public().Compress(),
 69	}
 70	txCompressedData, err = tx.TxCompressedData(uint16(0))
 71	require.NoError(t, err)
 72	expectedStr = "c60be60f"
 73	assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
 74
 75	txCompressedDataV2, err = tx.TxCompressedDataV2()
 76	require.NoError(t, err)
 77	assert.Equal(t, "0", txCompressedDataV2.String())
 78
 79	amount, ok = new(big.Int).SetString("63000000000000000", 10)
 80	require.True(t, ok)
 81	tx = PoolL2Tx{
 82		FromIdx: 324,
 83		ToIdx:   256,
 84		Amount:  amount,
 85		TokenID: 123,
 86		Nonce:   76,
 87		Fee:     214,
 88		ToBJJ:   skNegative.Public().Compress(),
 89	}
 90	txCompressedData, err = tx.TxCompressedData(uint16(1))
 91	require.NoError(t, err)
 92	expectedStr = "d6000000004c0000007b0000000001000000000001440001c60be60f"
 93	assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
 94
 95	txCompressedDataV2, err = tx.TxCompressedDataV2()
 96	require.NoError(t, err)
 97	expectedStr = "d6000000004c0000007b3977825f00000000000100000000000144"
 98	assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedDataV2.Bytes()))
 99
100	tx = PoolL2Tx{
101		FromIdx: 1,
102		ToIdx:   2,
103		TokenID: 3,
104		Nonce:   4,
105		Fee:     5,
106		ToBJJ:   skNegative.Public().Compress(),
107	}
108	txCompressedData, err = tx.TxCompressedData(uint16(0))
109	require.NoError(t, err)
110	expectedStr = "050000000004000000030000000000020000000000010000c60be60f"
111	assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
112
113	tx = PoolL2Tx{
114		FromIdx: 2,
115		ToIdx:   3,
116		TokenID: 4,
117		Nonce:   5,
118		Fee:     6,
119		ToBJJ:   skPositive.Public().Compress(),
120	}
121	txCompressedData, err = tx.TxCompressedData(uint16(0))
122	require.NoError(t, err)
123	expectedStr = "01060000000005000000040000000000030000000000020000c60be60f"
124	assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
125}
126
127func TestRqTxCompressedDataV2(t *testing.T) {
128	var sk babyjub.PrivateKey
129	_, err := hex.Decode(sk[:],
130		[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
131	assert.NoError(t, err)
132	tx := PoolL2Tx{
133		RqFromIdx: 7,
134		RqToIdx:   8,
135		RqAmount:  big.NewInt(9),
136		RqTokenID: 10,
137		RqNonce:   11,
138		RqFee:     12,
139		RqToBJJ:   sk.Public().Compress(),
140	}
141	txCompressedData, err := tx.RqTxCompressedDataV2()
142	assert.NoError(t, err)
143	// test vector value generated from javascript implementation
144	expectedStr := "110248805340524920412994530176819463725852160917809517418728390663"
145	assert.Equal(t, expectedStr, txCompressedData.String())
146	expected, ok := new(big.Int).SetString(expectedStr, 10)
147	assert.True(t, ok)
148	assert.Equal(t, expected.Bytes(), txCompressedData.Bytes())
149	assert.Equal(t, "010c000000000b0000000a0000000009000000000008000000000007",
150		hex.EncodeToString(txCompressedData.Bytes()))
151}
152
153func TestHashToSign(t *testing.T) {
154	chainID := uint16(0)
155	tx := PoolL2Tx{
156		FromIdx:   2,
157		ToIdx:     3,
158		Amount:    big.NewInt(4),
159		TokenID:   5,
160		Nonce:     6,
161		ToEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
162	}
163	toSign, err := tx.HashToSign(chainID)
164	assert.NoError(t, err)
165	assert.Equal(t, "2d49ce1d4136e06f64e3eb1f79a346e6ee3e93ceeac909a57806a8d87005c263",
166		hex.EncodeToString(toSign.Bytes()))
167}
168
169func TestVerifyTxSignature(t *testing.T) {
170	chainID := uint16(0)
171	var sk babyjub.PrivateKey
172	_, err := hex.Decode(sk[:],
173		[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
174	assert.NoError(t, err)
175	tx := PoolL2Tx{
176		FromIdx:     2,
177		ToIdx:       3,
178		Amount:      big.NewInt(4),
179		TokenID:     5,
180		Nonce:       6,
181		ToBJJ:       sk.Public().Compress(),
182		RqToEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
183		RqToBJJ:     sk.Public().Compress(),
184	}
185	toSign, err := tx.HashToSign(chainID)
186	assert.NoError(t, err)
187	assert.Equal(t,
188		"1571327027383224465388301747239444557034990637650927918405777653988509342917",
189		toSign.String())
190
191	sig := sk.SignPoseidon(toSign)
192	tx.Signature = sig.Compress()
193	assert.True(t, tx.VerifySignature(chainID, sk.Public().Compress()))
194}
195
196func TestDecompressEmptyBJJComp(t *testing.T) {
197	pkComp := EmptyBJJComp
198	pk, err := pkComp.Decompress()
199	require.NoError(t, err)
200	assert.Equal(t,
201		"2957874849018779266517920829765869116077630550401372566248359756137677864698",
202		pk.X.String())
203	assert.Equal(t, "0", pk.Y.String())
204}
205
206func TestPoolL2TxID(t *testing.T) {
207	tx0 := PoolL2Tx{
208		FromIdx: 5,
209		ToIdx:   5,
210		Amount:  big.NewInt(5),
211		Fee:     126,
212		TokenID: 5,
213		Nonce:   5,
214	}
215	err := tx0.SetID()
216	require.NoError(t, err)
217
218	// differ TokenID
219	tx1 := PoolL2Tx{
220		FromIdx: 5,
221		ToIdx:   5,
222		Amount:  big.NewInt(5),
223		Fee:     126,
224		TokenID: 4,
225		Nonce:   5,
226	}
227	err = tx1.SetID()
228	require.NoError(t, err)
229	assert.NotEqual(t, tx0.TxID, tx1.TxID)
230	// differ Nonce
231	tx1 = PoolL2Tx{
232		FromIdx: 5,
233		ToIdx:   5,
234		Amount:  big.NewInt(5),
235		Fee:     126,
236		TokenID: 5,
237		Nonce:   4,
238	}
239	err = tx1.SetID()
240	require.NoError(t, err)
241	assert.NotEqual(t, tx0.TxID, tx1.TxID)
242	// differ Fee
243	tx1 = PoolL2Tx{
244		FromIdx: 5,
245		ToIdx:   5,
246		Amount:  big.NewInt(5),
247		Fee:     124,
248		TokenID: 5,
249		Nonce:   5,
250	}
251	err = tx1.SetID()
252	require.NoError(t, err)
253	assert.NotEqual(t, tx0.TxID, tx1.TxID)
254}