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