hermez-node/txselector/txselector_test.go
txselector/txselector_test.goRaw
1package txselector
2
3import (
4 "fmt"
5 "io/ioutil"
6 "os"
7 "strconv"
8 "testing"
9 "time"
10
11 ethCommon "github.com/ethereum/go-ethereum/common"
12 ethCrypto "github.com/ethereum/go-ethereum/crypto"
13 "github.com/hermeznetwork/hermez-node/common"
14 dbUtils "github.com/hermeznetwork/hermez-node/db"
15 "github.com/hermeznetwork/hermez-node/db/historydb"
16 "github.com/hermeznetwork/hermez-node/db/l2db"
17 "github.com/hermeznetwork/hermez-node/db/statedb"
18 "github.com/hermeznetwork/hermez-node/log"
19 "github.com/hermeznetwork/hermez-node/test"
20 "github.com/hermeznetwork/hermez-node/test/til"
21 "github.com/hermeznetwork/hermez-node/test/txsets"
22 "github.com/hermeznetwork/hermez-node/txprocessor"
23 "github.com/jmoiron/sqlx"
24 "github.com/stretchr/testify/assert"
25 "github.com/stretchr/testify/require"
26)
27
28func initTest(t *testing.T, chainID uint16, hermezContractAddr ethCommon.Address, coordUser *til.User) *TxSelector {
29 pass := os.Getenv("POSTGRES_PASS")
30 db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
31 require.NoError(t, err)
32 l2DB := l2db.NewL2DB(db, 10, 100, 24*time.Hour)
33
34 dir, err := ioutil.TempDir("", "tmpdb")
35 require.NoError(t, err)
36 defer assert.NoError(t, os.RemoveAll(dir))
37 syncStateDB, err := statedb.NewStateDB(dir, 128, statedb.TypeTxSelector, 0)
38 require.NoError(t, err)
39
40 txselDir, err := ioutil.TempDir("", "tmpTxSelDB")
41 require.NoError(t, err)
42 defer assert.NoError(t, os.RemoveAll(dir))
43
44 // use Til Coord keys for tests compatibility
45 coordAccount := &CoordAccount{
46 Addr: coordUser.Addr,
47 BJJ: coordUser.BJJ.Public().Compress(),
48 AccountCreationAuth: nil,
49 }
50 fmt.Printf("%v", coordAccount)
51 auth := common.AccountCreationAuth{
52 EthAddr: coordUser.Addr,
53 BJJ: coordUser.BJJ.Public().Compress(),
54 }
55 err = auth.Sign(func(hash []byte) ([]byte, error) {
56 return ethCrypto.Sign(hash, coordUser.EthSk)
57 }, chainID, hermezContractAddr)
58 assert.NoError(t, err)
59 coordAccount.AccountCreationAuth = auth.Signature
60
61 txsel, err := NewTxSelector(coordAccount, txselDir, syncStateDB, l2DB)
62 require.NoError(t, err)
63
64 test.WipeDB(txsel.l2db.DB())
65
66 return txsel
67}
68
69func addAccCreationAuth(t *testing.T, tc *til.Context, txsel *TxSelector, chainID uint16, hermezContractAddr ethCommon.Address, username string) []byte {
70 user := tc.Users[username]
71 auth := &common.AccountCreationAuth{
72 EthAddr: user.Addr,
73 BJJ: user.BJJ.Public().Compress(),
74 }
75 err := auth.Sign(func(hash []byte) ([]byte, error) {
76 return ethCrypto.Sign(hash, user.EthSk)
77 }, chainID, hermezContractAddr)
78 assert.NoError(t, err)
79
80 err = txsel.l2db.AddAccountCreationAuth(auth)
81 assert.NoError(t, err)
82 return auth.Signature
83}
84
85func addL2Txs(t *testing.T, txsel *TxSelector, poolL2Txs []common.PoolL2Tx) {
86 for i := 0; i < len(poolL2Txs); i++ {
87 err := txsel.l2db.AddTxTest(&poolL2Txs[i])
88 if err != nil {
89 log.Error(err)
90 }
91 require.NoError(t, err)
92 }
93}
94
95func addTokens(t *testing.T, tc *til.Context, db *sqlx.DB) {
96 var tokens []common.Token
97 for i := 0; i < int(tc.LastRegisteredTokenID); i++ {
98 tokens = append(tokens, common.Token{
99 TokenID: common.TokenID(i + 1),
100 EthBlockNum: 1,
101 EthAddr: ethCommon.BytesToAddress([]byte{byte(i + 1)}),
102 Name: strconv.Itoa(i),
103 Symbol: strconv.Itoa(i),
104 Decimals: 18,
105 })
106 }
107
108 hdb := historydb.NewHistoryDB(db)
109 assert.NoError(t, hdb.AddBlock(&common.Block{
110 Num: 1,
111 }))
112 assert.NoError(t, hdb.AddTokens(tokens))
113}
114
115func checkBalance(t *testing.T, tc *til.Context, txsel *TxSelector, username string, tokenid int, expected string) {
116 // Accounts.Idx does not match with the TxSelector tests as we are not
117 // using the Til L1CoordinatorTxs (as are generated by the TxSelector
118 // itself when processing the txs, so the Idxs does not match the Til
119 // idxs). But the Idx is obtained through StateDB.GetIdxByEthAddrBJJ
120 user := tc.Users[username]
121 idx, err := txsel.localAccountsDB.GetIdxByEthAddrBJJ(user.Addr, user.BJJ.Public().Compress(), common.TokenID(tokenid))
122 require.NoError(t, err)
123 checkBalanceByIdx(t, txsel, idx, expected)
124}
125
126func checkBalanceByIdx(t *testing.T, txsel *TxSelector, idx common.Idx, expected string) {
127 acc, err := txsel.localAccountsDB.GetAccount(idx)
128 require.NoError(t, err)
129 assert.Equal(t, expected, acc.Balance.String())
130}
131
132// checkSortedByNonce takes as input testAccNonces map, and the array of
133// common.PoolL2Txs, and checks if the nonces correspond to the accumulated
134// values of the map. Also increases the Nonces computed on the map.
135func checkSortedByNonce(t *testing.T, testAccNonces map[common.Idx]common.Nonce, txs []common.PoolL2Tx) {
136 for _, tx := range txs {
137 assert.True(t, testAccNonces[tx.FromIdx] == tx.Nonce,
138 fmt.Sprintf("Idx: %d, expected: %d, tx.Nonce: %d",
139 tx.FromIdx, testAccNonces[tx.FromIdx], tx.Nonce))
140 testAccNonces[tx.FromIdx] = testAccNonces[tx.FromIdx] + 1
141 }
142}
143
144func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
145 chainID := uint16(0)
146 tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
147 // generate test transactions, the L1CoordinatorTxs generated by Til
148 // will be ignored at this test, as will be the TxSelector who
149 // generates them when needed
150 blocks, err := tc.GenerateBlocks(txsets.SetBlockchainMinimumFlow0)
151 assert.NoError(t, err)
152
153 hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
154 txsel := initTest(t, chainID, hermezContractAddr, tc.Users["Coord"])
155
156 // restart nonces of TilContext, as will be set by generating directly
157 // the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
158 tc.RestartNonces()
159 testAccNonces := make(map[common.Idx]common.Nonce)
160
161 // add tokens to HistoryDB to avoid breaking FK constrains
162 addTokens(t, tc, txsel.l2db.DB())
163
164 tpc := txprocessor.Config{
165 NLevels: 16,
166 MaxFeeTx: 10,
167 MaxTx: 20,
168 MaxL1Tx: 10,
169 ChainID: chainID,
170 }
171 selectionConfig := &SelectionConfig{
172 MaxL1UserTxs: 5,
173 TxProcessorConfig: tpc,
174 }
175
176 // coordIdxs, accAuths, l1UserTxs, l1CoordTxs, l2Txs, err
177
178 log.Debug("block:0 batch:1")
179 l1UserTxs := []common.L1Tx{}
180 _, _, oL1UserTxs, oL1CoordTxs, oL2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
181 require.NoError(t, err)
182 assert.Equal(t, 0, len(oL1UserTxs))
183 assert.Equal(t, 0, len(oL1CoordTxs))
184 assert.Equal(t, 0, len(oL2Txs))
185 assert.Equal(t, common.BatchNum(1), txsel.localAccountsDB.CurrentBatch())
186 assert.Equal(t, common.Idx(255), txsel.localAccountsDB.CurrentIdx())
187
188 log.Debug("block:0 batch:2")
189 l1UserTxs = []common.L1Tx{}
190 _, _, oL1UserTxs, oL1CoordTxs, oL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
191 require.NoError(t, err)
192 assert.Equal(t, 0, len(oL1UserTxs))
193 assert.Equal(t, 0, len(oL1CoordTxs))
194 assert.Equal(t, 0, len(oL2Txs))
195 assert.Equal(t, common.BatchNum(2), txsel.localAccountsDB.CurrentBatch())
196 assert.Equal(t, common.Idx(255), txsel.localAccountsDB.CurrentIdx())
197
198 log.Debug("block:0 batch:3")
199 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
200 _, _, oL1UserTxs, oL1CoordTxs, oL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
201 require.NoError(t, err)
202 assert.Equal(t, 2, len(oL1UserTxs))
203 assert.Equal(t, 0, len(oL1CoordTxs))
204 assert.Equal(t, 0, len(oL2Txs))
205 assert.Equal(t, common.BatchNum(3), txsel.localAccountsDB.CurrentBatch())
206 assert.Equal(t, common.Idx(257), txsel.localAccountsDB.CurrentIdx())
207 checkBalance(t, tc, txsel, "A", 0, "500")
208 checkBalance(t, tc, txsel, "C", 1, "0")
209
210 log.Debug("block:0 batch:4")
211 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
212 _, _, oL1UserTxs, oL1CoordTxs, oL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
213 require.NoError(t, err)
214 assert.Equal(t, 1, len(oL1UserTxs))
215 assert.Equal(t, 0, len(oL1CoordTxs))
216 assert.Equal(t, 0, len(oL2Txs))
217 assert.Equal(t, common.BatchNum(4), txsel.localAccountsDB.CurrentBatch())
218 assert.Equal(t, common.Idx(258), txsel.localAccountsDB.CurrentIdx())
219 checkBalance(t, tc, txsel, "A", 0, "500")
220 checkBalance(t, tc, txsel, "A", 1, "500")
221 checkBalance(t, tc, txsel, "C", 1, "0")
222
223 log.Debug("block:0 batch:5")
224 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
225 _, _, oL1UserTxs, oL1CoordTxs, oL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
226 require.NoError(t, err)
227 assert.Equal(t, 0, len(oL1UserTxs))
228 assert.Equal(t, 0, len(oL1CoordTxs))
229 assert.Equal(t, 0, len(oL2Txs))
230 assert.Equal(t, common.BatchNum(5), txsel.localAccountsDB.CurrentBatch())
231 assert.Equal(t, common.Idx(258), txsel.localAccountsDB.CurrentIdx())
232 checkBalance(t, tc, txsel, "A", 0, "500")
233 checkBalance(t, tc, txsel, "A", 1, "500")
234 checkBalance(t, tc, txsel, "C", 1, "0")
235
236 log.Debug("block:0 batch:6")
237 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
238 _, _, oL1UserTxs, oL1CoordTxs, oL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
239 require.NoError(t, err)
240 assert.Equal(t, 1, len(oL1UserTxs))
241 assert.Equal(t, 0, len(oL1CoordTxs))
242 assert.Equal(t, 0, len(oL2Txs))
243 assert.Equal(t, common.BatchNum(6), txsel.localAccountsDB.CurrentBatch())
244 assert.Equal(t, common.Idx(259), txsel.localAccountsDB.CurrentIdx())
245 checkBalance(t, tc, txsel, "A", 0, "600")
246 checkBalance(t, tc, txsel, "A", 1, "500")
247 checkBalance(t, tc, txsel, "B", 0, "400")
248 checkBalance(t, tc, txsel, "C", 1, "0")
249
250 log.Debug("block:0 batch:7")
251 // simulate the PoolL2Txs of the batch7
252 batchPoolL2 := `
253 Type: PoolL2
254 PoolTransferToEthAddr(1) A-B: 200 (126)
255 PoolTransferToEthAddr(0) B-C: 100 (126)`
256 poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
257 require.NoError(t, err)
258 // add AccountCreationAuths that will be used at the next batch
259 accAuthSig0 := addAccCreationAuth(t, tc, txsel, chainID, hermezContractAddr, "B")
260 accAuthSig1 := addAccCreationAuth(t, tc, txsel, chainID, hermezContractAddr, "C")
261 // add the PoolL2Txs to the l2DB
262 addL2Txs(t, txsel, poolL2Txs)
263 // check signatures of L2Txs from the L2DB (to check that the
264 // parameters of the PoolL2Tx match the original parameters signed
265 // before inserting it to the L2DB)
266 l2TxsFromDB, err := txsel.l2db.GetPendingTxs()
267 require.NoError(t, err)
268 assert.True(t, l2TxsFromDB[0].VerifySignature(chainID, tc.Users["A"].BJJ.Public().Compress()))
269 assert.True(t, l2TxsFromDB[1].VerifySignature(chainID, tc.Users["B"].BJJ.Public().Compress()))
270 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
271 coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
272 require.NoError(t, err)
273 assert.Equal(t, []common.Idx{261, 262}, coordIdxs)
274 assert.Equal(t, txsel.coordAccount.AccountCreationAuth, accAuths[0])
275 assert.Equal(t, txsel.coordAccount.AccountCreationAuth, accAuths[1])
276 assert.Equal(t, accAuthSig0, accAuths[2])
277 assert.Equal(t, accAuthSig1, accAuths[3])
278 assert.Equal(t, 1, len(oL1UserTxs))
279 assert.Equal(t, 4, len(oL1CoordTxs))
280 assert.Equal(t, 2, len(oL2Txs))
281 assert.Equal(t, len(oL1CoordTxs), len(accAuths))
282 assert.Equal(t, common.BatchNum(7), txsel.localAccountsDB.CurrentBatch())
283 assert.Equal(t, common.Idx(264), txsel.localAccountsDB.CurrentIdx())
284 checkBalanceByIdx(t, txsel, 261, "20") // CoordIdx for TokenID=1
285 checkBalanceByIdx(t, txsel, 262, "10") // CoordIdx for TokenID=0
286 checkBalance(t, tc, txsel, "A", 0, "600")
287 checkBalance(t, tc, txsel, "A", 1, "280")
288 checkBalance(t, tc, txsel, "B", 0, "290")
289 checkBalance(t, tc, txsel, "B", 1, "200")
290 checkBalance(t, tc, txsel, "C", 0, "100")
291 checkBalance(t, tc, txsel, "D", 0, "800")
292 checkSortedByNonce(t, testAccNonces, oL2Txs)
293 err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs), txsel.localAccountsDB.CurrentBatch())
294 require.NoError(t, err)
295
296 log.Debug("block:0 batch:8")
297 // simulate the PoolL2Txs of the batch8
298 batchPoolL2 = `
299 Type: PoolL2
300 PoolTransfer(0) A-B: 100 (126)
301 PoolTransfer(0) C-A: 50 (126)
302 PoolTransfer(1) B-C: 100 (126)
303 PoolExit(0) A: 100 (126)`
304 poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
305 require.NoError(t, err)
306 addL2Txs(t, txsel, poolL2Txs)
307 // check signatures of L2Txs from the L2DB (to check that the
308 // parameters of the PoolL2Tx match the original parameters signed
309 // before inserting it to the L2DB)
310 l2TxsFromDB, err = txsel.l2db.GetPendingTxs()
311 require.NoError(t, err)
312 assert.True(t, l2TxsFromDB[0].VerifySignature(chainID, tc.Users["A"].BJJ.Public().Compress()))
313 assert.True(t, l2TxsFromDB[1].VerifySignature(chainID, tc.Users["C"].BJJ.Public().Compress()))
314 assert.True(t, l2TxsFromDB[2].VerifySignature(chainID, tc.Users["B"].BJJ.Public().Compress()))
315 assert.True(t, l2TxsFromDB[3].VerifySignature(chainID, tc.Users["A"].BJJ.Public().Compress()))
316 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
317 coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
318 require.NoError(t, err)
319 assert.Equal(t, []common.Idx{261, 262}, coordIdxs)
320 assert.Equal(t, 0, len(accAuths))
321 assert.Equal(t, 0, len(oL1UserTxs))
322 assert.Equal(t, 0, len(oL1CoordTxs))
323 assert.Equal(t, 4, len(oL2Txs))
324 assert.Equal(t, len(oL1CoordTxs), len(accAuths))
325 assert.Equal(t, common.BatchNum(8), txsel.localAccountsDB.CurrentBatch())
326 assert.Equal(t, common.Idx(264), txsel.localAccountsDB.CurrentIdx())
327 checkBalanceByIdx(t, txsel, 261, "30")
328 checkBalanceByIdx(t, txsel, 262, "35")
329 checkBalance(t, tc, txsel, "A", 0, "430")
330 checkBalance(t, tc, txsel, "A", 1, "280")
331 checkBalance(t, tc, txsel, "B", 0, "390")
332 checkBalance(t, tc, txsel, "B", 1, "90")
333 checkBalance(t, tc, txsel, "C", 0, "45")
334 checkBalance(t, tc, txsel, "C", 1, "100")
335 checkBalance(t, tc, txsel, "D", 0, "800")
336 checkSortedByNonce(t, testAccNonces, oL2Txs)
337 err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs), txsel.localAccountsDB.CurrentBatch())
338 require.NoError(t, err)
339
340 log.Debug("(batch9)block:1 batch:1")
341 // simulate the PoolL2Txs of the batch9
342 batchPoolL2 = `
343 Type: PoolL2
344 PoolTransfer(0) D-A: 300 (126)
345 PoolTransfer(0) B-D: 100 (126)
346 `
347 poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
348 require.NoError(t, err)
349 addL2Txs(t, txsel, poolL2Txs)
350 // check signatures of L2Txs from the L2DB (to check that the
351 // parameters of the PoolL2Tx match the original parameters signed
352 // before inserting it to the L2DB)
353 l2TxsFromDB, err = txsel.l2db.GetPendingTxs()
354 require.NoError(t, err)
355 assert.True(t, l2TxsFromDB[0].VerifySignature(chainID, tc.Users["D"].BJJ.Public().Compress()))
356 assert.True(t, l2TxsFromDB[1].VerifySignature(chainID, tc.Users["B"].BJJ.Public().Compress()))
357 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
358 coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
359 require.NoError(t, err)
360 assert.Equal(t, []common.Idx{262}, coordIdxs)
361 assert.Equal(t, 0, len(accAuths))
362 assert.Equal(t, 4, len(oL1UserTxs))
363 assert.Equal(t, 0, len(oL1CoordTxs))
364 assert.Equal(t, 2, len(oL2Txs))
365 assert.Equal(t, len(oL1CoordTxs), len(accAuths))
366 assert.Equal(t, common.BatchNum(9), txsel.localAccountsDB.CurrentBatch())
367 assert.Equal(t, common.Idx(264), txsel.localAccountsDB.CurrentIdx())
368 checkBalanceByIdx(t, txsel, 261, "30")
369 checkBalanceByIdx(t, txsel, 262, "75")
370 checkBalance(t, tc, txsel, "A", 0, "730")
371 checkBalance(t, tc, txsel, "A", 1, "280")
372 checkBalance(t, tc, txsel, "B", 0, "380")
373 checkBalance(t, tc, txsel, "B", 1, "90")
374 checkBalance(t, tc, txsel, "C", 0, "845")
375 checkBalance(t, tc, txsel, "C", 1, "100")
376 checkBalance(t, tc, txsel, "D", 0, "470")
377 checkSortedByNonce(t, testAccNonces, oL2Txs)
378 err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs), txsel.localAccountsDB.CurrentBatch())
379 require.NoError(t, err)
380}
381
382func TestPoolL2TxsWithoutEnoughBalance(t *testing.T) {
383 set := `
384 Type: Blockchain
385
386 CreateAccountDeposit(0) Coord: 0
387 CreateAccountDeposit(0) A: 100
388 CreateAccountDeposit(0) B: 100
389
390 > batchL1 // freeze L1User{1}
391 > batchL1 // forge L1User{1}
392 > block
393 `
394
395 chainID := uint16(0)
396 tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
397 // generate test transactions, the L1CoordinatorTxs generated by Til
398 // will be ignored at this test, as will be the TxSelector who
399 // generates them when needed
400 blocks, err := tc.GenerateBlocks(set)
401 assert.NoError(t, err)
402
403 hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
404 txsel := initTest(t, chainID, hermezContractAddr, tc.Users["Coord"])
405
406 // restart nonces of TilContext, as will be set by generating directly
407 // the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
408 tc.RestartNonces()
409
410 tpc := txprocessor.Config{
411 NLevels: 16,
412 MaxFeeTx: 10,
413 MaxTx: 20,
414 MaxL1Tx: 10,
415 ChainID: chainID,
416 }
417 selectionConfig := &SelectionConfig{
418 MaxL1UserTxs: 5,
419 TxProcessorConfig: tpc,
420 }
421 // batch1
422 l1UserTxs := []common.L1Tx{}
423 _, _, _, _, _, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
424 require.NoError(t, err)
425
426 // batch2
427 // prepare the PoolL2Txs
428 batchPoolL2 := `
429 Type: PoolL2
430 PoolTransferToEthAddr(0) A-B: 100 (126)
431 PoolExit(0) B: 100 (126)`
432 poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
433 require.NoError(t, err)
434 // add the PoolL2Txs to the l2DB
435 addL2Txs(t, txsel, poolL2Txs)
436
437 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
438 _, _, oL1UserTxs, oL1CoordTxs, oL2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
439 require.NoError(t, err)
440 assert.Equal(t, 3, len(oL1UserTxs))
441 assert.Equal(t, 0, len(oL1CoordTxs))
442 assert.Equal(t, 0, len(oL2Txs)) // should be 0 as the 2 PoolL2Txs does not have enough funds
443 err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
444 require.NoError(t, err)
445
446 // as the PoolL2Txs have not been really processed, restart nonces
447 tc.RestartNonces()
448
449 // batch3
450 // NOTE: this batch will result with 1 L2Tx, as the PoolExit tx is not
451 // possible, as the PoolTransferToEthAddr is not processed yet when
452 // checking availability of PoolExit. This, in a near-future iteration
453 // of the TxSelector will return the 2 transactions as valid and
454 // selected, as the TxSelector will handle this kind of combinations.
455 batchPoolL2 = `
456 Type: PoolL2
457 PoolTransferToEthAddr(0) A-B: 50 (126)`
458 poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
459 require.NoError(t, err)
460 addL2Txs(t, txsel, poolL2Txs)
461
462 l1UserTxs = []common.L1Tx{}
463 _, _, oL1UserTxs, oL1CoordTxs, oL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
464 require.NoError(t, err)
465 assert.Equal(t, 0, len(oL1UserTxs))
466 assert.Equal(t, 0, len(oL1CoordTxs))
467 assert.Equal(t, 1, len(oL2Txs)) // see 'NOTE' at the beginning of 'batch3' of this test
468 assert.Equal(t, common.TxTypeTransferToEthAddr, oL2Txs[0].Type)
469 err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
470 require.NoError(t, err)
471
472 // batch4
473 // make the selection of another batch, which should include the
474 // initial PoolExit, which now is valid as B has enough Balance
475 l1UserTxs = []common.L1Tx{}
476 _, _, oL1UserTxs, oL1CoordTxs, oL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
477 require.NoError(t, err)
478 assert.Equal(t, 0, len(oL1UserTxs))
479 assert.Equal(t, 0, len(oL1CoordTxs))
480 assert.Equal(t, 1, len(oL2Txs))
481 assert.Equal(t, common.TxTypeExit, oL2Txs[0].Type)
482 err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
483 require.NoError(t, err)
484}