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.

210 lines
5.7 KiB

  1. package coordinator
  2. import (
  3. "io/ioutil"
  4. "math/big"
  5. "os"
  6. "testing"
  7. "time"
  8. ethCommon "github.com/ethereum/go-ethereum/common"
  9. "github.com/hermeznetwork/hermez-node/batchbuilder"
  10. dbUtils "github.com/hermeznetwork/hermez-node/db"
  11. "github.com/hermeznetwork/hermez-node/db/historydb"
  12. "github.com/hermeznetwork/hermez-node/db/l2db"
  13. "github.com/hermeznetwork/hermez-node/db/statedb"
  14. "github.com/hermeznetwork/hermez-node/log"
  15. "github.com/hermeznetwork/hermez-node/test"
  16. "github.com/hermeznetwork/hermez-node/txselector"
  17. "github.com/stretchr/testify/assert"
  18. "github.com/stretchr/testify/require"
  19. )
  20. func newTestModules(t *testing.T) (*txselector.TxSelector, *batchbuilder.BatchBuilder) { // FUTURE once Synchronizer is ready, should return it also
  21. nLevels := 32
  22. synchDBPath, err := ioutil.TempDir("", "tmpSynchDB")
  23. require.Nil(t, err)
  24. defer assert.Nil(t, os.RemoveAll(synchDBPath))
  25. synchSdb, err := statedb.NewStateDB(synchDBPath, statedb.TypeSynchronizer, nLevels)
  26. assert.Nil(t, err)
  27. // txselDBPath, err := ioutil.TempDir("", "tmpTxSelDB")
  28. // require.Nil(t, err)
  29. // bbDBPath, err := ioutil.TempDir("", "tmpBBDB")
  30. // require.Nil(t, err)
  31. // txselSdb, err := statedb.NewLocalStateDB(txselDBPath, synchSdb, statedb.TypeTxSelector, nLevels)
  32. // assert.Nil(t, err)
  33. // bbSdb, err := statedb.NewLocalStateDB(bbDBPath, synchSdb, statedb.TypeBatchBuilder, nLevels)
  34. // assert.Nil(t, err)
  35. pass := os.Getenv("POSTGRES_PASS")
  36. db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
  37. require.Nil(t, err)
  38. l2DB := l2db.NewL2DB(db, 10, 100, 24*time.Hour)
  39. txselDir, err := ioutil.TempDir("", "tmpTxSelDB")
  40. require.Nil(t, err)
  41. defer assert.Nil(t, os.RemoveAll(txselDir))
  42. txsel, err := txselector.NewTxSelector(txselDir, synchSdb, l2DB, 10, 10, 10)
  43. assert.Nil(t, err)
  44. bbDir, err := ioutil.TempDir("", "tmpBatchBuilderDB")
  45. require.Nil(t, err)
  46. defer assert.Nil(t, os.RemoveAll(bbDir))
  47. bb, err := batchbuilder.NewBatchBuilder(bbDir, synchSdb, nil, 0, uint64(nLevels))
  48. assert.Nil(t, err)
  49. // l1Txs, coordinatorL1Txs, poolL2Txs := test.GenerateTestTxsFromSet(t, test.SetTest0)
  50. return txsel, bb
  51. }
  52. // CoordNode is an example of a Node that handles the goroutines for the coordinator
  53. type CoordNode struct {
  54. c *Coordinator
  55. stopForge chan bool
  56. stopGetProofCallForge chan bool
  57. stopForgeCallConfirm chan bool
  58. }
  59. func NewCoordNode(c *Coordinator) *CoordNode {
  60. return &CoordNode{
  61. c: c,
  62. }
  63. }
  64. func (cn *CoordNode) Start() {
  65. log.Debugw("Starting CoordNode...")
  66. cn.stopForge = make(chan bool)
  67. cn.stopGetProofCallForge = make(chan bool)
  68. cn.stopForgeCallConfirm = make(chan bool)
  69. queueSize := 8
  70. batchCh0 := make(chan *BatchInfo, queueSize)
  71. batchCh1 := make(chan *BatchInfo, queueSize)
  72. go func() {
  73. for {
  74. select {
  75. case <-cn.stopForge:
  76. return
  77. default:
  78. if forge, err := cn.c.ForgeLoopFn(batchCh0, cn.stopForge); err == ErrStop {
  79. return
  80. } else if err != nil {
  81. log.Errorw("CoordNode ForgeLoopFn", "error", err)
  82. time.Sleep(200 * time.Millisecond) // Avoid overflowing log with errors
  83. } else if !forge {
  84. time.Sleep(200 * time.Millisecond)
  85. }
  86. }
  87. }
  88. }()
  89. go func() {
  90. for {
  91. select {
  92. case <-cn.stopGetProofCallForge:
  93. return
  94. default:
  95. if err := cn.c.GetProofCallForgeLoopFn(
  96. batchCh0, batchCh1, cn.stopGetProofCallForge); err == ErrStop {
  97. return
  98. } else if err != nil {
  99. log.Errorw("CoordNode GetProofCallForgeLoopFn", "error", err)
  100. }
  101. }
  102. }
  103. }()
  104. go func() {
  105. for {
  106. select {
  107. case <-cn.stopForgeCallConfirm:
  108. return
  109. default:
  110. if err := cn.c.ForgeCallConfirmLoopFn(
  111. batchCh1, cn.stopForgeCallConfirm); err == ErrStop {
  112. return
  113. } else if err != nil {
  114. log.Errorw("CoordNode ForgeCallConfirmLoopFn", "error", err)
  115. }
  116. }
  117. }
  118. }()
  119. }
  120. func (cn *CoordNode) Stop() {
  121. log.Debugw("Stopping CoordNode...")
  122. cn.stopForge <- true
  123. cn.stopGetProofCallForge <- true
  124. cn.stopForgeCallConfirm <- true
  125. }
  126. type timer struct {
  127. time int64
  128. }
  129. func (t *timer) Time() int64 {
  130. currentTime := t.time
  131. t.time++
  132. return currentTime
  133. }
  134. func waitForSlot(t *testing.T, c *test.Client, slot int64) {
  135. for {
  136. blockNum, err := c.EthCurrentBlock()
  137. require.Nil(t, err)
  138. nextBlockSlot, err := c.AuctionGetSlotNumber(blockNum + 1)
  139. require.Nil(t, err)
  140. if nextBlockSlot == slot {
  141. break
  142. }
  143. c.CtlMineBlock()
  144. }
  145. }
  146. func TestCoordinator(t *testing.T) {
  147. txsel, bb := newTestModules(t)
  148. conf := Config{}
  149. hdb := &historydb.HistoryDB{}
  150. serverProofs := []ServerProofInterface{&ServerProofMock{}, &ServerProofMock{}}
  151. var timer timer
  152. ethClientSetup := test.NewClientSetupExample()
  153. bidder := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
  154. forger := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
  155. ethClient := test.NewClient(true, &timer, &bidder, ethClientSetup)
  156. // Bid for slot 2 and 4
  157. _, err := ethClient.AuctionSetCoordinator(forger, "https://foo.bar")
  158. require.Nil(t, err)
  159. _, err = ethClient.AuctionBid(2, big.NewInt(9999))
  160. require.Nil(t, err)
  161. _, err = ethClient.AuctionBid(4, big.NewInt(9999))
  162. require.Nil(t, err)
  163. c := NewCoordinator(conf, hdb, txsel, bb, serverProofs, ethClient)
  164. cn := NewCoordNode(c)
  165. cn.Start()
  166. time.Sleep(1 * time.Second)
  167. // simulate forgeSequence time
  168. waitForSlot(t, ethClient, 2)
  169. log.Info("simulate entering in forge time")
  170. time.Sleep(1 * time.Second)
  171. // simulate going out from forgeSequence
  172. waitForSlot(t, ethClient, 3)
  173. log.Info("simulate going out from forge time")
  174. time.Sleep(1 * time.Second)
  175. // simulate entering forgeSequence time again
  176. waitForSlot(t, ethClient, 4)
  177. log.Info("simulate entering in forge time again")
  178. time.Sleep(2 * time.Second)
  179. // simulate stopping forgerLoop by channel
  180. log.Info("simulate stopping forgerLoop by closing coordinator stopch")
  181. cn.Stop()
  182. time.Sleep(1 * time.Second)
  183. }