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