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}