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