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}