hermez-node/txselector/txselector_test.go
txselector/txselector_test.goRaw
1package txselector
2
3import (
4 "io/ioutil"
5 "os"
6 "strconv"
7 "testing"
8 "time"
9
10 ethCommon "github.com/ethereum/go-ethereum/common"
11 "github.com/hermeznetwork/hermez-node/common"
12 dbUtils "github.com/hermeznetwork/hermez-node/db"
13 "github.com/hermeznetwork/hermez-node/db/historydb"
14 "github.com/hermeznetwork/hermez-node/db/l2db"
15 "github.com/hermeznetwork/hermez-node/db/statedb"
16 "github.com/hermeznetwork/hermez-node/test"
17 "github.com/hermeznetwork/hermez-node/test/til"
18 "github.com/jmoiron/sqlx"
19 "github.com/stretchr/testify/assert"
20 "github.com/stretchr/testify/require"
21)
22
23func initTest(t *testing.T, testSet string) *TxSelector {
24 pass := os.Getenv("POSTGRES_PASS")
25 db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
26 require.NoError(t, err)
27 l2DB := l2db.NewL2DB(db, 10, 100, 24*time.Hour)
28
29 dir, err := ioutil.TempDir("", "tmpdb")
30 require.NoError(t, err)
31 defer assert.Nil(t, os.RemoveAll(dir))
32 sdb, err := statedb.NewStateDB(dir, statedb.TypeTxSelector, 0)
33 require.NoError(t, err)
34
35 txselDir, err := ioutil.TempDir("", "tmpTxSelDB")
36 require.NoError(t, err)
37 defer assert.Nil(t, os.RemoveAll(dir))
38
39 coordAccount := &CoordAccount{ // TODO TMP
40 Addr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
41 BJJ: nil,
42 AccountCreationAuth: nil,
43 }
44
45 txsel, err := NewTxSelector(coordAccount, txselDir, sdb, l2DB)
46 require.NoError(t, err)
47
48 return txsel
49}
50func addL2Txs(t *testing.T, txsel *TxSelector, poolL2Txs []common.PoolL2Tx) {
51 for i := 0; i < len(poolL2Txs); i++ {
52 err := txsel.l2db.AddTxTest(&poolL2Txs[i])
53 require.NoError(t, err)
54 }
55}
56
57func addTokens(t *testing.T, tokens []common.Token, db *sqlx.DB) {
58 hdb := historydb.NewHistoryDB(db)
59 test.WipeDB(hdb.DB())
60 assert.NoError(t, hdb.AddBlock(&common.Block{
61 Num: 1,
62 }))
63 assert.NoError(t, hdb.AddTokens(tokens))
64}
65
66func TestCoordIdxsDB(t *testing.T) {
67 txsel := initTest(t, til.SetPool0)
68 test.WipeDB(txsel.l2db.DB())
69
70 coordIdxs := make(map[common.TokenID]common.Idx)
71 coordIdxs[common.TokenID(0)] = common.Idx(256)
72 coordIdxs[common.TokenID(1)] = common.Idx(257)
73 coordIdxs[common.TokenID(2)] = common.Idx(258)
74
75 err := txsel.AddCoordIdxs(coordIdxs)
76 assert.NoError(t, err)
77
78 r, err := txsel.GetCoordIdxs()
79 assert.NoError(t, err)
80 assert.Equal(t, coordIdxs, r)
81}
82
83func TestGetL2TxSelection(t *testing.T) {
84 txsel := initTest(t, til.SetPool0)
85 test.WipeDB(txsel.l2db.DB())
86
87 tc := til.NewContext(common.RollupConstMaxL1UserTx)
88 // generate test transactions
89 blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
90 assert.NoError(t, err)
91 // poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPool0)
92 // assert.Nil(t, err)
93
94 coordIdxs := make(map[common.TokenID]common.Idx)
95 coordIdxs[common.TokenID(0)] = common.Idx(256)
96 coordIdxs[common.TokenID(1)] = common.Idx(257)
97 coordIdxs[common.TokenID(2)] = common.Idx(258)
98 coordIdxs[common.TokenID(3)] = common.Idx(259)
99 err = txsel.AddCoordIdxs(coordIdxs)
100 assert.NoError(t, err)
101
102 // add tokens to HistoryDB to avoid breaking FK constrains
103 var tokens []common.Token
104 for i := 0; i < int(tc.LastRegisteredTokenID); i++ {
105 tokens = append(tokens, common.Token{
106 TokenID: common.TokenID(i + 1),
107 EthBlockNum: 1,
108 EthAddr: ethCommon.BytesToAddress([]byte{byte(i + 1)}),
109 Name: strconv.Itoa(i),
110 Symbol: strconv.Itoa(i),
111 Decimals: 18,
112 })
113 }
114 addTokens(t, tokens, txsel.l2db.DB())
115
116 ptc := statedb.ProcessTxsConfig{
117 NLevels: 32,
118 MaxFeeTx: 64,
119 MaxTx: 512,
120 MaxL1Tx: 64,
121 }
122 selectionConfig := &SelectionConfig{
123 MaxL1UserTxs: 32,
124 MaxL1CoordinatorTxs: 32,
125 ProcessTxsConfig: ptc,
126 }
127
128 // Process the 1st batch, which contains the L1CoordinatorTxs necessary
129 // to create the Coordinator accounts to receive the fees
130 _, err = txsel.localAccountsDB.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
131 require.NoError(t, err)
132
133 // add the 1st batch of transactions to the TxSelector
134 addL2Txs(t, txsel, common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[0].L2Txs))
135
136 _, l1CoordTxs, l2Txs, err := txsel.GetL2TxSelection(selectionConfig, 0)
137 assert.NoError(t, err)
138 assert.Equal(t, 0, len(l2Txs))
139 assert.Equal(t, 0, len(l1CoordTxs))
140
141 _, _, _, _, err = txsel.GetL1L2TxSelection(selectionConfig, 0, blocks[0].Rollup.L1UserTxs)
142 assert.NoError(t, err)
143
144 // TODO once L2DB is updated to return error in case that AddTxTest
145 // fails, and the Til is updated, update this test, checking that the
146 // selected PoolL2Tx are correctly sorted by Nonce
147
148 // TODO once L2DB is updated to store the parameter AbsoluteFee (which
149 // is used by TxSelector to sort L2Txs), uncomment this next lines of
150 // test, and put the expected value for
151 // l2Txs[len(l2Txs)-1].AbsoluteFee, which is the Tx which has the
152 // Fee==192.
153 /*
154 // add the 3rd batch of transactions to the TxSelector
155 addL2Txs(t, txsel, common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs))
156
157 _, l2Txs, err = txsel.GetL2TxSelection(coordIdxs, 0)
158 assert.Nil(t, err)
159 for _, tx := range l2Txs {
160 fmt.Println(tx.FromIdx, tx.ToIdx, tx.AbsoluteFee)
161 }
162 require.Equal(t, 10, len(l2Txs))
163 assert.Equal(t, float64(0), l2Txs[0].AbsoluteFee)
164
165 fmt.Println(l2Txs[len(l2Txs)-1].Amount)
166 assert.Equal(t, float64(4), l2Txs[len(l2Txs)-1].AbsoluteFee)
167 */
168}