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