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 TestVerifyTxSignatureEthAddrWith0(t *testing.T) {
197	chainID := uint16(5)
198	var sk babyjub.PrivateKey
199	_, err := hex.Decode(sk[:],
200		[]byte("02f0b4f87065af3797aaaf934e8b5c31563c17f2272fa71bd0146535bfbb4184"))
201	assert.NoError(t, err)
202	tx := PoolL2Tx{
203		FromIdx:   10659,
204		ToIdx:     0,
205		ToEthAddr: ethCommon.HexToAddress("0x0004308BD15Ead4F1173624dC289DBdcC806a309"),
206		Amount:    big.NewInt(5000),
207		TokenID:   0,
208		Nonce:     946,
209		Fee:       231,
210	}
211	toSign, err := tx.HashToSign(chainID)
212	assert.NoError(t, err)
213
214	sig := sk.SignPoseidon(toSign)
215	assert.Equal(t,
216		"93ce988ecac87908513648d0d021d8ad56d3b504eb38204200f07a8f6c20551de9951397d3051143d4c71203205f8849cd7382d2bcf4bd10092c1e052bb40d01",
217		sig.Compress().String(),
218	)
219	tx.Signature = sig.Compress()
220	assert.True(t, tx.VerifySignature(chainID, sk.Public().Compress()))
221}
222
223func TestDecompressEmptyBJJComp(t *testing.T) {
224	pkComp := EmptyBJJComp
225	pk, err := pkComp.Decompress()
226	require.NoError(t, err)
227	assert.Equal(t,
228		"2957874849018779266517920829765869116077630550401372566248359756137677864698",
229		pk.X.String())
230	assert.Equal(t, "0", pk.Y.String())
231}
232
233func TestPoolL2TxID(t *testing.T) {
234	tx0 := PoolL2Tx{
235		FromIdx: 5,
236		ToIdx:   5,
237		Amount:  big.NewInt(5),
238		Fee:     126,
239		TokenID: 5,
240		Nonce:   5,
241	}
242	err := tx0.SetID()
243	require.NoError(t, err)
244
245	// differ TokenID
246	tx1 := PoolL2Tx{
247		FromIdx: 5,
248		ToIdx:   5,
249		Amount:  big.NewInt(5),
250		Fee:     126,
251		TokenID: 4,
252		Nonce:   5,
253	}
254	err = tx1.SetID()
255	require.NoError(t, err)
256	assert.NotEqual(t, tx0.TxID, tx1.TxID)
257	// differ Nonce
258	tx1 = PoolL2Tx{
259		FromIdx: 5,
260		ToIdx:   5,
261		Amount:  big.NewInt(5),
262		Fee:     126,
263		TokenID: 5,
264		Nonce:   4,
265	}
266	err = tx1.SetID()
267	require.NoError(t, err)
268	assert.NotEqual(t, tx0.TxID, tx1.TxID)
269	// differ Fee
270	tx1 = PoolL2Tx{
271		FromIdx: 5,
272		ToIdx:   5,
273		Amount:  big.NewInt(5),
274		Fee:     124,
275		TokenID: 5,
276		Nonce:   5,
277	}
278	err = tx1.SetID()
279	require.NoError(t, err)
280	assert.NotEqual(t, tx0.TxID, tx1.TxID)
281}