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