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}