arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
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}