hermez-node/db/statedb/txprocessors_test.go
db/statedb/txprocessors_test.goRaw
1package statedb
2
3import (
4 "encoding/binary"
5 "encoding/hex"
6 "io/ioutil"
7 "math/big"
8 "os"
9 "testing"
10
11 ethCommon "github.com/ethereum/go-ethereum/common"
12 "github.com/hermeznetwork/hermez-node/common"
13 "github.com/hermeznetwork/hermez-node/log"
14 "github.com/hermeznetwork/hermez-node/test/til"
15 "github.com/stretchr/testify/assert"
16 "github.com/stretchr/testify/require"
17)
18
19func checkBalance(t *testing.T, tc *til.Context, sdb *StateDB, username string, tokenid int, expected string) {
20 idx := tc.Users[username].Accounts[common.TokenID(tokenid)].Idx
21 acc, err := sdb.GetAccount(idx)
22 require.Nil(t, err)
23 assert.Equal(t, expected, acc.Balance.String())
24}
25
26func TestComputeEffectiveAmounts(t *testing.T) {
27 dir, err := ioutil.TempDir("", "tmpdb")
28 require.Nil(t, err)
29 defer assert.Nil(t, os.RemoveAll(dir))
30
31 sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
32 assert.Nil(t, err)
33
34 set := `
35 Type: Blockchain
36 AddToken(1)
37
38 CreateAccountDeposit(0) A: 10
39 CreateAccountDeposit(0) B: 10
40 CreateAccountDeposit(1) C: 10
41 > batchL1
42 > batchL1
43 > block
44 `
45 tc := til.NewContext(common.RollupConstMaxL1UserTx)
46 blocks, err := tc.GenerateBlocks(set)
47 require.Nil(t, err)
48
49 ptc := ProcessTxsConfig{
50 NLevels: 32,
51 MaxFeeTx: 64,
52 MaxTx: 512,
53 MaxL1Tx: 16,
54 }
55 _, err = sdb.ProcessTxs(ptc, nil, blocks[0].Rollup.L1UserTxs, nil, nil)
56 require.Nil(t, err)
57
58 tx := common.L1Tx{
59 FromIdx: 256,
60 ToIdx: 257,
61 Amount: big.NewInt(10),
62 DepositAmount: big.NewInt(0),
63 FromEthAddr: tc.Users["A"].Addr,
64 UserOrigin: true,
65 }
66 sdb.computeEffectiveAmounts(&tx)
67 assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
68 assert.Equal(t, big.NewInt(10), tx.EffectiveAmount)
69
70 // expect error due not enough funds
71 tx = common.L1Tx{
72 FromIdx: 256,
73 ToIdx: 257,
74 Amount: big.NewInt(11),
75 DepositAmount: big.NewInt(0),
76 FromEthAddr: tc.Users["A"].Addr,
77 UserOrigin: true,
78 }
79 sdb.computeEffectiveAmounts(&tx)
80 assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
81 assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
82
83 // expect no-error as there are enough funds in a
84 // CreateAccountDepositTransfer transction
85 tx = common.L1Tx{
86 FromIdx: 0,
87 ToIdx: 257,
88 Amount: big.NewInt(10),
89 DepositAmount: big.NewInt(10),
90 UserOrigin: true,
91 }
92 sdb.computeEffectiveAmounts(&tx)
93 assert.Equal(t, big.NewInt(10), tx.EffectiveDepositAmount)
94 assert.Equal(t, big.NewInt(10), tx.EffectiveAmount)
95
96 // expect error due not enough funds in a CreateAccountDepositTransfer
97 // transction
98 tx = common.L1Tx{
99 FromIdx: 0,
100 ToIdx: 257,
101 Amount: big.NewInt(11),
102 DepositAmount: big.NewInt(10),
103 UserOrigin: true,
104 }
105 sdb.computeEffectiveAmounts(&tx)
106 assert.Equal(t, big.NewInt(10), tx.EffectiveDepositAmount)
107 assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
108
109 // expect error due not same TokenID
110 tx = common.L1Tx{
111 FromIdx: 256,
112 ToIdx: 258,
113 Amount: big.NewInt(5),
114 DepositAmount: big.NewInt(0),
115 FromEthAddr: tc.Users["A"].Addr,
116 UserOrigin: true,
117 }
118 sdb.computeEffectiveAmounts(&tx)
119 assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
120 assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
121
122 // expect error due not same EthAddr
123 tx = common.L1Tx{
124 FromIdx: 256,
125 ToIdx: 257,
126 Amount: big.NewInt(8),
127 DepositAmount: big.NewInt(0),
128 FromEthAddr: tc.Users["B"].Addr,
129 UserOrigin: true,
130 }
131 sdb.computeEffectiveAmounts(&tx)
132 assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
133 assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
134
135 // expect on TxTypeDepositTransfer EffectiveAmount=0, but
136 // EffectiveDepositAmount!=0, due not enough funds to make the transfer
137 tx = common.L1Tx{
138 FromIdx: 256,
139 ToIdx: 257,
140 Amount: big.NewInt(20),
141 DepositAmount: big.NewInt(8),
142 FromEthAddr: tc.Users["A"].Addr,
143 UserOrigin: true,
144 }
145 sdb.computeEffectiveAmounts(&tx)
146 assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
147 assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
148
149 // expect on TxTypeDepositTransfer EffectiveAmount=0, but
150 // EffectiveDepositAmount!=0, due different EthAddr from FromIdx
151 // address
152 tx = common.L1Tx{
153 FromIdx: 256,
154 ToIdx: 257,
155 Amount: big.NewInt(8),
156 DepositAmount: big.NewInt(8),
157 FromEthAddr: tc.Users["B"].Addr,
158 UserOrigin: true,
159 }
160 sdb.computeEffectiveAmounts(&tx)
161 assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
162 assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
163}
164
165func TestProcessTxsBalances(t *testing.T) {
166 dir, err := ioutil.TempDir("", "tmpdb")
167 require.Nil(t, err)
168 defer assert.Nil(t, os.RemoveAll(dir))
169
170 sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
171 assert.Nil(t, err)
172
173 // generate test transactions from test.SetBlockchain0 code
174 tc := til.NewContext(common.RollupConstMaxL1UserTx)
175 blocks, err := tc.GenerateBlocks(til.SetBlockchainMinimumFlow0)
176 require.Nil(t, err)
177
178 // Coordinator Idx where to send the fees
179 coordIdxs := []common.Idx{256, 257}
180 ptc := ProcessTxsConfig{
181 NLevels: 32,
182 MaxFeeTx: 64,
183 MaxTx: 512,
184 MaxL1Tx: 16,
185 }
186
187 log.Debug("block:0 batch:0, only L1CoordinatorTxs")
188 _, err = sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
189 require.Nil(t, err)
190
191 log.Debug("block:0 batch:1")
192 l1UserTxs := []common.L1Tx{}
193 l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
194 _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
195 require.Nil(t, err)
196
197 log.Debug("block:0 batch:2")
198 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
199 l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
200 _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
201 require.Nil(t, err)
202 checkBalance(t, tc, sdb, "A", 0, "500")
203
204 log.Debug("block:0 batch:3")
205 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
206 l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[3].L2Txs)
207 _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[3].L1CoordinatorTxs, l2Txs)
208 require.Nil(t, err)
209 checkBalance(t, tc, sdb, "A", 0, "500")
210 checkBalance(t, tc, sdb, "A", 1, "500")
211
212 log.Debug("block:0 batch:4")
213 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
214 l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[4].L2Txs)
215 _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[4].L1CoordinatorTxs, l2Txs)
216 require.Nil(t, err)
217 checkBalance(t, tc, sdb, "A", 0, "500")
218 checkBalance(t, tc, sdb, "A", 1, "500")
219
220 log.Debug("block:0 batch:5")
221 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
222 l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[5].L2Txs)
223 _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[5].L1CoordinatorTxs, l2Txs)
224 require.Nil(t, err)
225 checkBalance(t, tc, sdb, "A", 0, "600")
226 checkBalance(t, tc, sdb, "A", 1, "500")
227 checkBalance(t, tc, sdb, "B", 0, "400")
228
229 log.Debug("block:0 batch:6")
230 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
231 l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[6].L2Txs)
232 _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
233 require.Nil(t, err)
234 checkBalance(t, tc, sdb, "Coord", 0, "10")
235 checkBalance(t, tc, sdb, "Coord", 1, "20")
236 checkBalance(t, tc, sdb, "A", 0, "600")
237 checkBalance(t, tc, sdb, "A", 1, "280")
238 checkBalance(t, tc, sdb, "B", 0, "290")
239 checkBalance(t, tc, sdb, "B", 1, "200")
240 checkBalance(t, tc, sdb, "C", 0, "100")
241 checkBalance(t, tc, sdb, "D", 0, "800")
242
243 log.Debug("block:0 batch:7")
244 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
245 l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[7].L2Txs)
246 _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
247 require.Nil(t, err)
248 checkBalance(t, tc, sdb, "Coord", 0, "35")
249 checkBalance(t, tc, sdb, "Coord", 1, "30")
250 checkBalance(t, tc, sdb, "A", 0, "430")
251 checkBalance(t, tc, sdb, "A", 1, "280")
252 checkBalance(t, tc, sdb, "B", 0, "390")
253 checkBalance(t, tc, sdb, "B", 1, "90")
254 checkBalance(t, tc, sdb, "C", 0, "45")
255 checkBalance(t, tc, sdb, "C", 1, "100")
256 checkBalance(t, tc, sdb, "D", 0, "800")
257
258 log.Debug("block:1 batch:0")
259 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
260 l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
261 _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
262 require.Nil(t, err)
263 checkBalance(t, tc, sdb, "Coord", 0, "75")
264 checkBalance(t, tc, sdb, "Coord", 1, "30")
265 checkBalance(t, tc, sdb, "A", 0, "730")
266 checkBalance(t, tc, sdb, "A", 1, "280")
267 checkBalance(t, tc, sdb, "B", 0, "380")
268 checkBalance(t, tc, sdb, "B", 1, "90")
269 checkBalance(t, tc, sdb, "C", 0, "845")
270 checkBalance(t, tc, sdb, "C", 1, "100")
271 checkBalance(t, tc, sdb, "D", 0, "470")
272
273 log.Debug("block:1 batch:1")
274 l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
275 l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
276 _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
277 require.Nil(t, err)
278
279 // use Set of PoolL2 txs
280 poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPoolL2MinimumFlow1)
281 assert.Nil(t, err)
282
283 _, err = sdb.ProcessTxs(ptc, coordIdxs, []common.L1Tx{}, []common.L1Tx{}, poolL2Txs)
284 require.Nil(t, err)
285 checkBalance(t, tc, sdb, "Coord", 0, "105")
286 checkBalance(t, tc, sdb, "Coord", 1, "40")
287 checkBalance(t, tc, sdb, "A", 0, "510")
288 checkBalance(t, tc, sdb, "A", 1, "170")
289 checkBalance(t, tc, sdb, "B", 0, "480")
290 checkBalance(t, tc, sdb, "B", 1, "190")
291 checkBalance(t, tc, sdb, "C", 0, "845")
292 checkBalance(t, tc, sdb, "C", 1, "100")
293 checkBalance(t, tc, sdb, "D", 0, "360")
294 checkBalance(t, tc, sdb, "F", 0, "100")
295}
296
297func TestProcessTxsSynchronizer(t *testing.T) {
298 dir, err := ioutil.TempDir("", "tmpdb")
299 require.Nil(t, err)
300 defer assert.Nil(t, os.RemoveAll(dir))
301
302 sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
303 assert.Nil(t, err)
304
305 // generate test transactions from test.SetBlockchain0 code
306 tc := til.NewContext(common.RollupConstMaxL1UserTx)
307 blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
308 require.Nil(t, err)
309
310 assert.Equal(t, 31, len(blocks[0].Rollup.L1UserTxs))
311 assert.Equal(t, 4, len(blocks[0].Rollup.Batches[0].L1CoordinatorTxs))
312 assert.Equal(t, 0, len(blocks[0].Rollup.Batches[1].L1CoordinatorTxs))
313 assert.Equal(t, 22, len(blocks[0].Rollup.Batches[2].L2Txs))
314 assert.Equal(t, 1, len(blocks[1].Rollup.Batches[0].L1CoordinatorTxs))
315 assert.Equal(t, 62, len(blocks[1].Rollup.Batches[0].L2Txs))
316 assert.Equal(t, 1, len(blocks[1].Rollup.Batches[1].L1CoordinatorTxs))
317 assert.Equal(t, 8, len(blocks[1].Rollup.Batches[1].L2Txs))
318
319 // Coordinator Idx where to send the fees
320 coordIdxs := []common.Idx{256, 257, 258, 259}
321
322 // Idx of user 'A'
323 idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
324
325 ptc := ProcessTxsConfig{
326 NLevels: 32,
327 MaxFeeTx: 64,
328 MaxTx: 512,
329 MaxL1Tx: 32,
330 }
331
332 // Process the 1st batch, which contains the L1CoordinatorTxs necessary
333 // to create the Coordinator accounts to receive the fees
334 log.Debug("block:0 batch:0, only L1CoordinatorTxs")
335 ptOut, err := sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
336 require.Nil(t, err)
337 assert.Equal(t, 4, len(ptOut.CreatedAccounts))
338 assert.Equal(t, 0, len(ptOut.CollectedFees))
339
340 log.Debug("block:0 batch:1")
341 l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
342 ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[0].Rollup.L1UserTxs,
343 blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
344 require.Nil(t, err)
345 assert.Equal(t, 0, len(ptOut.ExitInfos))
346 assert.Equal(t, 31, len(ptOut.CreatedAccounts))
347 assert.Equal(t, 4, len(ptOut.CollectedFees))
348 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
349 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
350 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
351 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
352 acc, err := sdb.GetAccount(idxA1)
353 require.Nil(t, err)
354 assert.Equal(t, "50", acc.Balance.String())
355
356 log.Debug("block:0 batch:2")
357 l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
358 ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
359 require.Nil(t, err)
360 assert.Equal(t, 0, len(ptOut.ExitInfos))
361 assert.Equal(t, 0, len(ptOut.CreatedAccounts))
362 assert.Equal(t, 4, len(ptOut.CollectedFees))
363 assert.Equal(t, "2", ptOut.CollectedFees[common.TokenID(0)].String())
364 assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
365 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
366 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
367 acc, err = sdb.GetAccount(idxA1)
368 require.Nil(t, err)
369 assert.Equal(t, "35", acc.Balance.String())
370
371 log.Debug("block:1 batch:0")
372 l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
373 // before processing expect l2Txs[0:2].Nonce==0
374 assert.Equal(t, common.Nonce(0), l2Txs[0].Nonce)
375 assert.Equal(t, common.Nonce(0), l2Txs[1].Nonce)
376 assert.Equal(t, common.Nonce(0), l2Txs[2].Nonce)
377
378 ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
379 require.Nil(t, err)
380
381 // after processing expect l2Txs[0:2].Nonce!=0 and has expected value
382 assert.Equal(t, common.Nonce(6), l2Txs[0].Nonce)
383 assert.Equal(t, common.Nonce(7), l2Txs[1].Nonce)
384 assert.Equal(t, common.Nonce(8), l2Txs[2].Nonce)
385
386 assert.Equal(t, 4, len(ptOut.ExitInfos)) // the 'ForceExit(1)' is not computed yet, as the batch is without L1UserTxs
387 assert.Equal(t, 1, len(ptOut.CreatedAccounts))
388 assert.Equal(t, 4, len(ptOut.CollectedFees))
389 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
390 assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
391 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
392 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
393 acc, err = sdb.GetAccount(idxA1)
394 require.Nil(t, err)
395 assert.Equal(t, "57", acc.Balance.String())
396
397 log.Debug("block:1 batch:1")
398 l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
399 ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[1].Rollup.L1UserTxs,
400 blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
401 require.Nil(t, err)
402
403 assert.Equal(t, 2, len(ptOut.ExitInfos)) // 2, as previous batch was without L1UserTxs, and has pending the 'ForceExit(1) A: 5'
404 assert.Equal(t, 1, len(ptOut.CreatedAccounts))
405 assert.Equal(t, 4, len(ptOut.CollectedFees))
406 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
407 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
408 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
409 assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
410 acc, err = sdb.GetAccount(idxA1)
411 assert.Nil(t, err)
412 assert.Equal(t, "77", acc.Balance.String())
413
414 idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
415 acc, err = sdb.GetAccount(idxB0)
416 require.Nil(t, err)
417 assert.Equal(t, "51", acc.Balance.String())
418
419 // get balance of Coordinator account for TokenID==0
420 acc, err = sdb.GetAccount(common.Idx(256))
421 require.Nil(t, err)
422 assert.Equal(t, "2", acc.Balance.String())
423}
424
425func TestProcessTxsBatchBuilder(t *testing.T) {
426 dir, err := ioutil.TempDir("", "tmpdb")
427 require.Nil(t, err)
428 defer assert.Nil(t, os.RemoveAll(dir))
429
430 sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
431 assert.Nil(t, err)
432
433 // generate test transactions from test.SetBlockchain0 code
434 tc := til.NewContext(common.RollupConstMaxL1UserTx)
435 blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
436 require.Nil(t, err)
437
438 // Coordinator Idx where to send the fees
439 coordIdxs := []common.Idx{256, 257, 258, 259}
440
441 // Idx of user 'A'
442 idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
443
444 ptc := ProcessTxsConfig{
445 NLevels: 32,
446 MaxFeeTx: 64,
447 MaxTx: 512,
448 MaxL1Tx: 32,
449 }
450
451 // Process the 1st batch, which contains the L1CoordinatorTxs necessary
452 // to create the Coordinator accounts to receive the fees
453 log.Debug("block:0 batch:0, only L1CoordinatorTxs")
454 ptOut, err := sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
455 require.Nil(t, err)
456 // expect 0 at CreatedAccount, as is only computed when StateDB.Type==TypeSynchronizer
457 assert.Equal(t, 0, len(ptOut.CreatedAccounts))
458
459 log.Debug("block:0 batch:1")
460 l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
461 ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[0].Rollup.L1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
462 require.Nil(t, err)
463 assert.Equal(t, 0, len(ptOut.ExitInfos))
464 assert.Equal(t, 0, len(ptOut.CreatedAccounts))
465 acc, err := sdb.GetAccount(idxA1)
466 require.Nil(t, err)
467 assert.Equal(t, "50", acc.Balance.String())
468
469 log.Debug("block:0 batch:2")
470 l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
471 ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
472 require.Nil(t, err)
473 assert.Equal(t, 0, len(ptOut.ExitInfos))
474 assert.Equal(t, 0, len(ptOut.CreatedAccounts))
475 acc, err = sdb.GetAccount(idxA1)
476 require.Nil(t, err)
477 assert.Equal(t, "35", acc.Balance.String())
478
479 log.Debug("block:1 batch:0")
480 l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
481 _, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
482 require.Nil(t, err)
483 acc, err = sdb.GetAccount(idxA1)
484 require.Nil(t, err)
485 assert.Equal(t, "57", acc.Balance.String())
486
487 log.Debug("block:1 batch:1")
488 l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
489 _, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[1].Rollup.L1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
490 require.Nil(t, err)
491 acc, err = sdb.GetAccount(idxA1)
492 assert.Nil(t, err)
493 assert.Equal(t, "77", acc.Balance.String())
494
495 idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
496 acc, err = sdb.GetAccount(idxB0)
497 require.Nil(t, err)
498 assert.Equal(t, "51", acc.Balance.String())
499
500 // get balance of Coordinator account for TokenID==0
501 acc, err = sdb.GetAccount(common.Idx(256))
502 require.Nil(t, err)
503 assert.Equal(t, common.TokenID(0), acc.TokenID)
504 assert.Equal(t, "2", acc.Balance.String())
505 acc, err = sdb.GetAccount(common.Idx(257))
506 require.Nil(t, err)
507 assert.Equal(t, common.TokenID(1), acc.TokenID)
508 assert.Equal(t, "2", acc.Balance.String())
509
510 assert.Equal(t, "2720257526434001367979405991743527513807903085728407823609738212616896104498", sdb.mt.Root().BigInt().String())
511}
512
513func TestProcessTxsRootTestVectors(t *testing.T) {
514 dir, err := ioutil.TempDir("", "tmpdb")
515 require.Nil(t, err)
516 defer assert.Nil(t, os.RemoveAll(dir))
517
518 sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
519 assert.Nil(t, err)
520
521 // same values than in the js test
522 bjj0, err := common.BJJFromStringWithChecksum("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
523 assert.Nil(t, err)
524 l1Txs := []common.L1Tx{
525 {
526 FromIdx: 0,
527 DepositAmount: big.NewInt(16000000),
528 Amount: big.NewInt(0),
529 TokenID: 1,
530 FromBJJ: bjj0,
531 FromEthAddr: ethCommon.HexToAddress("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"),
532 ToIdx: 0,
533 Type: common.TxTypeCreateAccountDeposit,
534 UserOrigin: true,
535 },
536 }
537 l2Txs := []common.PoolL2Tx{
538 {
539 FromIdx: 256,
540 ToIdx: 256,
541 TokenID: 1,
542 Amount: big.NewInt(1000),
543 Nonce: 0,
544 Fee: 126,
545 Type: common.TxTypeTransfer,
546 },
547 }
548
549 ptc := ProcessTxsConfig{
550 NLevels: 32,
551 MaxFeeTx: 8,
552 MaxTx: 32,
553 MaxL1Tx: 16,
554 }
555 _, err = sdb.ProcessTxs(ptc, nil, l1Txs, nil, l2Txs)
556 require.Nil(t, err)
557 assert.Equal(t, "9827704113668630072730115158977131501210702363656902211840117643154933433410", sdb.mt.Root().BigInt().String())
558}
559
560func TestCreateAccountDepositMaxValue(t *testing.T) {
561 dir, err := ioutil.TempDir("", "tmpdb")
562 require.Nil(t, err)
563 defer assert.Nil(t, os.RemoveAll(dir))
564
565 nLevels := 16
566
567 sdb, err := NewStateDB(dir, TypeBatchBuilder, nLevels)
568 assert.Nil(t, err)
569
570 users := generateJsUsers(t)
571
572 daMaxHex, err := hex.DecodeString("FFFF")
573 require.Nil(t, err)
574 daMaxF16 := common.Float16(binary.BigEndian.Uint16(daMaxHex))
575 daMaxBI := daMaxF16.BigInt()
576 assert.Equal(t, "10235000000000000000000000000000000", daMaxBI.String())
577
578 daMax1Hex, err := hex.DecodeString("FFFE")
579 require.Nil(t, err)
580 daMax1F16 := common.Float16(binary.BigEndian.Uint16(daMax1Hex))
581 daMax1BI := daMax1F16.BigInt()
582 assert.Equal(t, "10225000000000000000000000000000000", daMax1BI.String())
583
584 l1Txs := []common.L1Tx{
585 {
586 FromIdx: 0,
587 DepositAmount: daMaxBI,
588 Amount: big.NewInt(0),
589 TokenID: 1,
590 FromBJJ: users[0].BJJ.Public(),
591 FromEthAddr: users[0].Addr,
592 ToIdx: 0,
593 Type: common.TxTypeCreateAccountDeposit,
594 UserOrigin: true,
595 },
596 {
597 FromIdx: 0,
598 DepositAmount: daMax1BI,
599 Amount: big.NewInt(0),
600 TokenID: 1,
601 FromBJJ: users[1].BJJ.Public(),
602 FromEthAddr: users[1].Addr,
603 ToIdx: 0,
604 Type: common.TxTypeCreateAccountDeposit,
605 UserOrigin: true,
606 },
607 }
608
609 ptc := ProcessTxsConfig{
610 NLevels: uint32(nLevels),
611 MaxTx: 3,
612 MaxL1Tx: 2,
613 MaxFeeTx: 2,
614 }
615
616 _, err = sdb.ProcessTxs(ptc, nil, l1Txs, nil, nil)
617 require.Nil(t, err)
618
619 // check balances
620 acc, err := sdb.GetAccount(common.Idx(256))
621 require.Nil(t, err)
622 assert.Equal(t, daMaxBI, acc.Balance)
623 acc, err = sdb.GetAccount(common.Idx(257))
624 require.Nil(t, err)
625 assert.Equal(t, daMax1BI, acc.Balance)
626}