arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/test/til/txs_test.go
test/til/txs_test.goRaw
  1package til
  2
  3import (
  4	"math/big"
  5	"testing"
  6
  7	"github.com/hermeznetwork/hermez-node/common"
  8	"github.com/stretchr/testify/assert"
  9	"github.com/stretchr/testify/require"
 10)
 11
 12func TestGenerateBlocksNoBatches(t *testing.T) {
 13	set := `
 14		Type: Blockchain
 15		AddToken(1)
 16		AddToken(2)
 17
 18		CreateAccountDeposit(1) A: 11
 19		CreateAccountDeposit(2) B: 22
 20
 21		> block
 22	`
 23	tc := NewContext(0, common.RollupConstMaxL1UserTx)
 24	blocks, err := tc.GenerateBlocks(set)
 25	require.NoError(t, err)
 26	assert.Equal(t, 1, len(blocks))
 27	assert.Equal(t, 0, len(blocks[0].Rollup.Batches))
 28	assert.Equal(t, 2, len(blocks[0].Rollup.AddedTokens))
 29	assert.Equal(t, 2, len(blocks[0].Rollup.L1UserTxs))
 30}
 31
 32func TestGenerateBlocks(t *testing.T) {
 33	set := `
 34		Type: Blockchain
 35		AddToken(1)
 36		AddToken(2)
 37		AddToken(3)
 38	
 39		CreateAccountDeposit(1) A: 10
 40		CreateAccountDeposit(2) A: 20
 41		CreateAccountDeposit(1) B: 5
 42		CreateAccountDeposit(1) C: 5
 43		CreateAccountDeposit(1) D: 5
 44
 45		> batchL1 // batchNum = 1
 46		> batchL1 // batchNum = 2
 47
 48		CreateAccountDepositTransfer(1) F-A: 15, 10
 49
 50		Transfer(1) A-B: 6 (1)
 51		Transfer(1) B-D: 3 (1)
 52		Transfer(1) A-D: 1 (1)
 53
 54		// set new batch
 55		> batch // batchNum = 3
 56		CreateAccountCoordinator(1) E
 57		CreateAccountCoordinator(2) B
 58
 59		DepositTransfer(1) A-B: 15, 10
 60		Transfer(1) C-A : 3 (1)
 61		Transfer(2) A-B: 15 (1)
 62		Transfer(1) A-E: 1 (1)
 63
 64		CreateAccountDeposit(1) User0: 20
 65		CreateAccountDeposit(3) User1: 20
 66		CreateAccountCoordinator(1) User1
 67		CreateAccountCoordinator(3) User0
 68		> batchL1 // batchNum = 4
 69		Transfer(1) User0-User1: 15 (1)
 70		Transfer(3) User1-User0: 15 (1)
 71		Transfer(1) A-C: 1 (1)
 72
 73		> batchL1 // batchNum = 5
 74
 75		Transfer(1) User1-User0: 1 (1)
 76
 77		> block
 78
 79		// Exits
 80		Transfer(1) A-B: 1 (1)
 81		Exit(1) A: 5 (1)
 82		
 83		> batch // batchNum = 6
 84		> block
 85
 86		// this transaction should not be generated, as it's after last
 87		// batch and last block
 88		Transfer(1) User1-User0: 1 (1)
 89	`
 90	tc := NewContext(0, common.RollupConstMaxL1UserTx)
 91	blocks, err := tc.GenerateBlocks(set)
 92	require.NoError(t, err)
 93	assert.Equal(t, 2, len(blocks))
 94	assert.Equal(t, 5, len(blocks[0].Rollup.Batches))
 95	assert.Equal(t, 1, len(blocks[1].Rollup.Batches))
 96	assert.Equal(t, 9, len(blocks[0].Rollup.L1UserTxs))
 97	assert.Equal(t, 4, len(blocks[0].Rollup.Batches[3].L1CoordinatorTxs))
 98	assert.Equal(t, 0, len(blocks[1].Rollup.L1UserTxs))
 99
100	// Check expected values generated by each line
101	// #0: Deposit(1) A: 10
102	tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[0], common.TxTypeCreateAccountDeposit, 1, "A", "", big.NewInt(10), nil)
103	// #1: Deposit(2) A: 20
104	tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[1], common.TxTypeCreateAccountDeposit, 2, "A", "", big.NewInt(20), nil)
105	// // #2: Deposit(1) A: 20
106	tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[2], common.TxTypeCreateAccountDeposit, 1, "B", "", big.NewInt(5), nil)
107	// // #3: CreateAccountDeposit(1) C: 5
108	tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[3], common.TxTypeCreateAccountDeposit, 1, "C", "", big.NewInt(5), nil)
109	// // #4: CreateAccountDeposit(1) D: 5
110	tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[4], common.TxTypeCreateAccountDeposit, 1, "D", "", big.NewInt(5), nil)
111	// #5: Transfer(1) A-B: 6 (1)
112	tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[0], common.TxTypeTransfer, 1, "A", "B", big.NewInt(6), common.BatchNum(3))
113	// #6: Transfer(1) B-D: 3 (1)
114	tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[1], common.TxTypeTransfer, 1, "B", "D", big.NewInt(3), common.BatchNum(3))
115	// #7: Transfer(1) A-D: 1 (1)
116	tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[2], common.TxTypeTransfer, 1, "A", "D", big.NewInt(1), common.BatchNum(3))
117	// change of Batch
118	// #8: CreateAccountDepositTransfer(1) F-A: 15, 10 (3)
119	tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[5], common.TxTypeCreateAccountDepositTransfer, 1, "F", "A", big.NewInt(15), big.NewInt(10))
120	// #9: DepositTransfer(1) A-B: 15, 10 (1)
121	tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[6], common.TxTypeDepositTransfer, 1, "A", "B", big.NewInt(15), big.NewInt(10))
122	// #11: Transfer(1) C-A : 3 (1)
123	tc.checkL2TxParams(t, blocks[0].Rollup.Batches[3].L2Txs[0], common.TxTypeTransfer, 1, "C", "A", big.NewInt(3), common.BatchNum(4))
124	// #12: Transfer(2) A-B: 15 (1)
125	tc.checkL2TxParams(t, blocks[0].Rollup.Batches[3].L2Txs[1], common.TxTypeTransfer, 2, "A", "B", big.NewInt(15), common.BatchNum(4))
126	// #13: Deposit(1) User0: 20
127	tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[7], common.TxTypeCreateAccountDeposit, 1, "User0", "", big.NewInt(20), nil)
128	// // #14: Deposit(3) User1: 20
129	tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[8], common.TxTypeCreateAccountDeposit, 3, "User1", "", big.NewInt(20), nil)
130	// #15: Transfer(1) User0-User1: 15 (1)
131	tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[0], common.TxTypeTransfer, 1, "User0", "User1", big.NewInt(15), common.BatchNum(5))
132	// #16: Transfer(3) User1-User0: 15 (1)
133	tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[1], common.TxTypeTransfer, 3, "User1", "User0", big.NewInt(15), common.BatchNum(5))
134	// #17: Transfer(1) A-C: 1 (1)
135	tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[2], common.TxTypeTransfer, 1, "A", "C", big.NewInt(1), common.BatchNum(5))
136	// change of Batch
137	// #18: Transfer(1) User1-User0: 1 (1)
138	tc.checkL2TxParams(t, blocks[1].Rollup.Batches[0].L2Txs[0], common.TxTypeTransfer, 1, "User1", "User0", big.NewInt(1), common.BatchNum(6))
139	// change of Block (implies also a change of batch)
140	// #19: Transfer(1) A-B: 1 (1)
141	tc.checkL2TxParams(t, blocks[1].Rollup.Batches[0].L2Txs[1], common.TxTypeTransfer, 1, "A", "B", big.NewInt(1), common.BatchNum(6))
142}
143
144func (tc *Context) checkL1TxParams(t *testing.T, tx common.L1Tx, typ common.TxType, tokenID common.TokenID, from, to string, depositAmount, amount *big.Int) {
145	assert.Equal(t, typ, tx.Type)
146	if tx.FromIdx != common.Idx(0) {
147		assert.Equal(t, tc.Users[from].Accounts[tokenID].Idx, tx.FromIdx)
148	}
149	assert.Equal(t, tc.Users[from].Addr.Hex(), tx.FromEthAddr.Hex())
150	assert.Equal(t, tc.Users[from].BJJ.Public().Compress(), tx.FromBJJ)
151	if tx.ToIdx != common.Idx(0) {
152		assert.Equal(t, tc.Users[to].Accounts[tokenID].Idx, tx.ToIdx)
153	}
154	if depositAmount != nil {
155		assert.Equal(t, depositAmount, tx.DepositAmount)
156	}
157	if amount != nil {
158		assert.Equal(t, amount, tx.Amount)
159	}
160}
161
162func (tc *Context) checkL2TxParams(t *testing.T, tx common.L2Tx, typ common.TxType, tokenID common.TokenID, from, to string, amount *big.Int, batchNum common.BatchNum) {
163	assert.Equal(t, typ, tx.Type)
164	assert.Equal(t, tc.Users[from].Accounts[tokenID].Idx, tx.FromIdx)
165	if tx.Type != common.TxTypeExit {
166		assert.Equal(t, tc.Users[to].Accounts[tokenID].Idx, tx.ToIdx)
167	}
168	if amount != nil {
169		assert.Equal(t, amount, tx.Amount)
170	}
171	assert.Equal(t, batchNum, tx.BatchNum)
172}
173
174func TestGeneratePoolL2Txs(t *testing.T) {
175	set := `
176		Type: Blockchain
177		AddToken(1)
178		AddToken(2)
179		AddToken(3)
180	
181		CreateAccountDeposit(1) A: 10
182		CreateAccountDeposit(2) A: 20
183		CreateAccountDeposit(1) B: 5
184		CreateAccountDeposit(1) C: 5
185		CreateAccountDeposit(1) User0: 5
186		CreateAccountDeposit(1) User1: 0
187		CreateAccountDeposit(3) User0: 0
188		CreateAccountDeposit(3) User1: 5
189		CreateAccountDeposit(2) B: 5
190		CreateAccountDeposit(2) D: 0
191		> batchL1
192		> batchL1
193	`
194	tc := NewContext(0, common.RollupConstMaxL1UserTx)
195	_, err := tc.GenerateBlocks(set)
196	require.NoError(t, err)
197	set = `
198		Type: PoolL2
199		PoolTransfer(1) A-B: 6 (1)
200		PoolTransfer(1) B-C: 3 (1)
201		PoolTransfer(1) C-A: 3 (1)
202		PoolTransfer(1) A-B: 1 (1)
203		PoolTransfer(2) A-B: 15 (1)
204		PoolTransfer(1) User0-User1: 15 (1)
205		PoolTransfer(3) User1-User0: 15 (1)
206		PoolTransfer(2) B-D: 3 (1)
207		PoolExit(1) A: 3 (1)
208		PoolTransferToEthAddr(1) A-B: 1 (1)
209		PoolTransferToBJJ(1) A-B: 1 (1)
210	`
211	poolL2Txs, err := tc.GeneratePoolL2Txs(set)
212	require.NoError(t, err)
213	assert.Equal(t, 11, len(poolL2Txs))
214	assert.Equal(t, common.TxTypeTransfer, poolL2Txs[0].Type)
215	assert.Equal(t, common.TxTypeExit, poolL2Txs[8].Type)
216	assert.Equal(t, tc.Users["B"].Addr.Hex(), poolL2Txs[0].ToEthAddr.Hex())
217	assert.Equal(t, tc.Users["B"].BJJ.Public().String(), poolL2Txs[0].ToBJJ.String())
218	assert.Equal(t, tc.Users["User1"].Addr.Hex(), poolL2Txs[5].ToEthAddr.Hex())
219	assert.Equal(t, tc.Users["User1"].BJJ.Public().String(), poolL2Txs[5].ToBJJ.String())
220
221	assert.Equal(t, common.Nonce(0), poolL2Txs[0].Nonce)
222	assert.Equal(t, common.Nonce(0), poolL2Txs[1].Nonce)
223	assert.Equal(t, common.Nonce(0), poolL2Txs[2].Nonce)
224	assert.Equal(t, common.Nonce(1), poolL2Txs[3].Nonce)
225	assert.Equal(t, common.Nonce(0), poolL2Txs[4].Nonce)
226	assert.Equal(t, common.Nonce(0), poolL2Txs[5].Nonce)
227	assert.Equal(t, common.Nonce(0), poolL2Txs[6].Nonce)
228	assert.Equal(t, common.Nonce(0), poolL2Txs[7].Nonce)
229	assert.Equal(t, common.Nonce(2), poolL2Txs[8].Nonce)
230	assert.Equal(t, common.Nonce(3), poolL2Txs[9].Nonce)
231
232	assert.Equal(t, tc.Users["B"].Addr.Hex(), poolL2Txs[9].ToEthAddr.Hex())
233	assert.Equal(t, common.EmptyBJJComp, poolL2Txs[9].ToBJJ)
234	assert.Equal(t, common.TxTypeTransferToEthAddr, poolL2Txs[9].Type)
235	assert.Equal(t, common.FFAddr, poolL2Txs[10].ToEthAddr)
236	assert.Equal(t, tc.Users["B"].BJJ.Public().String(), poolL2Txs[10].ToBJJ.String())
237	assert.Equal(t, common.TxTypeTransferToBJJ, poolL2Txs[10].Type)
238
239	// load another set in the same Context
240	set = `
241		Type: PoolL2
242		PoolTransfer(1) A-B: 6 (1)
243		PoolTransfer(1) B-C: 3 (1)
244		PoolTransfer(1) A-C: 3 (1)
245	`
246	poolL2Txs, err = tc.GeneratePoolL2Txs(set)
247	require.NoError(t, err)
248	assert.Equal(t, common.Nonce(5), poolL2Txs[0].Nonce)
249	assert.Equal(t, common.Nonce(1), poolL2Txs[1].Nonce)
250	assert.Equal(t, common.Nonce(6), poolL2Txs[2].Nonce)
251
252	// check that a PoolL2Tx can be done to a non existing ToIdx
253	set = `
254		Type: Blockchain
255		AddToken(1)
256		CreateAccountDeposit(1) A: 10
257		> batchL1
258		> batchL1
259		> block
260	`
261	tc = NewContext(0, common.RollupConstMaxL1UserTx)
262	_, err = tc.GenerateBlocks(set)
263	require.NoError(t, err)
264	set = `
265		Type: PoolL2
266		PoolTransferToEthAddr(1) A-B: 3 (1)
267		PoolTransferToBJJ(1) A-C: 3 (1)
268	`
269	_, err = tc.GeneratePoolL2Txs(set)
270	require.NoError(t, err)
271	// expect error, as FromIdx=B is still not created for TokenID=1
272	set = `
273		Type: PoolL2
274		PoolTransferToEthAddr(1) B-A: 3 (1)
275		PoolTransferToBJJ(1) B-A: 3 (1)
276	`
277	_, err = tc.GeneratePoolL2Txs(set)
278	require.NotNil(t, err)
279}
280
281func TestGeneratePoolL2TxsFromInstructions(t *testing.T) {
282	// Generate necessary L1 data
283	set := `
284		Type: Blockchain
285		AddToken(1)
286	
287		CreateAccountCoordinator(1) A
288		CreateAccountDeposit(1) B: 7
289		> batchL1
290		> batchL1
291	`
292	tc := NewContext(0, common.RollupConstMaxL1UserTx)
293	_, err := tc.GenerateBlocks(set)
294	require.NoError(t, err)
295
296	// Generate Pool txs using instructions
297	instructionSet := []Instruction{}
298	i := 0
299	a := big.NewInt(3)
300	instructionSet = append(instructionSet, Instruction{
301		LineNum: i,
302		// Literal: "PoolTransferToEthAddr(1) B-A: 3 (1)",
303		Typ:     common.TxTypeTransferToEthAddr,
304		From:    "B",
305		To:      "A",
306		TokenID: 1,
307		Amount:  a,
308		Fee:     1,
309	})
310	i++
311	instructionSet = append(instructionSet, Instruction{
312		LineNum: i,
313		// Literal: "PoolTransferToBJJ(1) B-A: 3 (1)",
314		Typ:     common.TxTypeTransferToBJJ,
315		From:    "B",
316		To:      "A",
317		TokenID: 1,
318		Amount:  a,
319		Fee:     1,
320	})
321	txsFromInstructions, err := tc.GeneratePoolL2TxsFromInstructions(instructionSet)
322	require.NoError(t, err)
323	// Generate Pool txs using string
324	tc = NewContext(0, common.RollupConstMaxL1UserTx)
325	_, err = tc.GenerateBlocks(set)
326	require.NoError(t, err)
327	stringSet := `
328		Type: PoolL2
329		PoolTransferToEthAddr(1) B-A: 3 (1)
330		PoolTransferToBJJ(1) B-A: 3 (1)
331	`
332	txsFromString, err := tc.GeneratePoolL2Txs(stringSet)
333	require.NoError(t, err)
334	// Compare generated txs from instructions and string
335	// timestamps will be different
336	for i := 0; i < len(txsFromString); i++ {
337		txsFromInstructions[i].Timestamp = txsFromString[i].Timestamp
338	}
339	assert.Equal(t, txsFromString, txsFromInstructions)
340}
341
342func TestGenerateErrors(t *testing.T) {
343	// unregistered token
344	set := `Type: Blockchain
345		CreateAccountDeposit(1) A: 5
346		> batchL1
347		`
348	tc := NewContext(0, common.RollupConstMaxL1UserTx)
349	_, err := tc.GenerateBlocks(set)
350	assert.Equal(t, "Line 2: Can not process CreateAccountDeposit: TokenID 1 not registered, last registered TokenID: 0", err.Error())
351
352	// ensure AddToken sequentiality and not using 0
353	set = `
354		Type: Blockchain
355		AddToken(0)
356	`
357	tc = NewContext(0, common.RollupConstMaxL1UserTx)
358	_, err = tc.GenerateBlocks(set)
359	require.Equal(t, "Line 2: AddToken can not register TokenID 0", err.Error())
360
361	set = `
362		Type: Blockchain
363		AddToken(2)
364	`
365	tc = NewContext(0, common.RollupConstMaxL1UserTx)
366	_, err = tc.GenerateBlocks(set)
367	require.Equal(t, "Line 2: AddToken TokenID should be sequential, expected TokenID: 1, defined TokenID: 2", err.Error())
368
369	set = `
370		Type: Blockchain
371		AddToken(1)
372		AddToken(2)
373		AddToken(3)
374		AddToken(5)
375	`
376	tc = NewContext(0, common.RollupConstMaxL1UserTx)
377	_, err = tc.GenerateBlocks(set)
378	require.Equal(t, "Line 5: AddToken TokenID should be sequential, expected TokenID: 4, defined TokenID: 5", err.Error())
379
380	// check transactions when account is not created yet
381	set = `
382		Type: Blockchain
383		AddToken(1)
384		CreateAccountDeposit(1) A: 10
385		> batchL1
386		CreateAccountDeposit(1) B
387		Transfer(1) A-B: 6 (1)
388		> batch
389	`
390	tc = NewContext(0, common.RollupConstMaxL1UserTx)
391	_, err = tc.GenerateBlocks(set)
392	require.Equal(t, "Line 5: CreateAccountDeposit(1)BTransfer(1) A-B: 6 (1)\n, err: Expected ':', found 'Transfer'", err.Error())
393	set = `
394		Type: Blockchain
395		AddToken(1)
396		CreateAccountDeposit(1) A: 10
397		> batchL1
398		CreateAccountCoordinator(1) B
399		> batchL1
400		> batch
401		Transfer(1) A-B: 6 (1)
402		> batch
403	`
404	tc = NewContext(0, common.RollupConstMaxL1UserTx)
405	_, err = tc.GenerateBlocks(set)
406	require.NoError(t, err)
407
408	// check nonces
409	set = `
410		Type: Blockchain
411		AddToken(1)
412		CreateAccountDeposit(1) A: 10
413		> batchL1
414		CreateAccountCoordinator(1) B
415		> batchL1
416		Transfer(1) A-B: 6 (1)
417		Transfer(1) A-B: 6 (1) // on purpose this is moving more money that what it has in the account, Til should not fail
418		Transfer(1) B-A: 6 (1)
419		Exit(1) A: 3 (1)
420		> batch
421	`
422	tc = NewContext(0, common.RollupConstMaxL1UserTx)
423	_, err = tc.GenerateBlocks(set)
424	require.NoError(t, err)
425	assert.Equal(t, common.Nonce(3), tc.Users["A"].Accounts[common.TokenID(1)].Nonce)
426	assert.Equal(t, common.Idx(256), tc.Users["A"].Accounts[common.TokenID(1)].Idx)
427	assert.Equal(t, common.Nonce(1), tc.Users["B"].Accounts[common.TokenID(1)].Nonce)
428	assert.Equal(t, common.Idx(257), tc.Users["B"].Accounts[common.TokenID(1)].Idx)
429}
430
431func TestGenerateFromInstructions(t *testing.T) {
432	// Generate block from instructions
433	setInst := []Instruction{}
434	i := 0
435	setInst = append(setInst, Instruction{
436		LineNum: i,
437		// Literal: "AddToken(1)",
438		Typ:     TypeAddToken,
439		TokenID: 1,
440	})
441	i++
442	da := big.NewInt(10)
443	setInst = append(setInst, Instruction{
444		LineNum: i,
445		// Literal: "CreateAccountDeposit(1) A: 10",
446		Typ:           common.TxTypeCreateAccountDeposit,
447		From:          "A",
448		TokenID:       1,
449		DepositAmount: da,
450	})
451	i++
452	setInst = append(setInst, Instruction{
453		LineNum: i,
454		// Literal: "> batchL1",
455		Typ: TypeNewBatchL1,
456	})
457	i++
458	setInst = append(setInst, Instruction{
459		LineNum: i,
460		// Literal: "CreateAccountCoordinator(1) B",
461		Typ:     TxTypeCreateAccountDepositCoordinator,
462		From:    "B",
463		TokenID: 1,
464	})
465	i++
466	setInst = append(setInst, Instruction{
467		LineNum: i,
468		// Literal: "> batchL1",
469		Typ: TypeNewBatchL1,
470	})
471	i++
472	a := big.NewInt(6)
473	setInst = append(setInst, Instruction{
474		LineNum: i, // 5
475		// Literal: "Transfer(1) A-B: 6 (1)",
476		Typ:     common.TxTypeTransfer,
477		From:    "A",
478		To:      "B",
479		TokenID: 1,
480		Amount:  a,
481		Fee:     1,
482	})
483	i++
484	setInst = append(setInst, Instruction{
485		LineNum: i,
486		// Literal: "Transfer(1) A-B: 6 (1)",
487		Typ:     common.TxTypeTransfer,
488		From:    "A",
489		To:      "B",
490		TokenID: 1,
491		Amount:  a,
492		Fee:     1,
493	})
494	i++
495	setInst = append(setInst, Instruction{
496		LineNum: i,
497		// Literal: "Transfer(1) B-A: 6 (1)",
498		Typ:     common.TxTypeTransfer,
499		From:    "B",
500		To:      "A",
501		TokenID: 1,
502		Amount:  a,
503		Fee:     1,
504	})
505	i++
506	a = big.NewInt(3)
507	setInst = append(setInst, Instruction{
508		LineNum: i,
509		// Literal: "Exit(1) A: 3 (1)",
510		Typ:     common.TxTypeExit,
511		From:    "A",
512		TokenID: 1,
513		Amount:  a,
514		Fee:     1,
515	})
516	i++
517	setInst = append(setInst, Instruction{
518		LineNum: i,
519		// Literal: "> batch",
520		Typ: TypeNewBatch,
521	})
522	setInst = append(setInst, Instruction{
523		LineNum: i,
524		// Literal: "> block",
525		Typ: TypeNewBlock,
526	})
527
528	tc := NewContext(0, common.RollupConstMaxL1UserTx)
529	blockFromInstructions, err := tc.GenerateBlocksFromInstructions(setInst)
530	require.NoError(t, err)
531
532	// Generate block from string
533	setString := `
534		Type: Blockchain
535		AddToken(1)
536		CreateAccountDeposit(1) A: 10
537		> batchL1
538		CreateAccountCoordinator(1) B
539		> batchL1
540		Transfer(1) A-B: 6 (1)
541		Transfer(1) A-B: 6 (1) // on purpose this is moving more money that what it has in the account, Til should not fail
542		Transfer(1) B-A: 6 (1)
543		Exit(1) A: 3 (1)
544		> batch
545		> block
546	`
547	tc = NewContext(0, common.RollupConstMaxL1UserTx)
548	blockFromString, err := tc.GenerateBlocks(setString)
549	require.NoError(t, err)
550
551	// Generated data should be equivalent, except for Eth Addrs and BJJs
552	for i, strBatch := range blockFromString[0].Rollup.Batches {
553		// instBatch := blockFromInstructions[0].Rollup.Batches[i]
554		for j := 0; j < len(strBatch.L1CoordinatorTxs); j++ {
555			blockFromInstructions[0].Rollup.Batches[i].L1CoordinatorTxs[j].FromEthAddr =
556				blockFromString[0].Rollup.Batches[i].L1CoordinatorTxs[j].FromEthAddr
557			blockFromInstructions[0].Rollup.Batches[i].L1CoordinatorTxs[j].FromBJJ =
558				blockFromString[0].Rollup.Batches[i].L1CoordinatorTxs[j].FromBJJ
559		}
560		for j := 0; j < len(strBatch.L1UserTxs); j++ {
561			blockFromInstructions[0].Rollup.Batches[i].L1UserTxs[j].FromEthAddr =
562				blockFromString[0].Rollup.Batches[i].L1UserTxs[j].FromEthAddr
563			blockFromInstructions[0].Rollup.Batches[i].L1UserTxs[j].FromBJJ =
564				blockFromString[0].Rollup.Batches[i].L1UserTxs[j].FromBJJ
565		}
566	}
567	for i := 0; i < len(blockFromString[0].Rollup.L1UserTxs); i++ {
568		blockFromInstructions[0].Rollup.L1UserTxs[i].FromEthAddr =
569			blockFromString[0].Rollup.L1UserTxs[i].FromEthAddr
570		blockFromInstructions[0].Rollup.L1UserTxs[i].FromBJJ =
571			blockFromString[0].Rollup.L1UserTxs[i].FromBJJ
572	}
573	assert.Equal(t, blockFromString, blockFromInstructions)
574}