You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

689 lines
24 KiB

  1. package txprocessor
  2. import (
  3. "encoding/binary"
  4. "encoding/hex"
  5. "io/ioutil"
  6. "math/big"
  7. "os"
  8. "testing"
  9. ethCommon "github.com/ethereum/go-ethereum/common"
  10. "github.com/hermeznetwork/hermez-node/common"
  11. "github.com/hermeznetwork/hermez-node/db/statedb"
  12. "github.com/hermeznetwork/hermez-node/log"
  13. "github.com/hermeznetwork/hermez-node/test/til"
  14. "github.com/stretchr/testify/assert"
  15. "github.com/stretchr/testify/require"
  16. )
  17. func checkBalance(t *testing.T, tc *til.Context, sdb *statedb.StateDB, username string, tokenid int, expected string) {
  18. idx := tc.Users[username].Accounts[common.TokenID(tokenid)].Idx
  19. acc, err := sdb.GetAccount(idx)
  20. require.NoError(t, err)
  21. assert.Equal(t, expected, acc.Balance.String())
  22. }
  23. func TestComputeEffectiveAmounts(t *testing.T) {
  24. dir, err := ioutil.TempDir("", "tmpdb")
  25. require.NoError(t, err)
  26. defer assert.NoError(t, os.RemoveAll(dir))
  27. sdb, err := statedb.NewStateDB(dir, 128, statedb.TypeSynchronizer, 32)
  28. assert.NoError(t, err)
  29. set := `
  30. Type: Blockchain
  31. AddToken(1)
  32. CreateAccountDeposit(0) A: 10
  33. CreateAccountDeposit(0) B: 10
  34. CreateAccountDeposit(1) C: 10
  35. > batchL1
  36. > batchL1
  37. > block
  38. `
  39. chainID := uint16(0)
  40. tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
  41. blocks, err := tc.GenerateBlocks(set)
  42. require.NoError(t, err)
  43. config := Config{
  44. NLevels: 32,
  45. MaxFeeTx: 64,
  46. MaxTx: 512,
  47. MaxL1Tx: 16,
  48. ChainID: chainID,
  49. }
  50. tp := NewTxProcessor(sdb, config)
  51. _, err = tp.ProcessTxs(nil, blocks[0].Rollup.L1UserTxs, nil, nil)
  52. require.NoError(t, err)
  53. tx := common.L1Tx{
  54. FromIdx: 256,
  55. ToIdx: 257,
  56. Amount: big.NewInt(10),
  57. DepositAmount: big.NewInt(0),
  58. FromEthAddr: tc.Users["A"].Addr,
  59. UserOrigin: true,
  60. }
  61. tp.computeEffectiveAmounts(&tx)
  62. assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
  63. assert.Equal(t, big.NewInt(10), tx.EffectiveAmount)
  64. // expect error due not enough funds
  65. tx = common.L1Tx{
  66. FromIdx: 256,
  67. ToIdx: 257,
  68. Amount: big.NewInt(11),
  69. DepositAmount: big.NewInt(0),
  70. FromEthAddr: tc.Users["A"].Addr,
  71. UserOrigin: true,
  72. }
  73. tp.computeEffectiveAmounts(&tx)
  74. assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
  75. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  76. // expect no-error as there are enough funds in a
  77. // CreateAccountDepositTransfer transction
  78. tx = common.L1Tx{
  79. FromIdx: 0,
  80. ToIdx: 257,
  81. Amount: big.NewInt(10),
  82. DepositAmount: big.NewInt(10),
  83. UserOrigin: true,
  84. }
  85. tp.computeEffectiveAmounts(&tx)
  86. assert.Equal(t, big.NewInt(10), tx.EffectiveDepositAmount)
  87. assert.Equal(t, big.NewInt(10), tx.EffectiveAmount)
  88. // expect error due not enough funds in a CreateAccountDepositTransfer
  89. // transction
  90. tx = common.L1Tx{
  91. FromIdx: 0,
  92. ToIdx: 257,
  93. Amount: big.NewInt(11),
  94. DepositAmount: big.NewInt(10),
  95. UserOrigin: true,
  96. }
  97. tp.computeEffectiveAmounts(&tx)
  98. assert.Equal(t, big.NewInt(10), tx.EffectiveDepositAmount)
  99. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  100. // expect error due not same TokenID
  101. tx = common.L1Tx{
  102. FromIdx: 256,
  103. ToIdx: 258,
  104. Amount: big.NewInt(5),
  105. DepositAmount: big.NewInt(0),
  106. FromEthAddr: tc.Users["A"].Addr,
  107. UserOrigin: true,
  108. }
  109. tp.computeEffectiveAmounts(&tx)
  110. assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
  111. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  112. // expect error due not same EthAddr
  113. tx = common.L1Tx{
  114. FromIdx: 256,
  115. ToIdx: 257,
  116. Amount: big.NewInt(8),
  117. DepositAmount: big.NewInt(0),
  118. FromEthAddr: tc.Users["B"].Addr,
  119. UserOrigin: true,
  120. }
  121. tp.computeEffectiveAmounts(&tx)
  122. assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
  123. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  124. // expect on TxTypeDepositTransfer EffectiveAmount=0, but
  125. // EffectiveDepositAmount!=0, due not enough funds to make the transfer
  126. tx = common.L1Tx{
  127. FromIdx: 256,
  128. ToIdx: 257,
  129. Amount: big.NewInt(20),
  130. DepositAmount: big.NewInt(8),
  131. FromEthAddr: tc.Users["A"].Addr,
  132. UserOrigin: true,
  133. }
  134. tp.computeEffectiveAmounts(&tx)
  135. assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
  136. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  137. // expect on TxTypeDepositTransfer EffectiveAmount=0, but
  138. // EffectiveDepositAmount!=0, due different EthAddr from FromIdx
  139. // address
  140. tx = common.L1Tx{
  141. FromIdx: 256,
  142. ToIdx: 257,
  143. Amount: big.NewInt(8),
  144. DepositAmount: big.NewInt(8),
  145. FromEthAddr: tc.Users["B"].Addr,
  146. UserOrigin: true,
  147. }
  148. tp.computeEffectiveAmounts(&tx)
  149. assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
  150. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  151. // CreateAccountDepositTransfer for TokenID=1 when receiver does not
  152. // have an account for that TokenID, expect that the
  153. // EffectiveDepositAmount=DepositAmount, but EffectiveAmount==0
  154. tx = common.L1Tx{
  155. FromIdx: 0,
  156. ToIdx: 257,
  157. Amount: big.NewInt(8),
  158. DepositAmount: big.NewInt(8),
  159. FromEthAddr: tc.Users["A"].Addr,
  160. TokenID: 2,
  161. UserOrigin: true,
  162. Type: common.TxTypeCreateAccountDepositTransfer,
  163. }
  164. tp.computeEffectiveAmounts(&tx)
  165. assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
  166. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  167. // DepositTransfer for TokenID=1 when receiver does not have an account
  168. // for that TokenID, expect that the
  169. // EffectiveDepositAmount=DepositAmount, but EffectiveAmount=0
  170. tx = common.L1Tx{
  171. FromIdx: 258,
  172. ToIdx: 256,
  173. Amount: big.NewInt(8),
  174. DepositAmount: big.NewInt(8),
  175. FromEthAddr: tc.Users["C"].Addr,
  176. TokenID: 1,
  177. UserOrigin: true,
  178. Type: common.TxTypeDepositTransfer,
  179. }
  180. tp.computeEffectiveAmounts(&tx)
  181. assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
  182. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  183. }
  184. func TestProcessTxsBalances(t *testing.T) {
  185. dir, err := ioutil.TempDir("", "tmpdb")
  186. require.NoError(t, err)
  187. defer assert.NoError(t, os.RemoveAll(dir))
  188. sdb, err := statedb.NewStateDB(dir, 128, statedb.TypeSynchronizer, 32)
  189. assert.NoError(t, err)
  190. chainID := uint16(0)
  191. // generate test transactions from test.SetBlockchain0 code
  192. tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
  193. blocks, err := tc.GenerateBlocks(til.SetBlockchainMinimumFlow0)
  194. require.NoError(t, err)
  195. config := Config{
  196. NLevels: 32,
  197. MaxFeeTx: 64,
  198. MaxTx: 512,
  199. MaxL1Tx: 16,
  200. ChainID: chainID,
  201. }
  202. tp := NewTxProcessor(sdb, config)
  203. log.Debug("block:0 batch:1, only L1CoordinatorTxs")
  204. _, err = tp.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  205. require.NoError(t, err)
  206. assert.Equal(t, "0", tp.s.MT.Root().BigInt().String())
  207. log.Debug("block:0 batch:2")
  208. l1UserTxs := []common.L1Tx{}
  209. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  210. _, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  211. require.NoError(t, err)
  212. assert.Equal(t, "0", tp.s.MT.Root().BigInt().String())
  213. log.Debug("block:0 batch:3")
  214. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
  215. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  216. _, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  217. require.NoError(t, err)
  218. checkBalance(t, tc, sdb, "A", 0, "500")
  219. assert.Equal(t, "13644148972047617726265275926674266298636745191961029124811988256139761111521", tp.s.MT.Root().BigInt().String())
  220. log.Debug("block:0 batch:4")
  221. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
  222. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[3].L2Txs)
  223. _, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[3].L1CoordinatorTxs, l2Txs)
  224. require.NoError(t, err)
  225. checkBalance(t, tc, sdb, "A", 0, "500")
  226. checkBalance(t, tc, sdb, "A", 1, "500")
  227. assert.Equal(t, "12433441613247342495680642890662773367605896324555599297255745922589338651261", tp.s.MT.Root().BigInt().String())
  228. log.Debug("block:0 batch:5")
  229. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
  230. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[4].L2Txs)
  231. _, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[4].L1CoordinatorTxs, l2Txs)
  232. require.NoError(t, err)
  233. checkBalance(t, tc, sdb, "A", 0, "500")
  234. checkBalance(t, tc, sdb, "A", 1, "500")
  235. assert.Equal(t, "12433441613247342495680642890662773367605896324555599297255745922589338651261", tp.s.MT.Root().BigInt().String())
  236. log.Debug("block:0 batch:6")
  237. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
  238. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[5].L2Txs)
  239. _, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[5].L1CoordinatorTxs, l2Txs)
  240. require.NoError(t, err)
  241. checkBalance(t, tc, sdb, "A", 0, "600")
  242. checkBalance(t, tc, sdb, "A", 1, "500")
  243. checkBalance(t, tc, sdb, "B", 0, "400")
  244. assert.Equal(t, "4191361650490017591061467288209836928064232431729236465872209988325272262963", tp.s.MT.Root().BigInt().String())
  245. coordIdxs := []common.Idx{261, 262}
  246. log.Debug("block:0 batch:7")
  247. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
  248. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[6].L2Txs)
  249. _, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
  250. require.NoError(t, err)
  251. checkBalance(t, tc, sdb, "Coord", 0, "10")
  252. checkBalance(t, tc, sdb, "Coord", 1, "20")
  253. checkBalance(t, tc, sdb, "A", 0, "600")
  254. checkBalance(t, tc, sdb, "A", 1, "280")
  255. checkBalance(t, tc, sdb, "B", 0, "290")
  256. checkBalance(t, tc, sdb, "B", 1, "200")
  257. checkBalance(t, tc, sdb, "C", 0, "100")
  258. checkBalance(t, tc, sdb, "D", 0, "800")
  259. assert.Equal(t, "7614010373759339299470010949167613050707822522530721724565424494781010548240", tp.s.MT.Root().BigInt().String())
  260. log.Debug("block:0 batch:8")
  261. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
  262. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[7].L2Txs)
  263. _, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
  264. require.NoError(t, err)
  265. checkBalance(t, tc, sdb, "Coord", 0, "35")
  266. checkBalance(t, tc, sdb, "Coord", 1, "30")
  267. checkBalance(t, tc, sdb, "A", 0, "430")
  268. checkBalance(t, tc, sdb, "A", 1, "280")
  269. checkBalance(t, tc, sdb, "B", 0, "390")
  270. checkBalance(t, tc, sdb, "B", 1, "90")
  271. checkBalance(t, tc, sdb, "C", 0, "45")
  272. checkBalance(t, tc, sdb, "C", 1, "100")
  273. checkBalance(t, tc, sdb, "D", 0, "800")
  274. assert.Equal(t, "21231789250434471575486264439945776732824482207853465397552873521865656677689", tp.s.MT.Root().BigInt().String())
  275. coordIdxs = []common.Idx{262}
  276. log.Debug("block:1 batch:1")
  277. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
  278. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
  279. _, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  280. require.NoError(t, err)
  281. checkBalance(t, tc, sdb, "Coord", 0, "75")
  282. checkBalance(t, tc, sdb, "Coord", 1, "30")
  283. checkBalance(t, tc, sdb, "A", 0, "730")
  284. checkBalance(t, tc, sdb, "A", 1, "280")
  285. checkBalance(t, tc, sdb, "B", 0, "380")
  286. checkBalance(t, tc, sdb, "B", 1, "90")
  287. checkBalance(t, tc, sdb, "C", 0, "845")
  288. checkBalance(t, tc, sdb, "C", 1, "100")
  289. checkBalance(t, tc, sdb, "D", 0, "470")
  290. assert.Equal(t, "11289313644810782435120113035387729451095637380468777086895109386127538554246", tp.s.MT.Root().BigInt().String())
  291. coordIdxs = []common.Idx{}
  292. log.Debug("block:1 batch:2")
  293. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
  294. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
  295. _, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  296. require.NoError(t, err)
  297. assert.Equal(t, "10342681351319338354912862547249967104198317571995055517008223832276478908482", tp.s.MT.Root().BigInt().String())
  298. // use Set of PoolL2 txs
  299. poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPoolL2MinimumFlow1)
  300. assert.NoError(t, err)
  301. _, err = tp.ProcessTxs(coordIdxs, []common.L1Tx{}, []common.L1Tx{}, poolL2Txs)
  302. require.NoError(t, err)
  303. checkBalance(t, tc, sdb, "Coord", 0, "75")
  304. checkBalance(t, tc, sdb, "Coord", 1, "30")
  305. checkBalance(t, tc, sdb, "A", 0, "510")
  306. checkBalance(t, tc, sdb, "A", 1, "170")
  307. checkBalance(t, tc, sdb, "B", 0, "480")
  308. checkBalance(t, tc, sdb, "B", 1, "190")
  309. checkBalance(t, tc, sdb, "C", 0, "845")
  310. checkBalance(t, tc, sdb, "C", 1, "100")
  311. checkBalance(t, tc, sdb, "D", 0, "360")
  312. checkBalance(t, tc, sdb, "F", 0, "100")
  313. }
  314. func TestProcessTxsSynchronizer(t *testing.T) {
  315. dir, err := ioutil.TempDir("", "tmpdb")
  316. require.NoError(t, err)
  317. defer assert.NoError(t, os.RemoveAll(dir))
  318. sdb, err := statedb.NewStateDB(dir, 128, statedb.TypeSynchronizer, 32)
  319. assert.NoError(t, err)
  320. chainID := uint16(0)
  321. // generate test transactions from test.SetBlockchain0 code
  322. tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
  323. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  324. require.NoError(t, err)
  325. assert.Equal(t, 31, len(blocks[0].Rollup.L1UserTxs))
  326. assert.Equal(t, 4, len(blocks[0].Rollup.Batches[0].L1CoordinatorTxs))
  327. assert.Equal(t, 0, len(blocks[0].Rollup.Batches[1].L1CoordinatorTxs))
  328. assert.Equal(t, 22, len(blocks[0].Rollup.Batches[2].L2Txs))
  329. assert.Equal(t, 1, len(blocks[1].Rollup.Batches[0].L1CoordinatorTxs))
  330. assert.Equal(t, 62, len(blocks[1].Rollup.Batches[0].L2Txs))
  331. assert.Equal(t, 1, len(blocks[1].Rollup.Batches[1].L1CoordinatorTxs))
  332. assert.Equal(t, 8, len(blocks[1].Rollup.Batches[1].L2Txs))
  333. // Coordinator Idx where to send the fees
  334. coordIdxs := []common.Idx{256, 257, 258, 259}
  335. // Idx of user 'A'
  336. idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
  337. config := Config{
  338. NLevels: 32,
  339. MaxFeeTx: 64,
  340. MaxTx: 512,
  341. MaxL1Tx: 32,
  342. ChainID: chainID,
  343. }
  344. tp := NewTxProcessor(sdb, config)
  345. // Process the 1st batch, which contains the L1CoordinatorTxs necessary
  346. // to create the Coordinator accounts to receive the fees
  347. log.Debug("block:0 batch:1, only L1CoordinatorTxs")
  348. ptOut, err := tp.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  349. require.NoError(t, err)
  350. assert.Equal(t, 4, len(ptOut.CreatedAccounts))
  351. assert.Equal(t, 0, len(ptOut.CollectedFees))
  352. log.Debug("block:0 batch:2")
  353. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  354. ptOut, err = tp.ProcessTxs(coordIdxs, blocks[0].Rollup.L1UserTxs,
  355. blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  356. require.NoError(t, err)
  357. assert.Equal(t, 0, len(ptOut.ExitInfos))
  358. assert.Equal(t, 31, len(ptOut.CreatedAccounts))
  359. assert.Equal(t, 4, len(ptOut.CollectedFees))
  360. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  361. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
  362. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  363. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  364. acc, err := sdb.GetAccount(idxA1)
  365. require.NoError(t, err)
  366. assert.Equal(t, "50", acc.Balance.String())
  367. log.Debug("block:0 batch:3")
  368. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  369. ptOut, err = tp.ProcessTxs(coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  370. require.NoError(t, err)
  371. assert.Equal(t, 0, len(ptOut.ExitInfos))
  372. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  373. assert.Equal(t, 4, len(ptOut.CollectedFees))
  374. assert.Equal(t, "2", ptOut.CollectedFees[common.TokenID(0)].String())
  375. assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
  376. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  377. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  378. acc, err = sdb.GetAccount(idxA1)
  379. require.NoError(t, err)
  380. assert.Equal(t, "35", acc.Balance.String())
  381. log.Debug("block:1 batch:1")
  382. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
  383. // before processing expect l2Txs[0:2].Nonce==0
  384. assert.Equal(t, common.Nonce(0), l2Txs[0].Nonce)
  385. assert.Equal(t, common.Nonce(0), l2Txs[1].Nonce)
  386. assert.Equal(t, common.Nonce(0), l2Txs[2].Nonce)
  387. ptOut, err = tp.ProcessTxs(coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  388. require.NoError(t, err)
  389. // after processing expect l2Txs[0:2].Nonce!=0 and has expected value
  390. assert.Equal(t, common.Nonce(5), l2Txs[0].Nonce)
  391. assert.Equal(t, common.Nonce(6), l2Txs[1].Nonce)
  392. assert.Equal(t, common.Nonce(7), l2Txs[2].Nonce)
  393. assert.Equal(t, 4, len(ptOut.ExitInfos)) // the 'ForceExit(1)' is not computed yet, as the batch is without L1UserTxs
  394. assert.Equal(t, 1, len(ptOut.CreatedAccounts))
  395. assert.Equal(t, 4, len(ptOut.CollectedFees))
  396. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  397. assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
  398. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  399. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  400. acc, err = sdb.GetAccount(idxA1)
  401. require.NoError(t, err)
  402. assert.Equal(t, "57", acc.Balance.String())
  403. log.Debug("block:1 batch:2")
  404. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
  405. ptOut, err = tp.ProcessTxs(coordIdxs, blocks[1].Rollup.L1UserTxs,
  406. blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  407. require.NoError(t, err)
  408. assert.Equal(t, 2, len(ptOut.ExitInfos)) // 2, as previous batch was without L1UserTxs, and has pending the 'ForceExit(1) A: 5'
  409. assert.Equal(t, 1, len(ptOut.CreatedAccounts))
  410. assert.Equal(t, 4, len(ptOut.CollectedFees))
  411. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  412. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
  413. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  414. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  415. acc, err = sdb.GetAccount(idxA1)
  416. assert.NoError(t, err)
  417. assert.Equal(t, "77", acc.Balance.String())
  418. idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
  419. acc, err = sdb.GetAccount(idxB0)
  420. require.NoError(t, err)
  421. assert.Equal(t, "51", acc.Balance.String())
  422. // get balance of Coordinator account for TokenID==0
  423. acc, err = sdb.GetAccount(common.Idx(256))
  424. require.NoError(t, err)
  425. assert.Equal(t, "2", acc.Balance.String())
  426. }
  427. func TestProcessTxsBatchBuilder(t *testing.T) {
  428. dir, err := ioutil.TempDir("", "tmpdb")
  429. require.NoError(t, err)
  430. defer assert.NoError(t, os.RemoveAll(dir))
  431. sdb, err := statedb.NewStateDB(dir, 128, statedb.TypeBatchBuilder, 32)
  432. assert.NoError(t, err)
  433. chainID := uint16(0)
  434. // generate test transactions from test.SetBlockchain0 code
  435. tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
  436. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  437. require.NoError(t, err)
  438. // Coordinator Idx where to send the fees
  439. coordIdxs := []common.Idx{256, 257, 258, 259}
  440. // Idx of user 'A'
  441. idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
  442. config := Config{
  443. NLevels: 32,
  444. MaxFeeTx: 64,
  445. MaxTx: 512,
  446. MaxL1Tx: 32,
  447. ChainID: chainID,
  448. }
  449. tp := NewTxProcessor(sdb, config)
  450. // Process the 1st batch, which contains the L1CoordinatorTxs necessary
  451. // to create the Coordinator accounts to receive the fees
  452. log.Debug("block:0 batch:1, only L1CoordinatorTxs")
  453. ptOut, err := tp.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  454. require.NoError(t, err)
  455. // expect 0 at CreatedAccount, as is only computed when StateDB.Type==TypeSynchronizer
  456. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  457. log.Debug("block:0 batch:2")
  458. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  459. ptOut, err = tp.ProcessTxs(coordIdxs, blocks[0].Rollup.L1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  460. require.NoError(t, err)
  461. assert.Equal(t, 0, len(ptOut.ExitInfos))
  462. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  463. acc, err := sdb.GetAccount(idxA1)
  464. require.NoError(t, err)
  465. assert.Equal(t, "50", acc.Balance.String())
  466. log.Debug("block:0 batch:3")
  467. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  468. ptOut, err = tp.ProcessTxs(coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  469. require.NoError(t, err)
  470. assert.Equal(t, 0, len(ptOut.ExitInfos))
  471. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  472. acc, err = sdb.GetAccount(idxA1)
  473. require.NoError(t, err)
  474. assert.Equal(t, "35", acc.Balance.String())
  475. log.Debug("block:1 batch:1")
  476. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
  477. _, err = tp.ProcessTxs(coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  478. require.NoError(t, err)
  479. acc, err = sdb.GetAccount(idxA1)
  480. require.NoError(t, err)
  481. assert.Equal(t, "57", acc.Balance.String())
  482. log.Debug("block:1 batch:2")
  483. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
  484. _, err = tp.ProcessTxs(coordIdxs, blocks[1].Rollup.L1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  485. require.NoError(t, err)
  486. acc, err = sdb.GetAccount(idxA1)
  487. assert.NoError(t, err)
  488. assert.Equal(t, "77", acc.Balance.String())
  489. idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
  490. acc, err = sdb.GetAccount(idxB0)
  491. require.NoError(t, err)
  492. assert.Equal(t, "51", acc.Balance.String())
  493. // get balance of Coordinator account for TokenID==0
  494. acc, err = sdb.GetAccount(common.Idx(256))
  495. require.NoError(t, err)
  496. assert.Equal(t, common.TokenID(0), acc.TokenID)
  497. assert.Equal(t, "2", acc.Balance.String())
  498. acc, err = sdb.GetAccount(common.Idx(257))
  499. require.NoError(t, err)
  500. assert.Equal(t, common.TokenID(1), acc.TokenID)
  501. assert.Equal(t, "2", acc.Balance.String())
  502. assert.Equal(t, "18894163991492573893706613133132363559300580460789469708968288074813925659539", sdb.MT.Root().BigInt().String())
  503. }
  504. func TestProcessTxsRootTestVectors(t *testing.T) {
  505. dir, err := ioutil.TempDir("", "tmpdb")
  506. require.NoError(t, err)
  507. defer assert.NoError(t, os.RemoveAll(dir))
  508. sdb, err := statedb.NewStateDB(dir, 128, statedb.TypeBatchBuilder, 32)
  509. assert.NoError(t, err)
  510. // same values than in the js test
  511. bjj0, err := common.BJJFromStringWithChecksum("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
  512. assert.NoError(t, err)
  513. l1Txs := []common.L1Tx{
  514. {
  515. FromIdx: 0,
  516. DepositAmount: big.NewInt(16000000),
  517. Amount: big.NewInt(0),
  518. TokenID: 1,
  519. FromBJJ: bjj0,
  520. FromEthAddr: ethCommon.HexToAddress("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"),
  521. ToIdx: 0,
  522. Type: common.TxTypeCreateAccountDeposit,
  523. UserOrigin: true,
  524. },
  525. }
  526. l2Txs := []common.PoolL2Tx{
  527. {
  528. FromIdx: 256,
  529. ToIdx: 256,
  530. TokenID: 1,
  531. Amount: big.NewInt(1000),
  532. Nonce: 0,
  533. Fee: 126,
  534. Type: common.TxTypeTransfer,
  535. },
  536. }
  537. chainID := uint16(0)
  538. config := Config{
  539. NLevels: 32,
  540. MaxFeeTx: 8,
  541. MaxTx: 32,
  542. MaxL1Tx: 16,
  543. ChainID: chainID,
  544. }
  545. tp := NewTxProcessor(sdb, config)
  546. _, err = tp.ProcessTxs(nil, l1Txs, nil, l2Txs)
  547. require.NoError(t, err)
  548. assert.Equal(t, "9827704113668630072730115158977131501210702363656902211840117643154933433410", sdb.MT.Root().BigInt().String())
  549. }
  550. func TestCreateAccountDepositMaxValue(t *testing.T) {
  551. dir, err := ioutil.TempDir("", "tmpdb")
  552. require.NoError(t, err)
  553. defer assert.NoError(t, os.RemoveAll(dir))
  554. nLevels := 16
  555. sdb, err := statedb.NewStateDB(dir, 128, statedb.TypeBatchBuilder, nLevels)
  556. assert.NoError(t, err)
  557. users := generateJsUsers(t)
  558. daMaxHex, err := hex.DecodeString("FFFF")
  559. require.NoError(t, err)
  560. daMaxF16 := common.Float16(binary.BigEndian.Uint16(daMaxHex))
  561. daMaxBI := daMaxF16.BigInt()
  562. assert.Equal(t, "10235000000000000000000000000000000", daMaxBI.String())
  563. daMax1Hex, err := hex.DecodeString("FFFE")
  564. require.NoError(t, err)
  565. daMax1F16 := common.Float16(binary.BigEndian.Uint16(daMax1Hex))
  566. daMax1BI := daMax1F16.BigInt()
  567. assert.Equal(t, "10225000000000000000000000000000000", daMax1BI.String())
  568. l1Txs := []common.L1Tx{
  569. {
  570. FromIdx: 0,
  571. DepositAmount: daMaxBI,
  572. Amount: big.NewInt(0),
  573. TokenID: 1,
  574. FromBJJ: users[0].BJJ.Public().Compress(),
  575. FromEthAddr: users[0].Addr,
  576. ToIdx: 0,
  577. Type: common.TxTypeCreateAccountDeposit,
  578. UserOrigin: true,
  579. },
  580. {
  581. FromIdx: 0,
  582. DepositAmount: daMax1BI,
  583. Amount: big.NewInt(0),
  584. TokenID: 1,
  585. FromBJJ: users[1].BJJ.Public().Compress(),
  586. FromEthAddr: users[1].Addr,
  587. ToIdx: 0,
  588. Type: common.TxTypeCreateAccountDeposit,
  589. UserOrigin: true,
  590. },
  591. }
  592. chainID := uint16(0)
  593. config := Config{
  594. NLevels: uint32(nLevels),
  595. MaxTx: 3,
  596. MaxL1Tx: 2,
  597. MaxFeeTx: 2,
  598. ChainID: chainID,
  599. }
  600. tp := NewTxProcessor(sdb, config)
  601. _, err = tp.ProcessTxs(nil, l1Txs, nil, nil)
  602. require.NoError(t, err)
  603. // check balances
  604. acc, err := sdb.GetAccount(common.Idx(256))
  605. require.NoError(t, err)
  606. assert.Equal(t, daMaxBI, acc.Balance)
  607. acc, err = sdb.GetAccount(common.Idx(257))
  608. require.NoError(t, err)
  609. assert.Equal(t, daMax1BI, acc.Balance)
  610. }