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