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.

182 lines
5.4 KiB

  1. package l2db
  2. import (
  3. "fmt"
  4. "math/big"
  5. "os"
  6. "strconv"
  7. "testing"
  8. "time"
  9. eth "github.com/ethereum/go-ethereum/common"
  10. "github.com/hermeznetwork/hermez-node/common"
  11. "github.com/iden3/go-iden3-crypto/babyjub"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. var l2DB *L2DB
  15. // In order to run the test you need to run a Posgres DB with
  16. // a database named "l2" that is accessible by
  17. // user: "hermez"
  18. // pass: set it using the env var POSTGRES_PASS
  19. // This can be achieved by running: POSTGRES_PASS=your_strong_pass && sudo docker run --rm --name hermez-db-test -p 5432:5432 -e POSTGRES_DB=history -e POSTGRES_USER=hermez -e POSTGRES_PASSWORD=$POSTGRES_PASS -d postgres && sleep 2s && sudo docker exec -it hermez-db-test psql -a history -U hermez -c "CREATE DATABASE l2;"
  20. // After running the test you can stop the container by running: sudo docker kill hermez-ydb-test
  21. // If you already did that for the HistoryDB you don't have to do it again
  22. func TestMain(m *testing.M) {
  23. // init DB
  24. var err error
  25. pass := os.Getenv("POSTGRES_PASS")
  26. l2DB, err = NewL2DB(5432, "localhost", "hermez", pass, "l2", 10, 512, 24*time.Hour)
  27. if err != nil {
  28. panic(err)
  29. }
  30. // Run tests
  31. result := m.Run()
  32. // Close DB
  33. if err := l2DB.Close(); err != nil {
  34. fmt.Println("Error closing the history DB:", err)
  35. }
  36. os.Exit(result)
  37. }
  38. func TestAddTx(t *testing.T) {
  39. const nInserts = 20
  40. cleanDB()
  41. txs := genTxs(nInserts)
  42. for _, tx := range txs {
  43. err := l2DB.AddTx(tx)
  44. assert.NoError(t, err)
  45. fetchedTx, err := l2DB.GetTx(tx.TxID)
  46. assert.NoError(t, err)
  47. assert.Equal(t, tx.Timestamp.Unix(), fetchedTx.Timestamp.Unix())
  48. tx.Timestamp = fetchedTx.Timestamp
  49. assert.Equal(t, tx.AbsoluteFeeUpdate.Unix(), fetchedTx.AbsoluteFeeUpdate.Unix())
  50. tx.Timestamp = fetchedTx.Timestamp
  51. tx.AbsoluteFeeUpdate = fetchedTx.AbsoluteFeeUpdate
  52. assert.Equal(t, tx, fetchedTx)
  53. }
  54. }
  55. func BenchmarkAddTx(b *testing.B) {
  56. const nInserts = 20
  57. cleanDB()
  58. txs := genTxs(nInserts)
  59. now := time.Now()
  60. for _, tx := range txs {
  61. _ = l2DB.AddTx(tx)
  62. }
  63. elapsedTime := time.Since(now)
  64. fmt.Println("Time to insert 2048 txs:", elapsedTime)
  65. }
  66. func TestGetPending(t *testing.T) {
  67. const nInserts = 20
  68. cleanDB()
  69. txs := genTxs(nInserts)
  70. var pendingTxs []*common.PoolL2Tx
  71. for _, tx := range txs {
  72. err := l2DB.AddTx(tx)
  73. assert.NoError(t, err)
  74. if tx.State == common.PoolL2TxStatePending {
  75. pendingTxs = append(pendingTxs, tx)
  76. }
  77. }
  78. fetchedTxs, err := l2DB.GetPendingTxs()
  79. assert.NoError(t, err)
  80. assert.Equal(t, len(pendingTxs), len(fetchedTxs))
  81. for i, fetchedTx := range fetchedTxs {
  82. assert.Equal(t, pendingTxs[i].Timestamp.Unix(), fetchedTx.Timestamp.Unix())
  83. pendingTxs[i].Timestamp = fetchedTx.Timestamp
  84. assert.Equal(t, pendingTxs[i].AbsoluteFeeUpdate.Unix(), fetchedTx.AbsoluteFeeUpdate.Unix())
  85. pendingTxs[i].AbsoluteFeeUpdate = fetchedTx.AbsoluteFeeUpdate
  86. assert.Equal(t, pendingTxs[i], fetchedTx)
  87. }
  88. }
  89. func TestStartForging(t *testing.T) {
  90. const nInserts = 24
  91. const fakeBlockNum = 33
  92. cleanDB()
  93. txs := genTxs(nInserts)
  94. var startForgingTxs []*common.PoolL2Tx
  95. var startForgingTxIDs []common.TxID
  96. randomizer := 0
  97. for _, tx := range txs {
  98. err := l2DB.AddTx(tx)
  99. assert.NoError(t, err)
  100. if tx.State == common.PoolL2TxStatePending && randomizer%2 == 0 {
  101. randomizer++
  102. startForgingTxs = append(startForgingTxs, tx)
  103. startForgingTxIDs = append(startForgingTxIDs, tx.TxID)
  104. }
  105. if tx.State == common.PoolL2TxStateForging {
  106. startForgingTxs = append(startForgingTxs, tx)
  107. }
  108. }
  109. fmt.Println(startForgingTxs) // TODO added print here to avoid lint complaining about startForgingTxs not being used
  110. err := l2DB.StartForging(startForgingTxIDs, fakeBlockNum)
  111. assert.NoError(t, err)
  112. // TODO: Fetch txs and check that they've been updated correctly
  113. }
  114. func genTxs(n int) []*common.PoolL2Tx {
  115. // WARNING: This tx doesn't follow the protocol (signature, txID, ...)
  116. // it's just to test geting/seting from/to the DB.
  117. // Type and RqTxCompressedData: not initialized because it's not stored
  118. // on the DB and add noise when checking results.
  119. txs := make([]*common.PoolL2Tx, 0, n)
  120. privK := babyjub.NewRandPrivKey()
  121. for i := 0; i < n; i++ {
  122. var state common.PoolL2TxState
  123. if i%4 == 0 {
  124. state = common.PoolL2TxStatePending
  125. } else if i%4 == 1 {
  126. state = common.PoolL2TxStateInvalid
  127. } else if i%4 == 2 {
  128. state = common.PoolL2TxStateForging
  129. } else if i%4 == 3 {
  130. state = common.PoolL2TxStateForged
  131. }
  132. tx := &common.PoolL2Tx{
  133. TxID: common.TxID(common.Hash([]byte(strconv.Itoa(i)))),
  134. FromIdx: 47,
  135. ToIdx: 96,
  136. ToEthAddr: eth.BigToAddress(big.NewInt(234523534)),
  137. ToBJJ: privK.Public(),
  138. TokenID: 73,
  139. Amount: big.NewInt(3487762374627846747),
  140. Fee: 99,
  141. Nonce: 28,
  142. State: state,
  143. Signature: *privK.SignPoseidon(big.NewInt(674238462)),
  144. Timestamp: time.Now().UTC(),
  145. }
  146. if i%2 == 0 { // Optional parameters: rq
  147. tx.RqFromIdx = 893
  148. tx.RqToIdx = 334
  149. tx.RqToEthAddr = eth.BigToAddress(big.NewInt(239457111187))
  150. tx.RqToBJJ = privK.Public()
  151. tx.RqTokenID = 222
  152. tx.RqAmount = big.NewInt(3487762374627846747)
  153. tx.RqFee = 11
  154. tx.RqNonce = 78
  155. }
  156. if i%3 == 0 { // Optional parameters: things that get updated "a posteriori"
  157. tx.BatchNum = 489
  158. tx.AbsoluteFee = 39.12345
  159. tx.AbsoluteFeeUpdate = time.Now().UTC()
  160. }
  161. txs = append(txs, tx)
  162. }
  163. return txs
  164. }
  165. func cleanDB() {
  166. if _, err := l2DB.db.Exec("DELETE FROM tx_pool"); err != nil {
  167. panic(err)
  168. }
  169. if _, err := l2DB.db.Exec("DELETE FROM account_creation_auth"); err != nil {
  170. panic(err)
  171. }
  172. }