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