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