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.

200 lines
6.0 KiB

  1. package historydb
  2. import (
  3. "fmt"
  4. "math/big"
  5. "os"
  6. "testing"
  7. "time"
  8. eth "github.com/ethereum/go-ethereum/common"
  9. "github.com/hermeznetwork/hermez-node/common"
  10. "github.com/hermeznetwork/hermez-node/db"
  11. "github.com/stretchr/testify/assert"
  12. )
  13. var historyDB *HistoryDB
  14. // In order to run the test you need to run a Posgres DB with
  15. // a database named "history" that is accessible by
  16. // user: "hermez"
  17. // pass: set it using the env var POSTGRES_PASS
  18. // 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;"
  19. // After running the test you can stop the container by running: sudo docker kill hermez-db-test
  20. // If you already did that for the L2DB you don't have to do it again
  21. func TestMain(m *testing.M) {
  22. // init DB
  23. var err error
  24. pass := os.Getenv("POSTGRES_PASS")
  25. historyDB, err = NewHistoryDB(5432, "localhost", "hermez", pass, "history")
  26. if err != nil {
  27. panic(err)
  28. }
  29. // Run tests
  30. result := m.Run()
  31. // Close DB
  32. if err := historyDB.Close(); err != nil {
  33. fmt.Println("Error closing the history DB:", err)
  34. }
  35. os.Exit(result)
  36. }
  37. func TestBlocks(t *testing.T) {
  38. var fromBlock, toBlock uint64
  39. fromBlock = 1
  40. toBlock = 5
  41. // Delete peviously created rows (clean previous test execs)
  42. assert.NoError(t, historyDB.Reorg(fromBlock-1))
  43. // Generate fake blocks
  44. blocks := genBlocks(fromBlock, toBlock)
  45. // Insert blocks into DB
  46. for _, block := range blocks {
  47. err := historyDB.AddBlock(&block)
  48. assert.NoError(t, err)
  49. }
  50. // Get all blocks from DB
  51. fetchedBlocks, err := historyDB.GetBlocks(fromBlock, toBlock)
  52. assert.Equal(t, len(blocks), len(fetchedBlocks))
  53. // Compare generated vs getted blocks
  54. assert.NoError(t, err)
  55. for i, fetchedBlock := range fetchedBlocks {
  56. assertEqualBlock(t, &blocks[i], fetchedBlock)
  57. }
  58. // Get blocks from the DB one by one
  59. for i := fromBlock; i < toBlock; i++ {
  60. fetchedBlock, err := historyDB.GetBlock(i)
  61. assert.NoError(t, err)
  62. assertEqualBlock(t, &blocks[i-1], fetchedBlock)
  63. }
  64. // Get last block
  65. lastBlock, err := historyDB.GetLastBlock()
  66. assert.NoError(t, err)
  67. assertEqualBlock(t, &blocks[len(blocks)-1], lastBlock)
  68. }
  69. func assertEqualBlock(t *testing.T, expected *common.Block, actual *common.Block) {
  70. assert.Equal(t, expected.EthBlockNum, actual.EthBlockNum)
  71. assert.Equal(t, expected.Hash, actual.Hash)
  72. assert.Equal(t, expected.Timestamp.Unix(), actual.Timestamp.Unix())
  73. }
  74. func TestBatches(t *testing.T) {
  75. const fromBlock uint64 = 1
  76. const toBlock uint64 = 3
  77. const nBatchesPerBlock = 3
  78. // Prepare blocks in the DB
  79. setTestBlocks(fromBlock, toBlock)
  80. // Generate fake batches
  81. var batches []common.Batch
  82. collectedFees := make(map[common.TokenID]*big.Int)
  83. for i := 0; i < 64; i++ {
  84. collectedFees[common.TokenID(i)] = big.NewInt(int64(i))
  85. }
  86. for i := fromBlock; i < toBlock; i++ {
  87. for j := 0; j < nBatchesPerBlock; j++ {
  88. batch := common.Batch{
  89. BatchNum: common.BatchNum(int(i-1)*nBatchesPerBlock + j),
  90. EthBlockNum: uint64(i),
  91. ForgerAddr: eth.BigToAddress(big.NewInt(239457111187)),
  92. CollectedFees: collectedFees,
  93. StateRoot: common.Hash([]byte("duhdqlwiucgwqeiu")),
  94. NumAccounts: j,
  95. ExitRoot: common.Hash([]byte("tykertheuhtgenuer3iuw3b")),
  96. SlotNum: common.SlotNum(j),
  97. }
  98. if j%2 == 0 {
  99. batch.ForgeL1TxsNum = uint32(i)
  100. }
  101. batches = append(batches, batch)
  102. }
  103. }
  104. // Add batches to the DB
  105. err := historyDB.addBatches(batches)
  106. assert.NoError(t, err)
  107. // Get batches from the DB
  108. fetchedBatches, err := historyDB.GetBatches(0, common.BatchNum(int(toBlock-fromBlock)*nBatchesPerBlock))
  109. assert.NoError(t, err)
  110. for i, fetchedBatch := range fetchedBatches {
  111. assert.Equal(t, batches[i], *fetchedBatch)
  112. }
  113. // Test GetLastBatchNum
  114. fetchedLastBatchNum, err := historyDB.GetLastBatchNum()
  115. assert.NoError(t, err)
  116. assert.Equal(t, batches[len(batches)-1].BatchNum, fetchedLastBatchNum)
  117. // Test GetLastL1TxsNum
  118. fetchedLastL1TxsNum, err := historyDB.GetLastL1TxsNum()
  119. assert.NoError(t, err)
  120. assert.Equal(t, batches[len(batches)-1-(int(toBlock-fromBlock+1)%nBatchesPerBlock)].ForgeL1TxsNum, fetchedLastL1TxsNum)
  121. }
  122. func TestBids(t *testing.T) {
  123. const fromBlock uint64 = 1
  124. const toBlock uint64 = 5
  125. const bidsPerSlot = 5
  126. // Prepare blocks in the DB
  127. setTestBlocks(fromBlock, toBlock)
  128. // Generate fake bids
  129. bids := make([]common.Bid, 0, (toBlock-fromBlock)*bidsPerSlot)
  130. for i := fromBlock; i < toBlock; i++ {
  131. for j := 0; j < bidsPerSlot; j++ {
  132. bids = append(bids, common.Bid{
  133. SlotNum: common.SlotNum(i),
  134. BidValue: big.NewInt(int64(j)),
  135. EthBlockNum: i,
  136. ForgerAddr: eth.BigToAddress(big.NewInt(int64(j))),
  137. })
  138. }
  139. }
  140. err := historyDB.addBids(bids)
  141. assert.NoError(t, err)
  142. // Fetch bids
  143. var fetchedBids []*common.Bid
  144. for i := fromBlock; i < toBlock; i++ {
  145. fetchedBidsSlot, err := historyDB.GetBidsBySlot(common.SlotNum(i))
  146. assert.NoError(t, err)
  147. fetchedBids = append(fetchedBids, fetchedBidsSlot...)
  148. }
  149. // Compare fetched bids vs generated bids
  150. for i, bid := range fetchedBids {
  151. assert.Equal(t, bids[i], *bid)
  152. }
  153. }
  154. // setTestBlocks WARNING: this will delete the blocks and recreate them
  155. func setTestBlocks(from, to uint64) {
  156. if from == 0 {
  157. if err := historyDB.Reorg(from); err != nil {
  158. panic(err)
  159. }
  160. } else {
  161. if err := historyDB.Reorg(from - 1); err != nil {
  162. panic(err)
  163. }
  164. }
  165. blocks := genBlocks(from, to)
  166. if err := addBlocks(blocks); err != nil {
  167. panic(err)
  168. }
  169. }
  170. func genBlocks(from, to uint64) []common.Block {
  171. var blocks []common.Block
  172. for i := from; i < to; i++ {
  173. blocks = append(blocks, common.Block{
  174. EthBlockNum: i,
  175. Timestamp: time.Now().Add(time.Second * 13).UTC(),
  176. Hash: eth.BigToHash(big.NewInt(int64(i))),
  177. })
  178. }
  179. return blocks
  180. }
  181. // addBlocks insert blocks into the DB. TODO: move method to test
  182. func addBlocks(blocks []common.Block) error {
  183. return db.BulkInsert(
  184. historyDB.db,
  185. "INSERT INTO block (eth_block_num, timestamp, hash) VALUES %s",
  186. blocks[:],
  187. )
  188. }