hermez-node/apitypes/apitypes_test.go
apitypes/apitypes_test.goRaw
1package apitypes
2
3import (
4 "database/sql"
5 "encoding/json"
6 "io/ioutil"
7 "math/big"
8 "os"
9 "testing"
10
11 ethCommon "github.com/ethereum/go-ethereum/common"
12 "github.com/hermeznetwork/hermez-node/common"
13 dbUtils "github.com/hermeznetwork/hermez-node/db"
14 "github.com/iden3/go-iden3-crypto/babyjub"
15 _ "github.com/mattn/go-sqlite3" //nolint sqlite driver
16 "github.com/russross/meddler"
17 "github.com/stretchr/testify/assert"
18)
19
20var db *sql.DB
21
22func TestMain(m *testing.M) {
23 // Register meddler
24 meddler.Default = meddler.SQLite
25 meddler.Register("bigint", dbUtils.BigIntMeddler{})
26 meddler.Register("bigintnull", dbUtils.BigIntNullMeddler{})
27 // Create temporary sqlite DB
28 dir, err := ioutil.TempDir("", "db")
29 if err != nil {
30 panic(err)
31 }
32 db, err = sql.Open("sqlite3", dir+"sqlite.db")
33 if err != nil {
34 panic(err)
35 }
36 defer os.RemoveAll(dir) //nolint
37 schema := `CREATE TABLE test (i BLOB);`
38 if _, err := db.Exec(schema); err != nil {
39 panic(err)
40 }
41 // Run tests
42 result := m.Run()
43 os.Exit(result)
44}
45
46func TestBigIntStrScannerValuer(t *testing.T) {
47 // Clean DB
48 _, err := db.Exec("delete from test")
49 assert.NoError(t, err)
50 // Example structs
51 type bigInMeddlerStruct struct {
52 I *big.Int `meddler:"i,bigint"` // note the bigint that instructs meddler to use BigIntMeddler
53 }
54 type bigIntStrStruct struct {
55 I BigIntStr `meddler:"i"` // note that no meddler is specified, and Scan/Value will be used
56 }
57 type bigInMeddlerStructNil struct {
58 I *big.Int `meddler:"i,bigintnull"` // note the bigint that instructs meddler to use BigIntNullMeddler
59 }
60 type bigIntStrStructNil struct {
61 I *BigIntStr `meddler:"i"` // note that no meddler is specified, and Scan/Value will be used
62 }
63
64 // Not nil case
65 // Insert into DB using meddler
66 const x = int64(12345)
67 fromMeddler := bigInMeddlerStruct{
68 I: big.NewInt(x),
69 }
70 err = meddler.Insert(db, "test", &fromMeddler)
71 assert.NoError(t, err)
72 // Read from DB using BigIntStr
73 toBigIntStr := bigIntStrStruct{}
74 err = meddler.QueryRow(db, &toBigIntStr, "select * from test")
75 assert.NoError(t, err)
76 assert.Equal(t, fromMeddler.I.String(), string(toBigIntStr.I))
77 // Clean DB
78 _, err = db.Exec("delete from test")
79 assert.NoError(t, err)
80 // Insert into DB using BigIntStr
81 fromBigIntStr := bigIntStrStruct{
82 I: "54321",
83 }
84 err = meddler.Insert(db, "test", &fromBigIntStr)
85 assert.NoError(t, err)
86 // Read from DB using meddler
87 toMeddler := bigInMeddlerStruct{}
88 err = meddler.QueryRow(db, &toMeddler, "select * from test")
89 assert.NoError(t, err)
90 assert.Equal(t, string(fromBigIntStr.I), toMeddler.I.String())
91
92 // Nil case
93 // Clean DB
94 _, err = db.Exec("delete from test")
95 assert.NoError(t, err)
96 // Insert into DB using meddler
97 fromMeddlerNil := bigInMeddlerStructNil{
98 I: nil,
99 }
100 err = meddler.Insert(db, "test", &fromMeddlerNil)
101 assert.NoError(t, err)
102 // Read from DB using BigIntStr
103 foo := BigIntStr("foo")
104 toBigIntStrNil := bigIntStrStructNil{
105 I: &foo, // check that this will be set to nil, not because of not being initialized
106 }
107 err = meddler.QueryRow(db, &toBigIntStrNil, "select * from test")
108 assert.NoError(t, err)
109 assert.Nil(t, toBigIntStrNil.I)
110 // Clean DB
111 _, err = db.Exec("delete from test")
112 assert.NoError(t, err)
113 // Insert into DB using BigIntStr
114 fromBigIntStrNil := bigIntStrStructNil{
115 I: nil,
116 }
117 err = meddler.Insert(db, "test", &fromBigIntStrNil)
118 assert.NoError(t, err)
119 // Read from DB using meddler
120 toMeddlerNil := bigInMeddlerStructNil{
121 I: big.NewInt(x), // check that this will be set to nil, not because of not being initialized
122 }
123 err = meddler.QueryRow(db, &toMeddlerNil, "select * from test")
124 assert.NoError(t, err)
125 assert.Nil(t, toMeddlerNil.I)
126}
127
128func TestStrBigInt(t *testing.T) {
129 type testStrBigInt struct {
130 I StrBigInt
131 }
132 from := []byte(`{"I":"4"}`)
133 to := &testStrBigInt{}
134 assert.NoError(t, json.Unmarshal(from, to))
135 assert.Equal(t, big.NewInt(4), (*big.Int)(&to.I))
136}
137
138func TestStrHezEthAddr(t *testing.T) {
139 type testStrHezEthAddr struct {
140 I StrHezEthAddr
141 }
142 withoutHez := "0xaa942cfcd25ad4d90a62358b0dd84f33b398262a"
143 from := []byte(`{"I":"hez:` + withoutHez + `"}`)
144 var addr ethCommon.Address
145 if err := addr.UnmarshalText([]byte(withoutHez)); err != nil {
146 panic(err)
147 }
148 to := &testStrHezEthAddr{}
149 assert.NoError(t, json.Unmarshal(from, to))
150 assert.Equal(t, addr, ethCommon.Address(to.I))
151}
152
153func TestStrHezBJJ(t *testing.T) {
154 type testStrHezBJJ struct {
155 I StrHezBJJ
156 }
157 priv := babyjub.NewRandPrivKey()
158 hezBjj := NewHezBJJ(priv.Public())
159 from := []byte(`{"I":"` + hezBjj + `"}`)
160 to := &testStrHezBJJ{}
161 assert.NoError(t, json.Unmarshal(from, to))
162 assert.Equal(t, priv.Public(), (*babyjub.PublicKey)(&to.I))
163}
164
165func TestStrHezIdx(t *testing.T) {
166 type testStrHezIdx struct {
167 I StrHezIdx
168 }
169 from := []byte(`{"I":"hez:foo:4"}`)
170 to := &testStrHezIdx{}
171 assert.NoError(t, json.Unmarshal(from, to))
172 assert.Equal(t, common.Idx(4), common.Idx(to.I))
173}
174
175func TestHezEthAddr(t *testing.T) {
176 // Clean DB
177 _, err := db.Exec("delete from test")
178 assert.NoError(t, err)
179 // Example structs
180 type ethAddrStruct struct {
181 I ethCommon.Address `meddler:"i"`
182 }
183 type hezEthAddrStruct struct {
184 I HezEthAddr `meddler:"i"`
185 }
186 type ethAddrStructNil struct {
187 I *ethCommon.Address `meddler:"i"`
188 }
189 type hezEthAddrStructNil struct {
190 I *HezEthAddr `meddler:"i"`
191 }
192
193 // Not nil case
194 // Insert into DB using ethCommon.Address Scan/Value
195 fromEth := ethAddrStruct{
196 I: ethCommon.BigToAddress(big.NewInt(73737373)),
197 }
198 err = meddler.Insert(db, "test", &fromEth)
199 assert.NoError(t, err)
200 // Read from DB using HezEthAddr Scan/Value
201 toHezEth := hezEthAddrStruct{}
202 err = meddler.QueryRow(db, &toHezEth, "select * from test")
203 assert.NoError(t, err)
204 assert.Equal(t, NewHezEthAddr(fromEth.I), toHezEth.I)
205 // Clean DB
206 _, err = db.Exec("delete from test")
207 assert.NoError(t, err)
208 // Insert into DB using HezEthAddr Scan/Value
209 fromHezEth := hezEthAddrStruct{
210 I: NewHezEthAddr(ethCommon.BigToAddress(big.NewInt(3786872586))),
211 }
212 err = meddler.Insert(db, "test", &fromHezEth)
213 assert.NoError(t, err)
214 // Read from DB using ethCommon.Address Scan/Value
215 toEth := ethAddrStruct{}
216 err = meddler.QueryRow(db, &toEth, "select * from test")
217 assert.NoError(t, err)
218 assert.Equal(t, fromHezEth.I, NewHezEthAddr(toEth.I))
219
220 // Nil case
221 // Clean DB
222 _, err = db.Exec("delete from test")
223 assert.NoError(t, err)
224 // Insert into DB using ethCommon.Address Scan/Value
225 fromEthNil := ethAddrStructNil{
226 I: nil,
227 }
228 err = meddler.Insert(db, "test", &fromEthNil)
229 assert.NoError(t, err)
230 // Read from DB using HezEthAddr Scan/Value
231 foo := HezEthAddr("foo")
232 toHezEthNil := hezEthAddrStructNil{
233 I: &foo, // check that this will be set to nil, not because of not being initialized
234 }
235 err = meddler.QueryRow(db, &toHezEthNil, "select * from test")
236 assert.NoError(t, err)
237 assert.Nil(t, toHezEthNil.I)
238 // Clean DB
239 _, err = db.Exec("delete from test")
240 assert.NoError(t, err)
241 // Insert into DB using HezEthAddr Scan/Value
242 fromHezEthNil := hezEthAddrStructNil{
243 I: nil,
244 }
245 err = meddler.Insert(db, "test", &fromHezEthNil)
246 assert.NoError(t, err)
247 // Read from DB using ethCommon.Address Scan/Value
248 fooAddr := ethCommon.BigToAddress(big.NewInt(1))
249 toEthNil := ethAddrStructNil{
250 I: &fooAddr, // check that this will be set to nil, not because of not being initialized
251 }
252 err = meddler.QueryRow(db, &toEthNil, "select * from test")
253 assert.NoError(t, err)
254 assert.Nil(t, toEthNil.I)
255}
256
257func TestHezBJJ(t *testing.T) {
258 // Clean DB
259 _, err := db.Exec("delete from test")
260 assert.NoError(t, err)
261 // Example structs
262 type bjjStruct struct {
263 I *babyjub.PublicKey `meddler:"i"`
264 }
265 type hezBJJStruct struct {
266 I HezBJJ `meddler:"i"`
267 }
268 type hezBJJStructNil struct {
269 I *HezBJJ `meddler:"i"`
270 }
271
272 // Not nil case
273 // Insert into DB using *babyjub.PublicKey Scan/Value
274 priv := babyjub.NewRandPrivKey()
275 fromBJJ := bjjStruct{
276 I: priv.Public(),
277 }
278 err = meddler.Insert(db, "test", &fromBJJ)
279 assert.NoError(t, err)
280 // Read from DB using HezBJJ Scan/Value
281 toHezBJJ := hezBJJStruct{}
282 err = meddler.QueryRow(db, &toHezBJJ, "select * from test")
283 assert.NoError(t, err)
284 assert.Equal(t, NewHezBJJ(fromBJJ.I), toHezBJJ.I)
285 // Clean DB
286 _, err = db.Exec("delete from test")
287 assert.NoError(t, err)
288 // Insert into DB using HezBJJ Scan/Value
289 fromHezBJJ := hezBJJStruct{
290 I: NewHezBJJ(priv.Public()),
291 }
292 err = meddler.Insert(db, "test", &fromHezBJJ)
293 assert.NoError(t, err)
294 // Read from DB using *babyjub.PublicKey Scan/Value
295 toBJJ := bjjStruct{}
296 err = meddler.QueryRow(db, &toBJJ, "select * from test")
297 assert.NoError(t, err)
298 assert.Equal(t, fromHezBJJ.I, NewHezBJJ(toBJJ.I))
299
300 // Nil case
301 // Clean DB
302 _, err = db.Exec("delete from test")
303 assert.NoError(t, err)
304 // Insert into DB using *babyjub.PublicKey Scan/Value
305 fromBJJNil := bjjStruct{
306 I: nil,
307 }
308 err = meddler.Insert(db, "test", &fromBJJNil)
309 assert.NoError(t, err)
310 // Read from DB using HezBJJ Scan/Value
311 foo := HezBJJ("foo")
312 toHezBJJNil := hezBJJStructNil{
313 I: &foo, // check that this will be set to nil, not because of not being initialized
314 }
315 err = meddler.QueryRow(db, &toHezBJJNil, "select * from test")
316 assert.NoError(t, err)
317 assert.Nil(t, toHezBJJNil.I)
318 // Clean DB
319 _, err = db.Exec("delete from test")
320 assert.NoError(t, err)
321 // Insert into DB using HezBJJ Scan/Value
322 fromHezBJJNil := hezBJJStructNil{
323 I: nil,
324 }
325 err = meddler.Insert(db, "test", &fromHezBJJNil)
326 assert.NoError(t, err)
327 // Read from DB using *babyjub.PublicKey Scan/Value
328 toBJJNil := bjjStruct{
329 I: priv.Public(), // check that this will be set to nil, not because of not being initialized
330 }
331 err = meddler.QueryRow(db, &toBJJNil, "select * from test")
332 assert.NoError(t, err)
333 assert.Nil(t, toBJJNil.I)
334}
335
336func TestEthSignature(t *testing.T) {
337 // Clean DB
338 _, err := db.Exec("delete from test")
339 assert.NoError(t, err)
340 // Example structs
341 type ethSignStruct struct {
342 I []byte `meddler:"i"`
343 }
344 type hezEthSignStruct struct {
345 I EthSignature `meddler:"i"`
346 }
347 type hezEthSignStructNil struct {
348 I *EthSignature `meddler:"i"`
349 }
350
351 // Not nil case
352 // Insert into DB using []byte Scan/Value
353 s := "someRandomFooForYou"
354 fromEth := ethSignStruct{
355 I: []byte(s),
356 }
357 err = meddler.Insert(db, "test", &fromEth)
358 assert.NoError(t, err)
359 // Read from DB using EthSignature Scan/Value
360 toHezEth := hezEthSignStruct{}
361 err = meddler.QueryRow(db, &toHezEth, "select * from test")
362 assert.NoError(t, err)
363 assert.Equal(t, NewEthSignature(fromEth.I), &toHezEth.I)
364 // Clean DB
365 _, err = db.Exec("delete from test")
366 assert.NoError(t, err)
367 // Insert into DB using EthSignature Scan/Value
368 fromHezEth := hezEthSignStruct{
369 I: *NewEthSignature([]byte(s)),
370 }
371 err = meddler.Insert(db, "test", &fromHezEth)
372 assert.NoError(t, err)
373 // Read from DB using []byte Scan/Value
374 toEth := ethSignStruct{}
375 err = meddler.QueryRow(db, &toEth, "select * from test")
376 assert.NoError(t, err)
377 assert.Equal(t, &fromHezEth.I, NewEthSignature(toEth.I))
378
379 // Nil case
380 // Clean DB
381 _, err = db.Exec("delete from test")
382 assert.NoError(t, err)
383 // Insert into DB using []byte Scan/Value
384 fromEthNil := ethSignStruct{
385 I: nil,
386 }
387 err = meddler.Insert(db, "test", &fromEthNil)
388 assert.NoError(t, err)
389 // Read from DB using EthSignature Scan/Value
390 foo := EthSignature("foo")
391 toHezEthNil := hezEthSignStructNil{
392 I: &foo, // check that this will be set to nil, not because of not being initialized
393 }
394 err = meddler.QueryRow(db, &toHezEthNil, "select * from test")
395 assert.NoError(t, err)
396 assert.Nil(t, toHezEthNil.I)
397 // Clean DB
398 _, err = db.Exec("delete from test")
399 assert.NoError(t, err)
400 // Insert into DB using EthSignature Scan/Value
401 fromHezEthNil := hezEthSignStructNil{
402 I: nil,
403 }
404 err = meddler.Insert(db, "test", &fromHezEthNil)
405 assert.NoError(t, err)
406 // Read from DB using []byte Scan/Value
407 toEthNil := ethSignStruct{
408 I: []byte(s), // check that this will be set to nil, not because of not being initialized
409 }
410 err = meddler.QueryRow(db, &toEthNil, "select * from test")
411 assert.NoError(t, err)
412 assert.Nil(t, toEthNil.I)
413}