arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
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,
  29	coordUser *til.User) (*TxSelector, *historydb.HistoryDB) {
  30	pass := os.Getenv("POSTGRES_PASS")
  31	db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
  32	require.NoError(t, err)
  33	l2DB := l2db.NewL2DB(db, db, 10, 100, 0.0, 24*time.Hour, nil)
  34
  35	historyDB := historydb.NewHistoryDB(db, db, nil)
  36
  37	dir, err := ioutil.TempDir("", "tmpdb")
  38	require.NoError(t, err)
  39	defer assert.NoError(t, os.RemoveAll(dir))
  40	syncStateDB, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128,
  41		Type: statedb.TypeTxSelector, NLevels: 0})
  42	require.NoError(t, err)
  43
  44	txselDir, err := ioutil.TempDir("", "tmpTxSelDB")
  45	require.NoError(t, err)
  46	defer assert.NoError(t, os.RemoveAll(dir))
  47
  48	// use Til Coord keys for tests compatibility
  49	coordAccount := &CoordAccount{
  50		Addr:                coordUser.Addr,
  51		BJJ:                 coordUser.BJJ.Public().Compress(),
  52		AccountCreationAuth: nil,
  53	}
  54	// fmt.Printf("%v\n", coordAccount)
  55	auth := common.AccountCreationAuth{
  56		EthAddr: coordUser.Addr,
  57		BJJ:     coordUser.BJJ.Public().Compress(),
  58	}
  59	err = auth.Sign(func(hash []byte) ([]byte, error) {
  60		return ethCrypto.Sign(hash, coordUser.EthSk)
  61	}, chainID, hermezContractAddr)
  62	assert.NoError(t, err)
  63	coordAccount.AccountCreationAuth = auth.Signature
  64
  65	txsel, err := NewTxSelector(coordAccount, txselDir, syncStateDB, l2DB)
  66	require.NoError(t, err)
  67
  68	test.WipeDB(txsel.l2db.DB())
  69
  70	return txsel, historyDB
  71}
  72
  73func addAccCreationAuth(t *testing.T, tc *til.Context, txsel *TxSelector, chainID uint16,
  74	hermezContractAddr ethCommon.Address, username string) []byte {
  75	user := tc.Users[username]
  76	auth := &common.AccountCreationAuth{
  77		EthAddr: user.Addr,
  78		BJJ:     user.BJJ.Public().Compress(),
  79	}
  80	err := auth.Sign(func(hash []byte) ([]byte, error) {
  81		return ethCrypto.Sign(hash, user.EthSk)
  82	}, chainID, hermezContractAddr)
  83	assert.NoError(t, err)
  84
  85	err = txsel.l2db.AddAccountCreationAuth(auth)
  86	assert.NoError(t, err)
  87	return auth.Signature
  88}
  89
  90func addL2Txs(t *testing.T, txsel *TxSelector, poolL2Txs []common.PoolL2Tx) {
  91	for i := 0; i < len(poolL2Txs); i++ {
  92		err := txsel.l2db.AddTxTest(&poolL2Txs[i])
  93		if err != nil {
  94			log.Error(err)
  95		}
  96		require.NoError(t, err)
  97	}
  98}
  99
 100func addTokens(t *testing.T, tc *til.Context, db *sqlx.DB) {
 101	var tokens []common.Token
 102	for i := 0; i < int(tc.LastRegisteredTokenID); i++ {
 103		tokens = append(tokens, common.Token{
 104			TokenID:     common.TokenID(i + 1),
 105			EthBlockNum: 1,
 106			EthAddr:     ethCommon.BytesToAddress([]byte{byte(i + 1)}),
 107			Name:        strconv.Itoa(i),
 108			Symbol:      strconv.Itoa(i),
 109			Decimals:    18,
 110		})
 111	}
 112
 113	hdb := historydb.NewHistoryDB(db, db, nil)
 114	assert.NoError(t, hdb.AddBlock(&common.Block{
 115		Num: 1,
 116	}))
 117	assert.NoError(t, hdb.AddTokens(tokens))
 118}
 119
 120func checkBalance(t *testing.T, tc *til.Context, txsel *TxSelector, username string,
 121	tokenid int, expected string) {
 122	// Accounts.Idx does not match with the TxSelector tests as we are not
 123	// using the Til L1CoordinatorTxs (as are generated by the TxSelector
 124	// itself when processing the txs, so the Idxs does not match the Til
 125	// idxs). But the Idx is obtained through StateDB.GetIdxByEthAddrBJJ
 126	user := tc.Users[username]
 127	idx, err := txsel.localAccountsDB.GetIdxByEthAddrBJJ(user.Addr, user.BJJ.Public().Compress(),
 128		common.TokenID(tokenid))
 129	require.NoError(t, err)
 130	checkBalanceByIdx(t, txsel, idx, expected)
 131}
 132
 133func checkBalanceByIdx(t *testing.T, txsel *TxSelector, idx common.Idx, expected string) {
 134	acc, err := txsel.localAccountsDB.GetAccount(idx)
 135	require.NoError(t, err)
 136	assert.Equal(t, expected, acc.Balance.String())
 137}
 138
 139// checkSortedByNonce takes as input testAccNonces map, and the array of
 140// common.PoolL2Txs, and checks if the nonces correspond to the accumulated
 141// values of the map. Also increases the Nonces computed on the map.
 142func checkSortedByNonce(t *testing.T, testAccNonces map[common.Idx]common.Nonce,
 143	txs []common.PoolL2Tx) {
 144	for _, tx := range txs {
 145		assert.True(t, testAccNonces[tx.FromIdx] == tx.Nonce,
 146			fmt.Sprintf("Idx: %d, expected: %d, tx.Nonce: %d",
 147				tx.FromIdx, testAccNonces[tx.FromIdx], tx.Nonce))
 148		testAccNonces[tx.FromIdx] = testAccNonces[tx.FromIdx] + 1
 149	}
 150}
 151
 152func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
 153	chainID := uint16(0)
 154	tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
 155	// generate test transactions, the L1CoordinatorTxs generated by Til
 156	// will be ignored at this test, as will be the TxSelector who
 157	// generates them when needed
 158	blocks, err := tc.GenerateBlocks(txsets.SetBlockchainMinimumFlow0)
 159	assert.NoError(t, err)
 160
 161	hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
 162	txsel, _ := initTest(t, chainID, hermezContractAddr, tc.Users["Coord"])
 163
 164	// restart nonces of TilContext, as will be set by generating directly
 165	// the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
 166	tc.RestartNonces()
 167	testAccNonces := make(map[common.Idx]common.Nonce)
 168
 169	// add tokens to HistoryDB to avoid breaking FK constrains
 170	addTokens(t, tc, txsel.l2db.DB())
 171
 172	tpc := txprocessor.Config{
 173		NLevels:  16,
 174		MaxFeeTx: 10,
 175		MaxTx:    20,
 176		MaxL1Tx:  10,
 177		ChainID:  chainID,
 178	}
 179
 180	// coordIdxs, accAuths, l1UserTxs, l1CoordTxs, l2Txs, err
 181
 182	log.Debug("block:0 batch:1")
 183	l1UserTxs := []common.L1Tx{}
 184	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err :=
 185		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 186	require.NoError(t, err)
 187	assert.Equal(t, 0, len(oL1UserTxs))
 188	assert.Equal(t, 0, len(oL1CoordTxs))
 189	assert.Equal(t, 0, len(oL2Txs))
 190	assert.Equal(t, common.BatchNum(1), txsel.localAccountsDB.CurrentBatch())
 191	assert.Equal(t, common.Idx(255), txsel.localAccountsDB.CurrentIdx())
 192
 193	log.Debug("block:0 batch:2")
 194	l1UserTxs = []common.L1Tx{}
 195	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
 196		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 197	require.NoError(t, err)
 198	assert.Equal(t, 0, len(oL1UserTxs))
 199	assert.Equal(t, 0, len(oL1CoordTxs))
 200	assert.Equal(t, 0, len(oL2Txs))
 201	assert.Equal(t, common.BatchNum(2), txsel.localAccountsDB.CurrentBatch())
 202	assert.Equal(t, common.Idx(255), txsel.localAccountsDB.CurrentIdx())
 203
 204	log.Debug("block:0 batch:3")
 205	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
 206	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
 207		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 208	require.NoError(t, err)
 209	assert.Equal(t, 2, len(oL1UserTxs))
 210	assert.Equal(t, 0, len(oL1CoordTxs))
 211	assert.Equal(t, 0, len(oL2Txs))
 212	assert.Equal(t, common.BatchNum(3), txsel.localAccountsDB.CurrentBatch())
 213	assert.Equal(t, common.Idx(257), txsel.localAccountsDB.CurrentIdx())
 214	checkBalance(t, tc, txsel, "A", 0, "500")
 215	checkBalance(t, tc, txsel, "C", 1, "0")
 216
 217	log.Debug("block:0 batch:4")
 218	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
 219	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
 220		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 221	require.NoError(t, err)
 222	assert.Equal(t, 1, len(oL1UserTxs))
 223	assert.Equal(t, 0, len(oL1CoordTxs))
 224	assert.Equal(t, 0, len(oL2Txs))
 225	assert.Equal(t, common.BatchNum(4), txsel.localAccountsDB.CurrentBatch())
 226	assert.Equal(t, common.Idx(258), txsel.localAccountsDB.CurrentIdx())
 227	checkBalance(t, tc, txsel, "A", 0, "500")
 228	checkBalance(t, tc, txsel, "A", 1, "500")
 229	checkBalance(t, tc, txsel, "C", 1, "0")
 230
 231	log.Debug("block:0 batch:5")
 232	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
 233	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
 234		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 235	require.NoError(t, err)
 236	assert.Equal(t, 0, len(oL1UserTxs))
 237	assert.Equal(t, 0, len(oL1CoordTxs))
 238	assert.Equal(t, 0, len(oL2Txs))
 239	assert.Equal(t, common.BatchNum(5), txsel.localAccountsDB.CurrentBatch())
 240	assert.Equal(t, common.Idx(258), txsel.localAccountsDB.CurrentIdx())
 241	checkBalance(t, tc, txsel, "A", 0, "500")
 242	checkBalance(t, tc, txsel, "A", 1, "500")
 243	checkBalance(t, tc, txsel, "C", 1, "0")
 244
 245	log.Debug("block:0 batch:6")
 246	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
 247	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
 248		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 249	require.NoError(t, err)
 250	assert.Equal(t, 1, len(oL1UserTxs))
 251	assert.Equal(t, 0, len(oL1CoordTxs))
 252	assert.Equal(t, 0, len(oL2Txs))
 253	assert.Equal(t, common.BatchNum(6), txsel.localAccountsDB.CurrentBatch())
 254	assert.Equal(t, common.Idx(259), txsel.localAccountsDB.CurrentIdx())
 255	checkBalance(t, tc, txsel, "A", 0, "600")
 256	checkBalance(t, tc, txsel, "A", 1, "500")
 257	checkBalance(t, tc, txsel, "B", 0, "400")
 258	checkBalance(t, tc, txsel, "C", 1, "0")
 259
 260	log.Debug("block:0 batch:7")
 261	// simulate the PoolL2Txs of the batch7
 262	batchPoolL2 := `
 263	Type: PoolL2
 264	PoolTransferToEthAddr(1) A-B: 200 (126)
 265	PoolTransferToEthAddr(0) B-C: 100 (126)`
 266	poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
 267	require.NoError(t, err)
 268	// add AccountCreationAuths that will be used at the next batch
 269	accAuthSig0 := addAccCreationAuth(t, tc, txsel, chainID, hermezContractAddr, "B")
 270	accAuthSig1 := addAccCreationAuth(t, tc, txsel, chainID, hermezContractAddr, "C")
 271	// add the PoolL2Txs to the l2DB
 272	addL2Txs(t, txsel, poolL2Txs)
 273	// check signatures of L2Txs from the L2DB (to check that the
 274	// parameters of the PoolL2Tx match the original parameters signed
 275	// before inserting it to the L2DB)
 276	l2TxsFromDB, err := txsel.l2db.GetPendingTxs()
 277	require.NoError(t, err)
 278	assert.True(t, l2TxsFromDB[0].VerifySignature(chainID, tc.Users["A"].BJJ.Public().Compress()))
 279	assert.True(t, l2TxsFromDB[1].VerifySignature(chainID, tc.Users["B"].BJJ.Public().Compress()))
 280	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
 281	coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
 282		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 283	require.NoError(t, err)
 284	assert.Equal(t, []common.Idx{261, 263}, coordIdxs)
 285	assert.Equal(t, txsel.coordAccount.AccountCreationAuth, accAuths[0])
 286	assert.Equal(t, txsel.coordAccount.AccountCreationAuth, accAuths[2])
 287	assert.Equal(t, accAuthSig0, accAuths[1])
 288	assert.Equal(t, accAuthSig1, accAuths[3])
 289	assert.Equal(t, 1, len(oL1UserTxs))
 290	assert.Equal(t, 4, len(oL1CoordTxs))
 291	assert.Equal(t, 2, len(oL2Txs))
 292	assert.Equal(t, 0, len(discardedL2Txs))
 293	assert.Equal(t, len(oL1CoordTxs), len(accAuths))
 294	assert.Equal(t, common.BatchNum(7), txsel.localAccountsDB.CurrentBatch())
 295	assert.Equal(t, common.Idx(264), txsel.localAccountsDB.CurrentIdx())
 296	checkBalance(t, tc, txsel, "Coord", 1, "20") // CoordIdx for TokenID=1
 297	checkBalance(t, tc, txsel, "Coord", 0, "10") // CoordIdx for TokenID=1
 298	checkBalance(t, tc, txsel, "A", 0, "600")
 299	checkBalance(t, tc, txsel, "A", 1, "280")
 300	checkBalance(t, tc, txsel, "B", 0, "290")
 301	checkBalance(t, tc, txsel, "B", 1, "200")
 302	checkBalance(t, tc, txsel, "C", 0, "100")
 303	checkBalance(t, tc, txsel, "D", 0, "800")
 304	checkSortedByNonce(t, testAccNonces, oL2Txs)
 305	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs),
 306		txsel.localAccountsDB.CurrentBatch())
 307	require.NoError(t, err)
 308
 309	log.Debug("block:0 batch:8")
 310	// simulate the PoolL2Txs of the batch8
 311	batchPoolL2 = `
 312	Type: PoolL2
 313	PoolTransfer(0) A-B: 100 (126)
 314	PoolTransfer(0) C-A: 50 (126)
 315	PoolTransfer(1) B-C: 100 (126)
 316	PoolExit(0) A: 100 (126)`
 317	poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
 318	require.NoError(t, err)
 319	addL2Txs(t, txsel, poolL2Txs)
 320	// check signatures of L2Txs from the L2DB (to check that the
 321	// parameters of the PoolL2Tx match the original parameters signed
 322	// before inserting it to the L2DB)
 323	l2TxsFromDB, err = txsel.l2db.GetPendingTxs()
 324	require.NoError(t, err)
 325	assert.True(t, l2TxsFromDB[0].VerifySignature(chainID, tc.Users["A"].BJJ.Public().Compress()))
 326	assert.True(t, l2TxsFromDB[1].VerifySignature(chainID, tc.Users["C"].BJJ.Public().Compress()))
 327	assert.True(t, l2TxsFromDB[2].VerifySignature(chainID, tc.Users["B"].BJJ.Public().Compress()))
 328	assert.True(t, l2TxsFromDB[3].VerifySignature(chainID, tc.Users["A"].BJJ.Public().Compress()))
 329	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
 330	coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
 331		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 332	require.NoError(t, err)
 333	assert.Equal(t, []common.Idx{261, 263}, coordIdxs)
 334	assert.Equal(t, 0, len(accAuths))
 335	assert.Equal(t, 0, len(oL1UserTxs))
 336	assert.Equal(t, 0, len(oL1CoordTxs))
 337	assert.Equal(t, 4, len(oL2Txs))
 338	assert.Equal(t, 0, len(discardedL2Txs))
 339	assert.Equal(t, len(oL1CoordTxs), len(accAuths))
 340	assert.Equal(t, common.BatchNum(8), txsel.localAccountsDB.CurrentBatch())
 341	assert.Equal(t, common.Idx(264), txsel.localAccountsDB.CurrentIdx())
 342	checkBalance(t, tc, txsel, "Coord", 1, "30") // CoordIdx for TokenID=1
 343	checkBalance(t, tc, txsel, "Coord", 0, "35") // CoordIdx for TokenID=1
 344	checkBalance(t, tc, txsel, "A", 0, "430")
 345	checkBalance(t, tc, txsel, "A", 1, "280")
 346	checkBalance(t, tc, txsel, "B", 0, "390")
 347	checkBalance(t, tc, txsel, "B", 1, "90")
 348	checkBalance(t, tc, txsel, "C", 0, "45")
 349	checkBalance(t, tc, txsel, "C", 1, "100")
 350	checkBalance(t, tc, txsel, "D", 0, "800")
 351	checkSortedByNonce(t, testAccNonces, oL2Txs)
 352	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs),
 353		txsel.localAccountsDB.CurrentBatch())
 354	require.NoError(t, err)
 355
 356	log.Debug("(batch9)block:1 batch:1")
 357	// simulate the PoolL2Txs of the batch9
 358	batchPoolL2 = `
 359	Type: PoolL2
 360	PoolTransfer(0) D-A: 300 (126)
 361	PoolTransfer(0) B-D: 100 (126)
 362	`
 363	poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
 364	require.NoError(t, err)
 365	addL2Txs(t, txsel, poolL2Txs)
 366	// check signatures of L2Txs from the L2DB (to check that the
 367	// parameters of the PoolL2Tx match the original parameters signed
 368	// before inserting it to the L2DB)
 369	l2TxsFromDB, err = txsel.l2db.GetPendingTxs()
 370	require.NoError(t, err)
 371	assert.True(t, l2TxsFromDB[0].VerifySignature(chainID, tc.Users["D"].BJJ.Public().Compress()))
 372	assert.True(t, l2TxsFromDB[1].VerifySignature(chainID, tc.Users["B"].BJJ.Public().Compress()))
 373	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
 374	coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
 375		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 376	require.NoError(t, err)
 377	assert.Equal(t, []common.Idx{263}, coordIdxs)
 378	assert.Equal(t, 0, len(accAuths))
 379	assert.Equal(t, 4, len(oL1UserTxs))
 380	assert.Equal(t, 0, len(oL1CoordTxs))
 381	assert.Equal(t, 2, len(oL2Txs))
 382	assert.Equal(t, len(oL1CoordTxs), len(accAuths))
 383	assert.Equal(t, common.BatchNum(9), txsel.localAccountsDB.CurrentBatch())
 384	assert.Equal(t, common.Idx(264), txsel.localAccountsDB.CurrentIdx())
 385	checkBalanceByIdx(t, txsel, 261, "30")
 386	checkBalanceByIdx(t, txsel, 263, "75")
 387	checkBalance(t, tc, txsel, "A", 0, "730")
 388	checkBalance(t, tc, txsel, "A", 1, "280")
 389	checkBalance(t, tc, txsel, "B", 0, "380")
 390	checkBalance(t, tc, txsel, "B", 1, "90")
 391	checkBalance(t, tc, txsel, "C", 0, "845")
 392	checkBalance(t, tc, txsel, "C", 1, "100")
 393	checkBalance(t, tc, txsel, "D", 0, "470")
 394	checkSortedByNonce(t, testAccNonces, oL2Txs)
 395	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs),
 396		txsel.localAccountsDB.CurrentBatch())
 397	require.NoError(t, err)
 398}
 399
 400func TestPoolL2TxsWithoutEnoughBalance(t *testing.T) {
 401	set := `
 402		Type: Blockchain
 403
 404		CreateAccountDeposit(0) Coord: 0
 405		CreateAccountDeposit(0) A: 100
 406		CreateAccountDeposit(0) B: 100
 407
 408		> batchL1 // freeze L1User{3}
 409		> batchL1 // forge L1User{3}
 410		> block
 411	`
 412
 413	chainID := uint16(0)
 414	tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
 415	// generate test transactions, the L1CoordinatorTxs generated by Til
 416	// will be ignored at this test, as will be the TxSelector who
 417	// generates them when needed
 418	blocks, err := tc.GenerateBlocks(set)
 419	assert.NoError(t, err)
 420
 421	hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
 422	txsel, _ := initTest(t, chainID, hermezContractAddr, tc.Users["Coord"])
 423
 424	// restart nonces of TilContext, as will be set by generating directly
 425	// the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
 426	tc.RestartNonces()
 427
 428	tpc := txprocessor.Config{
 429		NLevels:  16,
 430		MaxFeeTx: 10,
 431		MaxTx:    20,
 432		MaxL1Tx:  10,
 433		ChainID:  chainID,
 434	}
 435	// batch1
 436	l1UserTxs := []common.L1Tx{}
 437	_, _, _, _, _, _, err = txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 438	require.NoError(t, err)
 439	// 1st TransferToEthAddr
 440	expectedTxID0 := "0x028847b86613c0b70be18c8622119ed045b42e4e47d7938fa90bb3d1dc14928965"
 441	// 1st Exit
 442	expectedTxID1 := "0x0200b18773dcf56f770d65870fb02041cb59a088fd35b7c3f3df69f8a250b99a42"
 443	// 2nd TransferToEthAddr
 444	expectedTxID2 := "0x029720ff506153f970f120ac638cd7ee759eeff2c2012e7634a78e4fdc05c04a90"
 445
 446	// batch2
 447	// prepare the PoolL2Txs
 448	batchPoolL2 := `
 449	Type: PoolL2
 450	PoolTransferToEthAddr(0) A-B: 100 (126)
 451	PoolExit(0) B: 100 (126)`
 452	poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
 453	require.NoError(t, err)
 454	// add the PoolL2Txs to the l2DB
 455	addL2Txs(t, txsel, poolL2Txs)
 456
 457	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
 458	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
 459		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 460	require.NoError(t, err)
 461	assert.Equal(t, 3, len(oL1UserTxs))
 462	assert.Equal(t, 0, len(oL1CoordTxs))
 463	assert.Equal(t, 0, len(oL2Txs)) // should be 0 as the 2 PoolL2Txs does not have enough funds
 464	assert.Equal(t, 2, len(discardedL2Txs))
 465	assert.Equal(t, expectedTxID0, discardedL2Txs[0].TxID.String())
 466	assert.Equal(t, expectedTxID1, discardedL2Txs[1].TxID.String())
 467	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 468		txsel.localAccountsDB.CurrentBatch())
 469	require.NoError(t, err)
 470
 471	// as the PoolL2Txs have not been really processed, restart nonces
 472	tc.RestartNonces()
 473
 474	// batch3
 475	batchPoolL2 = `
 476	Type: PoolL2
 477	PoolTransferToEthAddr(0) A-B: 50 (126)`
 478	poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
 479	require.NoError(t, err)
 480	addL2Txs(t, txsel, poolL2Txs)
 481
 482	l1UserTxs = []common.L1Tx{}
 483	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
 484		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 485	require.NoError(t, err)
 486	assert.Equal(t, 0, len(oL1UserTxs))
 487	assert.Equal(t, 0, len(oL1CoordTxs))
 488	assert.Equal(t, 2, len(oL2Txs))
 489	assert.Equal(t, 1, len(discardedL2Txs))
 490	assert.Equal(t, expectedTxID2, oL2Txs[0].TxID.String())
 491	assert.Equal(t, expectedTxID1, oL2Txs[1].TxID.String())
 492	assert.Equal(t, expectedTxID0, discardedL2Txs[0].TxID.String())
 493	assert.Equal(t, common.TxTypeTransferToEthAddr, oL2Txs[0].Type)
 494	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 495		txsel.localAccountsDB.CurrentBatch())
 496	require.NoError(t, err)
 497
 498	// batch4
 499	// make the selection of another batch, which should include the
 500	// initial PoolExit, which now is valid as B has enough Balance
 501	l1UserTxs = []common.L1Tx{}
 502	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
 503		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 504	require.NoError(t, err)
 505	assert.Equal(t, 0, len(oL1UserTxs))
 506	assert.Equal(t, 0, len(oL1CoordTxs))
 507	assert.Equal(t, 0, len(oL2Txs))
 508	assert.Equal(t, 1, len(discardedL2Txs))
 509	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 510		txsel.localAccountsDB.CurrentBatch())
 511	require.NoError(t, err)
 512}
 513
 514func TestTransferToBjj(t *testing.T) {
 515	set := `
 516		Type: Blockchain
 517		AddToken(1)
 518
 519		CreateAccountDeposit(0) Coord: 0
 520		CreateAccountDeposit(0) A: 1000
 521		CreateAccountDeposit(0) B: 1000
 522		CreateAccountDeposit(1) B: 1000
 523
 524		> batchL1 // freeze L1User{4}
 525		> batchL1 // forge L1User{4}
 526		> block
 527	`
 528
 529	chainID := uint16(0)
 530	tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
 531	blocks, err := tc.GenerateBlocks(set)
 532	assert.NoError(t, err)
 533
 534	hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
 535	txsel, _ := initTest(t, chainID, hermezContractAddr, tc.Users["Coord"])
 536
 537	// restart nonces of TilContext, as will be set by generating directly
 538	// the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
 539	tc.RestartNonces()
 540
 541	addTokens(t, tc, txsel.l2db.DB())
 542
 543	tpc := txprocessor.Config{
 544		NLevels:  16,
 545		MaxFeeTx: 10,
 546		MaxTx:    20,
 547		MaxL1Tx:  10,
 548		ChainID:  chainID,
 549	}
 550	// batch1 to freeze L1UserTxs that will create some accounts with
 551	// positive balance
 552	l1UserTxs := []common.L1Tx{}
 553	_, _, _, _, _, _, err = txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 554	require.NoError(t, err)
 555
 556	// Transfer is ToBJJ to a BJJ-only account that doesn't exist
 557	// and the coordinator will create it via L1CoordTx.
 558
 559	batchPoolL2 := `
 560	Type: PoolL2
 561	PoolTransferToBJJ(0) A-B: 50 (126)
 562	`
 563	poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
 564	require.NoError(t, err)
 565
 566	// add the PoolL2Txs to the l2DB
 567	addL2Txs(t, txsel, poolL2Txs)
 568
 569	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
 570	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
 571		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 572	require.NoError(t, err)
 573	assert.Equal(t, 4, len(oL1UserTxs))
 574	// We expect the coordinator to add an L1CoordTx to create an account for the recipient of the l2tx
 575	require.Equal(t, 1, len(oL1CoordTxs))
 576	assert.Equal(t, poolL2Txs[0].ToEthAddr, oL1CoordTxs[0].FromEthAddr)
 577	assert.Equal(t, poolL2Txs[0].ToBJJ, oL1CoordTxs[0].FromBJJ)
 578	assert.Equal(t, 1, len(oL2Txs))
 579	assert.Equal(t, 0, len(discardedL2Txs))
 580	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 581		txsel.localAccountsDB.CurrentBatch())
 582	require.NoError(t, err)
 583
 584	// Now the BJJ-only account for B is already created, so the transfer
 585	// happens without an L1CoordTx that creates the user account.
 586
 587	batchPoolL2 = `
 588	Type: PoolL2
 589	PoolTransferToBJJ(0) A-B: 50 (126)
 590	`
 591
 592	poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
 593	require.NoError(t, err)
 594	addL2Txs(t, txsel, poolL2Txs)
 595
 596	l1UserTxs = []common.L1Tx{}
 597	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
 598		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 599	require.NoError(t, err)
 600	assert.Equal(t, 0, len(oL1UserTxs))
 601	// Since the BJJ-only account B already exists, the coordinator doesn't add any L1CoordTxs
 602	assert.Equal(t, 0, len(oL1CoordTxs))
 603	assert.Equal(t, 1, len(oL2Txs))
 604	assert.Equal(t, 0, len(discardedL2Txs))
 605	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 606		txsel.localAccountsDB.CurrentBatch())
 607	require.NoError(t, err)
 608
 609	// The transfer now is ToBJJ to a BJJ-only account that doesn't exist
 610	// and the coordinator will create it via L1CoordTx.   Since it's a
 611	// transfer of a token for which the coordinator doesn't have a fee
 612	// account, another L1CoordTx will be created for the coordinator to
 613	// receive the fees.
 614
 615	batchPoolL2 = `
 616	Type: PoolL2
 617	PoolTransferToBJJ(1) B-A: 50 (126)
 618	`
 619
 620	poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
 621	require.NoError(t, err)
 622	addL2Txs(t, txsel, poolL2Txs)
 623
 624	l1UserTxs = []common.L1Tx{}
 625	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
 626		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 627	require.NoError(t, err)
 628	assert.Equal(t, 0, len(oL1UserTxs))
 629	// We expect the coordinator to add an L1CoordTx to create an account
 630	// to receive the fees by the coordinator and another one for the
 631	// recipient of the l2tx
 632	assert.Equal(t, 2, len(oL1CoordTxs))
 633	// [0] Coordinator account cration for token 1
 634	assert.Equal(t, tc.Users["Coord"].Addr, oL1CoordTxs[0].FromEthAddr)
 635	// [1] User A BJJ-only account creation for token 1
 636	assert.Equal(t, poolL2Txs[0].ToEthAddr, oL1CoordTxs[1].FromEthAddr)
 637	assert.Equal(t, poolL2Txs[0].ToBJJ, oL1CoordTxs[1].FromBJJ)
 638	assert.Equal(t, common.TokenID(1), oL1CoordTxs[1].TokenID)
 639
 640	assert.Equal(t, 1, len(oL2Txs))
 641	assert.Equal(t, 0, len(discardedL2Txs))
 642	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 643		txsel.localAccountsDB.CurrentBatch())
 644	require.NoError(t, err)
 645}
 646
 647func TestTransferManyFromSameAccount(t *testing.T) {
 648	set := `
 649		Type: Blockchain
 650
 651		CreateAccountDeposit(0) Coord: 0
 652		CreateAccountDeposit(0) A: 1000
 653		CreateAccountDeposit(0) B: 1000
 654
 655		> batchL1 // freeze L1User{3}
 656		> batchL1 // forge L1User{3}
 657		> block
 658	`
 659
 660	chainID := uint16(0)
 661	tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
 662	blocks, err := tc.GenerateBlocks(set)
 663	assert.NoError(t, err)
 664
 665	hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
 666	txsel, _ := initTest(t, chainID, hermezContractAddr, tc.Users["Coord"])
 667
 668	// restart nonces of TilContext, as will be set by generating directly
 669	// the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
 670	tc.RestartNonces()
 671
 672	tpc := txprocessor.Config{
 673		NLevels:  16,
 674		MaxFeeTx: 10,
 675		MaxTx:    10,
 676		MaxL1Tx:  10,
 677		ChainID:  chainID,
 678	}
 679	// batch1 to freeze L1UserTxs
 680	l1UserTxs := []common.L1Tx{}
 681	_, _, _, _, _, _, err = txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 682	require.NoError(t, err)
 683
 684	// 8 transfers from the same account
 685	batchPoolL2 := `
 686	Type: PoolL2
 687	PoolTransfer(0) A-B: 10 (126) // 1
 688	PoolTransfer(0) A-B: 10 (126) // 2
 689	PoolTransfer(0) A-B: 10 (126) // 3
 690	PoolTransfer(0) A-B: 10 (126) // 4
 691	PoolTransfer(0) A-B: 10 (126) // 5
 692	PoolTransfer(0) A-B: 10 (126) // 6
 693	PoolTransfer(0) A-B: 10 (126) // 7
 694	PoolTransfer(0) A-B: 10 (126) // 8
 695	PoolTransfer(0) A-B: 10 (126) // 9
 696	PoolTransfer(0) A-B: 10 (126) // 10
 697	PoolTransfer(0) A-B: 10 (126) // 11
 698	`
 699	poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
 700	require.NoError(t, err)
 701	require.Equal(t, 11, len(poolL2Txs))
 702
 703	// reorder poolL2Txs so that nonces are not sorted
 704	poolL2Txs[0], poolL2Txs[7] = poolL2Txs[7], poolL2Txs[0]
 705	poolL2Txs[1], poolL2Txs[10] = poolL2Txs[10], poolL2Txs[1]
 706
 707	// add the PoolL2Txs to the l2DB
 708	addL2Txs(t, txsel, poolL2Txs)
 709	// batch 2 to crate some accounts with positive balance, and do 8 L2Tx
 710	// transfers from account A
 711	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
 712	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
 713		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 714	require.NoError(t, err)
 715	assert.Equal(t, 3, len(oL1UserTxs))
 716	require.Equal(t, 0, len(oL1CoordTxs))
 717	assert.Equal(t, 7, len(oL2Txs))
 718	assert.Equal(t, 4, len(discardedL2Txs))
 719
 720	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 721		txsel.localAccountsDB.CurrentBatch())
 722	require.NoError(t, err)
 723}
 724
 725func TestPoolL2TxInvalidNonces(t *testing.T) {
 726	// This test recreates the case where L2Txs of type TransferToEthAddr
 727	// for non existing accounts are not selected due not enough space for
 728	// the needed L1CoordinatorTxs (of account creation).
 729
 730	set := `
 731		Type: Blockchain
 732
 733		CreateAccountDeposit(0) Coord: 0
 734		CreateAccountDeposit(0) A: 100000
 735		CreateAccountDeposit(0) B: 10000
 736
 737		> batchL1 // Batch1: freeze L1User{3}
 738		> batchL1 // Batch2: forge L1User{3}
 739		> block
 740	`
 741
 742	chainID := uint16(0)
 743	tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
 744	blocks, err := tc.GenerateBlocks(set)
 745	assert.NoError(t, err)
 746
 747	hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
 748	txsel, _ := initTest(t, chainID, hermezContractAddr, tc.Users["Coord"])
 749
 750	// restart nonces of TilContext, as will be set by generating directly
 751	// the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
 752	tc.RestartNonces()
 753
 754	tpc := txprocessor.Config{
 755		NLevels:  16,
 756		MaxFeeTx: 10,
 757		MaxTx:    20,
 758		MaxL1Tx:  3,
 759		ChainID:  chainID,
 760	}
 761	// batch1 to freeze L1UserTxs
 762	l1UserTxs := []common.L1Tx{}
 763	_, _, _, _, _, _, err = txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 764	require.NoError(t, err)
 765
 766	batchPoolL2 := `
 767	Type: PoolL2
 768	PoolTransferToEthAddr(0) B-C: 10 (126)
 769	PoolTransfer(0) B-A: 10 (126)
 770	PoolTransferToEthAddr(0) B-D: 10 (126)
 771	PoolTransfer(0) B-A: 10 (126)
 772	PoolTransferToEthAddr(0) B-E: 10 (126)
 773	PoolTransfer(0) B-A: 10 (126)
 774	PoolTransferToEthAddr(0) B-F: 10 (126)
 775	PoolTransfer(0) B-A: 10 (126)
 776	PoolTransferToEthAddr(0) B-G: 10 (126)
 777	PoolTransfer(0) B-A: 10 (126)
 778	`
 779	poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
 780	require.NoError(t, err)
 781	require.Equal(t, 10, len(poolL2Txs))
 782
 783	// add AccountCreationAuths that will be used at the next batch
 784	_ = addAccCreationAuth(t, tc, txsel, chainID, hermezContractAddr, "C")
 785	_ = addAccCreationAuth(t, tc, txsel, chainID, hermezContractAddr, "D")
 786	_ = addAccCreationAuth(t, tc, txsel, chainID, hermezContractAddr, "E")
 787	_ = addAccCreationAuth(t, tc, txsel, chainID, hermezContractAddr, "F")
 788	_ = addAccCreationAuth(t, tc, txsel, chainID, hermezContractAddr, "G")
 789
 790	// add the PoolL2Txs to the l2DB
 791	addL2Txs(t, txsel, poolL2Txs)
 792	// batch 2 to crate the accounts (from L1UserTxs)
 793	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
 794
 795	// select L1 & L2 txs
 796	_, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
 797		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 798	require.NoError(t, err)
 799	require.Equal(t, 3, len(oL1UserTxs))
 800	require.Equal(t, 0, len(oL1CoordTxs))
 801	require.Equal(t, 0, len(oL2Txs))
 802	require.Equal(t, 10, len(discardedL2Txs))
 803	require.Equal(t, 0, len(accAuths))
 804
 805	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 806		txsel.localAccountsDB.CurrentBatch())
 807	require.NoError(t, err)
 808
 809	// batch 3
 810	l1UserTxs = []common.L1Tx{}
 811	_, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
 812		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 813	require.NoError(t, err)
 814
 815	require.Equal(t, 0, len(oL1UserTxs))
 816	require.Equal(t, 3, len(oL1CoordTxs))
 817	require.Equal(t, 8, len(oL2Txs))
 818	require.Equal(t, 2, len(discardedL2Txs))
 819	require.Equal(t, 3, len(accAuths))
 820
 821	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 822		txsel.localAccountsDB.CurrentBatch())
 823	require.NoError(t, err)
 824
 825	// batch 4
 826	l1UserTxs = []common.L1Tx{}
 827	_, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
 828		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 829	require.NoError(t, err)
 830
 831	require.Equal(t, 0, len(oL1UserTxs))
 832	require.Equal(t, 1, len(oL1CoordTxs))
 833	require.Equal(t, 2, len(oL2Txs))
 834	require.Equal(t, 0, len(discardedL2Txs))
 835	require.Equal(t, 1, len(accAuths))
 836
 837	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 838		txsel.localAccountsDB.CurrentBatch())
 839	require.NoError(t, err)
 840}
 841
 842func TestProcessL2Selection(t *testing.T) {
 843	set := `
 844		Type: Blockchain
 845
 846		CreateAccountDeposit(0) Coord: 0
 847		CreateAccountDeposit(0) A: 18
 848		CreateAccountDeposit(0) B: 0
 849
 850		> batchL1 // freeze L1User{3}
 851		> batchL1 // forge L1User{3}
 852		> block
 853	`
 854
 855	chainID := uint16(0)
 856	tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
 857	blocks, err := tc.GenerateBlocks(set)
 858	assert.NoError(t, err)
 859
 860	hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
 861	txsel, _ := initTest(t, chainID, hermezContractAddr, tc.Users["Coord"])
 862
 863	// restart nonces of TilContext, as will be set by generating directly
 864	// the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
 865	tc.RestartNonces()
 866
 867	tpc := txprocessor.Config{
 868		NLevels:  16,
 869		MaxFeeTx: 10,
 870		MaxTx:    10,
 871		MaxL1Tx:  10,
 872		ChainID:  chainID,
 873	}
 874	// batch1 to freeze L1UserTxs
 875	l1UserTxs := []common.L1Tx{}
 876	_, _, _, _, _, _, err = txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 877	require.NoError(t, err)
 878
 879	// 8 transfers from the same account
 880	batchPoolL2 := `
 881	Type: PoolL2
 882	PoolTransfer(0) A-B: 10 (126)
 883	PoolTransfer(0) A-B: 10 (126) // not enough funds
 884	PoolTransfer(0) A-B: 5 (126) // enough funds
 885	`
 886	poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
 887	require.NoError(t, err)
 888	require.Equal(t, 3, len(poolL2Txs))
 889
 890	// add the PoolL2Txs to the l2DB
 891	addL2Txs(t, txsel, poolL2Txs)
 892	// batch 2 to crate some accounts with positive balance, and do 8 L2Tx transfers from account A
 893	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
 894	_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
 895		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 896	require.NoError(t, err)
 897	assert.Equal(t, 3, len(oL1UserTxs))
 898	require.Equal(t, 0, len(oL1CoordTxs))
 899	// only 1st L2Tx should be accepted, as:
 900	// - 2nd will not be selected as has not enough funds
 901	// - 3rd will not be selected as has Nonce=2, and the account Nonce==1
 902	// (due the 2nd txs not being accepted)
 903	assert.Equal(t, 1, len(oL2Txs))
 904	assert.Equal(t, 2, len(discardedL2Txs))
 905	assert.Equal(t, common.Nonce(0), oL2Txs[0].Nonce)
 906	assert.Equal(t, common.Nonce(1), discardedL2Txs[0].Nonce)
 907	assert.Equal(t, common.Nonce(2), discardedL2Txs[1].Nonce)
 908	assert.Equal(t, "Tx not selected due to not enough Balance at the sender. "+
 909		"Current sender account Balance: 7, Amount+Fee: 11", discardedL2Txs[0].Info)
 910	assert.Equal(t, "Tx not selected due to not current Nonce. Tx.Nonce: 2, "+
 911		"Account.Nonce: 1", discardedL2Txs[1].Info)
 912
 913	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 914		txsel.localAccountsDB.CurrentBatch())
 915	require.NoError(t, err)
 916}
 917
 918func TestValidTxsWithLowFeeAndInvalidTxsWithHighFee(t *testing.T) {
 919	// This test recreates the case where there are
 920
 921	set := `
 922		Type: Blockchain
 923
 924		CreateAccountDeposit(0) Coord: 0
 925		CreateAccountDeposit(0) A: 100
 926		CreateAccountDeposit(0) B: 0
 927
 928		> batchL1 // Batch1: freeze L1User{3}
 929		> batchL1 // Batch2: forge L1User{3}
 930		> block
 931	`
 932
 933	chainID := uint16(0)
 934	tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
 935	tilCfgExtra := til.ConfigExtra{
 936		BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
 937		CoordUser:     "Coord",
 938	}
 939	blocks, err := tc.GenerateBlocks(set)
 940	require.NoError(t, err)
 941	err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
 942	require.NoError(t, err)
 943	err = tc.FillBlocksForgedL1UserTxs(blocks)
 944	require.NoError(t, err)
 945
 946	hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
 947	txsel, historyDB := initTest(t, chainID, hermezContractAddr, tc.Users["Coord"])
 948
 949	// Insert blocks into DB
 950	for i := range blocks {
 951		err = historyDB.AddBlockSCData(&blocks[i])
 952		assert.NoError(t, err)
 953	}
 954
 955	err = historyDB.UpdateTokenValue(common.EmptyAddr, 1000)
 956	require.NoError(t, err)
 957
 958	// restart nonces of TilContext, as will be set by generating directly
 959	// the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
 960	tc.RestartNonces()
 961
 962	tpc := txprocessor.Config{
 963		NLevels:  16,
 964		MaxFeeTx: 5,
 965		MaxTx:    5,
 966		MaxL1Tx:  3,
 967		ChainID:  chainID,
 968	}
 969	// batch1 to freeze L1UserTxs
 970	l1UserTxs := []common.L1Tx{}
 971	_, _, _, _, _, _, err = txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 972	require.NoError(t, err)
 973
 974	// batch 2 to crate the accounts (from L1UserTxs)
 975	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
 976
 977	// select L1 & L2 txs
 978	_, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
 979		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
 980	require.NoError(t, err)
 981	require.Equal(t, 3, len(oL1UserTxs))
 982	require.Equal(t, 0, len(oL1CoordTxs))
 983	require.Equal(t, 0, len(oL2Txs))
 984	require.Equal(t, 0, len(discardedL2Txs))
 985	require.Equal(t, 0, len(accAuths))
 986
 987	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
 988		txsel.localAccountsDB.CurrentBatch())
 989	require.NoError(t, err)
 990
 991	// batch 3. The A-B txs have lower fee, but are the only ones possible
 992	// with the current Accounts Balances, as the B-A tx of amount 40 will
 993	// not be included as will be processed first when there is not enough
 994	// balance at B (processed first as the TxSelector sorts by Fee and then
 995	// by Nonce).
 996	batchPoolL2 := `
 997	Type: PoolL2
 998	PoolTransfer(0) B-A: 40 (130) // B-A txs are only possible once A-B txs are processed
 999	PoolTransfer(0) B-A: 1 (126)
1000	PoolTransfer(0) B-A: 1 (126)
1001	PoolTransfer(0) B-A: 1 (126)
1002	PoolTransfer(0) B-A: 1 (126)
1003	PoolTransfer(0) B-A: 1 (126)
1004	PoolTransfer(0) B-A: 1 (126)
1005	PoolTransfer(0) B-A: 1 (126)
1006	PoolTransfer(0) A-B: 20 (20)
1007	PoolTransfer(0) A-B: 25 (150)
1008	PoolTransfer(0) A-B: 20 (20)
1009	`
1010	poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
1011	require.NoError(t, err)
1012	require.Equal(t, 11, len(poolL2Txs))
1013	// add the PoolL2Txs to the l2DB
1014	addL2Txs(t, txsel, poolL2Txs)
1015	l1UserTxs = []common.L1Tx{}
1016	_, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
1017		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
1018	require.NoError(t, err)
1019
1020	require.Equal(t, 0, len(oL1UserTxs))
1021	require.Equal(t, 0, len(oL1CoordTxs))
1022	require.Equal(t, 3, len(oL2Txs))         // the 3 txs A-B
1023	require.Equal(t, 8, len(discardedL2Txs)) // the 8 txs B-A
1024	require.Equal(t, 0, len(accAuths))
1025
1026	err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
1027		txsel.localAccountsDB.CurrentBatch())
1028	require.NoError(t, err)
1029
1030	// batch 4. In this Batch, account B has enough balance to send the txs
1031	_, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
1032		txsel.GetL1L2TxSelection(tpc, l1UserTxs)
1033	require.NoError(t, err)
1034
1035	require.Equal(t, 0, len(oL1UserTxs))
1036	require.Equal(t, 0, len(oL1CoordTxs))
1037	require.Equal(t, 5, len(oL2Txs))
1038	require.Equal(t, 3, len(discardedL2Txs))
1039	require.Equal(t, 0, len(accAuths))
1040}