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