You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
9.5 KiB

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