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/hex"
  5	"encoding/json"
  6	"fmt"
  7	"io/ioutil"
  8	"math/big"
  9	"os"
 10	"testing"
 11
 12	ethCommon "github.com/ethereum/go-ethereum/common"
 13	"github.com/hermeznetwork/hermez-node/common"
 14	"github.com/hermeznetwork/hermez-node/log"
 15	"github.com/hermeznetwork/hermez-node/test/til"
 16	"github.com/stretchr/testify/assert"
 17	"github.com/stretchr/testify/require"
 18)
 19
 20func checkBalance(t *testing.T, tc *til.Context, sdb *StateDB, username string, tokenid int, expected string) {
 21	idx := tc.Users[username].Accounts[common.TokenID(tokenid)].Idx
 22	acc, err := sdb.GetAccount(idx)
 23	require.Nil(t, err)
 24	assert.Equal(t, expected, acc.Balance.String())
 25}
 26
 27func TestCheckL1TxInvalidData(t *testing.T) {
 28	dir, err := ioutil.TempDir("", "tmpdb")
 29	require.Nil(t, err)
 30	defer assert.Nil(t, os.RemoveAll(dir))
 31
 32	sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
 33	assert.Nil(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(common.RollupConstMaxL1UserTx)
 47	blocks, err := tc.GenerateBlocks(set)
 48	require.Nil(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.Nil(t, err)
 58
 59	tx := common.L1Tx{
 60		FromIdx:     256,
 61		ToIdx:       257,
 62		Amount:      big.NewInt(10),
 63		LoadAmount:  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.EffectiveLoadAmount)
 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		LoadAmount:  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.EffectiveLoadAmount)
 82	assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
 83
 84	// expect no-error due not enough funds in a
 85	// CreateAccountDepositTransfer transction
 86	tx = common.L1Tx{
 87		FromIdx:    0,
 88		ToIdx:      257,
 89		Amount:     big.NewInt(10),
 90		LoadAmount: big.NewInt(10),
 91		UserOrigin: true,
 92	}
 93	sdb.computeEffectiveAmounts(&tx)
 94	assert.Equal(t, big.NewInt(10), tx.EffectiveLoadAmount)
 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		LoadAmount: big.NewInt(10),
104		UserOrigin: true,
105	}
106	sdb.computeEffectiveAmounts(&tx)
107	assert.Equal(t, big.NewInt(10), tx.EffectiveLoadAmount)
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		LoadAmount:  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.EffectiveLoadAmount)
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		LoadAmount:  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.EffectiveLoadAmount)
134	assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
135}
136
137func TestProcessTxsBalances(t *testing.T) {
138	dir, err := ioutil.TempDir("", "tmpdb")
139	require.Nil(t, err)
140	defer assert.Nil(t, os.RemoveAll(dir))
141
142	sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
143	assert.Nil(t, err)
144
145	// generate test transactions from test.SetBlockchain0 code
146	tc := til.NewContext(common.RollupConstMaxL1UserTx)
147	blocks, err := tc.GenerateBlocks(til.SetBlockchainMinimumFlow0)
148	require.Nil(t, err)
149
150	// Coordinator Idx where to send the fees
151	coordIdxs := []common.Idx{256, 257}
152	ptc := ProcessTxsConfig{
153		NLevels:  32,
154		MaxFeeTx: 64,
155		MaxTx:    512,
156		MaxL1Tx:  16,
157	}
158
159	log.Debug("block:0 batch:0, only L1CoordinatorTxs")
160	_, err = sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
161	require.Nil(t, err)
162
163	log.Debug("block:0 batch:1")
164	l1UserTxs := []common.L1Tx{}
165	l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
166	_, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
167	require.Nil(t, err)
168
169	log.Debug("block:0 batch:2")
170	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
171	l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
172	_, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
173	require.Nil(t, err)
174	checkBalance(t, tc, sdb, "A", 0, "500")
175
176	log.Debug("block:0 batch:3")
177	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
178	l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[3].L2Txs)
179	_, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[3].L1CoordinatorTxs, l2Txs)
180	require.Nil(t, err)
181	checkBalance(t, tc, sdb, "A", 0, "500")
182	checkBalance(t, tc, sdb, "A", 1, "500")
183
184	log.Debug("block:0 batch:4")
185	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
186	l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[4].L2Txs)
187	_, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[4].L1CoordinatorTxs, l2Txs)
188	require.Nil(t, err)
189	checkBalance(t, tc, sdb, "A", 0, "500")
190	checkBalance(t, tc, sdb, "A", 1, "500")
191
192	log.Debug("block:0 batch:5")
193	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
194	l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[5].L2Txs)
195	_, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[5].L1CoordinatorTxs, l2Txs)
196	require.Nil(t, err)
197	checkBalance(t, tc, sdb, "A", 0, "600")
198	checkBalance(t, tc, sdb, "A", 1, "500")
199	checkBalance(t, tc, sdb, "B", 0, "400")
200
201	log.Debug("block:0 batch:6")
202	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
203	l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[6].L2Txs)
204	_, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
205	require.Nil(t, err)
206	checkBalance(t, tc, sdb, "Coord", 0, "10")
207	checkBalance(t, tc, sdb, "Coord", 1, "20")
208	checkBalance(t, tc, sdb, "A", 0, "600")
209	checkBalance(t, tc, sdb, "A", 1, "280")
210	checkBalance(t, tc, sdb, "B", 0, "290")
211	checkBalance(t, tc, sdb, "B", 1, "200")
212	checkBalance(t, tc, sdb, "C", 0, "100")
213	checkBalance(t, tc, sdb, "D", 0, "800")
214
215	log.Debug("block:0 batch:7")
216	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
217	l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[7].L2Txs)
218	_, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
219	require.Nil(t, err)
220	checkBalance(t, tc, sdb, "Coord", 0, "35")
221	checkBalance(t, tc, sdb, "Coord", 1, "30")
222	checkBalance(t, tc, sdb, "A", 0, "430")
223	checkBalance(t, tc, sdb, "A", 1, "280")
224	checkBalance(t, tc, sdb, "B", 0, "390")
225	checkBalance(t, tc, sdb, "B", 1, "90")
226	checkBalance(t, tc, sdb, "C", 0, "45")
227	checkBalance(t, tc, sdb, "C", 1, "100")
228	checkBalance(t, tc, sdb, "D", 0, "800")
229
230	log.Debug("block:1 batch:0")
231	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
232	l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
233	_, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
234	require.Nil(t, err)
235	checkBalance(t, tc, sdb, "Coord", 0, "75")
236	checkBalance(t, tc, sdb, "Coord", 1, "30")
237	checkBalance(t, tc, sdb, "A", 0, "730")
238	checkBalance(t, tc, sdb, "A", 1, "280")
239	checkBalance(t, tc, sdb, "B", 0, "380")
240	checkBalance(t, tc, sdb, "B", 1, "90")
241	checkBalance(t, tc, sdb, "C", 0, "845")
242	checkBalance(t, tc, sdb, "C", 1, "100")
243	checkBalance(t, tc, sdb, "D", 0, "470")
244
245	log.Debug("block:1 batch:1")
246	l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
247	l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
248	_, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
249	require.Nil(t, err)
250
251	// use Set of PoolL2 txs
252	poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPoolL2MinimumFlow1)
253	assert.Nil(t, err)
254
255	_, err = sdb.ProcessTxs(ptc, coordIdxs, []common.L1Tx{}, []common.L1Tx{}, poolL2Txs)
256	require.Nil(t, err)
257	checkBalance(t, tc, sdb, "Coord", 0, "105")
258	checkBalance(t, tc, sdb, "Coord", 1, "40")
259	checkBalance(t, tc, sdb, "A", 0, "510")
260	checkBalance(t, tc, sdb, "A", 1, "170")
261	checkBalance(t, tc, sdb, "B", 0, "480")
262	checkBalance(t, tc, sdb, "B", 1, "190")
263	checkBalance(t, tc, sdb, "C", 0, "845")
264	checkBalance(t, tc, sdb, "C", 1, "100")
265	checkBalance(t, tc, sdb, "D", 0, "360")
266	checkBalance(t, tc, sdb, "F", 0, "100")
267}
268
269func TestProcessTxsSynchronizer(t *testing.T) {
270	dir, err := ioutil.TempDir("", "tmpdb")
271	require.Nil(t, err)
272	defer assert.Nil(t, os.RemoveAll(dir))
273
274	sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
275	assert.Nil(t, err)
276
277	// generate test transactions from test.SetBlockchain0 code
278	tc := til.NewContext(common.RollupConstMaxL1UserTx)
279	blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
280	require.Nil(t, err)
281
282	assert.Equal(t, 31, len(blocks[0].Rollup.L1UserTxs))
283	assert.Equal(t, 4, len(blocks[0].Rollup.Batches[0].L1CoordinatorTxs))
284	assert.Equal(t, 0, len(blocks[0].Rollup.Batches[1].L1CoordinatorTxs))
285	assert.Equal(t, 22, len(blocks[0].Rollup.Batches[2].L2Txs))
286	assert.Equal(t, 1, len(blocks[1].Rollup.Batches[0].L1CoordinatorTxs))
287	assert.Equal(t, 62, len(blocks[1].Rollup.Batches[0].L2Txs))
288	assert.Equal(t, 1, len(blocks[1].Rollup.Batches[1].L1CoordinatorTxs))
289	assert.Equal(t, 8, len(blocks[1].Rollup.Batches[1].L2Txs))
290
291	// Coordinator Idx where to send the fees
292	coordIdxs := []common.Idx{256, 257, 258, 259}
293
294	// Idx of user 'A'
295	idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
296
297	ptc := ProcessTxsConfig{
298		NLevels:  32,
299		MaxFeeTx: 64,
300		MaxTx:    512,
301		MaxL1Tx:  16,
302	}
303
304	// Process the 1st batch, which contains the L1CoordinatorTxs necessary
305	// to create the Coordinator accounts to receive the fees
306	log.Debug("block:0 batch:0, only L1CoordinatorTxs")
307	ptOut, err := sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
308	require.Nil(t, err)
309	assert.Equal(t, 4, len(ptOut.CreatedAccounts))
310	assert.Equal(t, 0, len(ptOut.CollectedFees))
311
312	log.Debug("block:0 batch:1")
313	l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
314	ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[0].Rollup.L1UserTxs,
315		blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
316	require.Nil(t, err)
317	assert.Equal(t, 0, len(ptOut.ExitInfos))
318	assert.Equal(t, 31, len(ptOut.CreatedAccounts))
319	assert.Equal(t, 4, len(ptOut.CollectedFees))
320	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
321	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
322	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
323	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
324	acc, err := sdb.GetAccount(idxA1)
325	require.Nil(t, err)
326	assert.Equal(t, "50", acc.Balance.String())
327
328	log.Debug("block:0 batch:2")
329	l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
330	ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
331	require.Nil(t, err)
332	assert.Equal(t, 0, len(ptOut.ExitInfos))
333	assert.Equal(t, 0, len(ptOut.CreatedAccounts))
334	assert.Equal(t, 4, len(ptOut.CollectedFees))
335	assert.Equal(t, "2", ptOut.CollectedFees[common.TokenID(0)].String())
336	assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
337	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
338	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
339	acc, err = sdb.GetAccount(idxA1)
340	require.Nil(t, err)
341	assert.Equal(t, "35", acc.Balance.String())
342
343	log.Debug("block:1 batch:0")
344	l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
345	// before processing expect l2Txs[0:2].Nonce==0
346	assert.Equal(t, common.Nonce(0), l2Txs[0].Nonce)
347	assert.Equal(t, common.Nonce(0), l2Txs[1].Nonce)
348	assert.Equal(t, common.Nonce(0), l2Txs[2].Nonce)
349
350	ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
351	require.Nil(t, err)
352
353	// after processing expect l2Txs[0:2].Nonce!=0 and has expected value
354	assert.Equal(t, common.Nonce(6), l2Txs[0].Nonce)
355	assert.Equal(t, common.Nonce(7), l2Txs[1].Nonce)
356	assert.Equal(t, common.Nonce(8), l2Txs[2].Nonce)
357
358	assert.Equal(t, 4, len(ptOut.ExitInfos)) // the 'ForceExit(1)' is not computed yet, as the batch is without L1UserTxs
359	assert.Equal(t, 1, len(ptOut.CreatedAccounts))
360	assert.Equal(t, 4, len(ptOut.CollectedFees))
361	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
362	assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
363	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
364	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
365	acc, err = sdb.GetAccount(idxA1)
366	require.Nil(t, err)
367	assert.Equal(t, "57", acc.Balance.String())
368
369	log.Debug("block:1 batch:1")
370	l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
371	ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[1].Rollup.L1UserTxs,
372		blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
373	require.Nil(t, err)
374
375	assert.Equal(t, 2, len(ptOut.ExitInfos)) // 2, as previous batch was without L1UserTxs, and has pending the 'ForceExit(1) A: 5'
376	assert.Equal(t, 1, len(ptOut.CreatedAccounts))
377	assert.Equal(t, 4, len(ptOut.CollectedFees))
378	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
379	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
380	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
381	assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
382	acc, err = sdb.GetAccount(idxA1)
383	assert.Nil(t, err)
384	assert.Equal(t, "77", acc.Balance.String())
385
386	idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
387	acc, err = sdb.GetAccount(idxB0)
388	require.Nil(t, err)
389	assert.Equal(t, "51", acc.Balance.String())
390
391	// get balance of Coordinator account for TokenID==0
392	acc, err = sdb.GetAccount(common.Idx(256))
393	require.Nil(t, err)
394	assert.Equal(t, "2", acc.Balance.String())
395}
396
397func TestProcessTxsBatchBuilder(t *testing.T) {
398	dir, err := ioutil.TempDir("", "tmpdb")
399	require.Nil(t, err)
400	defer assert.Nil(t, os.RemoveAll(dir))
401
402	sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
403	assert.Nil(t, err)
404
405	// generate test transactions from test.SetBlockchain0 code
406	tc := til.NewContext(common.RollupConstMaxL1UserTx)
407	blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
408	require.Nil(t, err)
409
410	// Coordinator Idx where to send the fees
411	coordIdxs := []common.Idx{256, 257, 258, 259}
412
413	// Idx of user 'A'
414	idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
415
416	ptc := ProcessTxsConfig{
417		NLevels:  32,
418		MaxFeeTx: 64,
419		MaxTx:    512,
420		MaxL1Tx:  32,
421	}
422
423	// Process the 1st batch, which contains the L1CoordinatorTxs necessary
424	// to create the Coordinator accounts to receive the fees
425	log.Debug("block:0 batch:0, only L1CoordinatorTxs")
426	ptOut, err := sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
427	require.Nil(t, err)
428	// expect 0 at CreatedAccount, as is only computed when StateDB.Type==TypeSynchronizer
429	assert.Equal(t, 0, len(ptOut.CreatedAccounts))
430
431	log.Debug("block:0 batch:1")
432	l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
433	ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[0].Rollup.L1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
434	require.Nil(t, err)
435	assert.Equal(t, 0, len(ptOut.ExitInfos))
436	assert.Equal(t, 0, len(ptOut.CreatedAccounts))
437	acc, err := sdb.GetAccount(idxA1)
438	require.Nil(t, err)
439	assert.Equal(t, "50", acc.Balance.String())
440
441	log.Debug("block:0 batch:2")
442	l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
443	ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
444	require.Nil(t, err)
445	assert.Equal(t, 0, len(ptOut.ExitInfos))
446	assert.Equal(t, 0, len(ptOut.CreatedAccounts))
447	acc, err = sdb.GetAccount(idxA1)
448	require.Nil(t, err)
449	assert.Equal(t, "35", acc.Balance.String())
450
451	log.Debug("block:1 batch:0")
452	l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
453	_, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
454	require.Nil(t, err)
455	acc, err = sdb.GetAccount(idxA1)
456	require.Nil(t, err)
457	assert.Equal(t, "57", acc.Balance.String())
458
459	log.Debug("block:1 batch:1")
460	l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
461	_, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[1].Rollup.L1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
462	require.Nil(t, err)
463	acc, err = sdb.GetAccount(idxA1)
464	assert.Nil(t, err)
465	assert.Equal(t, "77", acc.Balance.String())
466
467	idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
468	acc, err = sdb.GetAccount(idxB0)
469	require.Nil(t, err)
470	assert.Equal(t, "51", acc.Balance.String())
471
472	// get balance of Coordinator account for TokenID==0
473	acc, err = sdb.GetAccount(common.Idx(256))
474	require.Nil(t, err)
475	assert.Equal(t, common.TokenID(0), acc.TokenID)
476	assert.Equal(t, "2", acc.Balance.String())
477	acc, err = sdb.GetAccount(common.Idx(257))
478	require.Nil(t, err)
479	assert.Equal(t, common.TokenID(1), acc.TokenID)
480	assert.Equal(t, "2", acc.Balance.String())
481}
482
483func TestZKInputsGeneration(t *testing.T) {
484	dir, err := ioutil.TempDir("", "tmpdb")
485	require.Nil(t, err)
486	defer assert.Nil(t, os.RemoveAll(dir))
487
488	sdb, err := NewStateDB(dir, TypeBatchBuilder, 4)
489	assert.Nil(t, err)
490
491	set := `
492		Type: Blockchain
493		AddToken(1)
494		CreateAccountDeposit(1) A: 10
495		> batchL1
496		CreateAccountCoordinator(1) B
497		CreateAccountCoordinator(1) C
498		> batchL1
499		// idxs: A:258, B:256, C:257
500
501		Transfer(1) A-B: 6 (1)
502		Transfer(1) A-C: 2 (1)
503		> batch
504		> block
505	`
506	// generate test transactions from test.SetBlockchain0 code
507	tc := til.NewContext(common.RollupConstMaxL1UserTx)
508	blocks, err := tc.GenerateBlocks(set)
509	require.Nil(t, err)
510
511	// Coordinator Idx where to send the fees
512	coordIdxs := []common.Idx{256}
513
514	ptc := ProcessTxsConfig{
515		NLevels:  32,
516		MaxFeeTx: 8,
517		MaxTx:    32,
518		MaxL1Tx:  16,
519	}
520
521	log.Debug("block:0 batch:0, only L1UserTx")
522	_, err = sdb.ProcessTxs(ptc, nil, blocks[0].Rollup.L1UserTxs, nil, nil)
523	require.Nil(t, err)
524
525	log.Debug("block:0 batch:1, only L1CoordinatorTxs")
526	_, err = sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, nil)
527	require.Nil(t, err)
528
529	log.Debug("block:0 batch:2, only L2Txs")
530	l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
531	ptOut, err := sdb.ProcessTxs(ptc, coordIdxs, nil, nil, l2Txs)
532	require.Nil(t, err)
533	checkBalance(t, tc, sdb, "A", 1, "2")
534
535	s, err := json.Marshal(ptOut.ZKInputs)
536	require.Nil(t, err)
537	debug := false
538	debug = true
539	if debug {
540		fmt.Println(string(s))
541	}
542}
543
544func TestProcessTxsRootTestVectors(t *testing.T) {
545	dir, err := ioutil.TempDir("", "tmpdb")
546	require.Nil(t, err)
547	defer assert.Nil(t, os.RemoveAll(dir))
548
549	sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
550	assert.Nil(t, err)
551
552	// same values than in the js test
553	bjj0, err := common.BJJFromStringWithChecksum("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
554	assert.Nil(t, err)
555	l1Txs := []common.L1Tx{
556		{
557			FromIdx:     0,
558			LoadAmount:  big.NewInt(16000000),
559			Amount:      big.NewInt(0),
560			TokenID:     1,
561			FromBJJ:     bjj0,
562			FromEthAddr: ethCommon.HexToAddress("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"),
563			ToIdx:       0,
564			Type:        common.TxTypeCreateAccountDeposit,
565			UserOrigin:  true,
566		},
567	}
568	l2Txs := []common.PoolL2Tx{
569		{
570			FromIdx: 256,
571			ToIdx:   256,
572			TokenID: 1,
573			Amount:  big.NewInt(1000),
574			Nonce:   0,
575			Fee:     126,
576			Type:    common.TxTypeTransfer,
577		},
578	}
579
580	ptc := ProcessTxsConfig{
581		NLevels:  32,
582		MaxFeeTx: 8,
583		MaxTx:    32,
584		MaxL1Tx:  16,
585	}
586	_, err = sdb.ProcessTxs(ptc, nil, l1Txs, nil, l2Txs)
587	require.Nil(t, err)
588	assert.Equal(t, "9827704113668630072730115158977131501210702363656902211840117643154933433410", sdb.mt.Root().BigInt().String())
589}
590
591func TestCircomTest(t *testing.T) {
592	dir, err := ioutil.TempDir("", "tmpdb")
593	require.Nil(t, err)
594	defer assert.Nil(t, os.RemoveAll(dir))
595
596	sdb, err := NewStateDB(dir, TypeBatchBuilder, 8)
597	assert.Nil(t, err)
598
599	// same values than in the js test
600	bjj0, err := common.BJJFromStringWithChecksum("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
601	assert.Nil(t, err)
602	l1Txs := []common.L1Tx{
603		{
604			FromIdx: 0,
605			// LoadAmount:  big.NewInt(10400),
606			LoadAmount:  big.NewInt(16000000),
607			Amount:      big.NewInt(0),
608			TokenID:     1,
609			FromBJJ:     bjj0,
610			FromEthAddr: ethCommon.HexToAddress("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"),
611			ToIdx:       0,
612			Type:        common.TxTypeCreateAccountDeposit,
613			UserOrigin:  true,
614		},
615	}
616	l2Txs := []common.PoolL2Tx{
617		{
618			FromIdx: 256,
619			ToIdx:   256,
620			TokenID: 1,
621			Amount:  big.NewInt(1000),
622			Nonce:   0,
623			Fee:     126,
624			Type:    common.TxTypeTransfer,
625		},
626	}
627
628	ptc := ProcessTxsConfig{
629		NLevels:  8,
630		MaxFeeTx: 2,
631		MaxTx:    5,
632		MaxL1Tx:  2,
633	}
634	ptOut, err := sdb.ProcessTxs(ptc, nil, l1Txs, nil, l2Txs)
635	require.Nil(t, err)
636
637	// check expected account keys values from tx inputs
638	acc, err := sdb.GetAccount(common.Idx(256))
639	require.Nil(t, err)
640	assert.Equal(t, "d746824f7d0ac5044a573f51b278acb56d823bec39551d1d7bf7378b68a1b021", acc.PublicKey.Compress().String())
641	assert.Equal(t, "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf", acc.EthAddr.Hex())
642
643	// check that there no exist more accounts
644	_, err = sdb.GetAccount(common.Idx(257))
645	require.NotNil(t, err)
646	ptOut.ZKInputs.FeeIdxs[0] = common.Idx(256).BigInt()
647
648	s, err := json.Marshal(ptOut.ZKInputs)
649	require.Nil(t, err)
650	debug := false
651	if debug {
652		fmt.Println("\nCopy&Paste into js circom test:\n	let zkInput = JSON.parse(`" + string(s) + "`);")
653
654		h, err := ptOut.ZKInputs.HashGlobalData()
655		require.Nil(t, err)
656		fmt.Printf(`
657		const output={
658			hashGlobalInputs: "%s",
659		};
660		await circuit.assertOut(w, output);
661		`, h.String())
662		fmt.Println("")
663	}
664}
665
666func TestZKInputsHashTestVector0(t *testing.T) {
667	dir, err := ioutil.TempDir("", "tmpdb")
668	require.Nil(t, err)
669	defer assert.Nil(t, os.RemoveAll(dir))
670
671	sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
672	assert.Nil(t, err)
673
674	// same values than in the js test
675	bjj0, err := common.BJJFromStringWithChecksum("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
676	assert.Nil(t, err)
677	l1Txs := []common.L1Tx{
678		{
679			FromIdx:     0,
680			LoadAmount:  big.NewInt(16000000),
681			Amount:      big.NewInt(0),
682			TokenID:     1,
683			FromBJJ:     bjj0,
684			FromEthAddr: ethCommon.HexToAddress("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"),
685			ToIdx:       0,
686			Type:        common.TxTypeCreateAccountDeposit,
687			UserOrigin:  true,
688		},
689	}
690	l2Txs := []common.PoolL2Tx{
691		{
692			FromIdx: 256,
693			ToIdx:   256,
694			TokenID: 1,
695			Amount:  big.NewInt(1000),
696			Nonce:   0,
697			Fee:     126,
698			Type:    common.TxTypeTransfer,
699		},
700	}
701
702	ptc := ProcessTxsConfig{
703		NLevels:  32,
704		MaxFeeTx: 8,
705		MaxTx:    32,
706		MaxL1Tx:  16,
707	}
708	// skip first batch to do the test with BatchNum=1
709	_, err = sdb.ProcessTxs(ptc, nil, nil, nil, nil)
710	require.Nil(t, err)
711
712	ptOut, err := sdb.ProcessTxs(ptc, nil, l1Txs, nil, l2Txs)
713	require.Nil(t, err)
714
715	// check expected account keys values from tx inputs
716	acc, err := sdb.GetAccount(common.Idx(256))
717	require.Nil(t, err)
718	assert.Equal(t, "d746824f7d0ac5044a573f51b278acb56d823bec39551d1d7bf7378b68a1b021", acc.PublicKey.Compress().String())
719	assert.Equal(t, "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf", acc.EthAddr.Hex())
720
721	// check that there no exist more accounts
722	_, err = sdb.GetAccount(common.Idx(257))
723	require.NotNil(t, err)
724	ptOut.ZKInputs.FeeIdxs[0] = common.Idx(256).BigInt()
725
726	toHash, err := ptOut.ZKInputs.ToHashGlobalData()
727	assert.Nil(t, err)
728	// value from js test vector
729	expectedToHash := "0000000000ff000000000100000000000000000000000000000000000000000000000000000000000000000015ba488d749f6b891d29d0bf3a72481ec812e4d4ecef2bf7a3fc64f3c010444200000000000000000000000000000000000000000000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d700000000000028a00000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010003e87e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000001"
730	// checks are splitted to find the difference easier
731	assert.Equal(t, expectedToHash[:1000], hex.EncodeToString(toHash)[:1000])
732	assert.Equal(t, expectedToHash[1000:2000], hex.EncodeToString(toHash)[1000:2000])
733	assert.Equal(t, expectedToHash[2000:], hex.EncodeToString(toHash)[2000:])
734
735	h, err := ptOut.ZKInputs.HashGlobalData()
736	require.Nil(t, err)
737	// value from js test vector
738	assert.Equal(t, "4356692423721763303547321618014315464040324829724049399065961225345730555597", h.String())
739}
740
741func TestZKInputsHashTestVector1(t *testing.T) {
742	dir, err := ioutil.TempDir("", "tmpdb")
743	require.Nil(t, err)
744	defer assert.Nil(t, os.RemoveAll(dir))
745
746	sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
747	assert.Nil(t, err)
748
749	// same values than in the js test
750	bjj0, err := common.BJJFromStringWithChecksum("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
751	assert.Nil(t, err)
752	bjj1, err := common.BJJFromStringWithChecksum("093985b1993d9f743f9d7d943ed56f38601cb8b196db025f79650c4007c3054d")
753	assert.Nil(t, err)
754	l1Txs := []common.L1Tx{
755		{
756			FromIdx: 0,
757			// LoadAmount:  big.NewInt(10400),
758			LoadAmount:  big.NewInt(16000000),
759			Amount:      big.NewInt(0),
760			TokenID:     1,
761			FromBJJ:     bjj0,
762			FromEthAddr: ethCommon.HexToAddress("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"),
763			ToIdx:       0,
764			Type:        common.TxTypeCreateAccountDeposit,
765			UserOrigin:  true,
766		},
767		{
768			FromIdx:     0,
769			LoadAmount:  big.NewInt(16000000),
770			Amount:      big.NewInt(0),
771			TokenID:     1,
772			FromBJJ:     bjj1,
773			FromEthAddr: ethCommon.HexToAddress("0x2b5ad5c4795c026514f8317c7a215e218dccd6cf"),
774			ToIdx:       0,
775			Type:        common.TxTypeCreateAccountDeposit,
776			UserOrigin:  true,
777		},
778	}
779	l2Txs := []common.PoolL2Tx{
780		{
781			FromIdx: 257,
782			ToIdx:   256,
783			TokenID: 1,
784			Amount:  big.NewInt(1000),
785			Nonce:   0,
786			Fee:     137,
787			Type:    common.TxTypeTransfer,
788		},
789	}
790
791	ptc := ProcessTxsConfig{
792		NLevels:  32,
793		MaxFeeTx: 8,
794		MaxTx:    32,
795		MaxL1Tx:  16,
796	}
797	// skip first batch to do the test with BatchNum=1
798	_, err = sdb.ProcessTxs(ptc, nil, nil, nil, nil)
799	require.Nil(t, err)
800
801	ptOut, err := sdb.ProcessTxs(ptc, nil, l1Txs, nil, l2Txs)
802	require.Nil(t, err)
803
804	// check expected account keys values from tx inputs
805	acc, err := sdb.GetAccount(common.Idx(256))
806	require.Nil(t, err)
807	assert.Equal(t, "d746824f7d0ac5044a573f51b278acb56d823bec39551d1d7bf7378b68a1b021", acc.PublicKey.Compress().String())
808	assert.Equal(t, "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf", acc.EthAddr.Hex())
809	acc, err = sdb.GetAccount(common.Idx(257))
810	require.Nil(t, err)
811	assert.Equal(t, "4d05c307400c65795f02db96b1b81c60386fd53e947d9d3f749f3d99b1853909", acc.PublicKey.Compress().String())
812	assert.Equal(t, "0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF", acc.EthAddr.Hex())
813
814	// check that there no exist more accounts
815	_, err = sdb.GetAccount(common.Idx(258))
816	require.NotNil(t, err)
817	ptOut.ZKInputs.FeeIdxs[0] = common.Idx(257).BigInt()
818
819	toHash, err := ptOut.ZKInputs.ToHashGlobalData()
820	assert.Nil(t, err)
821	// value from js test vector
822	expectedToHash := "0000000000ff0000000001010000000000000000000000000000000000000000000000000000000000000000304a3f3aef4f416cca887aab7265227449077627138345c2eb25bf8ff946b09500000000000000000000000000000000000000000000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d700000000000028a00000000000010000000000002b5ad5c4795c026514f8317c7a215e218dccd6cf093985b1993d9f743f9d7d943ed56f38601cb8b196db025f79650c4007c3054d00000000000028a000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010000010003e889000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000000001"
823	// checks are splitted to find the difference easier
824	assert.Equal(t, expectedToHash[:1000], hex.EncodeToString(toHash)[:1000])
825	assert.Equal(t, expectedToHash[1000:2000], hex.EncodeToString(toHash)[1000:2000])
826	assert.Equal(t, expectedToHash[2000:], hex.EncodeToString(toHash)[2000:])
827
828	h, err := ptOut.ZKInputs.HashGlobalData()
829	require.Nil(t, err)
830	// value from js test vector
831	assert.Equal(t, "20293112365009290386650039345314592436395562810005523677125576447132206192598", h.String())
832}