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
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())
161 from := []byte(`{"I":"` + hezBjj + `"}`)
162 to := &testStrHezBJJ{}
163 assert.NoError(t, json.Unmarshal(from, to))
164 assert.Equal(t, priv.Public(), (*babyjub.PublicKey)(&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.PublicKey `meddler:"i"`
266 }
267 type hezBJJStruct struct {
268 I HezBJJ `meddler:"i"`
269 }
270 type hezBJJStructNil struct {
271 I *HezBJJ `meddler:"i"`
272 }
273
274 // Not nil case
275 // Insert into DB using *babyjub.PublicKey Scan/Value
276 priv := babyjub.NewRandPrivKey()
277 fromBJJ := bjjStruct{
278 I: priv.Public(),
279 }
280 err = meddler.Insert(db, "test", &fromBJJ)
281 assert.NoError(t, err)
282 // Read from DB using HezBJJ Scan/Value
283 toHezBJJ := hezBJJStruct{}
284 err = meddler.QueryRow(db, &toHezBJJ, "select * from test")
285 assert.NoError(t, err)
286 assert.Equal(t, NewHezBJJ(fromBJJ.I), toHezBJJ.I)
287 // Clean DB
288 _, err = db.Exec("delete from test")
289 assert.NoError(t, err)
290 // Insert into DB using HezBJJ Scan/Value
291 fromHezBJJ := hezBJJStruct{
292 I: NewHezBJJ(priv.Public()),
293 }
294 err = meddler.Insert(db, "test", &fromHezBJJ)
295 assert.NoError(t, err)
296 // Read from DB using *babyjub.PublicKey Scan/Value
297 toBJJ := bjjStruct{}
298 err = meddler.QueryRow(db, &toBJJ, "select * from test")
299 assert.NoError(t, err)
300 assert.Equal(t, fromHezBJJ.I, NewHezBJJ(toBJJ.I))
301
302 // Nil case
303 // Clean DB
304 _, err = db.Exec("delete from test")
305 assert.NoError(t, err)
306 // Insert into DB using *babyjub.PublicKey Scan/Value
307 fromBJJNil := bjjStruct{
308 I: nil,
309 }
310 err = meddler.Insert(db, "test", &fromBJJNil)
311 assert.NoError(t, err)
312 // Read from DB using HezBJJ Scan/Value
313 foo := HezBJJ("foo")
314 toHezBJJNil := hezBJJStructNil{
315 I: &foo, // check that this will be set to nil, not because of not being initialized
316 }
317 err = meddler.QueryRow(db, &toHezBJJNil, "select * from test")
318 assert.NoError(t, err)
319 assert.Nil(t, toHezBJJNil.I)
320 // Clean DB
321 _, err = db.Exec("delete from test")
322 assert.NoError(t, err)
323 // Insert into DB using HezBJJ Scan/Value
324 fromHezBJJNil := hezBJJStructNil{
325 I: nil,
326 }
327 err = meddler.Insert(db, "test", &fromHezBJJNil)
328 assert.NoError(t, err)
329 // Read from DB using *babyjub.PublicKey Scan/Value
330 toBJJNil := bjjStruct{
331 I: priv.Public(), // check that this will be set to nil, not because of not being initialized
332 }
333 err = meddler.QueryRow(db, &toBJJNil, "select * from test")
334 assert.NoError(t, err)
335 assert.Nil(t, toBJJNil.I)
336}
337
338func TestEthSignature(t *testing.T) {
339 // Clean DB
340 _, err := db.Exec("delete from test")
341 assert.NoError(t, err)
342 // Example structs
343 type ethSignStruct struct {
344 I []byte `meddler:"i"`
345 }
346 type hezEthSignStruct struct {
347 I EthSignature `meddler:"i"`
348 }
349 type hezEthSignStructNil struct {
350 I *EthSignature `meddler:"i"`
351 }
352
353 // Not nil case
354 // Insert into DB using []byte Scan/Value
355 s := "someRandomFooForYou"
356 fromEth := ethSignStruct{
357 I: []byte(s),
358 }
359 err = meddler.Insert(db, "test", &fromEth)
360 assert.NoError(t, err)
361 // Read from DB using EthSignature Scan/Value
362 toHezEth := hezEthSignStruct{}
363 err = meddler.QueryRow(db, &toHezEth, "select * from test")
364 assert.NoError(t, err)
365 assert.Equal(t, NewEthSignature(fromEth.I), &toHezEth.I)
366 // Clean DB
367 _, err = db.Exec("delete from test")
368 assert.NoError(t, err)
369 // Insert into DB using EthSignature Scan/Value
370 fromHezEth := hezEthSignStruct{
371 I: *NewEthSignature([]byte(s)),
372 }
373 err = meddler.Insert(db, "test", &fromHezEth)
374 assert.NoError(t, err)
375 // Read from DB using []byte Scan/Value
376 toEth := ethSignStruct{}
377 err = meddler.QueryRow(db, &toEth, "select * from test")
378 assert.NoError(t, err)
379 assert.Equal(t, &fromHezEth.I, NewEthSignature(toEth.I))
380
381 // Nil case
382 // Clean DB
383 _, err = db.Exec("delete from test")
384 assert.NoError(t, err)
385 // Insert into DB using []byte Scan/Value
386 fromEthNil := ethSignStruct{
387 I: nil,
388 }
389 err = meddler.Insert(db, "test", &fromEthNil)
390 assert.NoError(t, err)
391 // Read from DB using EthSignature Scan/Value
392 foo := EthSignature("foo")
393 toHezEthNil := hezEthSignStructNil{
394 I: &foo, // check that this will be set to nil, not because of not being initialized
395 }
396 err = meddler.QueryRow(db, &toHezEthNil, "select * from test")
397 assert.NoError(t, err)
398 assert.Nil(t, toHezEthNil.I)
399 // Clean DB
400 _, err = db.Exec("delete from test")
401 assert.NoError(t, err)
402 // Insert into DB using EthSignature Scan/Value
403 fromHezEthNil := hezEthSignStructNil{
404 I: nil,
405 }
406 err = meddler.Insert(db, "test", &fromHezEthNil)
407 assert.NoError(t, err)
408 // Read from DB using []byte Scan/Value
409 toEthNil := ethSignStruct{
410 I: []byte(s), // check that this will be set to nil, not because of not being initialized
411 }
412 err = meddler.QueryRow(db, &toEthNil, "select * from test")
413 assert.NoError(t, err)
414 assert.Nil(t, toEthNil.I)
415}