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